// Load the sample assets.
void D3D12Fullscreen::LoadAssets()
{
    // Create an empty root signature.
    {
        CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
        rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

        ComPtr<ID3DBlob> signature;
        ComPtr<ID3DBlob> error;
        ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
        ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
        NAME_D3D12_OBJECT(m_rootSignature);
    }

    // Create the pipeline state, which includes compiling and loading shaders.
    {
        ComPtr<ID3DBlob> vertexShader;
        ComPtr<ID3DBlob> pixelShader;
        ComPtr<ID3DBlob> error;

#if defined(_DEBUG)
        // Enable better shader debugging with the graphics debugging tools.
        UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
        UINT compileFlags = 0;
#endif

        ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, &error));
        ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, &error));

        // Define the vertex input layout.
        D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
            { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
        };

        // Describe and create the graphics pipeline state object (PSO).
        D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
        psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
        psoDesc.pRootSignature = m_rootSignature.Get();
        psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get());
        psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get());
        psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
        psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
        psoDesc.DepthStencilState.DepthEnable = FALSE;
        psoDesc.DepthStencilState.StencilEnable = FALSE;
        psoDesc.SampleMask = UINT_MAX;
        psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
        psoDesc.NumRenderTargets = 1;
        psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
        psoDesc.SampleDesc.Count = 1;

        ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));
        NAME_D3D12_OBJECT(m_pipelineState);
    }

    // Create the command list.
    ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList)));
    NAME_D3D12_OBJECT(m_commandList);

    LoadSizeDependentResources();

    // Close the command list and execute it to begin the vertex buffer copy into
    // the default heap.
    ThrowIfFailed(m_commandList->Close());
    ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
    m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

    // Create synchronization objects and wait until assets have been uploaded to the GPU.
    {
        ThrowIfFailed(m_device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
        m_fenceValues[m_frameIndex]++;

        // Create an event handle to use for frame synchronization.
        m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
        if (m_fenceEvent == nullptr)
        {
            ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
        }

        // Wait for the command list to execute; we are reusing the same command
        // list in our main loop but for now, we just want to wait for setup to
        // complete before continuing.
        WaitForGpu();
    }
}
// Load the rendering pipeline dependencies.
void D3D12PredicationQueries::LoadPipeline()
{
#if defined(_DEBUG)
	// Enable the D3D12 debug layer.
	{
		ComPtr<ID3D12Debug> debugController;
		if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
		{
			debugController->EnableDebugLayer();
		}
	}
#endif

	ComPtr<IDXGIFactory4> factory;
	ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

	if (m_useWarpDevice)
	{
		ComPtr<IDXGIAdapter> warpAdapter;
		ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

		ThrowIfFailed(D3D12CreateDevice(
			warpAdapter.Get(),
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_device)
			));
	}
	else
	{
		ComPtr<IDXGIAdapter1> hardwareAdapter;
		GetHardwareAdapter(factory.Get(), &hardwareAdapter);

		ThrowIfFailed(D3D12CreateDevice(
			hardwareAdapter.Get(),
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_device)
			));
	}

	// Describe and create the command queue.
	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

	ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
	NAME_D3D12_OBJECT(m_commandQueue);

	// Describe and create the swap chain.
	DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
	swapChainDesc.BufferCount = FrameCount;
	swapChainDesc.Width = m_width;
	swapChainDesc.Height = m_height;
	swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	swapChainDesc.SampleDesc.Count = 1;

	ComPtr<IDXGISwapChain1> swapChain;
	ThrowIfFailed(factory->CreateSwapChainForCoreWindow(
		m_commandQueue.Get(),		// Swap chain needs the queue so that it can force a flush on it.
		reinterpret_cast<IUnknown*>(Windows::UI::Core::CoreWindow::GetForCurrentThread()),
		&swapChainDesc,
		nullptr,
		&swapChain
		));

	ThrowIfFailed(swapChain.As(&m_swapChain));
	m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

	// Create descriptor heaps.
	{
		// Describe and create a render target view (RTV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
		rtvHeapDesc.NumDescriptors = FrameCount;
		rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
		rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

		// Describe and create a depth stencil view (DSV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
		dsvHeapDesc.NumDescriptors = 1;
		dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
		dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));

		// Describe and create a constant buffer view (CBV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC cbvHeapDesc = {};
		cbvHeapDesc.NumDescriptors = CbvCountPerFrame * FrameCount;
		cbvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
		cbvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&cbvHeapDesc, IID_PPV_ARGS(&m_cbvHeap)));
		NAME_D3D12_OBJECT(m_cbvHeap);

		// Describe and create a heap for occlusion queries.
		D3D12_QUERY_HEAP_DESC queryHeapDesc = {};
		queryHeapDesc.Count = 1;
		queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
		ThrowIfFailed(m_device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_queryHeap)));

		m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
		m_cbvSrvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
	}

	// Create frame resources.
	{
		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());

		// Create a RTV and a command allocator for each frame.
		for (UINT n = 0; n < FrameCount; n++)
		{
			ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
			m_device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);
			rtvHandle.Offset(1, m_rtvDescriptorSize);

			NAME_D3D12_OBJECT_INDEXED(m_renderTargets, n);

			ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
		}
	}
}
Example #3
0
/// <summary>
/// Get image .NET runtime version
/// </summary>
/// <returns>runtime version, "n/a" if nothing found</returns>
std::wstring ImageNET::GetImageRuntimeVer( const wchar_t* ImagePath )
{
    std::wstring LatestVersion = L"n/a";

    CComPtr<ICLRMetaHost> MetaHost;
    
    // Check if .NET 4 or higher is present
    auto clrCreate = reinterpret_cast<fnCLRCreateInstancen>(
        GetProcAddress( LoadLibraryW( L"mscoree.dll" ), "CLRCreateInstance" ));

    // Legacy runtime. Get exact required version
    if(!clrCreate)
    {
        wchar_t ver[64] = { 0 };
        DWORD bytes = 0;

        auto clrGetVer = reinterpret_cast<fnGetRequestedRuntimeVersion>(
            GetProcAddress( GetModuleHandleW( L"mscoree.dll" ), "GetRequestedRuntimeVersion" ));

        clrGetVer( const_cast<LPWSTR>(ImagePath), ver, 64, &bytes );

        FreeLibrary( GetModuleHandleW( L"mscoree.dll" ) );
        return ver;
    }
    // Get highest available
    else
    {
        if (FAILED( clrCreate( CLSID_CLRMetaHost, IID_ICLRMetaHost, reinterpret_cast<LPVOID*>(&MetaHost) ) ))
            return LatestVersion;

        CComPtr<IEnumUnknown> Runtimes;
        if (FAILED( MetaHost->EnumerateInstalledRuntimes( &Runtimes ) ))
            return LatestVersion;

        CComPtr<IUnknown> Runtime;
        CComPtr<ICLRRuntimeInfo> Latest;

        while (Runtimes->Next( 1, &Runtime, NULL ) == S_OK)
        {
            CComPtr<ICLRRuntimeInfo> Current;
            wchar_t tmpString[MAX_PATH];
            DWORD tmp = MAX_PATH * sizeof(wchar_t);

            if (SUCCEEDED( Runtime->QueryInterface( IID_PPV_ARGS( &Current ) ) ))
            {
                if (!Latest)
                {
                    if (SUCCEEDED( Current->QueryInterface( IID_PPV_ARGS( &Latest ) ) ))
                    {
                        Latest->GetVersionString( tmpString, &tmp );
                        LatestVersion = tmpString;
                    }
                }
                else
                {
                    if (SUCCEEDED( Current->GetVersionString( tmpString, &tmp ) ))
                    {
                        std::wstring CurrentVersion = tmpString;
                        if (CurrentVersion.compare( LatestVersion ) > 0)
                        {
                            LatestVersion = CurrentVersion;
                            Latest.Release();
                            Current->QueryInterface( IID_PPV_ARGS( &Latest ) );
                        }
                    }
                }
            }

            Runtime.Release();
        }

        return LatestVersion;
    }
    
}
// Writes a set of properties for all objects.
void WriteContentPropertiesBulk(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                                       hr                = S_OK;
    GUID                                          guidContext       = GUID_NULL;
    CSetBulkValuesCallback*                       pCallback         = NULL;
    CComPtr<IPortableDeviceProperties>            pProperties;
    CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
    CComPtr<IPortableDeviceValues>                pObjectProperties;
    CComPtr<IPortableDeviceContent>               pContent;
    CComPtr<IPortableDeviceValuesCollection>      pPropertiesToWrite;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    DWORD                                         cObjectIDs        = 0;


    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) Check to see if the driver supports BULK property operations by call QueryInterface
    // on the IPortableDeviceProperties interface for IPortableDevicePropertiesBulk
    if (SUCCEEDED(hr))
    {
        hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
        if (FAILED(hr))
        {
            printf("This driver does not support BULK property operations.\n");
        }
    }

    // 4) CoCreate an IPortableDeviceValuesCollection interface to hold the the properties
    // we wish to write.
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_PPV_ARGS(&pPropertiesToWrite));
        if (FAILED(hr))
        {
            printf("! Failed to CoCreate IPortableDeviceValuesCollection for bulk property values, hr = 0x%lx\n", hr);
        }
    }

    // 6) Create an instance of the IPortableDevicePropertiesBulkCallback object.
    if (SUCCEEDED(hr))
    {
        pCallback = new (std::nothrow) CSetBulkValuesCallback();
        if (pCallback == NULL)
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to allocate CSetBulkValuesCallback, hr = 0x%lx\n", hr);
        }
    }

    // 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
    // to enumerate and create an IPortableDevicePropVariantCollection with the object
    // identifiers needed to perform the bulk operation on.
    if (SUCCEEDED(hr))
    {
        hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pContent,
                                                                        &pObjectIDs);
    }

    if (SUCCEEDED(hr))
    {
        hr = pObjectIDs->GetCount(&cObjectIDs);
        if (FAILED(hr))
        {
            printf("! Failed to get number of objectIDs from IPortableDevicePropVariantCollection, hr = 0x%lx\n", hr);
        }
    }

    // 8) Iterate through object list and add appropriate IPortableDeviceValues to collection
    if (SUCCEEDED(hr))
    {
        for(DWORD dwIndex = 0; (dwIndex < cObjectIDs) && (hr == S_OK); dwIndex++)
        {
            CComPtr<IPortableDeviceValues>  pValues;
            PROPVARIANT                     pv = {0};

            PropVariantInit(&pv);
            hr = CoCreateInstance(CLSID_PortableDeviceValues,
                                  NULL,
                                  CLSCTX_INPROC_SERVER,
                                  IID_PPV_ARGS(&pValues));
            if (FAILED(hr))
            {
                printf("! Failed to CoCreate CLSID_PortableDeviceValues, hr = 0x%lx\n", hr);
            }

            // Get the Object ID whose properties we will set
            if (hr == S_OK)
            {
                hr = pObjectIDs->GetAt(dwIndex, &pv);
                if (FAILED(hr))
                {
                    printf("! Failed to get next Object ID from list, hr = 0x%lx\n", hr);
                }
            }

            // Save them into the IPortableDeviceValues so the driver knows which object this proeprty set belongs to
            if (hr == S_OK)
            {
                hr = pValues->SetStringValue(WPD_OBJECT_ID, pv.pwszVal);
                if (FAILED(hr))
                {
                    printf("! Failed to set WPD_OBJECT_ID, hr = 0x%lx\n", hr);
                }
            }

            // Set the new values.  In this sample, we attempt to set the name property.
            if (hr == S_OK)
            {
                CAtlStringW strValue;
                strValue.Format(L"NewName%d", dwIndex);

                hr = pValues->SetStringValue(WPD_OBJECT_NAME, strValue.GetString());
                if (FAILED(hr))
                {
                    printf("! Failed to set WPD_OBJECT_NAME, hr = 0x%lx\n", hr);
                }
            }

            // Add this property set to the collection
            if (hr == S_OK)
            {
                hr = pPropertiesToWrite->Add(pValues);
                if (FAILED(hr))
                {
                    printf("! Failed to add values to collection, hr = 0x%lx\n", hr);
                }
            }
            PropVariantClear(&pv);
        }
    }

    // 9) Call QueueSetValuesByObjectList to initialize the Asynchronous
    // property operation.
    if (SUCCEEDED(hr))
    {
        hr = pPropertiesBulk->QueueSetValuesByObjectList(pPropertiesToWrite,
                                                         pCallback,
                                                         &guidContext);
        // 10) Call Start() to actually being the property operation
        if(SUCCEEDED(hr))
        {
            // Cleanup any previously created global event handles.
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                CloseHandle(g_hBulkPropertyOperationEvent);
                g_hBulkPropertyOperationEvent = NULL;
            }

            // In order to create a simpler to follow example we create and wait infinitly
            // for the bulk property operation to complete and ignore any errors.
            // Production code should be written in a more robust manner.
            // Create the global event handle to wait on for the bulk operation
            // to complete.
            g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                // Call Start() to actually being the Asynchronous bulk operation.
                hr = pPropertiesBulk->Start(guidContext);
                if(FAILED(hr))
                {
                    printf("! Failed to start property operation, hr = 0x%lx\n", hr);
                }
            }
            else
            {
                printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
            }
        }
        else
        {
            printf("! QueueSetValuesByObjectList Failed, hr = 0x%lx\n", hr);
        }
    }

    // In order to create a simpler to follow example we will wait infinitly for the operation
    // to complete and ignore any errors.  Production code should be written in a more
    // robust manner.
    if (SUCCEEDED(hr))
    {
        if (g_hBulkPropertyOperationEvent != NULL)
        {
            WaitForSingleObject(g_hBulkPropertyOperationEvent, INFINITE);
        }
    }

    if (pCallback != NULL)
    {
        pCallback->Release();
        pCallback = NULL;
    }

    // Cleanup any created global event handles before exiting..
    if (g_hBulkPropertyOperationEvent != NULL)
    {
        CloseHandle(g_hBulkPropertyOperationEvent);
        g_hBulkPropertyOperationEvent = NULL;
    }
}
Example #5
0
			/// <summary>
			/// Called when an asynchronous operation is completed.
			/// </summary>
			/// <param name="pAsyncResult">Pointer to the IMFAsyncResult interface. Pass this pointer to the asynchronous End... method to complete the asynchronous call.</param>
			/// <returns>The result of the operation.</returns>
			HRESULT ReadByteAsyncCallback::Invoke(IMFAsyncResult* pAsyncResult)
			{
				// Enter critical section.
				EnterCriticalSection(&_critsec);
				HRESULT hr = S_OK;

				ULONG pcbRead;
				IUnknown *pState = NULL;
				IUnknown *pUnk = NULL;
				IMFAsyncResult *pCallerResult = NULL;
				ReadByteContainer *pReader = NULL;

				// Get the asynchronous result object for the application callback. 
				hr = pAsyncResult->GetState(&pState);
				if (FAILED(hr))
				{
					goto done;
				}

				// Get the caller result interface.
				hr = pState->QueryInterface(IID_PPV_ARGS(&pCallerResult));
				if (FAILED(hr))
				{
					goto done;
				}

				// Get the object that holds the state information for the asynchronous method.
				hr = pCallerResult->GetObject(&pUnk);
				if (FAILED(hr))
				{
					goto done;
				}

				// Get the reader byte container.
				pReader = static_cast<ReadByteContainer*>(pUnk);

				// Write the bytes.
				_byteStream->Read(pReader->_pb, pReader->_cb, &pcbRead);

				// Assign the number of bytes writen.
				pReader->_pcbRead = pcbRead;

			done:
				// Set the result.
				// Signal the application.
				if (pCallerResult)
				{
					pCallerResult->SetStatus(hr);
					MFInvokeCallback(pCallerResult);
				}

				// Clean-up.
				SafeRelease(&pState);
				SafeRelease(&pUnk);
				SafeRelease(&pCallerResult);

				// Leave critical section.
				LeaveCriticalSection(&_critsec);

				// Return the result.
				return hr;
			}
void DirectShowMetaDataControl::updateMetadata(IFilterGraph2 *graph, IBaseFilter *source, const QString &fileSrc)
{
    m_metadata.clear();

#ifndef QT_NO_SHELLITEM
    if (!sHCreateItemFromParsingName) {
        QSystemLibrary lib(QStringLiteral("shell32"));
        sHCreateItemFromParsingName = (q_SHCreateItemFromParsingName)(lib.resolve("SHCreateItemFromParsingName"));
    }

    if (!fileSrc.isEmpty() && sHCreateItemFromParsingName) {
        IShellItem2* shellItem = 0;
        if (sHCreateItemFromParsingName(reinterpret_cast<const WCHAR*>(fileSrc.utf16()),
                                        0, IID_PPV_ARGS(&shellItem)) == S_OK) {

            IPropertyStore *pStore = 0;
            if (shellItem->GetPropertyStore(GPS_DEFAULT, IID_PPV_ARGS(&pStore)) == S_OK) {
                DWORD cProps;
                if (SUCCEEDED(pStore->GetCount(&cProps))) {
                    for (DWORD i = 0; i < cProps; ++i)
                    {
                        PROPERTYKEY key;
                        PROPVARIANT var;
                        PropVariantInit(&var);
                        if (FAILED(pStore->GetAt(i, &key)))
                            continue;
                        if (FAILED(pStore->GetValue(key, &var)))
                            continue;

                        if (IsEqualPropertyKey(key, PKEY_Author)) {
                            m_metadata.insert(QMediaMetaData::Author, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Title)) {
                            m_metadata.insert(QMediaMetaData::Title, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_SubTitle)) {
                            m_metadata.insert(QMediaMetaData::SubTitle, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_ParentalRating)) {
                            m_metadata.insert(QMediaMetaData::ParentalRating, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Comment)) {
                            m_metadata.insert(QMediaMetaData::Description, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Copyright)) {
                            m_metadata.insert(QMediaMetaData::Copyright, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_ProviderStyle)) {
                            m_metadata.insert(QMediaMetaData::Genre, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_Year)) {
                            m_metadata.insert(QMediaMetaData::Year, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_DateEncoded)) {
                            m_metadata.insert(QMediaMetaData::Date, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Rating)) {
                            m_metadata.insert(QMediaMetaData::UserRating,
                                              int((convertValue(var).toUInt() - 1) / qreal(98) * 100));
                        } else if (IsEqualPropertyKey(key, PKEY_Keywords)) {
                            m_metadata.insert(QMediaMetaData::Keywords, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Language)) {
                            m_metadata.insert(QMediaMetaData::Language, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_Publisher)) {
                            m_metadata.insert(QMediaMetaData::Publisher, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_Duration)) {
                            m_metadata.insert(QMediaMetaData::Duration,
                                              (convertValue(var).toLongLong() + 10000) / 10000);
                        } else if (IsEqualPropertyKey(key, PKEY_Audio_EncodingBitrate)) {
                            m_metadata.insert(QMediaMetaData::AudioBitRate, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_AverageLevel)) {
                            m_metadata.insert(QMediaMetaData::AverageLevel, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Audio_ChannelCount)) {
                            m_metadata.insert(QMediaMetaData::ChannelCount, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Audio_PeakValue)) {
                            m_metadata.insert(QMediaMetaData::PeakValue, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Audio_SampleRate)) {
                            m_metadata.insert(QMediaMetaData::SampleRate, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_AlbumTitle)) {
                            m_metadata.insert(QMediaMetaData::AlbumTitle, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_AlbumArtist)) {
                            m_metadata.insert(QMediaMetaData::AlbumArtist, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Artist)) {
                            m_metadata.insert(QMediaMetaData::ContributingArtist, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Composer)) {
                            m_metadata.insert(QMediaMetaData::Composer, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Conductor)) {
                            m_metadata.insert(QMediaMetaData::Conductor, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Lyrics)) {
                            m_metadata.insert(QMediaMetaData::Lyrics, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Mood)) {
                            m_metadata.insert(QMediaMetaData::Mood, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_TrackNumber)) {
                            m_metadata.insert(QMediaMetaData::TrackNumber, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Music_Genre)) {
                            m_metadata.insert(QMediaMetaData::Genre, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_ThumbnailStream)) {
                            m_metadata.insert(QMediaMetaData::ThumbnailImage, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Video_FrameHeight)) {
                            QSize res;
                            res.setHeight(convertValue(var).toUInt());
                            if (SUCCEEDED(pStore->GetValue(PKEY_Video_FrameWidth, &var)))
                                res.setWidth(convertValue(var).toUInt());
                            m_metadata.insert(QMediaMetaData::Resolution, res);
                        } else if (IsEqualPropertyKey(key, PKEY_Video_HorizontalAspectRatio)) {
                            QSize aspectRatio;
                            aspectRatio.setWidth(convertValue(var).toUInt());
                            if (SUCCEEDED(pStore->GetValue(PKEY_Video_VerticalAspectRatio, &var)))
                                aspectRatio.setHeight(convertValue(var).toUInt());
                            m_metadata.insert(QMediaMetaData::PixelAspectRatio, aspectRatio);
                        } else if (IsEqualPropertyKey(key, PKEY_Video_FrameRate)) {
                            m_metadata.insert(QMediaMetaData::VideoFrameRate,
                                              convertValue(var).toReal() / 1000);
                        } else if (IsEqualPropertyKey(key, PKEY_Video_EncodingBitrate)) {
                            m_metadata.insert(QMediaMetaData::VideoBitRate, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Video_Director)) {
                            m_metadata.insert(QMediaMetaData::Director, convertValue(var));
                        } else if (IsEqualPropertyKey(key, PKEY_Media_Writer)) {
                            m_metadata.insert(QMediaMetaData::Writer, convertValue(var));
                        }

                        PropVariantClear(&var);
                    }
                }

                pStore->Release();
            }

            shellItem->Release();
        }
    }

    if (!m_metadata.isEmpty())
        goto send_event;
#endif

#ifndef QT_NO_WMSDK
    IWMHeaderInfo *info = com_cast<IWMHeaderInfo>(source, IID_IWMHeaderInfo);

    if (info) {
        Q_FOREACH (const QWMMetaDataKey &key, *qt_wmMetaDataKeys()) {
            QVariant var = getValue(info, key.wmName);
            if (var.isValid()) {
                if (key.qtName == QMediaMetaData::Duration) {
                    // duration is provided in 100-nanosecond units, convert to milliseconds
                    var = (var.toLongLong() + 10000) / 10000;
                } else if (key.qtName == QMediaMetaData::Resolution) {
                    QSize res;
                    res.setHeight(var.toUInt());
                    res.setWidth(getValue(info, L"WM/VideoWidth").toUInt());
                    var = res;
                } else if (key.qtName == QMediaMetaData::VideoFrameRate) {
                    var = var.toReal() / 1000.f;
                } else if (key.qtName == QMediaMetaData::PixelAspectRatio) {
                    QSize aspectRatio;
                    aspectRatio.setWidth(var.toUInt());
                    aspectRatio.setHeight(getValue(info, L"AspectRatioY").toUInt());
                    var = aspectRatio;
                } else if (key.qtName == QMediaMetaData::UserRating) {
                    var = (var.toUInt() - 1) / qreal(98) * 100;
                }

                m_metadata.insert(key.qtName, var);
            }
        }

        info->Release();
    }

    if (!m_metadata.isEmpty())
        goto send_event;
#endif
    {
        IAMMediaContent *content = 0;

        if ((!graph || graph->QueryInterface(
                 IID_IAMMediaContent, reinterpret_cast<void **>(&content)) != S_OK)
                && (!source || source->QueryInterface(
                        IID_IAMMediaContent, reinterpret_cast<void **>(&content)) != S_OK)) {
            content = 0;
        }

        if (content) {
            BSTR string = 0;

            if (content->get_AuthorName(&string) == S_OK)
                m_metadata.insert(QMediaMetaData::Author, convertBSTR(&string));

            if (content->get_Title(&string) == S_OK)
                m_metadata.insert(QMediaMetaData::Title, convertBSTR(&string));

            if (content->get_Description(&string) == S_OK)
                m_metadata.insert(QMediaMetaData::Description, convertBSTR(&string));

            if (content->get_Rating(&string) == S_OK)
                m_metadata.insert(QMediaMetaData::UserRating, convertBSTR(&string));

            if (content->get_Copyright(&string) == S_OK)
                m_metadata.insert(QMediaMetaData::Copyright, convertBSTR(&string));

            content->Release();
        }
    }

send_event:
    // DirectShowMediaPlayerService holds a lock at this point so defer emitting signals to a later
    // time.
    QCoreApplication::postEvent(this, new QEvent(QEvent::Type(MetaDataChanged)));
}
// Retreives the object identifier for the persistent unique identifer
void GetObjectIdentifierFromPersistentUniqueIdentifier(
    IPortableDevice* pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                                         hr                  = S_OK;
    WCHAR                                           szSelection[81]     = {0};
    CComPtr<IPortableDeviceContent>                 pContent;
    CComPtr<IPortableDevicePropVariantCollection>   pPersistentUniqueIDs;
    CComPtr<IPortableDevicePropVariantCollection>   pObjectIDs;
	//<SnippetContentProp7>
    // Prompt user to enter an unique identifier to convert to an object idenifier.
    printf("Enter the Persistant Unique Identifier of the object you wish to convert into an object identifier.\n>");
    hr = StringCbGetsW(szSelection,sizeof(szSelection));
    if (FAILED(hr))
    {
        printf("An invalid persistent object identifier was specified, aborting the query operation\n");
    }
	//</SnippetContentProp7>
    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
	//<SnippetContentProp8>
    if (SUCCEEDED(hr))
    {
        hr = pDevice->Content(&pContent);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }
	//</SnippetContentProp8>

    // 2) CoCreate an IPortableDevicePropVariantCollection interface to hold the the Unique Identifiers
    // to query for Object Identifiers.
    //
    // NOTE: This is a collection interface so more than 1 identifier can be requested at a time.
    //       This sample only requests a single unique identifier.
	//<SnippetContentProp9>
    hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_PPV_ARGS(&pPersistentUniqueIDs));
	//</SnippetContentProp9>
	//<SnippetContentProp10>
    if (SUCCEEDED(hr))
    {
        if (pPersistentUniqueIDs != NULL)
        {
            PROPVARIANT pv = {0};
            PropVariantInit(&pv);

            // Initialize a PROPVARIANT structure with the object identifier string
            // that the user selected above. Notice we are allocating memory for the
            // PWSTR value.  This memory will be freed when PropVariantClear() is
            // called below.
            pv.vt      = VT_LPWSTR;
            pv.pwszVal = AtlAllocTaskWideString(szSelection);
            if (pv.pwszVal != NULL)
            {
                // Add the object identifier to the objects-to-delete list
                // (We are only deleting 1 in this example)
                hr = pPersistentUniqueIDs->Add(&pv);
                if (SUCCEEDED(hr))
                {
                    // 3) Attempt to get the unique idenifier for the object from the device
                    hr = pContent->GetObjectIDsFromPersistentUniqueIDs(pPersistentUniqueIDs,
                                                                       &pObjectIDs);
                    if (SUCCEEDED(hr))
                    {
                        PROPVARIANT pvId = {0};
                        hr = pObjectIDs->GetAt(0, &pvId);
                        if (SUCCEEDED(hr))
                        {
                            printf("The persistent unique identifier '%ws' relates to object identifier '%ws' on the device.\n", szSelection, pvId.pwszVal);
                        }
                        else
                        {
                            printf("! Failed to get the object identifier for '%ws' from the IPortableDevicePropVariantCollection, hr = 0x%lx\n",szSelection, hr);
                        }

                        // Free the returned allocated string from the GetAt() call
                        PropVariantClear(&pvId);
                    }
                    else
                    {
                        printf("! Failed to get the object identifier from persistent object idenifier '%ws', hr = 0x%lx\n",szSelection, hr);
                    }
                }
                else
                {
                    printf("! Failed to get the object identifier from persistent object idenifier because we could no add the persistent object identifier string to the IPortableDevicePropVariantCollection, hr = 0x%lx\n",hr);
                }
            }
            else
            {
                hr = E_OUTOFMEMORY;
                printf("! Failed to get the object identifier because we could no allocate memory for the persistent object identifier string, hr = 0x%lx\n",hr);
            }

            // Free any allocated values in the PROPVARIANT before exiting
            PropVariantClear(&pv);
        }
    }
	//</SnippetContentProp10>
}
Example #8
0
CSaveThumbnailsDialog::CSaveThumbnailsDialog(
    int rows, int cols, int width, int quality, int levelPNG,
    LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
    LPCTSTR lpszFilter, CWnd* pParentWnd) :
    CFileDialog(FALSE, lpszDefExt, lpszFileName,
                OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST|OFN_NOCHANGEDIR,
                lpszFilter, pParentWnd)
    , m_rows(rows)
    , m_cols(cols)
    , m_width(width)
    , m_quality(quality)
    , m_levelPNG(levelPNG)
{
    if (IsWinVistaOrLater()) {

        IFileDialogCustomize* pfdc = GetIFileDialogCustomize();
        if (pfdc) {

            // Create an event handling object, and hook it up to the dialog.
            IFileDialogEvents *pfde = NULL;
            HRESULT hr = _CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
            if (SUCCEEDED(hr)) {
                // Hook up the event handler.
                DWORD dwCookie;
                hr = GetIFileSaveDialog()->Advise(pfde, &dwCookie);
                if (SUCCEEDED(hr)) {
                    ;
                }
            }

            CString str;

            pfdc->StartVisualGroup(IDS_THUMB_THUMBNAILS, ResStr(IDS_THUMB_THUMBNAILS));
            pfdc->AddText(IDS_THUMB_ROWNUMBER, ResStr(IDS_THUMB_ROWNUMBER));
            str.Format(L"%d", max(1, min(20, m_rows)));
            pfdc->AddEditBox(IDC_EDIT1, str);

            pfdc->AddText(IDS_THUMB_COLNUMBER, ResStr(IDS_THUMB_COLNUMBER));
            str.Format(L"%d", max(1, min(10, m_cols)));
            pfdc->AddEditBox(IDC_EDIT2, str);
            pfdc->EndVisualGroup();

            pfdc->StartVisualGroup(IDS_THUMB_IMAGE_WIDTH, ResStr(IDS_THUMB_IMAGE_WIDTH));
            pfdc->AddText(IDS_THUMB_PIXELS, ResStr(IDS_THUMB_PIXELS));
            str.Format(L"%d", max(256, min(2560, m_width)));
            pfdc->AddEditBox(IDC_EDIT3, str);
            pfdc->EndVisualGroup();

            pfdc->StartVisualGroup(IDS_THUMB_IMAGE_QUALITY, ResStr(IDS_THUMB_IMAGE_QUALITY));
            pfdc->AddText(IDS_THUMB_QUALITY, ResStr(IDS_THUMB_QUALITY));
            str.Format(L"%d", max(70, min(100, m_quality)));
            pfdc->AddEditBox(IDC_EDIT4, str);

            pfdc->AddText(IDS_THUMB_LEVEL, ResStr(IDS_THUMB_LEVEL));
            str.Format(L"%d", max(1, min(9, m_levelPNG)));
            pfdc->AddEditBox(IDC_EDIT5, str);
            pfdc->EndVisualGroup();

            pfdc->Release();
        }
    } else {
        SetTemplate(0, IDD_SAVETHUMBSDIALOGTEMPL);
    }
}
bool ResourceManager::LoadFile(ID2D1HwndRenderTarget* renderTarget, wchar_t * filename)
{
	HRESULT result;
	IWICImagingFactory2* wicFactory;
	IWICBitmapDecoder* wicDecoder;
	IWICBitmapFrameDecode* wicFrame;
	IWICBitmapFlipRotator* wicFlip;
	IWICFormatConverter *wicConverter;
	Sprite*	newSprite;

	// WIC의 각종 인터페이스를 사용하기 위한 factory 생성
	result = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&wicFactory));
	if (FAILED(result))
		return false;

	// 파일을 읽고 디코딩 하기 위한 decoder 생성
	result = wicFactory->CreateDecoderFromFilename(filename, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &wicDecoder);
	if (FAILED(result))
		return false;

	// decoder에서 프레임을 얻어옴, // 일반적인 이미지 파일은 single frame만을 지원하므로 0으로 고정
	result = wicDecoder->GetFrame(0, &wicFrame);
	if (FAILED(result))
		return false;

	// 수평으로 뒤집힌 이미지를 얻기 위해 BitmapFlipRotator 생성
	result = wicFactory->CreateBitmapFlipRotator(&wicFlip);
	if (FAILED(result))
		return false;

	// wicFrame를 수평으로 뒤집음
	wicFlip->Initialize(wicFrame, WICBitmapTransformFlipHorizontal);

	// WICBitmap을 D2DBitmap으로 변환시키기 위해 format converter 생성
	result = wicFactory->CreateFormatConverter(&wicConverter);
	if (FAILED(result))
		return false;

	// Converter[0]의 Format을 일반 이미지(wicFrame)에 맞춤
	result = wicConverter->Initialize(wicFrame, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
	if (FAILED(result))
		return false;

	// 리소스 정보를 저장 할 Sprite 생성
	newSprite = new Sprite(renderTarget);
	if (!newSprite)
		return false;

	// WICBitmap을 D2DBitmap으로 변환
	//result = renderTarget->CreateBitmapFromWicBitmap(wicConverter, nullptr, &m_Bitmap);
	result = renderTarget->CreateBitmapFromWicBitmap(wicConverter, nullptr, newSprite->GetBitmap());
	if (FAILED(result))
		return false;

	ID2D1Bitmap* bitmap = *(newSprite->GetBitmap());
	int numberOfFrame = bitmap->GetSize().width / IMAGE_SIZE;
	int numberOfAction = bitmap->GetSize().height / IMAGE_SIZE;
	newSprite->Initialize(numberOfFrame, numberOfAction);

	wchar_t* buffer = new wchar_t[128];
	wcscpy_s(buffer, wcslen(filename) + 1, filename);

	// 스프라이트 등록
	m_Sprites.push_back(newSprite);
	m_Filenames.push_back(buffer);

	wicConverter->Release();
	wicConverter = nullptr;

	wicFrame->Release();
	wicFrame = nullptr;

	wicFlip->Release();
	wicFlip = nullptr;

	wicDecoder->Release();
	wicDecoder = nullptr;

	wicFactory->Release();
	wicFactory = nullptr;

	return true;
}
// Load the rendering pipeline dependencies.
void D3D1211on12::LoadPipeline()
{
	UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
	D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
#ifdef _DEBUG
	// Enable the D2D debug layer.
	d2dFactoryOptions.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;

	// Enable the D3D11 debug layer.
	d3d11DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;

	// Enable the D3D12 debug layer.
	{
		ComPtr<ID3D12Debug> debugController;
		if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
		{
			debugController->EnableDebugLayer();
		}
	}
#endif

	ComPtr<IDXGIFactory4> factory;
	ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

	if (m_useWarpDevice)
	{
		ComPtr<IDXGIAdapter> warpAdapter;
		ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

		ThrowIfFailed(D3D12CreateDevice(
			warpAdapter.Get(),
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_d3d12Device)
			));
	}
	else
	{
		ThrowIfFailed(D3D12CreateDevice(
			nullptr,
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_d3d12Device)
			));
	}

	// Describe and create the command queue.
	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

	ThrowIfFailed(m_d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));

	// Describe the swap chain.
	DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
	swapChainDesc.BufferCount = FrameCount;
	swapChainDesc.BufferDesc.Width = m_width;
	swapChainDesc.BufferDesc.Height = m_height;
	swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	swapChainDesc.OutputWindow = m_hwnd;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.Windowed = TRUE;

	ComPtr<IDXGISwapChain> swapChain;
	ThrowIfFailed(factory->CreateSwapChain(
		m_commandQueue.Get(),		// Swap chain needs the queue so that it can force a flush on it.
		&swapChainDesc,
		&swapChain
		));

	ThrowIfFailed(swapChain.As(&m_swapChain));

	m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

	// Create an 11 device wrapped around the 12 device and share
	// 12's command queue.
	ComPtr<ID3D11Device> d3d11Device;
	ThrowIfFailed(D3D11On12CreateDevice(
		m_d3d12Device.Get(),
		d3d11DeviceFlags,
		nullptr,
		0,
		reinterpret_cast<IUnknown**>(m_commandQueue.GetAddressOf()),
		1,
		0,
		&d3d11Device,
		&m_d3d11DeviceContext,
		nullptr
		));

	// Query the 11On12 device from the 11 device.
	ThrowIfFailed(d3d11Device.As(&m_d3d11On12Device));

	// Create D2D/DWrite components.
	{
		D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
		ThrowIfFailed(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &m_d2dFactory));
		ComPtr<IDXGIDevice> dxgiDevice;
		ThrowIfFailed(m_d3d11On12Device.As(&dxgiDevice));
		ThrowIfFailed(m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice));
		ThrowIfFailed(m_d2dDevice->CreateDeviceContext(deviceOptions, &m_d2dDeviceContext));
		ThrowIfFailed(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &m_dWriteFactory));
	}

	// Query the desktop's dpi settings, which will be used to create
	// D2D's render targets.
	float dpiX;
	float dpiY;
	m_d2dFactory->GetDesktopDpi(&dpiX, &dpiY);
	D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(
		D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
		D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
		dpiX,
		dpiY
		);

	// Create descriptor heaps.
	{
		// Describe and create a render target view (RTV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
		rtvHeapDesc.NumDescriptors = FrameCount;
		rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
		rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		ThrowIfFailed(m_d3d12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

		m_rtvDescriptorSize = m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
	}

	// Create frame resources.
	{
		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());

		// Create a RTV, D2D render target, and a command allocator for each frame.
		for (UINT n = 0; n < FrameCount; n++)
		{
			ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
			m_d3d12Device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);

			// Create a wrapped 11On12 resource of this back buffer. Since we are 
			// rendering all D3D12 content first and then all D2D content, we specify 
			// the In resource state as RENDER_TARGET - because D3D12 will have last 
			// used it in this state - and the Out resource state as PRESENT. When 
			// ReleaseWrappedResources() is called on the 11On12 device, the resource 
			// will be transitioned to the PRESENT state.
			D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET };
			ThrowIfFailed(m_d3d11On12Device->CreateWrappedResource(
				m_renderTargets[n].Get(),
				&d3d11Flags,
				D3D12_RESOURCE_STATE_RENDER_TARGET,
				D3D12_RESOURCE_STATE_PRESENT,
				IID_PPV_ARGS(&m_wrappedBackBuffers[n])
				));

			// Create a render target for D2D to draw directly to this back buffer.
			ComPtr<IDXGISurface> surface;
			ThrowIfFailed(m_wrappedBackBuffers[n].As(&surface));
			ThrowIfFailed(m_d2dDeviceContext->CreateBitmapFromDxgiSurface(
				surface.Get(),
				&bitmapProperties,
				&m_d2dRenderTargets[n]
				));

			rtvHandle.Offset(1, m_rtvDescriptorSize);

			ThrowIfFailed(m_d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
		}
	}
}
Example #11
0
HBITMAP CGene::DecodePicture(CString filePath) {
	HRESULT hr;
	HBITMAP bitmapHandle = NULL;
#if WIC
	if (bitmapHandle == NULL) {
		// Windows Imaging Component and Direct2D Image Viewer Win32 Sample\C++\WicViewerD2D.cpp
		CComPtr<IWICImagingFactory> pWICFactory;
		hr = CoCreateInstance(
			CLSID_WICImagingFactory,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_PPV_ARGS(&pWICFactory)
			);
		if (SUCCEEDED(hr)) {
			CComPtr<IWICBitmapDecoder> pDecoder;
			hr = pWICFactory->CreateDecoderFromFilename(
				filePath,
				NULL,
				GENERIC_READ,
				WICDecodeMetadataCacheOnDemand,
				&pDecoder
				);

			if (SUCCEEDED(hr)) {
				CComPtr<IWICBitmapFrameDecode> pFrame;
				hr = pDecoder->GetFrame(0, &pFrame);
				if (SUCCEEDED(hr)) {
					CComPtr<IWICFormatConverter> pConvertedSourceBitmap;
					hr = pWICFactory->CreateFormatConverter(&pConvertedSourceBitmap);
					if (SUCCEEDED(hr)) {
						hr = pConvertedSourceBitmap->Initialize(
							pFrame,
							GUID_WICPixelFormat32bppBGRA,
							WICBitmapDitherTypeNone,
							NULL,
							0.f,
							WICBitmapPaletteTypeCustom
							);
						if (SUCCEEDED(hr)) {
							UINT cx = 0, cy = 0;
							hr = pConvertedSourceBitmap->GetSize(&cx, &cy);
							if (SUCCEEDED(hr)) {
								struct CompatibleDCHandle {
									HDC hMemDC;

									CompatibleDCHandle(): hMemDC(CreateCompatibleDC(NULL)) { }

									~CompatibleDCHandle() {
										if (hMemDC != NULL) {
											DeleteDC(hMemDC);
										}
									}
								};
								CompatibleDCHandle compatDC;
								BITMAPINFO bi = {
									sizeof(BITMAPINFOHEADER),
									(LONG)cx,
									-(LONG)cy,
									1,
									32,
									BI_RGB,
									4 * cx * cy
								};
								struct DIBSectionHandle {
									HBITMAP bitmapHandle;
									void *pvBits;

									DIBSectionHandle(CompatibleDCHandle &compatDC, BITMAPINFO &bi) {
										bitmapHandle = CreateDIBSection(
											compatDC.hMemDC, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0
											);
									}

									~DIBSectionHandle() {
										if (bitmapHandle != NULL) {
											DeleteObject(bitmapHandle);
										}
									}

									HBITMAP Detach() {
										HBITMAP hbm = bitmapHandle;
										bitmapHandle = NULL;
										return hbm;
									}

									bool Has() const {
										return bitmapHandle != NULL;
									}
								};
								DIBSectionHandle bitmap(compatDC, bi);
								if (bitmap.Has()) {
									WICRect bitmapRect = {0, 0, cx, cy};
									hr = pConvertedSourceBitmap->CopyPixels(
										&bitmapRect,
										4 * cx,
										bi.bmiHeader.biSizeImage,
										reinterpret_cast<PBYTE>(bitmap.pvBits)
										);
									if (SUCCEEDED(hr)) {
										bitmapHandle = bitmap.Detach();
									}
								}
							}
						}
					}
				}
			}
		}
	}
#endif
#if 1 // GDI_LOADIMAGE
	if (bitmapHandle == NULL) {
		bitmapHandle = reinterpret_cast<HBITMAP>(LoadImage(NULL, filePath, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE|LR_VGACOLOR));
	}
#endif
	return bitmapHandle;
}
// Load the sample assets.
void D3D1211on12::LoadAssets()
{
	// Create an empty root signature.
	{
		CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
		rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

		ComPtr<ID3DBlob> signature;
		ComPtr<ID3DBlob> error;
		ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
		ThrowIfFailed(m_d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
	}

	// Create the pipeline state, which includes compiling and loading shaders.
	{
		ComPtr<ID3DBlob> vertexShader;
		ComPtr<ID3DBlob> pixelShader;

#ifdef _DEBUG
		// Enable better shader debugging with the graphics debugging tools.
		UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
		UINT compileFlags = 0;
#endif

		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr));
		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr));

		// Define the vertex input layout.
		D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
		};

		// Describe and create the graphics pipeline state object (PSO).
		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
		psoDesc.pRootSignature = m_rootSignature.Get();
		psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() };
		psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() };
		psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
		psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
		psoDesc.DepthStencilState.DepthEnable = FALSE;
		psoDesc.DepthStencilState.StencilEnable = FALSE;
		psoDesc.SampleMask = UINT_MAX;
		psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		psoDesc.NumRenderTargets = 1;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
		psoDesc.SampleDesc.Count = 1;

		ThrowIfFailed(m_d3d12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));
	}

	ThrowIfFailed(m_d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList)));

	// Create D2D/DWrite objects for rendering text.
	{
		ThrowIfFailed(m_d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &m_textBrush));
		ThrowIfFailed(m_dWriteFactory->CreateTextFormat(
			L"Verdana",
			NULL,
			DWRITE_FONT_WEIGHT_NORMAL,
			DWRITE_FONT_STYLE_NORMAL,
			DWRITE_FONT_STRETCH_NORMAL,
			50,
			L"en-us",
			&m_textFormat
			));
		ThrowIfFailed(m_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
		ThrowIfFailed(m_textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER));
	}

	ComPtr<ID3D12Resource> vertexBufferUpload;

	// Create the vertex buffer.
	{
		// Define the geometry for a triangle.
		Vertex triangleVertices[] =
		{
			{ { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
			{ { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
			{ { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }
		};

		const UINT vertexBufferSize = sizeof(triangleVertices);

		ThrowIfFailed(m_d3d12Device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_vertexBuffer)));

		ThrowIfFailed(m_d3d12Device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&vertexBufferUpload)));

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the vertex buffer.
		D3D12_SUBRESOURCE_DATA vertexData = {};
		vertexData.pData = reinterpret_cast<UINT8*>(triangleVertices);
		vertexData.RowPitch = vertexBufferSize;
		vertexData.SlicePitch = vertexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUpload.Get(), 0, 0, 1, &vertexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

		// Initialize the vertex buffer view.
		m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
		m_vertexBufferView.StrideInBytes = sizeof(Vertex);
		m_vertexBufferView.SizeInBytes = vertexBufferSize;
	}

	// Close the command list and execute it to begin the vertex buffer copy into
	// the default heap.
	ThrowIfFailed(m_commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	{
		ThrowIfFailed(m_d3d12Device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.GetAddressOf())));
		m_fenceValues[m_frameIndex]++;

		// Create an event handle to use for frame synchronization.
		m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
		if (m_fenceEvent == nullptr)
		{
			ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
		}

		// Wait for the command list to execute; we are reusing the same command 
		// list in our main loop but for now, we just want to wait for setup to 
		// complete before continuing.
		WaitForGpu();
	}
}
// Load the rendering pipeline dependencies.
void D3D12Fullscreen::LoadPipeline()
{
#if defined(_DEBUG)
    // Enable the D3D12 debug layer.
    {
        ComPtr<ID3D12Debug> debugController;
        if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
        {
            debugController->EnableDebugLayer();
        }
    }
#endif

    ComPtr<IDXGIFactory4> factory;
    ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

    if (m_useWarpDevice)
    {
        ComPtr<IDXGIAdapter> warpAdapter;
        ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

        ThrowIfFailed(D3D12CreateDevice(
                          warpAdapter.Get(),
                          D3D_FEATURE_LEVEL_11_0,
                          IID_PPV_ARGS(&m_device)
                      ));
    }
    else
    {
        ComPtr<IDXGIAdapter1> hardwareAdapter;
        GetHardwareAdapter(factory.Get(), &hardwareAdapter);

        ThrowIfFailed(D3D12CreateDevice(
                          hardwareAdapter.Get(),
                          D3D_FEATURE_LEVEL_11_0,
                          IID_PPV_ARGS(&m_device)
                      ));
    }

    // Describe and create the command queue.
    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
    queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

    ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
    NAME_D3D12_OBJECT(m_commandQueue);

    // Describe and create the swap chain.
    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    swapChainDesc.BufferCount = FrameCount;
    swapChainDesc.Width = m_width;
    swapChainDesc.Height = m_height;
    swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.SampleDesc.Count = 1;

    ComPtr<IDXGISwapChain1> swapChain;
    ThrowIfFailed(factory->CreateSwapChainForHwnd(
                      m_commandQueue.Get(),		// Swap chain needs the queue so that it can force a flush on it.
                      Win32Application::GetHwnd(),
                      &swapChainDesc,
                      nullptr,
                      nullptr,
                      &swapChain
                  ));

    // This sample does not support fullscreen transitions.
    ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER));

    ThrowIfFailed(swapChain.As(&m_swapChain));
    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

    // Create descriptor heaps.
    {
        // Describe and create a render target view (RTV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
        rtvHeapDesc.NumDescriptors = FrameCount;
        rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
        rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

        m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
    }

    // Create a command allocator for each frame.
    for (UINT n = 0; n < FrameCount; n++)
    {
        ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
    }
}
void D3D12Fullscreen::LoadSizeDependentResources()
{
    m_viewport.Width = static_cast<float>(m_width);
    m_viewport.Height = static_cast<float>(m_height);
    m_viewport.MaxDepth = 1.0f;

    m_scissorRect.right = static_cast<LONG>(m_width);
    m_scissorRect.bottom = static_cast<LONG>(m_height);

    // Create frame resources.
    {
        CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());

        // Create a RTV for each frame.
        for (UINT n = 0; n < FrameCount; n++)
        {
            ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
            m_device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);
            rtvHandle.Offset(1, m_rtvDescriptorSize);

            WCHAR name[25];
            if (swprintf_s(name, L"m_renderTargets[%u]", n) > 0)
            {
                SetName(m_renderTargets[n].Get(), name);
            }
        }
    }

    // Create/update the vertex buffer. When updating the vertex buffer it is important
    // to ensure that the GPU is finished using the resource before it is released.
    // The OnSizeChanged method waits for the GPU to be idle before this method is
    // called.
    {
        // Define the geometry for a triangle that stays the same size regardless
        // of the window size. This is not the recommended way to transform vertices.
        // The same effect could be achieved by using constant buffers and
        // transforming a static set of vertices in the vertex shader, but this
        // sample merely demonstrates modifying a resource that is tied to the render
        // target size.
        // Other apps might also resize intermediate render targets or depth stencils
        // at this time.
        float x = TriangleWidth / m_viewport.Width;
        float y = TriangleWidth / m_viewport.Height;

        Vertex triangleVertices[] =
        {
            { { 0.0f, y, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
            { { x, -y, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
            { { -x, -y, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }
        };

        const UINT vertexBufferSize = sizeof(triangleVertices);

        ThrowIfFailed(m_device->CreateCommittedResource(
                          &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
                          D3D12_HEAP_FLAG_NONE,
                          &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
                          D3D12_RESOURCE_STATE_COPY_DEST,
                          nullptr,
                          IID_PPV_ARGS(&m_vertexBuffer)));

        ThrowIfFailed(m_device->CreateCommittedResource(
                          &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
                          D3D12_HEAP_FLAG_NONE,
                          &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
                          D3D12_RESOURCE_STATE_GENERIC_READ,
                          nullptr,
                          IID_PPV_ARGS(&m_vertexBufferUpload)));

        NAME_D3D12_OBJECT(m_vertexBuffer);

        // Copy data to the intermediate upload heap and then schedule a copy
        // from the upload heap to the vertex buffer.
        UINT8* pVertexDataBegin;
        CD3DX12_RANGE readRange(0, 0);		// We do not intend to read from this resource on the CPU.
        ThrowIfFailed(m_vertexBufferUpload->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
        memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
        m_vertexBufferUpload->Unmap(0, nullptr);

        m_commandList->CopyBufferRegion(m_vertexBuffer.Get(), 0, m_vertexBufferUpload.Get(), 0, vertexBufferSize);
        m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

        // Initialize the vertex buffer views.
        m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
        m_vertexBufferView.StrideInBytes = sizeof(Vertex);
        m_vertexBufferView.SizeInBytes = vertexBufferSize;
    }

    m_resizeResources = false;
}
Example #15
0
FramebufferManager::FramebufferManager()
{
    m_target_width = std::max(Renderer::GetTargetWidth(), 1);
    m_target_height = std::max(Renderer::GetTargetHeight(), 1);

    DXGI_SAMPLE_DESC sample_desc;
    sample_desc.Count = g_ActiveConfig.iMultisamples;
    sample_desc.Quality = 0;

    ID3D12Resource* buf12;
    D3D12_RESOURCE_DESC texdesc12;
    D3D12_CLEAR_VALUE optimized_clear_valueRTV = { DXGI_FORMAT_R8G8B8A8_UNORM, { 0.0f, 0.0f, 0.0f, 1.0f } };
    D3D12_CLEAR_VALUE optimized_clear_valueDSV = CD3DX12_CLEAR_VALUE(DXGI_FORMAT_D32_FLOAT, 0.0f, 0);

    HRESULT hr;

    m_EFBLayers = m_efb.slices = (g_ActiveConfig.iStereoMode > 0) ? 2 : 1;

    // EFB color texture - primary render target
    texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1, sample_desc.Count, sample_desc.Quality, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
    hr = D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, &optimized_clear_valueRTV, IID_PPV_ARGS(&buf12));

    m_efb.color_tex = new D3DTexture2D(buf12, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1), D3D12_RESOURCE_STATE_COMMON);
    SAFE_RELEASE(buf12);

    // Temporary EFB color texture - used in ReinterpretPixelData
    texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1, sample_desc.Count, sample_desc.Quality, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
    CheckHR(D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, &optimized_clear_valueRTV, IID_PPV_ARGS(&buf12)));
    m_efb.color_temp_tex = new D3DTexture2D(buf12, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM, (sample_desc.Count > 1), D3D12_RESOURCE_STATE_COMMON);
    SAFE_RELEASE(buf12);
    D3D::SetDebugObjectName12(m_efb.color_temp_tex->GetTex12(), "EFB color temp texture");

    // AccessEFB - Sysmem buffer used to retrieve the pixel data from color_tex
    texdesc12 = CD3DX12_RESOURCE_DESC::Buffer(64 * 1024);
    CheckHR(D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_efb.color_staging_buf)));
    CHECK(hr == S_OK, "create EFB color staging buffer (hr=%#x)", hr);

    // EFB depth buffer - primary depth buffer
    texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_TYPELESS, m_target_width, m_target_height, m_efb.slices, 1, sample_desc.Count, sample_desc.Quality, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
    CheckHR(D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, &optimized_clear_valueDSV, IID_PPV_ARGS(&buf12)));

    m_efb.depth_tex = new D3DTexture2D(buf12, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_UNKNOWN, (sample_desc.Count > 1), D3D12_RESOURCE_STATE_COMMON);
    SAFE_RELEASE(buf12);
    D3D::SetDebugObjectName12(m_efb.depth_tex->GetTex12(), "EFB depth texture");

    // Render buffer for AccessEFB (depth data)
    texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT, 1, 1, m_efb.slices, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);
    optimized_clear_valueRTV.Format = DXGI_FORMAT_R32_FLOAT;
    hr = D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, &optimized_clear_valueRTV, IID_PPV_ARGS(&buf12));
    CHECK(hr == S_OK, "create EFB depth read texture (hr=%#x)", hr);

    m_efb.depth_read_texture = new D3DTexture2D(buf12, D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, false, D3D12_RESOURCE_STATE_COMMON);

    SAFE_RELEASE(buf12);
    D3D::SetDebugObjectName12(m_efb.depth_read_texture->GetTex12(), "EFB depth read texture (used in Renderer::AccessEFB)");

    // AccessEFB - Sysmem buffer used to retrieve the pixel data from depth_read_texture
    texdesc12 = CD3DX12_RESOURCE_DESC::Buffer(64 * 1024);
    hr = D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_efb.depth_staging_buf));
    CHECK(hr == S_OK, "create EFB depth staging buffer (hr=%#x)", hr);

    D3D::SetDebugObjectName12(m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");

    if (g_ActiveConfig.iMultisamples > 1)
    {
        // Framebuffer resolve textures (color+depth)
        texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, m_target_width, m_target_height, m_efb.slices, 1);
        hr = D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&buf12));
        CHECK(hr == S_OK, "create EFB color resolve texture (size: %dx%d)", m_target_width, m_target_height);
        m_efb.resolved_color_tex = new D3DTexture2D(buf12, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, false, D3D12_RESOURCE_STATE_COMMON);
        SAFE_RELEASE(buf12);
        D3D::SetDebugObjectName12(m_efb.resolved_color_tex->GetTex12(), "EFB color resolve texture shader resource view");

        texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_TYPELESS, m_target_width, m_target_height, m_efb.slices, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
        hr = D3D::device12->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texdesc12, D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&buf12));
        CHECK(hr == S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr);
        m_efb.resolved_depth_tex = new D3DTexture2D(buf12, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_UNKNOWN, false, D3D12_RESOURCE_STATE_COMMON);
        SAFE_RELEASE(buf12);
        D3D::SetDebugObjectName12(m_efb.resolved_depth_tex->GetTex12(), "EFB depth resolve texture shader resource view");

        m_depth_resolve_depth_stencil_desc = {};
        m_depth_resolve_depth_stencil_desc.StencilEnable = FALSE;
        m_depth_resolve_depth_stencil_desc.DepthEnable = TRUE;
        m_depth_resolve_depth_stencil_desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
        m_depth_resolve_depth_stencil_desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
    }
    else
    {
        m_efb.resolved_color_tex = nullptr;
        m_efb.resolved_depth_tex = nullptr;
    }

    s_xfbEncoder.Init();
}
Example #16
0
void dx::initialise()
{
    gDX.viewport.Width = static_cast<float>(platform::ui::width());
    gDX.viewport.Height = static_cast<float>(platform::ui::height());
    gDX.viewport.MaxDepth = 1.0f;

    gDX.scissorRect.right = static_cast<LONG>(platform::ui::width());
    gDX.scissorRect.bottom = static_cast<LONG>(platform::ui::height());


#ifdef _DEBUG
    // Enable the D3D12 debug layer.
    {
        ComPtr<ID3D12Debug> debugController;
        if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
        {
            debugController->EnableDebugLayer();
        }
    }
#endif

    ComPtr<IDXGIFactory4> factory;
    ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

    // Always use WARP for now...
    static const bool USE_WARP_DEVICE = true;
    if (USE_WARP_DEVICE)
    {
        ComPtr<IDXGIAdapter> warpAdapter;
        ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

        ThrowIfFailed(D3D12CreateDevice(
                          warpAdapter.Get(),
                          D3D_FEATURE_LEVEL_11_0,
                          IID_PPV_ARGS(&gDX.device)
                      ));
    } else
    {
        ThrowIfFailed(D3D12CreateDevice(
                          nullptr,
                          D3D_FEATURE_LEVEL_11_0,
                          IID_PPV_ARGS(&gDX.device)
                      ));
    }

    // Describe and create the command queue.
    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
    queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

    ThrowIfFailed(gDX.device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&gDX.commandQueue)));

    // Describe and create the swap chain.
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    swapChainDesc.BufferCount = gDX.FrameCount;
    swapChainDesc.BufferDesc.Width = platform::ui::width();
    swapChainDesc.BufferDesc.Height = platform::ui::height();
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.OutputWindow = (HWND)platform::ui::hwnd();
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.Windowed = TRUE;

    ComPtr<IDXGISwapChain> swapChain;
    ThrowIfFailed(factory->CreateSwapChain(
                      gDX.commandQueue.Get(),		// Swap chain needs the queue so that it can force a flush on it.
                      &swapChainDesc,
                      &swapChain
                  ));

    ThrowIfFailed(swapChain.As(&gDX.swapChain));

    gDX.frameIndex = gDX.swapChain->GetCurrentBackBufferIndex();

    // Create descriptor heaps.
    {
        // Describe and create a render target view (RTV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
        rtvHeapDesc.NumDescriptors = gDX.FrameCount + 128;
        rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
        rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        gDX.rtvHeap = new DXHeap(gDX.device.Get(), rtvHeapDesc);

        // Describe and create a depth stencil view (DSV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
        dsvHeapDesc.NumDescriptors = 128;
        dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
        dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        gDX.dsvHeap = new DXHeap(gDX.device.Get(), dsvHeapDesc);

        // Describe and create a constant buffer view (CBV), Shader resource
        // view (SRV), and unordered access view (UAV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
        srvHeapDesc.NumDescriptors = 2048;
        srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
        srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
        gDX.srvHeap = new DXHeap(gDX.device.Get(), srvHeapDesc);
    }

    // Create frame resources.
    {
        // Create a RTV for each frame.
        for (UINT n = 0; n < gDX.FrameCount; n++)
        {
            ThrowIfFailed(gDX.swapChain->GetBuffer(n, IID_PPV_ARGS(&gDX.renderTargets[n])));

            gDX.scanbufferRtv[n] = gDX.rtvHeap->alloc();
            gDX.device->CreateRenderTargetView(gDX.renderTargets[n].Get(), nullptr, *gDX.scanbufferRtv[n]);
        }
    }

    // Create command allocators.
    {
        for (UINT n = 0; n < gDX.FrameCount; n++)
        {
            ThrowIfFailed(gDX.device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&gDX.commandAllocator[n])));
        }
    }

    // Create the root signature.
    {
        CD3DX12_DESCRIPTOR_RANGE ranges[1];
        ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);

        CD3DX12_ROOT_PARAMETER rootParameters[1];
        rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);

        D3D12_STATIC_SAMPLER_DESC sampler = {};
        sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
        sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.MipLODBias = 0;
        sampler.MaxAnisotropy = 0;
        sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
        sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
        sampler.MinLOD = 0.0f;
        sampler.MaxLOD = D3D12_FLOAT32_MAX;
        sampler.ShaderRegister = 0;
        sampler.RegisterSpace = 0;
        sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;

        CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
        rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 1, &sampler, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

        ComPtr<ID3DBlob> signature;
        ComPtr<ID3DBlob> error;
        ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
        ThrowIfFailed(gDX.device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&gDX.rootSignature)));
    }

    // Create the pipeline state, which includes compiling and loading shaders.
    {
        ComPtr<ID3DBlob> vertexShader;
        ComPtr<ID3DBlob> pixelShader;

#ifdef _DEBUG
        // Enable better shader debugging with the graphics debugging tools.
        UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
        UINT compileFlags = 0;
#endif

        ThrowIfFailed(D3DCompileFromFile(L"resources/shaders/screendraw.hlsl", nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr));
        ThrowIfFailed(D3DCompileFromFile(L"resources/shaders/screendraw.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr));

        // Define the vertex input layout.
        D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
            { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
        };

        {
            D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
            psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
            psoDesc.pRootSignature = gDX.rootSignature.Get();
            psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() };
            psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() };
            psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
            psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
            psoDesc.DepthStencilState.DepthEnable = FALSE;
            psoDesc.DepthStencilState.StencilEnable = FALSE;
            psoDesc.SampleMask = UINT_MAX;
            psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
            psoDesc.NumRenderTargets = 1;
            psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
            psoDesc.SampleDesc.Count = 1;
            ThrowIfFailed(gDX.device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&gDX.emuPipelineState)));
        }
    }

    gDX.pipelineMgr = new DXPipelineMgr();

    // Create the command list.
    gDX.frameIndex = gDX.swapChain->GetCurrentBackBufferIndex();

    ThrowIfFailed(gDX.device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, gDX.commandAllocator[gDX.frameIndex].Get(), gDX.emuPipelineState.Get(), IID_PPV_ARGS(&gDX.commandList)));



    {
#define SCREENSPACE(x, y) { -1 + ((x) / (float)platform::ui::width()) * 2, 1 - ((y) / (float)platform::ui::height()) * 2, 0.0f }
        float tvX = 0;
        float tvY = 0;
        float tvWidth = (float)platform::ui::tvWidth();
        float tvHeight = (float)platform::ui::tvHeight();
        float drcX = ((float)platform::ui::tvWidth() - (float)platform::ui::drcWidth()) / 2;
        float drcY = (float)platform::ui::tvHeight();
        float drcWidth = (float)platform::ui::drcWidth();
        float drcHeight = (float)platform::ui::drcHeight();

        struct Vertex {
            XMFLOAT3 pos;
            XMFLOAT2 uv;
        } triangleVertices[] =
        {
            { SCREENSPACE(tvX, tvY + tvHeight),{ 0.0f, 1.0f } },
            { SCREENSPACE(tvX, tvY),{ 0.0f, 0.0f } },
            { SCREENSPACE(tvX + tvWidth, tvY + tvHeight),{ 1.0f, 1.0f } },
            { SCREENSPACE(tvX + tvWidth, tvY),{ 1.0f, 0.0f } },
            { SCREENSPACE(drcX, drcY + drcHeight),{ 0.0f, 1.0f } },
            { SCREENSPACE(drcX, drcY),{ 0.0f, 0.0f } },
            { SCREENSPACE(drcX + drcWidth, drcY + drcHeight),{ 1.0f, 1.0f } },
            { SCREENSPACE(drcX + drcWidth, drcY),{ 1.0f, 0.0f } },
        };

#undef SCREENSPACE

        const UINT vertexBufferSize = sizeof(triangleVertices);

        // Note: using upload heaps to transfer static data like vert buffers is not
        // recommended. Every time the GPU needs it, the upload heap will be marshalled
        // over. Please read up on Default Heap usage. An upload heap is used here for
        // code simplicity and because there are very few verts to actually transfer.
        ThrowIfFailed(gDX.device->CreateCommittedResource(
                          &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
                          D3D12_HEAP_FLAG_NONE,
                          &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
                          D3D12_RESOURCE_STATE_GENERIC_READ,
                          nullptr,
                          IID_PPV_ARGS(&gDX.vertexBuffer)));

        // Copy the triangle data to the vertex buffer.
        UINT8* pVertexDataBegin;
        ThrowIfFailed(gDX.vertexBuffer->Map(0, nullptr, reinterpret_cast<void**>(&pVertexDataBegin)));
        memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
        gDX.vertexBuffer->Unmap(0, nullptr);

        // Initialize the vertex buffer view.
        gDX.vertexBufferView.BufferLocation = gDX.vertexBuffer->GetGPUVirtualAddress();
        gDX.vertexBufferView.StrideInBytes = sizeof(Vertex);
        gDX.vertexBufferView.SizeInBytes = vertexBufferSize;
    }

    // 10MB Temporary Vertex Buffer
    gDX.ppcVertexBuffer = new DXDynBuffer(gDX.device.Get(), 10 * 1024 * 1024);

    // Close the command list and execute it to begin the initial GPU setup.
    ThrowIfFailed(gDX.commandList->Close());
    ID3D12CommandList* ppCommandLists[] = { gDX.commandList.Get() };
    gDX.commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

    // Create synchronization objects.
    {
        ThrowIfFailed(gDX.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&gDX.fence)));

        // Create an event handle to use for frame synchronization.
        gDX.fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
        if (gDX.fenceEvent == nullptr)
        {
            ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
        }

        // Wait for frame completion
        gDX.swapCount++;
        const uint64_t fenceValue = gDX.swapCount;
        ThrowIfFailed(gDX.commandQueue->Signal(gDX.fence.Get(), fenceValue));

        if (gDX.fence->GetCompletedValue() < gDX.swapCount)
        {
            ThrowIfFailed(gDX.fence->SetEventOnCompletion(gDX.swapCount, gDX.fenceEvent));
            WaitForSingleObject(gDX.fenceEvent, INFINITE);
        }
    }

    _beginFrame();
}
Example #17
0
HRESULT BasicFileOpen(PWSTR* filePath)
{
	// CoCreate the File Open Dialog object.
	IFileDialog *pfd = NULL;
	HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
		NULL, 
		CLSCTX_INPROC_SERVER, 
		IID_PPV_ARGS(&pfd));
	if (SUCCEEDED(hr))
	{
		// Create an event handling object, and hook it up to the dialog.
		IFileDialogEvents *pfde = NULL;
		//DWORD dwCookie;
		// Set the options on the dialog.
		DWORD dwFlags;

		// Before setting, always get the options first in order 
		// not to override existing options.
		hr = pfd->GetOptions(&dwFlags);
		if (SUCCEEDED(hr))
		{
			// In this case, get shell items only for file system items.
			hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
			if (SUCCEEDED(hr))
			{
				static const COMDLG_FILTERSPEC c_rgSaveTypes[] =
				{
					{L"Executable Files(*.exe)",       L"*.exe"},
				};
				// Set the file types to display only. 
				// Notice that this is a 1-based array.
				hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
				if (SUCCEEDED(hr))
				{
					// Set the selected file type index to Word Docs for this example.
					hr = pfd->SetFileTypeIndex(1);
					if (SUCCEEDED(hr))
					{
						// Set the default extension to be ".doc" file.
						hr = pfd->SetDefaultExtension(L"exe");
						if (SUCCEEDED(hr))
						{
							// Show the dialog
							hr = pfd->Show(g_hwnd);
							if (SUCCEEDED(hr))
							{
								// Obtain the result once the user clicks 
								// the 'Open' button.
								// The result is an IShellItem object.
								IShellItem *psiResult;
								hr = pfd->GetResult(&psiResult);
								if (SUCCEEDED(hr))
								{
									// We are just going to print out the 
									// name of the file for sample sake.
									PWSTR pszFilePath = NULL;
									hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, 
										&pszFilePath);
									if (SUCCEEDED(hr))
									{
										*filePath=pszFilePath;
										
									}
									psiResult->Release();
								}
							}
						}
					}
				}
			}
		}
		pfd->Release();
	}
	else
	{
		hr=E_OUTOFMEMORY;
		OPENFILENAME ofn;
		LPWSTR pszFile=(LPWSTR)CoTaskMemAlloc(260*2);
		if(pszFile!=NULL)
		{
			memset1(&ofn,0,sizeof(ofn));
			ofn.lStructSize = sizeof(ofn);
			ofn.hwndOwner = g_hwnd;
			ofn.lpstrFile = pszFile;
			// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
			// use the contents of szFile to initialize itself.
			ofn.lpstrFile[0] = L'\0';
			ofn.nMaxFile = 260;
			ofn.lpstrFilter = L"Executable Files(*.exe)\0*.exe\0";
			ofn.nFilterIndex = 1;
			ofn.lpstrFileTitle = NULL;
			ofn.nMaxFileTitle = 0;
			ofn.lpstrInitialDir = NULL;
			ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

			if (GetOpenFileName(&ofn)==TRUE)
			{
				*filePath=pszFile;
				hr=0;
			}
		}

	}
	return hr;
}
Example #18
0
	/**
	*  @brief
	*    Constructor
	*/
	SwapChain::SwapChain(Direct3D11Renderer &direct3D11Renderer, handle nativeWindowHandle) :
		ISwapChain(direct3D11Renderer),
		mDxgiSwapChain(nullptr),
		mD3D11RenderTargetView(nullptr),
		mD3D11DepthStencilView(nullptr)
	{
		// Get the Direct3D 11 device instance
		ID3D11Device *d3d11Device = direct3D11Renderer.getD3D11Device();

		// Get the native window handle
		const HWND hWnd = reinterpret_cast<HWND>(nativeWindowHandle);

		// Get a IDXGIFactory1 instance
		IDXGIDevice *dxgiDevice = nullptr;
		IDXGIAdapter *dxgiAdapter = nullptr;
		IDXGIFactory1 *dxgiFactory1 = nullptr;
		d3d11Device->QueryInterface(&dxgiDevice);
		dxgiDevice->GetAdapter(&dxgiAdapter);
		dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory1));
		dxgiAdapter->Release();
		dxgiDevice->Release();

		// Get the width and height of the given native window and ensure they are never ever zero
		// -> See "getSafeWidthAndHeight()"-method comments for details
		long width  = 1;
		long height = 1;
		{
			// Get the client rectangle of the given native window
			RECT rect;
			::GetClientRect(hWnd, &rect);

			// Get the width and height...
			width  = rect.right  - rect.left;
			height = rect.bottom - rect.top;

			// ... and ensure that none of them is ever zero
			if (width < 1)
			{
				width = 1;
			}
			if (height < 1)
			{
				height = 1;
			}
		}

		// Create the swap chain
		DXGI_SWAP_CHAIN_DESC dxgiSwapChainDesc;
		::ZeroMemory(&dxgiSwapChainDesc, sizeof(dxgiSwapChainDesc));
		dxgiSwapChainDesc.BufferCount						 = 1;
		dxgiSwapChainDesc.BufferDesc.Width					 = static_cast<UINT>(width);
		dxgiSwapChainDesc.BufferDesc.Height					 = static_cast<UINT>(height);
		dxgiSwapChainDesc.BufferDesc.Format					 = DXGI_FORMAT_R8G8B8A8_UNORM;
		dxgiSwapChainDesc.BufferDesc.RefreshRate.Numerator	 = 60;
		dxgiSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
		dxgiSwapChainDesc.BufferUsage						 = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		dxgiSwapChainDesc.OutputWindow						 = hWnd;
		dxgiSwapChainDesc.SampleDesc.Count					 = 1;
		dxgiSwapChainDesc.SampleDesc.Quality				 = 0;
		dxgiSwapChainDesc.Windowed							 = TRUE;
		dxgiFactory1->CreateSwapChain(d3d11Device, &dxgiSwapChainDesc, &mDxgiSwapChain);
		dxgiFactory1->Release();

		// Disable alt-return for automatic fullscreen state change
		// -> We handle this manually to have more control over it
		dxgiFactory1->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);

		// Create the Direct3D 11 views
		if (nullptr != mDxgiSwapChain)
		{
			createDirect3D11Views();
		}

		// Assign a default name to the resource for debugging purposes
		#ifndef DIRECT3D11RENDERER_NO_DEBUG
			setDebugName("Swap chain");
		#endif
	}
// Writes properties on the user specified object.
void WriteContentProperties(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }
	//<SnippetContentProp3>
    HRESULT                               hr                   = S_OK;
    WCHAR                                 szSelection[81]      = {0};
    WCHAR                                 szNewObjectName[81]  = {0};
    CComPtr<IPortableDeviceProperties>    pProperties;
    CComPtr<IPortableDeviceContent>       pContent;
    CComPtr<IPortableDeviceValues>        pObjectPropertiesToWrite;
    CComPtr<IPortableDeviceValues>        pPropertyWriteResults;
    CComPtr<IPortableDeviceValues>        pAttributes;
    BOOL                                  bCanWrite            = FALSE;

    // Prompt user to enter an object identifier on the device to write properties on.
    printf("Enter the identifer of the object you wish to write properties on.\n>");
    hr = StringCbGetsW(szSelection,sizeof(szSelection));
    if (FAILED(hr))
    {
        printf("An invalid object identifier was specified, aborting property reading\n");
    }
	//</SnippetContentProp3>
    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
	//<SnippetContentProp4>
    if (SUCCEEDED(hr))
    {
        hr = pDevice->Content(&pContent);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) Check the property attributes to see if we can write/change the WPD_OBJECT_NAME property.
    if (SUCCEEDED(hr))
    {
        hr = pProperties->GetPropertyAttributes(szSelection,
                                                WPD_OBJECT_NAME,
                                                &pAttributes);
        if (SUCCEEDED(hr))
        {
            hr = pAttributes->GetBoolValue(WPD_PROPERTY_ATTRIBUTE_CAN_WRITE, &bCanWrite);
            if (SUCCEEDED(hr))
            {
                if (bCanWrite)
                {
                    printf("The attribute WPD_PROPERTY_ATTRIBUTE_CAN_WRITE for the WPD_OBJECT_NAME reports TRUE\nThis means that the property can be changed/updated\n\n");
                }
                else
                {
                    printf("The attribute WPD_PROPERTY_ATTRIBUTE_CAN_WRITE for the WPD_OBJECT_NAME reports FALSE\nThis means that the property cannot be changed/updated\n\n");
                }
            }
            else
            {
                printf("! Failed to get the WPD_PROPERTY_ATTRIBUTE_CAN_WRITE value from WPD_OBJECT_NAME on object '%ws', hr = 0x%lx\n",szSelection, hr);
            }
        }
    }
	//</SnippetContentProp4>

    // 4) Prompt the user for the new value of the WPD_OBJECT_NAME property only if the property attributes report
    // that it can be changed/updated.
	//<SnippetContentProp5>
    if (bCanWrite)
    {
        printf("Enter the new WPD_OBJECT_NAME for the object '%ws'.\n>",szSelection);
        hr = StringCbGetsW(szNewObjectName,sizeof(szNewObjectName));
        if (FAILED(hr))
        {
            printf("An invalid object name was specified, aborting property writing\n");
        }

        // 5) CoCreate an IPortableDeviceValues interface to hold the the property values
        // we wish to write.
        if (SUCCEEDED(hr))
        {
            hr = CoCreateInstance(CLSID_PortableDeviceValues,
                                  NULL,
                                  CLSCTX_INPROC_SERVER,
                                  IID_PPV_ARGS(&pObjectPropertiesToWrite));
            if (SUCCEEDED(hr))
            {
                if (pObjectPropertiesToWrite != NULL)
                {
                    hr = pObjectPropertiesToWrite->SetStringValue(WPD_OBJECT_NAME, szNewObjectName);
                    if (FAILED(hr))
                    {
                        printf("! Failed to add WPD_OBJECT_NAME to IPortableDeviceValues, hr= 0x%lx\n", hr);
                    }
                }
            }
        }
		//</SnippetContentProp5>
        // 6) Call SetValues() passing the collection of specified PROPERTYKEYs.
		//<SnippetContentProp6>
        if (SUCCEEDED(hr))
        {
            hr = pProperties->SetValues(szSelection,                // The object whose properties we are reading
                                        pObjectPropertiesToWrite,   // The properties we want to read
                                        &pPropertyWriteResults);    // Driver supplied property result values for the property read operation
            if (FAILED(hr))
            {
                printf("! Failed to set properties for object '%ws', hr= 0x%lx\n", szSelection, hr);
            }
            else
            {
                printf("The WPD_OBJECT_NAME property on object '%ws' was written successfully (Read the properties again to see the updated value)\n", szSelection);
            }
        }
		//</SnippetContentProp6>
    }
}
	int BaseGraphicsState::Initialize(ID3D12Device& device, const GfxGraphicsStateDesc& desc)
	{
		D3D12_INPUT_ELEMENT_DESC elements[32];
		SI_ASSERT(desc.m_inputElementCount < ArraySize(elements));
		uint32_t elementCont = SI::Min((uint32_t)desc.m_inputElementCount, (uint32_t)ArraySize(elements));
		for(uint32_t e=0; e<elementCont; ++e)
		{
			D3D12_INPUT_ELEMENT_DESC& outElem = elements[e];
			const GfxInputElement&     inElem = desc.m_inputElements[e];
			
			outElem.SemanticName         = inElem.m_semanticsName;
			outElem.SemanticIndex        = inElem.m_semanticsId;
			outElem.Format               = SI::GetDx12Format(inElem.m_format);
			outElem.InputSlot            = inElem.m_inputSlot;
			outElem.AlignedByteOffset    = inElem.m_alignedByteOffset;
			outElem.InputSlotClass       = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
			outElem.InstanceDataStepRate = 0;
		}
		
		const BaseShader* vertexShader = desc.m_vertexShader->GetBaseShader();
		const BaseShader* pixelShader  = desc.m_pixelShader->GetBaseShader();

		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = { elements, elementCont };
		psoDesc.pRootSignature = desc.m_rootSignature->GetBaseRootSignature()->GetComPtrRootSignature().Get();
		psoDesc.VS.pShaderBytecode = vertexShader? vertexShader->GetBinary() : nullptr;
		psoDesc.VS.BytecodeLength  = vertexShader? vertexShader->GetBinarySize() : 0;
		psoDesc.PS.pShaderBytecode = pixelShader? pixelShader->GetBinary() : nullptr;
		psoDesc.PS.BytecodeLength  = pixelShader? pixelShader->GetBinarySize() : 0;
				
		psoDesc.RasterizerState.FillMode              = GetDx12FillMode(desc.m_fillMode);
		psoDesc.RasterizerState.CullMode              = GetDx12CullMode(desc.m_cullMode);
		psoDesc.RasterizerState.FrontCounterClockwise = desc.m_frontCounterClockwise? TRUE : FALSE;
		psoDesc.RasterizerState.DepthBias             = desc.m_depthBias;
		psoDesc.RasterizerState.DepthBiasClamp        = desc.m_depthBiasClamp;
		psoDesc.RasterizerState.SlopeScaledDepthBias  = desc.m_slopeScaledDepthBias;
		psoDesc.RasterizerState.DepthClipEnable       = TRUE;
		psoDesc.RasterizerState.MultisampleEnable     = FALSE;
		psoDesc.RasterizerState.AntialiasedLineEnable = FALSE;
		psoDesc.RasterizerState.ForcedSampleCount     = 0;
		psoDesc.RasterizerState.ConservativeRaster    = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
		psoDesc.SampleMask                            = UINT_MAX;
		psoDesc.PrimitiveTopologyType                 = GetDx12PrimitiveTopologyType(desc.m_primitiveTopologyType);		
		psoDesc.SampleDesc.Count                      = 1;
		psoDesc.NumRenderTargets                      = desc.m_renderTargetCount;
		psoDesc.BlendState.AlphaToCoverageEnable      = FALSE;
		psoDesc.BlendState.IndependentBlendEnable     = FALSE;
		psoDesc.DepthStencilState.DepthEnable         = desc.m_depthEnable? TRUE : FALSE;
		psoDesc.DepthStencilState.StencilEnable       = desc.m_stencilEnable? TRUE : FALSE;
		if(psoDesc.DepthStencilState.DepthEnable)
		{
			psoDesc.DepthStencilState.DepthWriteMask  = GetDx12DepthWriteMask(desc.m_depthWriteMask);
			psoDesc.DepthStencilState.DepthFunc       = GetDx12ComparisonFunc(desc.m_depthFunc);
		}
		
		SI_ASSERT(desc.m_renderTargetCount <= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
		UINT blendRtCount = psoDesc.BlendState.IndependentBlendEnable? psoDesc.NumRenderTargets : 1;

		for (UINT rt = 0; rt<blendRtCount; ++rt)
		{
			D3D12_RENDER_TARGET_BLEND_DESC& outBlend = psoDesc.BlendState.RenderTarget[rt];
			const GfxRenderTargetBlendDesc&  inBlend = desc.m_rtvBlend[rt];

			outBlend.BlendEnable            = inBlend.m_blendEnable?   TRUE : FALSE;
			outBlend.LogicOpEnable          = inBlend.m_logicOpEnable? TRUE : FALSE;
			outBlend.SrcBlend               = GetDx12Blend(inBlend.m_srcBlend);
			outBlend.DestBlend              = GetDx12Blend(inBlend.m_destBlend);
			outBlend.BlendOp                = GetDx12BlendOp(inBlend.m_blendOp);
			outBlend.SrcBlendAlpha          = GetDx12Blend(inBlend.m_srcBlendAlpha);
			outBlend.DestBlendAlpha         = GetDx12Blend(inBlend.m_destBlendAlpha);
			outBlend.BlendOpAlpha           = GetDx12BlendOp(inBlend.m_blendOpAlpha);
			outBlend.LogicOp                = GetDx12LogicOp(inBlend.m_logicOp);
			outBlend.RenderTargetWriteMask  = GetDx12RenderTargetWriteMask(inBlend.m_rtWriteMask);
		}

		for (UINT rt = 0; rt<psoDesc.NumRenderTargets; ++rt)
		{			
			psoDesc.RTVFormats[rt] = GetDx12Format(desc.m_rtvFormats[rt]);
		}
		psoDesc.DSVFormat = GetDx12Format(desc.m_dsvFormat);

		HRESULT hr = device.CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState));
		if(FAILED(hr))
		{
			SI_ASSERT(0);
			return -1;
		}
		
		if(desc.m_name)
		{
			wchar_t wName[64];
			wName[0] = 0;
			size_t num = 0;
			errno_t ret = mbstowcs_s(&num, wName, desc.m_name, ArraySize(wName));
			if(ret == 0)
			{
				m_pipelineState->SetName(wName);
			}
		}

		return 0;
	}
// Reads a set of properties for all objects.
void ReadContentPropertiesBulk(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                                       hr                = S_OK;
    GUID                                          guidContext       = GUID_NULL;
    CGetBulkValuesCallback*                       pCallback         = NULL;
    CComPtr<IPortableDeviceProperties>            pProperties;
    CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
    CComPtr<IPortableDeviceValues>                pObjectProperties;
    CComPtr<IPortableDeviceContent>               pContent;
    CComPtr<IPortableDeviceKeyCollection>         pPropertiesToRead;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;


    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) Check to see if the driver supports BULK property operations by call QueryInterface
    // on the IPortableDeviceProperties interface for IPortableDevicePropertiesBulk
    if (SUCCEEDED(hr))
    {
        hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
        if (FAILED(hr))
        {
            printf("This driver does not support BULK property operations.\n");
        }
    }

    // 4) CoCreate an IPortableDeviceKeyCollection interface to hold the the property keys
    // we wish to read.
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_PPV_ARGS(&pPropertiesToRead));
        if (FAILED(hr))
        {
            printf("! Failed to CoCreate IPortableDeviceKeyCollection to hold the property keys to read, hr = 0x%lx\n",hr);
        }
    }                              

    if (SUCCEEDED(hr))
    {
        // 5) Populate the IPortableDeviceKeyCollection with the keys we wish to read.
        // NOTE: We are not handling any special error cases here so we can proceed with
        // adding as many of the target properties as we can.
        if (pPropertiesToRead != NULL)
        {
            HRESULT hrTemp = S_OK;
            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PARENT_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PARENT_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_NAME);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PERSISTENT_UNIQUE_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_FORMAT);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_FORMAT to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_CONTENT_TYPE);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_CONTENT_TYPE to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }
        }
    }

    // 6) Create an instance of the IPortableDevicePropertiesBulkCallback object.
    if (SUCCEEDED(hr))
    {
        pCallback = new (std::nothrow) CGetBulkValuesCallback();
        if (pCallback == NULL)
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to allocate CGetBulkValuesCallback, hr = 0x%lx\n", hr);
        }
    }

    // 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
    // to enumerate and create an IPortableDevicePropVariantCollection with the object
    // identifiers needed to perform the bulk operation on.
    if (SUCCEEDED(hr))
    {
        hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pContent,
                                                                        &pObjectIDs);
    }


    // 8) Call QueueGetValuesByObjectList to initialize the Asynchronous
    // property operation.
    if (SUCCEEDED(hr))
    {
        hr = pPropertiesBulk->QueueGetValuesByObjectList(pObjectIDs,
                                                         pPropertiesToRead,
                                                         pCallback,
                                                         &guidContext);
        // 9) Call Start() to actually being the property operation
        if(SUCCEEDED(hr))
        {
            // Cleanup any previously created global event handles.
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                CloseHandle(g_hBulkPropertyOperationEvent);
                g_hBulkPropertyOperationEvent = NULL;
            }

            // In order to create a simpler to follow example we create and wait infinitly
            // for the bulk property operation to complete and ignore any errors.
            // Production code should be written in a more robust manner.
            // Create the global event handle to wait on for the bulk operation
            // to complete.
            g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                // Call Start() to actually being the Asynchronous bulk operation.
                hr = pPropertiesBulk->Start(guidContext);
                if(FAILED(hr))
                {
                    printf("! Failed to start property operation, hr = 0x%lx\n", hr);
                }
            }
            else
            {
                printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
            }
        }
        else
        {
            printf("! QueueGetValuesByObjectList Failed, hr = 0x%lx\n", hr);
        }
    }

    // In order to create a simpler to follow example we will wait infinitly for the operation
    // to complete and ignore any errors.  Production code should be written in a more
    // robust manner.
    if (SUCCEEDED(hr))
    {
        if (g_hBulkPropertyOperationEvent != NULL)
        {
            WaitForSingleObject(g_hBulkPropertyOperationEvent, INFINITE);
        }
    }

    if (pCallback != NULL)
    {
        pCallback->Release();
        pCallback = NULL;
    }

    // Cleanup any created global event handles before exiting..
    if (g_hBulkPropertyOperationEvent != NULL)
    {
        CloseHandle(g_hBulkPropertyOperationEvent);
        g_hBulkPropertyOperationEvent = NULL;
    }
}
Example #22
0
void loadAssets()
{
	//
	// handles to vert and pixel shaders
	//

	ComPtr<ID3DBlob> blobShaderVert, blobShaderPixel;

	//
	// compile shaders
	//

	D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "VShader", "vs_5_0", 0, 0, blobShaderVert.GetAddressOf(), nullptr);
	D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "PShader", "ps_5_0", 0, 0, blobShaderPixel.GetAddressOf(), nullptr);

	//
	// create input layout
	//

	D3D12_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_PER_VERTEX_DATA, 0 }
	};
	UINT numElements = sizeof(layout) / sizeof(layout[0]);

	//
	// create an empty root signature
	//

	ComPtr<ID3DBlob> pOutBlob, pErrorBlob;
	D3D12_ROOT_SIGNATURE_DESC descRootSignature;
	descRootSignature.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
	D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf());
	mDevice->CreateRootSignature(0, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), IID_PPV_ARGS(mRootSignature.GetAddressOf()));

	//
	// create a PSO description
	//

	D3D12_GRAPHICS_PIPELINE_STATE_DESC descPso;
	ZeroMemory(&descPso, sizeof(descPso));
	descPso.InputLayout = { layout, numElements };
	descPso.pRootSignature = mRootSignature.Get();
	descPso.VS = { reinterpret_cast<BYTE*>(blobShaderVert->GetBufferPointer()), blobShaderVert->GetBufferSize() };
	descPso.PS = { reinterpret_cast<BYTE*>(blobShaderPixel->GetBufferPointer()), blobShaderPixel->GetBufferSize() };
	descPso.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
	descPso.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
	descPso.DepthStencilState.DepthEnable = FALSE;
	descPso.DepthStencilState.StencilEnable = FALSE;
	descPso.SampleMask = UINT_MAX;
	descPso.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
	descPso.NumRenderTargets = 1;
	descPso.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
	descPso.SampleDesc.Count = 1;

	//
	// create the actual PSO
	//

	mDevice->CreateGraphicsPipelineState(&descPso, IID_PPV_ARGS(mPSO.GetAddressOf()));

	//
	// create descriptor heap
	//

	D3D12_DESCRIPTOR_HEAP_DESC descHeap = {};
	descHeap.NumDescriptors = 1;
	descHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
	descHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
	mDevice->CreateDescriptorHeap(&descHeap, IID_PPV_ARGS(mDescriptorHeap.GetAddressOf()));

	//
	// create command list
	//

	mDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), mPSO.Get(), IID_PPV_ARGS(mCommandList.GetAddressOf()));

	//
	// create backbuffer/rendertarget
	//

	mSwapChain->GetBuffer(0, IID_PPV_ARGS(mRenderTarget.GetAddressOf()));
	mDevice->CreateRenderTargetView(mRenderTarget.Get(), nullptr, mDescriptorHeap->GetCPUDescriptorHandleForHeapStart());

	//
	// set the viewport
	//

	mViewPort =
	{
		0.0f,
		0.0f,
		static_cast<float>(mWidth),
		static_cast<float>(mHeight),
		0.0f,
		1.0f
	};

	//
	// create scissor rectangle
	//

	mRectScissor = { 0, 0, mWidth, mHeight };

	//
	// create geometry for a triangle
	//

	VERTEX triangleVerts[] =
	{
		{ 0.0f, 0.5f, 0.0f,{ 1.0f, 0.0f, 0.0f, 1.0f } },
		{ 0.45f, -0.5, 0.0f,{ 0.0f, 1.0f, 0.0f, 1.0f } },
		{ -0.45f, -0.5f, 0.0f,{ 0.0f, 0.0f, 1.0f, 1.0f } }
	};

	//
	// actually create the vert buffer
	// Note: using upload heaps to transfer static data like vert buffers is not recommended.
	// Every time the GPU needs it, the upload heap will be marshalled over.  Please read up on Default Heap usage.
	// An upload heap is used here for code simplicity and because there are very few verts to actually transfer
	//

	mDevice->CreateCommittedResource(
		&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
		D3D12_HEAP_FLAG_NONE,
		&CD3DX12_RESOURCE_DESC::Buffer(3 * sizeof(VERTEX)),
		D3D12_RESOURCE_STATE_GENERIC_READ,
		nullptr,    // Clear value
		IID_PPV_ARGS(mBufVerts.GetAddressOf()));

	//
	// copy the triangle data to the vertex buffer
	//

	UINT8* dataBegin;
	mBufVerts->Map(0, nullptr, reinterpret_cast<void**>(&dataBegin));
	memcpy(dataBegin, triangleVerts, sizeof(triangleVerts));
	mBufVerts->Unmap(0, nullptr);

	//
	// create vertex buffer view
	//

	mDescViewBufVert.BufferLocation = mBufVerts->GetGPUVirtualAddress();
	mDescViewBufVert.StrideInBytes = sizeof(VERTEX);
	mDescViewBufVert.SizeInBytes = sizeof(triangleVerts);

	//
	// create fencing object
	//

	mDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(mFence.GetAddressOf()));
	mCurrentFence = 1;

	//
	// close the command list and use it to execute the initial GPU setup
	//

	mCommandList->Close();
	ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
	mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	//
	// create event handle
	//

	mHandleEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);

	//
	// wait for the command list to execute; we are reusing the same command list in our main loop but for now, 
	// we just want to wait for setup to complete before continuing
	//

	waitForGPU();
}
// Reads properties for the user specified object.
void ReadContentProperties(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                               hr               = S_OK;
    WCHAR                                 szSelection[81]  = {0};
    CComPtr<IPortableDeviceProperties>    pProperties;
    CComPtr<IPortableDeviceValues>        pObjectProperties;
    CComPtr<IPortableDeviceContent>       pContent;
    CComPtr<IPortableDeviceKeyCollection> pPropertiesToRead;

    // Prompt user to enter an object identifier on the device to read properties from.
    printf("Enter the identifer of the object you wish to read properties from.\n>");
    hr = StringCbGetsW(szSelection,sizeof(szSelection));
    if (FAILED(hr))
    {
        printf("An invalid object identifier was specified, aborting property reading\n");
    }

    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pDevice->Content(&pContent);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) CoCreate an IPortableDeviceKeyCollection interface to hold the the property keys
    // we wish to read.
	//<SnippetContentProp1>
    hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_PPV_ARGS(&pPropertiesToRead));
    if (SUCCEEDED(hr))
    {
        // 4) Populate the IPortableDeviceKeyCollection with the keys we wish to read.
        // NOTE: We are not handling any special error cases here so we can proceed with
        // adding as many of the target properties as we can.
        if (pPropertiesToRead != NULL)
        {
            HRESULT hrTemp = S_OK;
            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PARENT_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PARENT_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_NAME);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PERSISTENT_UNIQUE_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_FORMAT);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_FORMAT to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_CONTENT_TYPE);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_CONTENT_TYPE to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }
        }
    }
	//</SnippetContentProp1>
	// 5) Call GetValues() passing the collection of specified PROPERTYKEYs.
	//<SnippetContentProp2>
    if (SUCCEEDED(hr))
    {
        hr = pProperties->GetValues(szSelection,         // The object whose properties we are reading
                                    pPropertiesToRead,   // The properties we want to read
                                    &pObjectProperties); // Driver supplied property values for the specified object
        if (FAILED(hr))
        {
            printf("! Failed to get all properties for object '%ws', hr= 0x%lx\n", szSelection, hr);
        }
    }
	//</SnippetContentProp2>
    // 6) Display the returned property values to the user
    if (SUCCEEDED(hr))
    {
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_PARENT_ID,            L"WPD_OBJECT_PARENT_ID");
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_NAME,                 L"WPD_OBJECT_NAME");
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_PERSISTENT_UNIQUE_ID, L"WPD_OBJECT_PERSISTENT_UNIQUE_ID");
        DisplayGuidProperty  (pObjectProperties, WPD_OBJECT_CONTENT_TYPE,         L"WPD_OBJECT_CONTENT_TYPE");
        DisplayGuidProperty  (pObjectProperties, WPD_OBJECT_FORMAT,               L"WPD_OBJECT_FORMAT");
    }
}
Example #24
0
  void Read(const SmallPsoDiskDesc &key, const u8* value, u32 value_size)
  {
    if (s_cache_is_corrupted)
      return;

    D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {};
    desc.GS = ShaderCache::GetGeometryShaderFromUid(key.gs_uid);
    if (key.using_uber_pixel_shader)
    {
      desc.PS = ShaderCache::GetPixelUberShaderFromUid(key.pus_uid);
    }
    else
    {
      desc.PS = ShaderCache::GetPixelShaderFromUid(key.ps_uid);
    }
    if (key.using_uber_vertex_shader)
    {
      desc.VS = ShaderCache::GetVertexShaderFromUid(key.vs_uid);
    }
    else
    {
      desc.VS = ShaderCache::GetVertexUberShaderFromUid(key.vus_uid);
    }
    desc.HS = ShaderCache::GetHullShaderFromUid(key.hds_uid);
    desc.DS = ShaderCache::GetDomainShaderFromUid(key.hds_uid);
    D3D::SetRootSignature(desc.GS.pShaderBytecode != nullptr, desc.HS.pShaderBytecode != nullptr, false);
    desc.pRootSignature = D3D::GetRootSignature(static_cast<size_t>(key.root_signature_index));
    desc.RTVFormats[0] = key.rtformat; // This state changes in PSTextureEncoder::Encode.
    desc.DSVFormat = DXGI_FORMAT_D32_FLOAT; // This state changes in PSTextureEncoder::Encode.
    desc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
    desc.NumRenderTargets = 1;
    desc.SampleMask = UINT_MAX;
    desc.SampleDesc = key.sample_desc;

    if (!desc.PS.pShaderBytecode || !desc.VS.pShaderBytecode)
    {
      s_cache_is_corrupted = true;
      return;
    }

    BlendingState blend_state = {};
    blend_state.hex = key.blend_state_hex;
    desc.BlendState = StateCache::GetDesc(blend_state);

    DepthState depth_stencil_state = {};
    depth_stencil_state.hex = key.depth_stencil_state_hex;
    desc.DepthStencilState = StateCache::GetDesc(depth_stencil_state);

    RasterizationState rasterizer_state = {};
    rasterizer_state.hex = key.rasterizer_state_hex;
    desc.RasterizerState = StateCache::GetDesc(rasterizer_state);

    desc.PrimitiveTopologyType = key.topology;

    // search for a cached native vertex format
    const PortableVertexDeclaration& native_vtx_decl = key.vertex_declaration;
    NativeVertexFormat* native = VertexLoaderManager::GetOrCreateMatchingFormat(native_vtx_decl);

    desc.InputLayout = static_cast<D3DVertexFormat*>(native)->GetActiveInputLayout();

    desc.CachedPSO.CachedBlobSizeInBytes = value_size;
    desc.CachedPSO.pCachedBlob = value;

    ComPtr<ID3D12PipelineState> pso;
    HRESULT hr = D3D::device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(pso.ReleaseAndGetAddressOf()));

    if (FAILED(hr))
    {
      // Failure can occur if disk cache is corrupted, or a driver upgrade invalidates the existing blobs.
      // In this case, we need to clear the disk cache.
      s_cache_is_corrupted = true;
      return;
    }

    SmallPsoDesc small_desc = {};
    small_desc.using_uber_pixel_shader = key.using_uber_pixel_shader;
    small_desc.using_uber_vertex_shader = key.using_uber_vertex_shader;
    small_desc.blend_state.hex = key.blend_state_hex;
    small_desc.depth_stencil_state.hex = key.depth_stencil_state_hex;
    small_desc.rasterizer_state.hex = key.rasterizer_state_hex;
    small_desc.gs_bytecode = desc.GS;
    small_desc.vs_bytecode = desc.VS;
    small_desc.ps_bytecode = desc.PS;
    small_desc.hs_bytecode = desc.HS;
    small_desc.ds_bytecode = desc.DS;
    small_desc.input_Layout = static_cast<D3DVertexFormat*>(native);
    small_desc.sample_count = key.sample_desc.Count;
    small_desc.rtformat = key.rtformat;
    s_gx_state_cache.m_small_pso_map[small_desc] = pso;
  }
// Load the sample assets.
void D3D12PredicationQueries::LoadAssets()
{
	// Create a root signature consisting of a single CBV parameter.
	{
		D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {};

		// This is the highest version the sample supports. If CheckFeatureSupport succeeds, the HighestVersion returned will not be greater than this.
		featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;

		if (FAILED(m_device->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData))))
		{
			featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
		}

		CD3DX12_DESCRIPTOR_RANGE1 ranges[1];
		CD3DX12_ROOT_PARAMETER1 rootParameters[1];

		ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
		rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_VERTEX);

		// Allow input layout and deny uneccessary access to certain pipeline stages.
		D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
			D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;

		CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
		rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags);

		ComPtr<ID3DBlob> signature;
		ComPtr<ID3DBlob> error;
		ThrowIfFailed(D3DX12SerializeVersionedRootSignature(&rootSignatureDesc, featureData.HighestVersion, &signature, &error));
		ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
		NAME_D3D12_OBJECT(m_rootSignature);
	}

	// Create the pipeline state, which includes compiling and loading shaders.
	{
		ComPtr<ID3DBlob> vertexShader;
		ComPtr<ID3DBlob> pixelShader;

#if defined(_DEBUG)
		// Enable better shader debugging with the graphics debugging tools.
		UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
		UINT compileFlags = 0;
#endif

		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr));
		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr));

		// Define the vertex input layout.
		D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
		};

		// Enable alpha blending so we can visualize the occlusion query results.
		CD3DX12_BLEND_DESC blendDesc(D3D12_DEFAULT);
		blendDesc.RenderTarget[0] =
		{
			TRUE, FALSE,
			D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
			D3D12_LOGIC_OP_NOOP,
			D3D12_COLOR_WRITE_ENABLE_ALL,
		};

		// Describe and create the graphics pipeline state objects (PSO).
		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
		psoDesc.pRootSignature = m_rootSignature.Get();
		psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get());
		psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get());
		psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
		psoDesc.BlendState = blendDesc;
		psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
		psoDesc.SampleMask = UINT_MAX;
		psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		psoDesc.NumRenderTargets = 1;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
		psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
		psoDesc.SampleDesc.Count = 1;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));
		NAME_D3D12_OBJECT(m_pipelineState);

		// Disable color writes and depth writes for the occlusion query's state.
		psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0;
		psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_queryState)));
		NAME_D3D12_OBJECT(m_queryState);
	}

	// Create the command list.
	ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList)));
	NAME_D3D12_OBJECT(m_commandList);

	// Note: ComPtr's are CPU objects but this resource needs to stay in scope until
	// the command list that references it has finished executing on the GPU.
	// We will flush the GPU at the end of this method to ensure the resource is not
	// prematurely destroyed.
	ComPtr<ID3D12Resource> vertexBufferUpload;

	// Create the vertex buffer.
	{
		// Create geometry for two quads and a bounding box for the occlusion query.
		// Geometry will be rendered back-to-front to support transparency in the scene.
		Vertex quadVertices[] =
		{
			// Far quad - in practice this would be a complex geometry.
			{ { -0.25f, -0.25f * m_aspectRatio, 0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
			{ { -0.25f, 0.25f * m_aspectRatio, 0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
			{ { 0.25f, -0.25f * m_aspectRatio, 0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
			{ { 0.25f, 0.25f * m_aspectRatio, 0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },

			// Near quad.
			{ { -0.5f, -0.35f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 0.65f } },
			{ { -0.5f, 0.35f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 0.65f } },
			{ { 0.5f, -0.35f * m_aspectRatio, 0.0f }, { 1.0f, 1.0f, 0.0f, 0.65f } },
			{ { 0.5f, 0.35f * m_aspectRatio, 0.0f }, { 1.0f, 1.0f, 0.0f, 0.65f } },

			// Far quad bounding box used for occlusion query (offset slightly to avoid z-fighting).
			{ { -0.25f, -0.25f * m_aspectRatio, 0.4999f }, { 0.0f, 0.0f, 0.0f, 1.0f } },
			{ { -0.25f, 0.25f * m_aspectRatio, 0.4999f }, { 0.0f, 0.0f, 0.0f, 1.0f } },
			{ { 0.25f, -0.25f * m_aspectRatio, 0.4999f }, { 0.0f, 0.0f, 0.0f, 1.0f } },
			{ { 0.25f, 0.25f * m_aspectRatio, 0.4999f }, { 0.0f, 0.0f, 0.0f, 1.0f } },
		};

		const UINT vertexBufferSize = sizeof(quadVertices);

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_vertexBuffer)));

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&vertexBufferUpload)));

		NAME_D3D12_OBJECT(m_vertexBuffer);

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the vertex buffer.
		D3D12_SUBRESOURCE_DATA vertexData = {};
		vertexData.pData = reinterpret_cast<UINT8*>(quadVertices);
		vertexData.RowPitch = vertexBufferSize;
		vertexData.SlicePitch = vertexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUpload.Get(), 0, 0, 1, &vertexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

		// Initialize the vertex buffer view.
		m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
		m_vertexBufferView.StrideInBytes = sizeof(Vertex);
		m_vertexBufferView.SizeInBytes = sizeof(quadVertices);
	}

	// Create the constant buffers.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(FrameCount * sizeof(m_constantBufferData)),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&m_constantBuffer)));

		NAME_D3D12_OBJECT(m_constantBuffer);

		// Initialize and map the constant buffers. We don't unmap this until the
		// app closes. Keeping things mapped for the lifetime of the resource is okay.
		ZeroMemory(&m_constantBufferData, sizeof(m_constantBufferData));
		CD3DX12_RANGE readRange(0, 0);		// We do not intend to read from this resource on the CPU.
		ThrowIfFailed(m_constantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&m_pCbvDataBegin)));
		ZeroMemory(m_pCbvDataBegin, FrameCount * sizeof(m_constantBufferData));

		// Create constant buffer views to access the upload buffer.
		CD3DX12_CPU_DESCRIPTOR_HANDLE cpuHandle(m_cbvHeap->GetCPUDescriptorHandleForHeapStart());
		D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = m_constantBuffer->GetGPUVirtualAddress();

		D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
		cbvDesc.SizeInBytes = sizeof(SceneConstantBuffer);

		for (UINT n = 0; n < FrameCount; n++)
		{
			cbvDesc.BufferLocation = gpuAddress;

			m_device->CreateConstantBufferView(&cbvDesc, cpuHandle);

			cpuHandle.Offset(m_cbvSrvDescriptorSize);
			gpuAddress += cbvDesc.SizeInBytes;
			cbvDesc.BufferLocation = gpuAddress;

			m_device->CreateConstantBufferView(&cbvDesc, cpuHandle);

			cpuHandle.Offset(m_cbvSrvDescriptorSize);
			gpuAddress += cbvDesc.SizeInBytes;
		}
	}

	// Create the depth stencil view.
	{
		D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
		depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
		depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
		depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

		D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
		depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
		depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
		depthOptimizedClearValue.DepthStencil.Stencil = 0;

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
			D3D12_RESOURCE_STATE_DEPTH_WRITE,
			&depthOptimizedClearValue,
			IID_PPV_ARGS(&m_depthStencil)
			));

		NAME_D3D12_OBJECT(m_depthStencil);

		m_device->CreateDepthStencilView(m_depthStencil.Get(), &depthStencilDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
	}

	// Create the query result buffer.
	{
		D3D12_RESOURCE_DESC queryResultDesc = CD3DX12_RESOURCE_DESC::Buffer(8);
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&queryResultDesc,
			D3D12_RESOURCE_STATE_PREDICATION,
			nullptr,
			IID_PPV_ARGS(&m_queryResult)
			));

		NAME_D3D12_OBJECT(m_queryResult);
	}

	// Close the command list and execute it to begin the vertex buffer copy into
	// the default heap.
	ThrowIfFailed(m_commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	{
		ThrowIfFailed(m_device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
		m_fenceValues[m_frameIndex]++;

		// Create an event handle to use for frame synchronization.
		m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
		if (m_fenceEvent == nullptr)
		{
			ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
		}

		// Wait for the command list to execute; we are reusing the same command 
		// list in our main loop but for now, we just want to wait for setup to 
		// complete before continuing.
		WaitForGpu();
	}
}
Example #26
0
HRESULT StateCache::GetPipelineStateObjectFromCache(const SmallPsoDesc& pso_desc, ID3D12PipelineState** pso, D3D12_PRIMITIVE_TOPOLOGY_TYPE topology)
{
  auto it = m_small_pso_map.find(pso_desc);

  if (it == m_small_pso_map.end())
  {
    // Not found, create new PSO.

    // RootSignature, SampleMask, NumRenderTargets, RTVFormats, DSVFormat
    // never change so they are set in constructor and forgotten.
    m_current_pso_desc.GS = pso_desc.gs_bytecode;
    m_current_pso_desc.PS = pso_desc.ps_bytecode;
    m_current_pso_desc.VS = pso_desc.vs_bytecode;
    m_current_pso_desc.HS = pso_desc.hs_bytecode;
    m_current_pso_desc.DS = pso_desc.ds_bytecode;
    m_current_pso_desc.RTVFormats[0] = pso_desc.rtformat;
    m_current_pso_desc.pRootSignature = D3D::GetRootSignature();

    m_current_pso_desc.BlendState = GetDesc(pso_desc.blend_state);
    m_current_pso_desc.DepthStencilState = GetDesc(pso_desc.depth_stencil_state);
    m_current_pso_desc.RasterizerState = GetDesc(pso_desc.rasterizer_state);
    m_current_pso_desc.PrimitiveTopologyType = topology;
    m_current_pso_desc.InputLayout = pso_desc.input_Layout->GetActiveInputLayout();
    m_current_pso_desc.SampleDesc.Count = pso_desc.sample_count;

    ComPtr<ID3D12PipelineState> new_pso;
    HRESULT hr = D3D::device->CreateGraphicsPipelineState(&m_current_pso_desc, IID_PPV_ARGS(new_pso.ReleaseAndGetAddressOf()));

    if (FAILED(hr))
    {
      CheckHR(hr);
      return hr;
    }

    m_small_pso_map[pso_desc] = new_pso;
    *pso = new_pso.Get();

    if (m_enable_disk_cache)
    {
      // This contains all of the information needed to reconstruct a PSO at startup.
      SmallPsoDiskDesc disk_desc = {};
      disk_desc.using_uber_pixel_shader = pso_desc.using_uber_pixel_shader;
      disk_desc.using_uber_vertex_shader = pso_desc.using_uber_vertex_shader;
      disk_desc.root_signature_index = static_cast<u32>(D3D::GetRootSignatureIndex());
      disk_desc.blend_state_hex = pso_desc.blend_state.hex;
      disk_desc.depth_stencil_state_hex = pso_desc.depth_stencil_state.hex;
      disk_desc.rasterizer_state_hex = pso_desc.rasterizer_state.hex;
      disk_desc.gs_uid = ShaderCache::GetActiveGeometryShaderUid();
      if (pso_desc.using_uber_pixel_shader)
      {
        disk_desc.pus_uid = ShaderCache::GetActivePixelUberShaderUid();
      }
      else
      {
        disk_desc.ps_uid = ShaderCache::GetActivePixelShaderUid();
      }
      if (pso_desc.using_uber_vertex_shader)
      {
        disk_desc.vus_uid = ShaderCache::GetActiveVertexUberShaderUid();
      }
      else
      {
        disk_desc.vs_uid = ShaderCache::GetActiveVertexShaderUid();
      }
      
      disk_desc.hds_uid = ShaderCache::GetActiveTessellationShaderUid();
      disk_desc.vertex_declaration = pso_desc.input_Layout->GetVertexDeclaration();
      disk_desc.topology = topology;
      disk_desc.sample_desc.Count = g_ActiveConfig.iMultisamples;
      disk_desc.rtformat = pso_desc.rtformat;
      // This shouldn't fail.. but if it does, don't cache to disk.
      ComPtr<ID3DBlob> psoBlob;
      hr = new_pso->GetCachedBlob(psoBlob.ReleaseAndGetAddressOf());
      if (SUCCEEDED(hr))
      {
        s_pso_disk_cache.Append(disk_desc, reinterpret_cast<const u8*>(psoBlob->GetBufferPointer()), static_cast<u32>(psoBlob->GetBufferSize()));
      }
    }
  }
  else
  {
    *pso = it->second.Get();
  }

  return S_OK;
}
Example #27
0
BOOL CPPageOutput::OnInitDialog()
{
    __super::OnInitDialog();

    SetHandCursor(m_hWnd, IDC_AUDRND_COMBO);

    const CAppSettings& s = AfxGetAppSettings();
    const CRenderersSettings& r = s.m_RenderersSettings;

    m_iDSVideoRendererType  = s.iDSVideoRendererType;
    m_iRMVideoRendererType  = s.iRMVideoRendererType;
    m_iQTVideoRendererType  = s.iQTVideoRendererType;

    m_APSurfaceUsageCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_SURF_OFFSCREEN));
    m_APSurfaceUsageCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_SURF_2D));
    m_APSurfaceUsageCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_SURF_3D));
    CorrectComboListWidth(m_APSurfaceUsageCtrl);
    m_iAPSurfaceUsage       = r.iAPSurfaceUsage;

    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZE_NN));
    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZER_BILIN));
    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZER_BIL_PS));
    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZER_BICUB1));
    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZER_BICUB2));
    m_DX9ResizerCtrl.AddString(ResStr(IDS_PPAGE_OUTPUT_RESIZER_BICUB3));
    m_iDX9Resizer           = r.iDX9Resizer;

    m_fVMR9MixerMode        = r.fVMR9MixerMode;
    m_fVMR9MixerYUV         = r.fVMR9MixerYUV;
    m_fVMR9AlterativeVSync  = r.m_AdvRendSets.bVMR9AlterativeVSync;
    m_fD3DFullscreen        = s.fD3DFullscreen;

    int EVRBuffers[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 35, 40, 45, 50, 55, 60 };
    CString EVRBuffer;
    for (size_t i = 0; i < _countof(EVRBuffers); i++) {
        EVRBuffer.Format(_T("%d"), EVRBuffers[i]);
        m_EVRBuffersCtrl.AddString(EVRBuffer);
    }
    m_iEvrBuffers.Format(_T("%d"), r.iEvrBuffers);

    m_iAudioRendererTypeCtrl.SetRedraw(FALSE);
    m_fResetDevice = s.m_RenderersSettings.fResetDevice;
    m_AudioRendererDisplayNames.Add(_T(""));
    m_iAudioRendererTypeCtrl.AddString(_T("1: ") + ResStr(IDS_PPAGE_OUTPUT_SYS_DEF));
    m_iAudioRendererType = 0;

    int i = 2;
    CString Cbstr;

    BeginEnumSysDev(CLSID_AudioRendererCategory, pMoniker) {
        CComHeapPtr<OLECHAR> olestr;
        if (FAILED(pMoniker->GetDisplayName(0, 0, &olestr))) {
            continue;
        }

        CStringW str(olestr);

        m_AudioRendererDisplayNames.Add(CString(str));

        CComPtr<IPropertyBag> pPB;
        if (SUCCEEDED(pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)))) {
            CComVariant var;
            if (SUCCEEDED(pPB->Read(_T("FriendlyName"), &var, nullptr))) {
                CString fstr(var.bstrVal);

                var.Clear();
                if (SUCCEEDED(pPB->Read(_T("FilterData"), &var, nullptr))) {
                    BSTR* pbstr;
                    if (SUCCEEDED(SafeArrayAccessData(var.parray, (void**)&pbstr))) {
                        fstr.Format(_T("%s (%08x)"), CString(fstr), *((DWORD*)pbstr + 1));
                        SafeArrayUnaccessData(var.parray);
                    }
                }
                Cbstr.Format(_T("%d: %s"), i, fstr);
            }
        } else {
            Cbstr.Format(_T("%d: %s"), i, CString(str));
        }
        m_iAudioRendererTypeCtrl.AddString(Cbstr);

        if (s.strAudioRendererDisplayName == str && m_iAudioRendererType == 0) {
            m_iAudioRendererType = m_iAudioRendererTypeCtrl.GetCount() - 1;
        }
        i++;
    }
HRESULT cDxCapture::GetInterfaces(void)
{
	HRESULT hr;

	// Create the filter graph
	hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
		IID_IGraphBuilder, (void **)&m_pGraph);
	if (FAILED(hr))
		return hr;

	// Create the capture graph builder
	hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
		IID_ICaptureGraphBuilder2, (void **)&m_pCapture);
	if (FAILED(hr))
		return hr;

	// Create the Sample Grabber filter.
	hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
		IID_PPV_ARGS(&m_pGrabberF));
	if (FAILED(hr))
		return hr;

	hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
		IID_PPV_ARGS(&m_pNullF));
	if (FAILED(hr))
		return hr;


	// Obtain interfaces for media control and Video Window
	hr = m_pGraph->QueryInterface(IID_IMediaControl, (LPVOID *)&m_pMC);
	if (FAILED(hr))
		return hr;

	hr = m_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *)&m_pVW);
	if (FAILED(hr))
		return hr;

	hr = m_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_pME);
	if (FAILED(hr))
		return hr;


	hr = m_pGraph->AddFilter(m_pGrabberF, L"Sample Grabber");
	if (FAILED(hr))
		return hr;

	hr = m_pGrabberF->QueryInterface(IID_PPV_ARGS(&m_pGrabber));
	if (FAILED(hr))
		return hr;

	// Set the window handle used to process graph events
	//	hr = m_pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0);


	AM_MEDIA_TYPE mt;
	ZeroMemory(&mt, sizeof(mt));
	mt.majortype = MEDIATYPE_Video;
	//mt.subtype = MEDIASUBTYPE_RGB8;
	mt.subtype = MEDIASUBTYPE_RGB24;
	hr = m_pGrabber->SetMediaType(&mt);
	if (FAILED(hr))
		return hr;

	return hr;
}
// Load the rendering pipeline dependencies.
void D3D12Bundles::LoadPipeline()
{
#if defined(_DEBUG)
	// Enable the D3D12 debug layer.
	{
		ComPtr<ID3D12Debug> debugController;
		if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
		{
			debugController->EnableDebugLayer();
		}
	}
#endif

	ComPtr<IDXGIFactory4> factory;
	ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

	if (m_useWarpDevice)
	{
		ComPtr<IDXGIAdapter> warpAdapter;
		ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

		ThrowIfFailed(D3D12CreateDevice(
			warpAdapter.Get(),
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_device)
			));
	}
	else
	{
		ComPtr<IDXGIAdapter1> hardwareAdapter;
		GetHardwareAdapter(factory.Get(), &hardwareAdapter);

		ThrowIfFailed(D3D12CreateDevice(
			hardwareAdapter.Get(),
			D3D_FEATURE_LEVEL_11_0,
			IID_PPV_ARGS(&m_device)
			));
	}

	// Describe and create the command queue.
	D3D12_COMMAND_QUEUE_DESC queueDesc = {};
	queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
	queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

	ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
	NAME_D3D12_OBJECT(m_commandQueue);

	// Describe and create the swap chain.
	DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
	swapChainDesc.BufferCount = FrameCount;
	swapChainDesc.Width = m_width;
	swapChainDesc.Height = m_height;
	swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	swapChainDesc.SampleDesc.Count = 1;

	ComPtr<IDXGISwapChain1> swapChain;
	ThrowIfFailed(factory->CreateSwapChainForCoreWindow(
		m_commandQueue.Get(),		// Swap chain needs the queue so that it can force a flush on it.
		reinterpret_cast<IUnknown*>(Windows::UI::Core::CoreWindow::GetForCurrentThread()),
		&swapChainDesc,
		nullptr,
		&swapChain
		));

	ThrowIfFailed(swapChain.As(&m_swapChain));
	m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

	// Create descriptor heaps.
	{
		// Describe and create a render target view (RTV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
		rtvHeapDesc.NumDescriptors = FrameCount;
		rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
		rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

		// Describe and create a depth stencil view (DSV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
		dsvHeapDesc.NumDescriptors = 1;
		dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
		dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));

		// Describe and create a shader resource view (SRV) and constant 
		// buffer view (CBV) descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC cbvSrvHeapDesc = {};
		cbvSrvHeapDesc.NumDescriptors =
			FrameCount * CityRowCount * CityColumnCount		// FrameCount frames * CityRowCount * CityColumnCount.
			+ 1;											// + 1 for the SRV.
		cbvSrvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
		cbvSrvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&cbvSrvHeapDesc, IID_PPV_ARGS(&m_cbvSrvHeap)));
		NAME_D3D12_OBJECT(m_cbvSrvHeap);

		// Describe and create a sampler descriptor heap.
		D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = {};
		samplerHeapDesc.NumDescriptors = 1;
		samplerHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
		samplerHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
		ThrowIfFailed(m_device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerHeap)));

		m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
		m_cbvSrvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
	}

	ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator)));
}
Example #30
-1
CBrowseFolder::retVal CBrowseFolder::Show(HWND parent, CString& path, const CString& sDefaultPath /* = CString() */)
{
    retVal ret = OK;        //assume OK
    m_sDefaultPath = sDefaultPath;
    if (m_sDefaultPath.IsEmpty() && !path.IsEmpty())
    {
        while (!PathFileExists(path) && !path.IsEmpty())
        {
            CString p = path.Left(path.ReverseFind('\\'));
            if ((p.GetLength() == 2)&&(p[1] == ':'))
            {
                p += L"\\";
                if (p.Compare(path) == 0)
                    p.Empty();
            }
            if (p.GetLength() < 2)
                p.Empty();
            path = p;
        }
        // if the result path already contains a path, use that as the default path
        m_sDefaultPath = path;
    }

    HRESULT hr;

    // Create a new common open file dialog
    IFileOpenDialog* pfd = NULL;
    hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Set the dialog as a folder picker
        DWORD dwOptions;
        if (SUCCEEDED(hr = pfd->GetOptions(&dwOptions)))
        {
            hr = pfd->SetOptions(dwOptions | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST);
        }

        // Set a title
        if (SUCCEEDED(hr))
        {
            TCHAR * nl = wcschr(m_title, '\n');
            if (nl)
                *nl = 0;
            pfd->SetTitle(m_title);
        }

        // set the default folder
        if (SUCCEEDED(hr))
        {
            IShellItem *psiDefault = 0;
            hr = SHCreateItemFromParsingName(m_sDefaultPath, NULL, IID_PPV_ARGS(&psiDefault));
            if (SUCCEEDED(hr))
            {
                hr = pfd->SetFolder(psiDefault);
                psiDefault->Release();
            }
        }

        if (m_CheckText[0] != 0)
        {
            IFileDialogCustomize* pfdCustomize = 0;
            hr = pfd->QueryInterface(IID_PPV_ARGS(&pfdCustomize));
            if (SUCCEEDED(hr))
            {
                pfdCustomize->StartVisualGroup(100, L"");
                pfdCustomize->AddCheckButton(101, m_CheckText, FALSE);
                if (m_CheckText2[0] != 0)
                {
                    pfdCustomize->AddCheckButton(102, m_CheckText2, FALSE);
                }
                pfdCustomize->EndVisualGroup();
                pfdCustomize->Release();
            }
        }

        // Show the open file dialog
        if (SUCCEEDED(hr) && SUCCEEDED(hr = pfd->Show(parent)))
        {
            // Get the selection from the user
            IShellItem* psiResult = NULL;
            hr = pfd->GetResult(&psiResult);
            if (SUCCEEDED(hr))
            {
                PWSTR pszPath = NULL;
                hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
                if (SUCCEEDED(hr))
                {
                    path = pszPath;
                    CoTaskMemFree(pszPath);
                }
                psiResult->Release();

                IFileDialogCustomize* pfdCustomize = 0;
                hr = pfd->QueryInterface(IID_PPV_ARGS(&pfdCustomize));
                if (SUCCEEDED(hr))
                {
                    pfdCustomize->GetCheckButtonState(101, &m_bCheck);
                    pfdCustomize->GetCheckButtonState(102, &m_bCheck2);
                    pfdCustomize->Release();
                }
            }
            else
                ret = CANCEL;
        }
        else
            ret = CANCEL;

        pfd->Release();
    }
    else
    {
        BROWSEINFO browseInfo       = {};
        browseInfo.hwndOwner        = parent;
        browseInfo.pidlRoot         = m_root;
        browseInfo.pszDisplayName   = m_displayName;
        browseInfo.lpszTitle        = m_title;
        browseInfo.ulFlags          = m_style;
        browseInfo.lParam           = (LPARAM)this;
        browseInfo.lpfn             = BrowseCallBackProc;

        PCIDLIST_ABSOLUTE itemIDList = SHBrowseForFolder(&browseInfo);

        //is the dialog canceled?
        if (!itemIDList)
            ret = CANCEL;

        if (ret != CANCEL)
        {
            if (!SHGetPathFromIDList(itemIDList, path.GetBuffer(MAX_PATH)))     // MAX_PATH ok. Explorer can't handle paths longer than MAX_PATH.
                ret = NOPATH;

            path.ReleaseBuffer();

            CoTaskMemFree((LPVOID)itemIDList);
        }
    }

    return ret;
}