// Load the rendering pipeline dependencies. void D3D12ExecuteIndirect::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 queues. 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); D3D12_COMMAND_QUEUE_DESC computeQueueDesc = {}; computeQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; computeQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; ThrowIfFailed(m_device->CreateCommandQueue(&computeQueueDesc, IID_PPV_ARGS(&m_computeCommandQueue))); NAME_D3D12_OBJECT(m_computeCommandQueue); // 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), Shader resource // view (SRV), and unordered access view (UAV) descriptor heap. D3D12_DESCRIPTOR_HEAP_DESC cbvSrvUavHeapDesc = {}; cbvSrvUavHeapDesc.NumDescriptors = CbvSrvUavDescriptorCountPerFrame * FrameCount; cbvSrvUavHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; cbvSrvUavHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; ThrowIfFailed(m_device->CreateDescriptorHeap(&cbvSrvUavHeapDesc, IID_PPV_ARGS(&m_cbvSrvUavHeap))); NAME_D3D12_OBJECT(m_cbvSrvUavHeap); m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_cbvSrvUavDescriptorSize = 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 command allocators 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]))); ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&m_computeCommandAllocators[n]))); } } }
/** * List network interfaces information (bridged/host only). * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. * @param fIsBridged Selects between listing host interfaces (for * use with bridging) or host only interfaces. */ static HRESULT listNetworkInterfaces(const ComPtr<IVirtualBox> pVirtualBox, bool fIsBridged) { HRESULT rc; ComPtr<IHost> host; CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); com::SafeIfaceArray<IHostNetworkInterface> hostNetworkInterfaces; #if defined(VBOX_WITH_NETFLT) if (fIsBridged) CHECK_ERROR(host, FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_Bridged, ComSafeArrayAsOutParam(hostNetworkInterfaces))); else CHECK_ERROR(host, FindHostNetworkInterfacesOfType(HostNetworkInterfaceType_HostOnly, ComSafeArrayAsOutParam(hostNetworkInterfaces))); #else CHECK_ERROR(host, COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(hostNetworkInterfaces))); #endif for (size_t i = 0; i < hostNetworkInterfaces.size(); ++i) { ComPtr<IHostNetworkInterface> networkInterface = hostNetworkInterfaces[i]; #ifndef VBOX_WITH_HOSTNETIF_API Bstr interfaceName; networkInterface->COMGETTER(Name)(interfaceName.asOutParam()); RTPrintf("Name: %ls\n", interfaceName.raw()); Guid interfaceGuid; networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam()); RTPrintf("GUID: %ls\n\n", Bstr(interfaceGuid.toString()).raw()); #else /* VBOX_WITH_HOSTNETIF_API */ Bstr interfaceName; networkInterface->COMGETTER(Name)(interfaceName.asOutParam()); RTPrintf("Name: %ls\n", interfaceName.raw()); Bstr interfaceGuid; networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam()); RTPrintf("GUID: %ls\n", interfaceGuid.raw()); BOOL bDHCPEnabled; networkInterface->COMGETTER(DHCPEnabled)(&bDHCPEnabled); RTPrintf("DHCP: %s\n", bDHCPEnabled ? "Enabled" : "Disabled"); Bstr IPAddress; networkInterface->COMGETTER(IPAddress)(IPAddress.asOutParam()); RTPrintf("IPAddress: %ls\n", IPAddress.raw()); Bstr NetworkMask; networkInterface->COMGETTER(NetworkMask)(NetworkMask.asOutParam()); RTPrintf("NetworkMask: %ls\n", NetworkMask.raw()); Bstr IPV6Address; networkInterface->COMGETTER(IPV6Address)(IPV6Address.asOutParam()); RTPrintf("IPV6Address: %ls\n", IPV6Address.raw()); ULONG IPV6NetworkMaskPrefixLength; networkInterface->COMGETTER(IPV6NetworkMaskPrefixLength)(&IPV6NetworkMaskPrefixLength); RTPrintf("IPV6NetworkMaskPrefixLength: %d\n", IPV6NetworkMaskPrefixLength); Bstr HardwareAddress; networkInterface->COMGETTER(HardwareAddress)(HardwareAddress.asOutParam()); RTPrintf("HardwareAddress: %ls\n", HardwareAddress.raw()); HostNetworkInterfaceMediumType_T Type; networkInterface->COMGETTER(MediumType)(&Type); RTPrintf("MediumType: %s\n", getHostIfMediumTypeText(Type)); HostNetworkInterfaceStatus_T Status; networkInterface->COMGETTER(Status)(&Status); RTPrintf("Status: %s\n", getHostIfStatusText(Status)); Bstr netName; networkInterface->COMGETTER(NetworkName)(netName.asOutParam()); RTPrintf("VBoxNetworkName: %ls\n\n", netName.raw()); #endif } return rc; }
/** * List USB devices attached to the host. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listUsbHost(const ComPtr<IVirtualBox> &pVirtualBox) { HRESULT rc; ComPtr<IHost> Host; CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(Host.asOutParam()), 1); SafeIfaceArray<IHostUSBDevice> CollPtr; CHECK_ERROR_RET(Host, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(CollPtr)), 1); RTPrintf("Host USB Devices:\n\n"); if (CollPtr.size() == 0) { RTPrintf("<none>\n\n"); } else { for (size_t i = 0; i < CollPtr.size(); ++i) { ComPtr<IHostUSBDevice> dev = CollPtr[i]; /* Query info. */ Bstr id; CHECK_ERROR_RET(dev, COMGETTER(Id)(id.asOutParam()), 1); USHORT usVendorId; CHECK_ERROR_RET(dev, COMGETTER(VendorId)(&usVendorId), 1); USHORT usProductId; CHECK_ERROR_RET(dev, COMGETTER(ProductId)(&usProductId), 1); USHORT bcdRevision; CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), 1); USHORT usPort; CHECK_ERROR_RET(dev, COMGETTER(Port)(&usPort), 1); USHORT usVersion; CHECK_ERROR_RET(dev, COMGETTER(Version)(&usVersion), 1); USHORT usPortVersion; CHECK_ERROR_RET(dev, COMGETTER(PortVersion)(&usPortVersion), 1); RTPrintf("UUID: %s\n" "VendorId: %#06x (%04X)\n" "ProductId: %#06x (%04X)\n" "Revision: %u.%u (%02u%02u)\n" "Port: %u\n" "USB version/speed: %u/%u\n", Utf8Str(id).c_str(), usVendorId, usVendorId, usProductId, usProductId, bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff, usPort, usVersion, usPortVersion); /* optional stuff. */ Bstr bstr; CHECK_ERROR_RET(dev, COMGETTER(Manufacturer)(bstr.asOutParam()), 1); if (!bstr.isEmpty()) RTPrintf("Manufacturer: %ls\n", bstr.raw()); CHECK_ERROR_RET(dev, COMGETTER(Product)(bstr.asOutParam()), 1); if (!bstr.isEmpty()) RTPrintf("Product: %ls\n", bstr.raw()); CHECK_ERROR_RET(dev, COMGETTER(SerialNumber)(bstr.asOutParam()), 1); if (!bstr.isEmpty()) RTPrintf("SerialNumber: %ls\n", bstr.raw()); CHECK_ERROR_RET(dev, COMGETTER(Address)(bstr.asOutParam()), 1); if (!bstr.isEmpty()) RTPrintf("Address: %ls\n", bstr.raw()); /* current state */ USBDeviceState_T state; CHECK_ERROR_RET(dev, COMGETTER(State)(&state), 1); const char *pszState = "?"; switch (state) { case USBDeviceState_NotSupported: pszState = "Not supported"; break; case USBDeviceState_Unavailable: pszState = "Unavailable"; break; case USBDeviceState_Busy: pszState = "Busy"; break; case USBDeviceState_Available: pszState = "Available"; break; case USBDeviceState_Held: pszState = "Held"; break; case USBDeviceState_Captured: pszState = "Captured"; break; default: ASSERT(false); break; } RTPrintf("Current State: %s\n\n", pszState); } } return rc; }
void FrameMixer::ProcessFrame(ID3D11Device *pDevice, ID3D11Texture2D *pInput, UINT uiInIndex, ID3D11Texture2D *pOutput, UINT uiOutIndex) { ComPtr<ID3D11DeviceContext> spd3dImmediateContext; // Render targets ComPtr<ID3D11RenderTargetView> rgpOrigRTV; ComPtr<ID3D11DepthStencilView> pOrigDSV; ComPtr<ID3D11RenderTargetView> spRTV; // Shader resources ComPtr<ID3D11ShaderResourceView> rgpOrigSRV; ComPtr<ID3D11ShaderResourceView> spSRV; // Vertex buffers ID3D11Buffer *pBuffers[1] = { m_spScreenQuadVB.Get() }; UINT vbStrides = sizeof( ScreenVertex ); UINT vbOffsets = 0; // Samplers ID3D11SamplerState *pSamplers[1] = { m_spSampleStateLinear.Get() }; // View port D3D11_VIEWPORT vpOld[D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX]; UINT nViewPorts = 1; D3D11_VIEWPORT vp; // Transition parameter; TransitionParameter parameter = m_transition_parameter; // Get the context pDevice->GetImmediateContext(&spd3dImmediateContext); // Get the resource views ThrowIfError(CreateShaderInputView(pInput, uiInIndex, pDevice, &spSRV)); ThrowIfError(CreateShaderOutputView(pOutput, uiOutIndex, pDevice, &spRTV)); // Setup the Draw call spd3dImmediateContext->IASetInputLayout(m_spQuadLayout.Get()); spd3dImmediateContext->IASetVertexBuffers(0, 1, pBuffers, &vbStrides, &vbOffsets); spd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); spd3dImmediateContext->PSSetSamplers(0, 1, pSamplers); spd3dImmediateContext->OMGetRenderTargets(1, &rgpOrigRTV, &pOrigDSV); const FLOAT background_color[4] = { parameter.m_backgound_color[0], parameter.m_backgound_color[1], parameter.m_backgound_color[2], parameter.m_backgound_color[3] }; if (parameter.m_draw_background) { spd3dImmediateContext->ClearRenderTargetView(spRTV.Get(), background_color); } spd3dImmediateContext->OMSetRenderTargets(1, spRTV.GetAddressOf(), nullptr); // apply transform and fading XMStoreFloat4x4( &m_vsTransformBufferData.transform, XMMatrixTranspose(XMMatrixTranslation(parameter.m_offset_x, parameter.m_offset_y, parameter.m_offset_z) * XMMatrixScaling(parameter.m_scaling_x, parameter.m_scaling_y, 1.0)) ); m_psFadingBufferData.fading = parameter.m_fading_ratio; spd3dImmediateContext->UpdateSubresource(m_vsTransformBuffer.Get(), 0, nullptr, &m_vsTransformBufferData, 0, 0); spd3dImmediateContext->UpdateSubresource(m_psFadingBuffer.Get(), 0, nullptr, &m_psFadingBufferData, 0, 0); // spd3dImmediateContext->PSGetShaderResources(0, 1, &rgpOrigSRV); spd3dImmediateContext->PSSetShaderResources(0, 1, spSRV.GetAddressOf()); spd3dImmediateContext->RSGetViewports(&nViewPorts, vpOld); // Setup the viewport to match the backbuffer vp.Width = (float)m_uiWidth; vp.Height = (float)m_uiHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; spd3dImmediateContext->RSSetViewports(1, &vp); spd3dImmediateContext->VSSetShader(m_spVertexShader.Get(), nullptr, 0); // Set the vertex shader constant buffer data. spd3dImmediateContext->VSSetConstantBuffers(0, 1, m_vsTransformBuffer.GetAddressOf()); spd3dImmediateContext->PSSetShader(m_spPixelShader.Get(), nullptr, 0); // Set the pixel shader constant buffer data. spd3dImmediateContext->PSSetConstantBuffers(0, 1, m_psFadingBuffer.GetAddressOf()); UINT sampleMask = 0xffffffff; spd3dImmediateContext->OMSetBlendState(m_spBlendStateNoBlend.Get(), background_color, sampleMask); spd3dImmediateContext->Draw(4, 0); // Restore the Old spd3dImmediateContext->RSSetViewports(nViewPorts, vpOld); spd3dImmediateContext->PSSetShaderResources(0, 1, rgpOrigSRV.GetAddressOf()); spd3dImmediateContext->OMSetRenderTargets(1, rgpOrigRTV.GetAddressOf(), pOrigDSV.Get()); }
TESTENV_API BOOL WINAPI Startup(HINSTANCE hInstance, HWND hWnd) { HRESULT lastHR = CreateDXGIFactory2(NULL, IID_PPV_ARGS(m_dxgiFactory.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("CreateDXGIFactory2"), lastHR); ComPtr<IDXGIAdapter> adapter; lastHR = m_dxgiFactory->EnumAdapters(0, adapter.GetAddressOf()); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("DXGIAdapter - EnumAdapters"), lastHR); lastHR = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(m_dxDevice.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("D3D12CreateDevice"), lastHR); lastHR = m_dxDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(m_cmdAllocator.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("ID3D12Device - CreateCommandAllocator"), lastHR); D3D12_COMMAND_QUEUE_DESC descCommandQueue; ZeroMemory(&descCommandQueue, sizeof(descCommandQueue)); descCommandQueue.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; descCommandQueue.Priority = 0; descCommandQueue.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; lastHR = m_dxDevice->CreateCommandQueue(&descCommandQueue, IID_PPV_ARGS(m_cmdQueue.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("ID3D12Device - CreateCommandQueue"), lastHR); m_hFenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL); lastHR = m_dxDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_queueFence.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("ID3D12Device - CreateFence"), lastHR); DXGI_SWAP_CHAIN_DESC descSwapChain; ZeroMemory(&descSwapChain, sizeof(descSwapChain)); descSwapChain.BufferCount = 2; descSwapChain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; descSwapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; descSwapChain.OutputWindow = hWnd; descSwapChain.SampleDesc.Count = 1; descSwapChain.Windowed = TRUE; descSwapChain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; descSwapChain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; lastHR = m_dxgiFactory->CreateSwapChain(m_cmdQueue.Get(), &descSwapChain, (IDXGISwapChain**)m_swapChain.GetAddressOf()); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("IDXGIFactory3 - CreateSwapChain"), lastHR); lastHR = m_dxDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_cmdAllocator.Get(), nullptr, IID_PPV_ARGS(m_cmdList.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("ID3D12Device - CreateCommandList"), lastHR); D3D12_DESCRIPTOR_HEAP_DESC descHeap; ZeroMemory(&descHeap, sizeof(descHeap)); descHeap.NumDescriptors = 2; descHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; descHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; lastHR = m_dxDevice->CreateDescriptorHeap(&descHeap, IID_PPV_ARGS(m_descriptorHeapRTV.GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("ID3D12Device - CreateDescriptorHeap"), lastHR); UINT strideHandleBytes = m_dxDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); for (UINT i = 0; i < descSwapChain.BufferCount; ++i) { lastHR = m_swapChain->GetBuffer(i, IID_PPV_ARGS(m_renderTarget[i].GetAddressOf())); if (FAILED(lastHR)) return ShowErrorMessage(MB_ICONERROR, TEXT("IDXGISwapChain3 - GetBuffer"), lastHR); m_handleRTV[i] = m_descriptorHeapRTV->GetCPUDescriptorHandleForHeapStart(); m_handleRTV[i].ptr += i * strideHandleBytes; m_dxDevice->CreateRenderTargetView(m_renderTarget[i].Get(), nullptr, m_handleRTV[i]); } RECT wndRect; GetWindowRect(hWnd, &wndRect); Resize(wndRect.right - wndRect.left, wndRect.bottom - wndRect.top); m_viewport.TopLeftX = 0; m_viewport.TopLeftY = 0; m_viewport.MinDepth = 0; m_viewport.MaxDepth = 1; return TRUE; }
// Allocate all memory resources that depend on the window size. void Direct3DBase::CreateWindowSizeDependentResources() { // Create a descriptor for the render target buffer. CD3D11_TEXTURE2D_DESC renderTargetDesc( DXGI_FORMAT_B8G8R8A8_UNORM, static_cast<UINT>(m_renderTargetSize.Width), static_cast<UINT>(m_renderTargetSize.Height), 1, 1, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE ); renderTargetDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE; // Allocate a 2-D surface as the render target buffer. DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &renderTargetDesc, nullptr, &m_renderTarget ) ); DX::ThrowIfFailed( m_d3dDevice->CreateRenderTargetView( m_renderTarget.Get(), nullptr, &m_renderTargetView ) ); // Create a depth stencil view. CD3D11_TEXTURE2D_DESC depthStencilDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, static_cast<UINT>(m_renderTargetSize.Width), static_cast<UINT>(m_renderTargetSize.Height), 1, 1, D3D11_BIND_DEPTH_STENCIL ); ComPtr<ID3D11Texture2D> depthStencil; DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &depthStencilDesc, nullptr, &depthStencil ) ); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); DX::ThrowIfFailed( m_d3dDevice->CreateDepthStencilView( depthStencil.Get(), &depthStencilViewDesc, &m_depthStencilView ) ); // Set the rendering viewport to target the entire window. CD3D11_VIEWPORT viewport( 0.0f, 0.0f, m_renderTargetSize.Width, m_renderTargetSize.Height ); m_viewport = viewport; m_d3dContext->RSSetViewports(1, &viewport); }
// 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))); 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 } }; // 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_d3d12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); NAME_D3D12_OBJECT(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))); NAME_D3D12_OBJECT(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)); } // 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. { // 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))); 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*>(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 = 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 D3D12HelloTexture::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))); // 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))); // Describe and create a shader resource view (SRV) heap for the texture. D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {}; srvHeapDesc.NumDescriptors = 1; srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; ThrowIfFailed(m_device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&m_srvHeap))); m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); } // 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); } } ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator))); }
//----------------------------------------------------------------------------- // Enum each PNP device using WMI and check each device ID to see if it contains // "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device // Unfortunately this information can not be found by just using DirectInput. // Checking against a VID/PID of 0x028E/0x045E won't find 3rd party or future // XInput devices. //----------------------------------------------------------------------------- HRESULT get_xinput_devices(std::list<DWORD> &xinput_id_list) const { ComPtr<IWbemServices> pIWbemServices; ComPtr<IEnumWbemClassObject> pEnumDevices; ComPtr<IWbemLocator> pIWbemLocator; ComArray<IWbemClassObject> pDevices(20); bstr_ptr bstrDeviceID; bstr_ptr bstrClassName; bstr_ptr bstrNamespace; DWORD uReturned = 0; UINT iDevice; variant_wrapper var; HRESULT hr; // CoInit if needed CoInitialize(nullptr); // Create WMI hr = CoCreateInstance( __uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), reinterpret_cast<void**>(pIWbemLocator.GetAddressOf())); if (FAILED(hr) || pIWbemLocator == nullptr) { osd_printf_error("Creating WbemLocator failed. Error: 0x%X\n", static_cast<unsigned int>(hr)); return hr; } // Create BSTRs for WMI bstrNamespace = bstr_ptr(SysAllocString(L"\\\\.\\root\\cimv2")); bstrDeviceID = bstr_ptr(SysAllocString(L"DeviceID")); bstrClassName = bstr_ptr(SysAllocString(L"Win32_PNPEntity")); // Connect to WMI hr = pIWbemLocator->ConnectServer( bstrNamespace.get(), nullptr, nullptr, nullptr, 0L, nullptr, nullptr, pIWbemServices.GetAddressOf()); if (FAILED(hr) || pIWbemServices == nullptr) { osd_printf_error("Connecting to WMI Server failed. Error: 0x%X\n", static_cast<unsigned int>(hr)); return hr; } // Switch security level to IMPERSONATE (void)CoSetProxyBlanket( pIWbemServices.Get(), RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0); // Get list of Win32_PNPEntity devices hr = pIWbemServices->CreateInstanceEnum(bstrClassName.get(), 0, nullptr, pEnumDevices.GetAddressOf()); if (FAILED(hr) || pEnumDevices == nullptr) { osd_printf_error("Getting list of Win32_PNPEntity devices failed. Error: 0x%X\n", static_cast<unsigned int>(hr)); return hr; } // Loop over all devices for (; ; ) { // Get a few at a time hr = pEnumDevices->Next(10000, pDevices.Size(), pDevices.ReleaseAndGetAddressOf(), &uReturned); if (FAILED(hr)) { osd_printf_error("Enumerating WMI classes failed. Error: 0x%X\n", static_cast<unsigned int>(hr)); return hr; } if (uReturned == 0) break; for (iDevice = 0; iDevice < uReturned; iDevice++) { if (!pDevices[iDevice]) continue; // For each device, get its device ID hr = pDevices[iDevice]->Get(bstrDeviceID.get(), 0L, var.ClearAndGetAddressOf(), nullptr, nullptr); if (SUCCEEDED(hr) && var.Get().vt == VT_BSTR && var.Get().bstrVal != nullptr) { // Check if the device ID contains "IG_". If it does, then it's an XInput device // Unfortunately this information can not be found by just using DirectInput if (wcsstr(var.Get().bstrVal, L"IG_")) { // If it does, then get the VID/PID from var.bstrVal DWORD dwPid = 0, dwVid = 0; WCHAR* strVid = wcsstr(var.Get().bstrVal, L"VID_"); if (strVid && swscanf(strVid, L"VID_%4X", &dwVid) != 1) dwVid = 0; WCHAR* strPid = wcsstr(var.Get().bstrVal, L"PID_"); if (strPid && swscanf(strPid, L"PID_%4X", &dwPid) != 1) dwPid = 0; DWORD dwVidPid = MAKELONG(dwVid, dwPid); // Add the VID/PID to a linked list xinput_id_list.push_back(dwVidPid); } } } } if (SUCCEEDED(hr)) hr = S_OK; return hr; }
bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) { Q_UNUSED(windowFlags) Q_UNUSED(windowModality) Q_UNUSED(parent) Q_D(QWinRTMessageDialogHelper); QSharedPointer<QMessageDialogOptions> options = this->options(); const QString informativeText = options->informativeText(); const QString title = options->windowTitle(); const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText); HRESULT hr; ComPtr<IMessageDialogFactory> dialogFactory; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(), IID_PPV_ARGS(&dialogFactory)); RETURN_FALSE_IF_FAILED("Failed to create dialog factory"); ComPtr<IUICommandFactory> commandFactory; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(), IID_PPV_ARGS(&commandFactory)); RETURN_FALSE_IF_FAILED("Failed to create command factory"); ComPtr<IMessageDialog> dialog; HStringReference nativeText(reinterpret_cast<LPCWSTR>(text.utf16()), text.size()); if (!title.isEmpty()) { HStringReference nativeTitle(reinterpret_cast<LPCWSTR>(title.utf16()), title.size()); hr = dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog); RETURN_FALSE_IF_FAILED("Failed to create dialog with title"); } else { hr = dialogFactory->Create(nativeText.Get(), &dialog); RETURN_FALSE_IF_FAILED("Failed to create dialog"); } // Add Buttons ComPtr<IVector<IUICommand *>> dialogCommands; hr = dialog->get_Commands(&dialogCommands); RETURN_FALSE_IF_FAILED("Failed to get dialog commands"); // If no button is specified we need to create one to get close notification int buttons = options->standardButtons(); if (buttons == 0) buttons = Ok; for (int i = FirstButton; i < LastButton; i<<=1) { if (!(buttons & i)) continue; // Add native command const QString label = d->theme->standardButtonText(i); HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size()); ComPtr<IUICommand> command; hr = commandFactory->Create(nativeLabel.Get(), &command); RETURN_FALSE_IF_FAILED("Failed to create message box command"); ComPtr<IInspectable> id = Make<CommandId>(static_cast<StandardButton>(i)); hr = command->put_Id(id.Get()); RETURN_FALSE_IF_FAILED("Failed to set command ID"); hr = dialogCommands->Append(command.Get()); if (hr == E_BOUNDS) { qErrnoWarning(hr, "The WinRT message dialog supports a maximum of three buttons"); continue; } RETURN_FALSE_IF_FAILED("Failed to append message box command"); if (i == Abort || i == Cancel || i == Close) { quint32 size; hr = dialogCommands->get_Size(&size); RETURN_FALSE_IF_FAILED("Failed to get command list size"); hr = dialog->put_CancelCommandIndex(size - 1); RETURN_FALSE_IF_FAILED("Failed to set cancel index"); } } ComPtr<IAsyncOperation<IUICommand *>> op; hr = dialog->ShowAsync(&op); RETURN_FALSE_IF_FAILED("Failed to show dialog"); hr = op->put_Completed(Callback<DialogCompletedHandler>(this, &QWinRTMessageDialogHelper::onCompleted).Get()); RETURN_FALSE_IF_FAILED("Failed to set dialog callback"); d->shown = true; hr = op.As(&d->info); RETURN_FALSE_IF_FAILED("Failed to acquire AsyncInfo for MessageDialog"); return true; }
// Load the sample assets. void D3D12HelloTexture::LoadAssets() { // 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(m_device->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; #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 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_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))); } // Create the command list. ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 0.5f, 0.0f } }, { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 1.0f, 1.0f } }, { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f } } }; 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(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_vertexBuffer))); // Copy the triangle data 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_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin))); memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); m_vertexBuffer->Unmap(0, nullptr); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // 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> textureUploadHeap; // Create the texture. { // Describe and create a Texture2D. D3D12_RESOURCE_DESC textureDesc = {}; textureDesc.MipLevels = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.Width = TextureWidth; textureDesc.Height = TextureHeight; textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; textureDesc.DepthOrArraySize = 1; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &textureDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_texture))); const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_texture.Get(), 0, 1); // Create the GPU upload buffer. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&textureUploadHeap))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. std::vector<UINT8> texture = GenerateTextureData(); D3D12_SUBRESOURCE_DATA textureData = {}; textureData.pData = &texture[0]; textureData.RowPitch = TextureWidth * TexturePixelSize; textureData.SlicePitch = textureData.RowPitch * TextureHeight; UpdateSubresources(m_commandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, 1, &textureData); m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); // Describe and create a SRV for the texture. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Format = textureDesc.Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; m_device->CreateShaderResourceView(m_texture.Get(), &srvDesc, m_srvHeap->GetCPUDescriptorHandleForHeapStart()); } // Close the command list and execute it to begin the initial GPU setup. 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(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); m_fenceValue = 1; // 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. WaitForPreviousFrame(); } }
Impl::World::World(const float(&terrainXform)[4][3])// : bvh(Hierarchy::SplitTechnique::MEAN, .5f) { extern ComPtr<ID3D12Device2> device; // create terrain root signature { CD3DX12_ROOT_PARAMETER1 CBV_params[2]; CBV_params[0].InitAsConstantBufferView(0, 0, D3D12_ROOT_DESCRIPTOR_FLAG_NONE, D3D12_SHADER_VISIBILITY_VERTEX); CBV_params[1].InitAsConstants(3, 0, 1, D3D12_SHADER_VISIBILITY_PIXEL); const CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC sigDesc(2, CBV_params, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> sig, error; const HRESULT hr = D3D12SerializeVersionedRootSignature(&sigDesc, &sig, &error); if (error) { cerr.write((const char *)error->GetBufferPointer(), error->GetBufferSize()) << endl; } CheckHR(hr); CheckHR(device->CreateRootSignature(0, sig->GetBufferPointer(), sig->GetBufferSize(), IID_PPV_ARGS(&terrainVectorLayerRootSig))); } // create terrain PSO { const CD3DX12_RASTERIZER_DESC rasterDesc ( D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE, FALSE, // front CCW D3D12_DEFAULT_DEPTH_BIAS, D3D12_DEFAULT_DEPTH_BIAS_CLAMP, D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, TRUE, // depth clip FALSE, // MSAA FALSE, // AA line 0, // force sample count D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF ); const CD3DX12_DEPTH_STENCIL_DESC dsDesc ( FALSE, // depth D3D12_DEPTH_WRITE_MASK_ZERO, D3D12_COMPARISON_FUNC_ALWAYS, FALSE, // stencil D3D12_DEFAULT_STENCIL_READ_MASK, D3D12_DEFAULT_STENCIL_WRITE_MASK, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS, // front D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS // back ); const D3D12_INPUT_ELEMENT_DESC VB_decl[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; D3D12_GRAPHICS_PIPELINE_STATE_DESC PSO_desc = { terrainVectorLayerRootSig.Get(), // root signature CD3DX12_SHADER_BYTECODE(vectorLayerVS, sizeof vectorLayerVS), // VS CD3DX12_SHADER_BYTECODE(vectorLayerPS, sizeof vectorLayerPS), // PS {}, // DS {}, // HS {}, // GS {}, // SO CD3DX12_BLEND_DESC(D3D12_DEFAULT), // blend UINT_MAX, // sample mask rasterDesc, // rasterizer dsDesc, // depth stencil { VB_decl, size(VB_decl) }, // IA D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, // restart primtive D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, // primitive topology 1, // render targets { DXGI_FORMAT_R8G8B8A8_UNORM }, // RT formats DXGI_FORMAT_UNKNOWN, // depth stencil format {1} // MSAA }; CheckHR(device->CreateGraphicsPipelineState(&PSO_desc, IID_PPV_ARGS(&terrainVectorLayerPSO))); } // create terrain CB { // create buffer CheckHR(device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(terrainCB_storeSize * CB_overlap/*, D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE*/), D3D12_RESOURCE_STATE_GENERIC_READ, NULL, // clear value IID_PPV_ARGS(&terrainCB))); #if PERSISTENT_MAPS // map buffer const CD3DX12_RANGE readRange(0, 0); CheckHR(terrainCB->Map(0, &readRange, const_cast<void **>(&terrainCB_CPU_ptr))); #endif } memcpy(this->terrainXform, terrainXform, sizeof terrainXform); }
// Load the rendering pipeline dependencies. void DX12ClothSimulation::LoadPipeline() { #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 ) ) ); 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 ) ) ); // Describe and create 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 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] ) ) ); } }
// Load the sample assets. void DX12ClothSimulation::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 ) ) ); } // 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_device->CreateGraphicsPipelineState( &psoDesc, IID_PPV_ARGS( &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 ) ) ); 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(); } }
void DXBitmap::Initialize() { // CreateDeviceIndependentResources D2D1_FACTORY_OPTIONS options; ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS)); #if defined(_DEBUG) // If the project is in a debug build, enable Direct2D debugging via SDK Layers. options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; #endif DX::ThrowIfFailed( D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), &options, &m_d2dFactory ) ); DX::ThrowIfFailed( DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &m_dwriteFactory ) ); DX::ThrowIfFailed( CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_wicFactory) ) ); // This flag adds support for surfaces with a different color channel ordering than the API default. // It is recommended usage, and is required for compatibility with Direct2D. UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) // If the project is in a debug build, enable debugging via SDK Layers with this flag. creationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. // Don't forget to declare your application's minimum required feature level in its // description. All applications are assumed to support 9.1 unless otherwise stated. D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; // Create the DX11 API device object, and get a corresponding context. ComPtr<ID3D11Device> d3dDevice; ComPtr<ID3D11DeviceContext> d3dContext; DX::ThrowIfFailed( D3D11CreateDevice( nullptr, // specify null to use the default adapter D3D_DRIVER_TYPE_HARDWARE, nullptr, // leave as nullptr unless software device creationFlags, // optionally set debug and Direct2D compatibility flags featureLevels, // list of feature levels this app can support ARRAYSIZE(featureLevels), // number of entries in above list D3D11_SDK_VERSION, // always set this to D3D11_SDK_VERSION for modern &d3dDevice, // returns the Direct3D device created &m_featureLevel, // returns feature level of device created &d3dContext // returns the device immediate context ) ); // Get the DirectX11.1 device by QI off the DirectX11 one. DX::ThrowIfFailed( d3dDevice.As(&m_d3dDevice) ); // And get the corresponding device context in the same way. DX::ThrowIfFailed( d3dContext.As(&m_d3dContext) ); // Obtain the underlying DXGI device of the Direct3D11.1 device. ComPtr<IDXGIDevice> dxgiDevice; DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); // Obtain the Direct2D device for 2D rendering. DX::ThrowIfFailed( m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice) ); // And get its corresponding device context object. DX::ThrowIfFailed( m_d2dDevice->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_d2dContext ) ); // Save the DPI of this display in our class. m_d2dContext->SetDpi(m_dpi, m_dpi); // Release the swap chain (if it exists) as it will be incompatible with // the new device. m_swapChain = nullptr; }
// // Copies dirty rectangles // bool ScreenProcessor::ProcessDirty(ComPtr<ID3D11Texture2D> sourceSurface, ComPtr<ID3D11Texture2D> sharedSurface, RECT* dirtyRects, unsigned int dirtyCount, int offsetX, int offsetY, const DXGI_OUTPUT_DESC& desktopDescription) { HRESULT hr; D3D11_TEXTURE2D_DESC sharedDescription; sharedSurface->GetDesc(&sharedDescription); D3D11_TEXTURE2D_DESC sourceDescription; sourceSurface->GetDesc(&sourceDescription); // Make sure we have a render target view if (!m_RTV) { hr = m_Device->CreateRenderTargetView(sharedSurface.Get(), nullptr, &m_RTV); if (FAILED(hr)) { SetAppropriateEvent(hr, SystemTransitionsExpectedErrors, m_ExpectedErrorEvent, m_UnexpectedErrorEvent); return false; } } // Create a shader resource view for the source D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc; shaderDesc.Format = sourceDescription.Format; shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderDesc.Texture2D.MostDetailedMip = sourceDescription.MipLevels - 1; shaderDesc.Texture2D.MipLevels = sourceDescription.MipLevels; ComPtr<ID3D11ShaderResourceView> shaderResource = nullptr; hr = m_Device->CreateShaderResourceView(sourceSurface.Get(), &shaderDesc, &shaderResource); if (FAILED(hr)) { SetAppropriateEvent(hr, SystemTransitionsExpectedErrors, m_ExpectedErrorEvent, m_UnexpectedErrorEvent); return false; } // Set up shader / blending states FLOAT blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; m_DeviceContext->OMSetBlendState(nullptr, blendFactor, 0xFFFFFFFF); m_DeviceContext->OMSetRenderTargets(1, m_RTV.GetAddressOf(), nullptr); m_DeviceContext->VSSetShader(m_VertexShader.Get(), nullptr, 0); m_DeviceContext->PSSetShader(m_PixelShader.Get(), nullptr, 0); m_DeviceContext->PSSetShaderResources(0, 1, shaderResource.GetAddressOf()); m_DeviceContext->PSSetSamplers(0, 1, m_SamplerLinear.GetAddressOf()); m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Create space for vertices for the dirty rects if the current space isn't large enough // 2 triangles per rect = 6 verts unsigned int numVerticesPerRect = 6; unsigned int numVertices = numVerticesPerRect * dirtyCount; if (numVertices == 0) { return true; } if (m_DirtyRectVertices.size() < numVertices) { m_DirtyRectVertices.resize(numVertices); } // Fill them in Vertex* vertex = &m_DirtyRectVertices[0]; for (unsigned int rectIndex = 0; rectIndex < dirtyCount; ++rectIndex, vertex += numVerticesPerRect) { BuildDirtyVerts(vertex, dirtyRects[rectIndex], offsetX, offsetY, desktopDescription, sharedDescription, sourceDescription); } // Create vertex buffer D3D11_BUFFER_DESC bufferDesc; RtlZeroMemory(&bufferDesc, sizeof(bufferDesc)); bufferDesc.Usage = D3D11_USAGE_DEFAULT; bufferDesc.ByteWidth = numVertices * sizeof(Vertex); bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA initData; RtlZeroMemory(&initData, sizeof(initData)); initData.pSysMem = &m_DirtyRectVertices[0]; ComPtr<ID3D11Buffer> vertexBuffer = nullptr; hr = m_Device->CreateBuffer(&bufferDesc, &initData, &vertexBuffer); if (FAILED(hr)) { SetAppropriateEvent(hr, SystemTransitionsExpectedErrors, m_ExpectedErrorEvent, m_UnexpectedErrorEvent); return false; } unsigned int stride = sizeof(Vertex); unsigned int offset = 0; m_DeviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset); // Setup the viewport D3D11_VIEWPORT viewport; viewport.Width = static_cast<FLOAT>(sharedDescription.Width); viewport.Height = static_cast<FLOAT>(sharedDescription.Height); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_DeviceContext->RSSetViewports(1, &viewport); // Draw the vertices m_DeviceContext->Draw(numVertices, 0); // Cleanup vertexBuffer = nullptr; shaderResource = nullptr; return true; }
void SampleOverlay::CreateDeviceDependentResources() { DX::ThrowIfFailed( m_deviceResources->GetD2DDeviceContext()->CreateSolidColorBrush(ColorF(ColorF::White), &m_whiteBrush) ); ComPtr<IWICBitmapDecoder> wicBitmapDecoder; DX::ThrowIfFailed( m_deviceResources->GetWicImagingFactory()->CreateDecoderFromFilename( L"Assets\\windowstitle-sdk.png", nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &wicBitmapDecoder ) ); ComPtr<IWICBitmapFrameDecode> wicBitmapFrame; DX::ThrowIfFailed( wicBitmapDecoder->GetFrame(0, &wicBitmapFrame) ); ComPtr<IWICFormatConverter> wicFormatConverter; DX::ThrowIfFailed( m_deviceResources->GetWicImagingFactory()->CreateFormatConverter(&wicFormatConverter) ); DX::ThrowIfFailed( wicFormatConverter->Initialize( wicBitmapFrame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0, WICBitmapPaletteTypeCustom // the BGRA format has no palette so this value is ignored ) ); double dpiX = 96.0; double dpiY = 96.0; DX::ThrowIfFailed( wicFormatConverter->GetResolution(&dpiX, &dpiY) ); DX::ThrowIfFailed( m_deviceResources->GetD2DDeviceContext()->CreateBitmapFromWicBitmap( wicFormatConverter.Get(), BitmapProperties( PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), static_cast<float>(dpiX), static_cast<float>(dpiY) ), &m_logoBitmap ) ); m_logoSize = m_logoBitmap->GetSize(); ComPtr<IDWriteTextFormat> nameTextFormat; DX::ThrowIfFailed( m_deviceResources->GetDWriteFactory()->CreateTextFormat( L"Segoe UI", nullptr, DWRITE_FONT_WEIGHT_LIGHT, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 36.0f, L"en-US", &nameTextFormat ) ); DX::ThrowIfFailed( nameTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING) ); DX::ThrowIfFailed( nameTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR) ); DX::ThrowIfFailed( m_deviceResources->GetDWriteFactory()->CreateTextLayout( m_caption.c_str(), static_cast<UINT32>(m_caption.size()), nameTextFormat.Get(), 4096.0f, 4096.0f, &m_textLayout ) ); DWRITE_TEXT_METRICS metrics = {0}; DX::ThrowIfFailed( m_textLayout->GetMetrics(&metrics) ); m_overlayWidth = m_padding * 3.0f + m_logoSize.width + metrics.width; DX::ThrowIfFailed( m_deviceResources->GetD2DFactory()->CreateDrawingStateBlock(&m_stateBlock) ); }
// Allocate all memory resources that change on a window SizeChanged event. void Game::CreateResources() { // Clear the previous window size specific context. ID3D11RenderTargetView* nullViews [] = { nullptr }; m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr); m_renderTargetView.Reset(); m_depthStencilView.Reset(); m_d3dContext->Flush(); RECT rc; GetWindowRect( m_window, &rc ); UINT backBufferWidth = std::max<UINT>( rc.right - rc.left, 1 ); UINT backBufferHeight = std::max<UINT>( rc.bottom - rc.top, 1); DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM; DXGI_FORMAT depthBufferFormat = (m_featureLevel >= D3D_FEATURE_LEVEL_10_0) ? DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_D16_UNORM; // If the swap chain already exists, resize it, otherwise create one. if (m_swapChain) { HRESULT hr = m_swapChain->ResizeBuffers(2, backBufferWidth, backBufferHeight, backBufferFormat, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { // If the device was removed for any reason, a new device and swap chain will need to be created. OnDeviceLost(); // Everything is set up now. Do not continue execution of this method. OnDeviceLost will reenter this method // and correctly set up the new device. return; } else { DX::ThrowIfFailed(hr); } } else { // First, retrieve the underlying DXGI Device from the D3D Device ComPtr<IDXGIDevice1> dxgiDevice; DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice)); // Identify the physical adapter (GPU or card) this device is running on. ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf())); // And obtain the factory object that created it. ComPtr<IDXGIFactory1> dxgiFactory; DX::ThrowIfFailed(dxgiAdapter->GetParent(__uuidof(IDXGIFactory1), &dxgiFactory)); ComPtr<IDXGIFactory2> dxgiFactory2; HRESULT hr = dxgiFactory.As(&dxgiFactory2); if (SUCCEEDED(hr)) { // DirectX 11.1 or later m_d3dDevice.As( &m_d3dDevice1 ); m_d3dContext.As( &m_d3dContext1 ); // Create a descriptor for the swap chain. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; swapChainDesc.Width = backBufferWidth; swapChainDesc.Height = backBufferHeight; swapChainDesc.Format = backBufferFormat; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsSwapChainDesc = { 0 }; fsSwapChainDesc.Windowed = TRUE; // Create a SwapChain from a CoreWindow. DX::ThrowIfFailed( dxgiFactory2->CreateSwapChainForHwnd( m_d3dDevice.Get(), m_window, &swapChainDesc, &fsSwapChainDesc, nullptr, m_swapChain1.ReleaseAndGetAddressOf() ) ); m_swapChain1.As( &m_swapChain ); } else { DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; swapChainDesc.BufferCount = 2; swapChainDesc.BufferDesc.Width = backBufferWidth; swapChainDesc.BufferDesc.Height = backBufferHeight; swapChainDesc.BufferDesc.Format = backBufferFormat; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = m_window; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = TRUE; DX::ThrowIfFailed( dxgiFactory->CreateSwapChain( m_d3dDevice.Get(), &swapChainDesc, m_swapChain.ReleaseAndGetAddressOf() ) ); } // This template does not support 'full-screen' mode and prevents the ALT+ENTER shortcut from working dxgiFactory->MakeWindowAssociation(m_window, DXGI_MWA_NO_ALT_ENTER); } // Obtain the backbuffer for this window which will be the final 3D rendertarget. ComPtr<ID3D11Texture2D> backBuffer; DX::ThrowIfFailed(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer)); // Create a view interface on the rendertarget to use on bind. DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, m_renderTargetView.ReleaseAndGetAddressOf())); // Allocate a 2-D surface as the depth/stencil buffer and // create a DepthStencil view on this surface to use on bind. CD3D11_TEXTURE2D_DESC depthStencilDesc(depthBufferFormat, backBufferWidth, backBufferHeight, 1, 1, D3D11_BIND_DEPTH_STENCIL); ComPtr<ID3D11Texture2D> depthStencil; DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&depthStencilDesc, nullptr, depthStencil.GetAddressOf())); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView(depthStencil.Get(), &depthStencilViewDesc, m_depthStencilView.ReleaseAndGetAddressOf())); // Create a viewport descriptor of the full window size. CD3D11_VIEWPORT viewPort(0.0f, 0.0f, static_cast<float>(backBufferWidth), static_cast<float>(backBufferHeight)); // Set the current viewport using the descriptor. m_d3dContext->RSSetViewports(1, &viewPort); // TODO: Initialize windows-size dependent objects here i_render_manager->create_resource(); }
concurrency::task<void> ObjectManager::CreateDeviceDependentResources(IResourceResovler * resourceResolver) { auto d3dDevice = _deviceContext.D3DDevice; // 为常量缓冲区创建描述符堆。 { D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; heapDesc.NumDescriptors = DeviceContext::FrameCount; heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; // 此标志指示此描述符堆可以绑定到管道,并且其中包含的描述符可以由根表引用。 heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; ThrowIfFailed(d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_cbvHeap))); } CD3DX12_HEAP_PROPERTIES uploadHeapProperties(D3D12_HEAP_TYPE_UPLOAD); CD3DX12_RESOURCE_DESC constantBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(DeviceContext::FrameCount * c_alignedConstantBufferSize); ThrowIfFailed(d3dDevice->CreateCommittedResource( &uploadHeapProperties, D3D12_HEAP_FLAG_NONE, &constantBufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&_constantBuffer))); // 创建常量缓冲区视图以访问上载缓冲区。 D3D12_GPU_VIRTUAL_ADDRESS cbvGpuAddress = _constantBuffer->GetGPUVirtualAddress(); CD3DX12_CPU_DESCRIPTOR_HANDLE cbvCpuHandle(_cbvHeap->GetCPUDescriptorHandleForHeapStart()); _cbvDescriptorSize = d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); for (size_t i = 0; i < DeviceContext::FrameCount; i++) { D3D12_CONSTANT_BUFFER_VIEW_DESC desc; desc.BufferLocation = cbvGpuAddress; desc.SizeInBytes = c_alignedConstantBufferSize; d3dDevice->CreateConstantBufferView(&desc, cbvCpuHandle); cbvGpuAddress += desc.SizeInBytes; cbvCpuHandle.Offset(_cbvDescriptorSize); } // 映射常量缓冲区。 CD3DX12_RANGE readRange(0, 0); // 我们不打算从 CPU 上的此资源中进行读取。 ThrowIfFailed(_constantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&_mappedConstantBuffer))); ZeroMemory(_mappedConstantBuffer, DeviceContext::FrameCount * c_alignedConstantBufferSize); // 创建具有单个常量缓冲区槽的根签名。 { CD3DX12_DESCRIPTOR_RANGE range[2]; range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); CD3DX12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &range[0], D3D12_SHADER_VISIBILITY_VERTEX); rootParameters[1].InitAsDescriptorTable(1, &range[1], D3D12_SHADER_VISIBILITY_ALL); D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // 只有输入汇编程序阶段才需要访问常量缓冲区。 D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; 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 descRootSignature; descRootSignature.Init(_countof(rootParameters), rootParameters, 1, &sampler, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> pSignature; ComPtr<ID3DBlob> pError; ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, &pSignature, &pError)); ThrowIfFailed(d3dDevice->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(), IID_PPV_ARGS(&_rootSignature))); } ComPtr<IResourceResovler> resourceResovlerHolder(resourceResolver); std::array<concurrency::task<std::vector<byte>>, 2> VsPsTasks{ resourceResovlerHolder->ResovleShader(SpriteVSName), resourceResovlerHolder->ResovleShader(SpritePSName) }; co_await concurrency::when_all(VsPsTasks.begin(), VsPsTasks.end()); auto vs = VsPsTasks[0].get(); auto ps = VsPsTasks[1].get(); D3D12_GRAPHICS_PIPELINE_STATE_DESC state{}; state.InputLayout = { inputLayout, _countof(inputLayout) }; state.pRootSignature = _rootSignature.Get(); state.VS = CD3DX12_SHADER_BYTECODE(vs.data(), vs.size()); state.PS = CD3DX12_SHADER_BYTECODE(ps.data(), ps.size()); state.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); CD3DX12_BLEND_DESC blendDesc(D3D12_DEFAULT); //blendDesc.RenderTarget[0].BlendEnable = TRUE; //blendDesc.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; //blendDesc.RenderTarget[0].DestBlend = D3D12_BLEND_ONE; //blendDesc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; //blendDesc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; //blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; state.BlendState = blendDesc; state.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); state.SampleMask = UINT_MAX; state.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; state.NumRenderTargets = 1; state.RTVFormats[0] = _deviceContext.BackBufferFormat; state.DSVFormat = _deviceContext.DepthBufferFormat; state.SampleDesc.Count = 1; ThrowIfFailed(d3dDevice->CreateGraphicsPipelineState(&state, IID_PPV_ARGS(&_pipelineState))); _deviceContext.CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, _pipelineState.Get(), IID_PPV_ARGS(&_commandList)); ThrowIfFailed(_commandList->Close()); auto art = co_await resourceResolver->ResolveUnitArt(L"GI"); auto sprite = co_await resourceResolver->ResolveSpritePackageFile(art.Sprite); _giTexture = _deviceContext.TextureManager.CreateTexture2D(sprite.Image.data(), sprite.Image.size(), L"image/dds"); auto coordinateReader = std::make_shared<SpriteCoordinateReader>(_giTexture.Width, _giTexture.Height, sprite.Coordinate); auto sequenceReader = std::make_shared<SpriteSequenceReader>(sprite.Sequence); _spriteBatches.emplace<std::wstring, SpriteBatch>(L"GI", { _deviceContext, _giTexture, coordinateReader, sequenceReader }); _spriteBatches.find(L"GI")->second.Attach(SpriteObject(_deviceContext, _giTexture, coordinateReader, sequenceReader)); }
// Настраивает устройство Direct3D и сохраняет его дескрипторы и контекст устройства. void DX::DeviceResources::CreateDeviceResources() { // Этот флаг добавляет поддержку поверхностей с порядком цветовых каналов, отличным // от предусмотренного в API по умолчанию. Он является обязательным для совместимости с Direct2D. UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) if (DX::SdkLayersAvailable()) { // Если проект находится в отладочной сборке, включите отладку посредством уровней SDK с помощью этого флага. creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } #endif // Этот массив определяет набор функциональных уровней оборудования DirectX, которые будет поддерживать данное приложение. // Обратите внимание, что необходимо сохранить порядок. // Не забудьте объявить минимальный требуемый функциональный уровень вашего приложения в его // описании. Предполагается, что все приложения поддерживают уровень 9.1, если не указано иное. D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; // Создание объекта устройства API Direct3D 11 и соответствующего контекста. ComPtr<ID3D11Device> device; ComPtr<ID3D11DeviceContext> context; HRESULT hr = D3D11CreateDevice( nullptr, // Указание nullptr для использования адаптера по умолчанию. D3D_DRIVER_TYPE_HARDWARE, // Создание устройства с помощью драйвера графического оборудования. 0, // Должно равняться 0, если драйвер не равен D3D_DRIVER_TYPE_SOFTWARE. creationFlags, // Установка флагов отладки и совместимости с Direct2D. featureLevels, // Список уровней компонентов, которые могут поддерживаться этим приложением. ARRAYSIZE(featureLevels), // Размер вышеприведенного списка. D3D11_SDK_VERSION, // Всегда устанавливать равным D3D11_SDK_VERSION для приложений Магазина Windows. &device, // Возвращает созданное устройство Direct3D. &m_d3dFeatureLevel, // Возвращает уровень компонентов созданного устройства. &context // Возвращает мгновенный контекст устройства. ); if (FAILED(hr)) { // В случае сбоя инициализации выполните откат до устройства WARP. // Дополнительные сведения о WARP см. на сайте // http://go.microsoft.com/fwlink/?LinkId=286690 DX::ThrowIfFailed( D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, // Создание устройства WARP вместо аппаратного устройства. 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &m_d3dFeatureLevel, &context ) ); } // Сохранение указателей на устройство API Direct3D 11.3 и в окружающий контекст. DX::ThrowIfFailed( device.As(&m_d3dDevice) ); DX::ThrowIfFailed( context.As(&m_d3dContext) ); // Создание объекта устройства Direct2D и соответствующего контекста. ComPtr<IDXGIDevice3> dxgiDevice; DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); DX::ThrowIfFailed( m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice) ); DX::ThrowIfFailed( m_d2dDevice->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_d2dContext ) ); }
// Load the rendering pipeline dependencies. void D3D1211on12::LoadPipeline() { UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; D2D1_FACTORY_OPTIONS d2dFactoryOptions = {}; #if defined(_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 { ComPtr<IDXGIAdapter1> hardwareAdapter; GetHardwareAdapter(factory.Get(), &hardwareAdapter); ThrowIfFailed(D3D12CreateDevice( hardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_d3d12Device) )); } #if defined(_DEBUG) // Filter a debug error coming from the 11on12 layer. ComPtr<ID3D12InfoQueue> infoQueue; if (SUCCEEDED(m_d3d12Device->QueryInterface(IID_PPV_ARGS(&infoQueue)))) { // Suppress whole categories of messages. //D3D12_MESSAGE_CATEGORY categories[] = {}; // Suppress messages based on their severity level. D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO, }; // Suppress individual messages by their ID. D3D12_MESSAGE_ID denyIds[] = { // This occurs when there are uninitialized descriptors in a descriptor table, even when a // shader does not access the missing descriptors. D3D12_MESSAGE_ID_INVALID_DESCRIPTOR_HANDLE, }; D3D12_INFO_QUEUE_FILTER filter = {}; //filter.DenyList.NumCategories = _countof(categories); //filter.DenyList.pCategoryList = categories; filter.DenyList.NumSeverities = _countof(severities); filter.DenyList.pSeverityList = severities; filter.DenyList.NumIDs = _countof(denyIds); filter.DenyList.pIDList = denyIds; ThrowIfFailed(infoQueue->PushStorageFilter(&filter)); } #endif // 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))); NAME_D3D12_OBJECT(m_commandQueue); // Describe 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 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); NAME_D3D12_OBJECT_INDEXED(m_renderTargets, n); // 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]))); } } }
// Эти ресурсы необходимо заново создавать при каждом изменении размера окна. void DX::DeviceResources::CreateWindowSizeDependentResources() { // Очистка контекста, связанного с размером предыдущего окна. ID3D11RenderTargetView* nullViews[] = {nullptr}; m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); m_d3dRenderTargetView = nullptr; m_d2dContext->SetTarget(nullptr); m_d2dTargetBitmap = nullptr; m_d3dDepthStencilView = nullptr; m_d3dContext->Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr); UpdateRenderTargetSize(); // Ширина и высота цепочки буферов должны зависеть от // ширины и высоты окна в собственной ориентации. Если окно не находится в собственной // ориентации, размеры необходимо поменять местами. DXGI_MODE_ROTATION displayRotation = ComputeDisplayRotation(); bool swapDimensions = displayRotation == DXGI_MODE_ROTATION_ROTATE90 || displayRotation == DXGI_MODE_ROTATION_ROTATE270; m_d3dRenderTargetSize.Width = swapDimensions ? m_outputSize.Height : m_outputSize.Width; m_d3dRenderTargetSize.Height = swapDimensions ? m_outputSize.Width : m_outputSize.Height; if (m_swapChain != nullptr) { // Если цепочка буферов уже существует, измените ее размер. HRESULT hr = m_swapChain->ResizeBuffers( 2, // Цепочка буферов с двойной буферизацией. lround(m_d3dRenderTargetSize.Width), lround(m_d3dRenderTargetSize.Height), DXGI_FORMAT_B8G8R8A8_UNORM, 0 ); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { // Если устройство было по какой-либо причине удалено, необходимо создать новое устройство и цепочку буферов. HandleDeviceLost(); // Все параметры настроены. Не продолжайте выполнение этого метода. HandleDeviceLost перезапустит этот метод // и правильно настроит новое устройство. return; } else { DX::ThrowIfFailed(hr); } } else { // В противном случае создайте новое устройство, используя тот же адаптер, что и имеющее устройство Direct3D. DXGI_SCALING scaling = DisplayMetrics::SupportHighResolutions ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH; DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width); // Сопоставление с размером окна. swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height); swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Это наиболее распространенный формат цепочки буферов. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Не используйте множественную дискретизацию. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // Использование двойной буферизации, чтобы свести задержку к минимуму. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // Все приложения Магазина Windows должны использовать эффект SwapEffect. swapChainDesc.Flags = 0; swapChainDesc.Scaling = scaling; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; // Эта последовательность получает фабрику DXGI, которая использовалась для создания вышеуказанного устройства Direct3D. ComPtr<IDXGIDevice3> dxgiDevice; DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed( dxgiDevice->GetAdapter(&dxgiAdapter) ); ComPtr<IDXGIFactory4> dxgiFactory; DX::ThrowIfFailed( dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)) ); ComPtr<IDXGISwapChain1> swapChain; DX::ThrowIfFailed( dxgiFactory->CreateSwapChainForCoreWindow( m_d3dDevice.Get(), reinterpret_cast<IUnknown*>(m_window.Get()), &swapChainDesc, nullptr, &swapChain ) ); DX::ThrowIfFailed( swapChain.As(&m_swapChain) ); // Проверка того, что DXGI не помещает в очередь более одного кадра одновременно. Это позволяет уменьшить задержку и // гарантировать, что приложение будет выполнять прорисовку только после каждой вертикальной синхронизации, что снижает энергопотребление. DX::ThrowIfFailed( dxgiDevice->SetMaximumFrameLatency(1) ); } // Установка правильной ориентации цепочки буферов и создание двумерных и // трехмерных матричных преобразований для прорисовки повернутой цепочки буферов. // Обратите внимание, что углы поворота для двумерных и трехмерных преобразований различаются. // Это связано с различием в пространствах координат. Кроме того, // трехмерная матрица задается явным образом, чтобы избежать ошибок округления. switch (displayRotation) { case DXGI_MODE_ROTATION_IDENTITY: m_orientationTransform2D = Matrix3x2F::Identity(); m_orientationTransform3D = ScreenRotation::Rotation0; break; case DXGI_MODE_ROTATION_ROTATE90: m_orientationTransform2D = Matrix3x2F::Rotation(90.0f) * Matrix3x2F::Translation(m_logicalSize.Height, 0.0f); m_orientationTransform3D = ScreenRotation::Rotation270; break; case DXGI_MODE_ROTATION_ROTATE180: m_orientationTransform2D = Matrix3x2F::Rotation(180.0f) * Matrix3x2F::Translation(m_logicalSize.Width, m_logicalSize.Height); m_orientationTransform3D = ScreenRotation::Rotation180; break; case DXGI_MODE_ROTATION_ROTATE270: m_orientationTransform2D = Matrix3x2F::Rotation(270.0f) * Matrix3x2F::Translation(0.0f, m_logicalSize.Width); m_orientationTransform3D = ScreenRotation::Rotation90; break; default: throw ref new FailureException(); } DX::ThrowIfFailed( m_swapChain->SetRotation(displayRotation) ); // Создание представления целевого объекта прорисовки для заднего буфера цепочки буферов. ComPtr<ID3D11Texture2D1> backBuffer; DX::ThrowIfFailed( m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)) ); DX::ThrowIfFailed( m_d3dDevice->CreateRenderTargetView1( backBuffer.Get(), nullptr, &m_d3dRenderTargetView ) ); // Создание представления трафарета глубины для использования с трехмерной прорисовкой, если это необходимо. CD3D11_TEXTURE2D_DESC1 depthStencilDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, lround(m_d3dRenderTargetSize.Width), lround(m_d3dRenderTargetSize.Height), 1, // Это представление трафарета глубины содержит только одну текстуру. 1, // Использование одного уровня MIP-карт. D3D11_BIND_DEPTH_STENCIL ); ComPtr<ID3D11Texture2D1> depthStencil; DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D1( &depthStencilDesc, nullptr, &depthStencil ) ); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); DX::ThrowIfFailed( m_d3dDevice->CreateDepthStencilView( depthStencil.Get(), &depthStencilViewDesc, &m_d3dDepthStencilView ) ); // Установка в качестве окна просмотра трехмерной прорисовки всего окна. m_screenViewport = CD3D11_VIEWPORT( 0.0f, 0.0f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height ); m_d3dContext->RSSetViewports(1, &m_screenViewport); // Создание целевого точечного рисунка Direct2D, связанного с // задним буфером цепочки буферов, и установка его в качестве текущего целевого объекта. D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), m_dpi, m_dpi ); ComPtr<IDXGISurface2> dxgiBackBuffer; DX::ThrowIfFailed( m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer)) ); DX::ThrowIfFailed( m_d2dContext->CreateBitmapFromDxgiSurface( dxgiBackBuffer.Get(), &bitmapProperties, &m_d2dTargetBitmap ) ); m_d2dContext->SetTarget(m_d2dTargetBitmap.Get()); m_d2dContext->SetDpi(m_effectiveDpi, m_effectiveDpi); // Сглаживание текста в оттенках серого рекомендуется для всех приложений Магазина Windows. m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); }
TESTENV_API BOOL WINAPI Render() { static int count = 0; int targetIndex = m_swapChain->GetCurrentBackBufferIndex(); SetResourceBarrier(m_cmdList.Get(), m_renderTarget[targetIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); m_cmdList->RSSetViewports(1, &m_viewport); m_cmdList->ClearRenderTargetView(m_handleRTV[targetIndex], m_clearColor, 0, nullptr); SetResourceBarrier(m_cmdList.Get(), m_renderTarget[targetIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); m_cmdList->Close(); ID3D12CommandList* pCommandList = m_cmdList.Get(); m_cmdQueue->ExecuteCommandLists(1, &pCommandList); m_swapChain->Present(1, 0); WaitForCommandQueue(m_cmdQueue.Get()); m_cmdAllocator->Reset(); m_cmdList->Reset(m_cmdAllocator.Get(), nullptr); count++; return TRUE; }
// These resources need to be recreated every time the window size is changed. void DX::DeviceResources::CreateWindowSizeDependentResources() { if (!m_window) { throw std::exception("Call SetWindow with a valid CoreWindow pointer"); } // Clear the previous window size specific context. ID3D11RenderTargetView* nullViews[] = {nullptr}; m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr); m_d3dRenderTargetView.Reset(); m_d3dDepthStencilView.Reset(); m_d3dContext->Flush(); // Determine the render target size in pixels. UINT backBufferWidth = std::max<UINT>(m_outputSize.right - m_outputSize.left, 1); UINT backBufferHeight = std::max<UINT>(m_outputSize.bottom - m_outputSize.top, 1); DXGI_FORMAT backBufferFormat = NoSRGB(m_backBufferFormat); if (m_swapChain) { // If the swap chain already exists, resize it. HRESULT hr = m_swapChain->ResizeBuffers( m_backBufferCount, backBufferWidth, backBufferHeight, backBufferFormat, 0 ); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { #ifdef _DEBUG char buff[64] = {}; sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr); OutputDebugStringA(buff); #endif // If the device was removed for any reason, a new device and swap chain will need to be created. HandleDeviceLost(); // Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method // and correctly set up the new device. return; } else { DX::ThrowIfFailed(hr); } } else { // Otherwise, create a new one using the same adapter as the existing Direct3D device. // This sequence obtains the DXGI factory that was used to create the Direct3D device above. ComPtr<IDXGIDevice3> dxgiDevice; DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice)); ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf())); ComPtr<IDXGIFactory2> dxgiFactory; DX::ThrowIfFailed(dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.GetAddressOf()))); DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.Width = backBufferWidth; swapChainDesc.Height = backBufferHeight; swapChainDesc.Format = backBufferFormat; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = m_backBufferCount; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Scaling = DXGI_SCALING_ASPECT_RATIO_STRETCH; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; ComPtr<IDXGISwapChain1> swapChain; DX::ThrowIfFailed(dxgiFactory->CreateSwapChainForCoreWindow( m_d3dDevice.Get(), m_window, &swapChainDesc, nullptr, swapChain.GetAddressOf() )); DX::ThrowIfFailed(swapChain.As(&m_swapChain)); // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and // ensures that the application will only render after each VSync, minimizing power consumption. DX::ThrowIfFailed(dxgiDevice->SetMaximumFrameLatency(1)); } // Set the proper orientation for the swap chain, and generate // matrix transformations for rendering to the rotated swap chain. switch (m_rotation) { default: case DXGI_MODE_ROTATION_IDENTITY: m_orientationTransform3D = ScreenRotation::Rotation0; break; case DXGI_MODE_ROTATION_ROTATE90: m_orientationTransform3D = ScreenRotation::Rotation270; break; case DXGI_MODE_ROTATION_ROTATE180: m_orientationTransform3D = ScreenRotation::Rotation180; break; case DXGI_MODE_ROTATION_ROTATE270: m_orientationTransform3D = ScreenRotation::Rotation90; break; } DX::ThrowIfFailed(m_swapChain->SetRotation(m_rotation)); // Create a render target view of the swap chain back buffer. ComPtr<ID3D11Texture2D> backBuffer; DX::ThrowIfFailed(m_swapChain->GetBuffer(0, IID_PPV_ARGS(backBuffer.GetAddressOf()))); CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc(D3D11_RTV_DIMENSION_TEXTURE2D, m_backBufferFormat); DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView( backBuffer.Get(), &renderTargetViewDesc, m_d3dRenderTargetView.ReleaseAndGetAddressOf() )); if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN) { // Create a depth stencil view for use with 3D rendering if needed. CD3D11_TEXTURE2D_DESC depthStencilDesc( m_depthBufferFormat, backBufferWidth, backBufferHeight, 1, // This depth stencil view has only one texture. 1, // Use a single mipmap level. D3D11_BIND_DEPTH_STENCIL ); ComPtr<ID3D11Texture2D> depthStencil; DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D( &depthStencilDesc, nullptr, depthStencil.GetAddressOf() )); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D); DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView( depthStencil.Get(), &depthStencilViewDesc, m_d3dDepthStencilView.ReleaseAndGetAddressOf() )); } // Set the 3D rendering viewport to target the entire window. m_screenViewport = CD3D11_VIEWPORT( 0.0f, 0.0f, static_cast<float>(backBufferWidth), static_cast<float>(backBufferHeight) ); }
int VBoxNetDhcp::initWithMain() { /* ok, here we should initiate instance of dhcp server * and listener for Dhcp configuration events */ AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR); std::string networkName = getNetworkName(); int rc = findDhcpServer(virtualbox, networkName, m_DhcpServer); AssertRCReturn(rc, rc); rc = findNatNetwork(virtualbox, networkName, m_NATNetwork); AssertRCReturn(rc, rc); BOOL fNeedDhcpServer = isDhcpRequired(m_NATNetwork); if (!fNeedDhcpServer) return VERR_CANCELLED; RTNETADDRIPV4 gateway; com::Bstr strGateway; HRESULT hrc = m_NATNetwork->COMGETTER(Gateway)(strGateway.asOutParam()); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway); ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager(); AssertPtrReturn(confManager, VERR_INTERNAL_ERROR); confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway); rc = fetchAndUpdateDnsInfo(); AssertMsgRCReturn(rc, ("Wasn't able to fetch Dns info"), rc); { ComEventTypeArray eventTypes; eventTypes.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange); eventTypes.push_back(VBoxEventType_OnNATNetworkStartStop); rc = createNatListener(m_VBoxListener, virtualbox, this, eventTypes); AssertRCReturn(rc, rc); } { ComEventTypeArray eventTypes; eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged); rc = createClientListener(m_VBoxClientListener, virtualboxClient, this, eventTypes); AssertRCReturn(rc, rc); } RTNETADDRIPV4 LowerAddress; rc = configGetBoundryAddress(m_DhcpServer, false, LowerAddress); AssertMsgRCReturn(rc, ("can't get lower boundrary adderss'"),rc); RTNETADDRIPV4 UpperAddress; rc = configGetBoundryAddress(m_DhcpServer, true, UpperAddress); AssertMsgRCReturn(rc, ("can't get upper boundrary adderss'"),rc); RTNETADDRIPV4 address = getIpv4Address(); RTNETADDRIPV4 netmask = getIpv4Netmask(); RTNETADDRIPV4 networkId = networkid(address, netmask); std::string name = std::string("default"); confManager->addNetwork(unconst(g_RootConfig), networkId, netmask, LowerAddress, UpperAddress); com::Bstr bstr; hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam()); com::Utf8StrFmt strXmlLeaseFile("%ls%c%s.leases", bstr.raw(), RTPATH_DELIMITER, networkName.c_str()); confManager->loadFromFile(strXmlLeaseFile); return VINF_SUCCESS; }
// This method is called in the event handler for the DisplayContentsInvalidated event. void DX::DeviceResources::ValidateDevice() { // The D3D Device is no longer valid if the default adapter changed since the device // was created or if the device has been removed. DXGI_ADAPTER_DESC previousDesc; { ComPtr<IDXGIDevice3> dxgiDevice; DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice)); ComPtr<IDXGIAdapter> deviceAdapter; DX::ThrowIfFailed(dxgiDevice->GetAdapter(deviceAdapter.GetAddressOf())); ComPtr<IDXGIFactory2> deviceFactory; DX::ThrowIfFailed(deviceAdapter->GetParent(IID_PPV_ARGS(deviceFactory.GetAddressOf()))); ComPtr<IDXGIAdapter1> previousDefaultAdapter; DX::ThrowIfFailed(deviceFactory->EnumAdapters1(0, previousDefaultAdapter.GetAddressOf())); DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc)); } DXGI_ADAPTER_DESC currentDesc; { ComPtr<IDXGIFactory2> currentFactory; DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(currentFactory.GetAddressOf()))); ComPtr<IDXGIAdapter1> currentDefaultAdapter; DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, currentDefaultAdapter.GetAddressOf())); DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc)); } // If the adapter LUIDs don't match, or if the device reports that it has been removed, // a new D3D device must be created. if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart || previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart || FAILED(m_d3dDevice->GetDeviceRemovedReason())) { #ifdef _DEBUG OutputDebugStringA("Device Lost on ValidateDevice\n"); #endif // Create a new device and swap chain. HandleDeviceLost(); } }
/** * List virtual image backends. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listHddBackends(const ComPtr<IVirtualBox> pVirtualBox) { HRESULT rc; ComPtr<ISystemProperties> systemProperties; CHECK_ERROR(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam())); com::SafeIfaceArray<IMediumFormat> mediumFormats; CHECK_ERROR(systemProperties, COMGETTER(MediumFormats)(ComSafeArrayAsOutParam(mediumFormats))); RTPrintf("Supported hard disk backends:\n\n"); for (size_t i = 0; i < mediumFormats.size(); ++i) { /* General information */ Bstr id; CHECK_ERROR(mediumFormats[i], COMGETTER(Id)(id.asOutParam())); Bstr description; CHECK_ERROR(mediumFormats[i], COMGETTER(Name)(description.asOutParam())); ULONG caps = 0; com::SafeArray <MediumFormatCapabilities_T> mediumFormatCap; CHECK_ERROR(mediumFormats[i], COMGETTER(Capabilities)(ComSafeArrayAsOutParam(mediumFormatCap))); for (ULONG j = 0; j < mediumFormatCap.size(); j++) caps |= mediumFormatCap[j]; RTPrintf("Backend %u: id='%ls' description='%ls' capabilities=%#06x extensions='", i, id.raw(), description.raw(), caps); /* File extensions */ com::SafeArray<BSTR> fileExtensions; com::SafeArray<DeviceType_T> deviceTypes; CHECK_ERROR(mediumFormats[i], DescribeFileExtensions(ComSafeArrayAsOutParam(fileExtensions), ComSafeArrayAsOutParam(deviceTypes))); for (size_t j = 0; j < fileExtensions.size(); ++j) { RTPrintf("%ls (%s)", Bstr(fileExtensions[j]).raw(), getDeviceTypeText(deviceTypes[j])); if (j != fileExtensions.size()-1) RTPrintf(","); } RTPrintf("'"); /* Configuration keys */ com::SafeArray<BSTR> propertyNames; com::SafeArray<BSTR> propertyDescriptions; com::SafeArray<DataType_T> propertyTypes; com::SafeArray<ULONG> propertyFlags; com::SafeArray<BSTR> propertyDefaults; CHECK_ERROR(mediumFormats[i], DescribeProperties(ComSafeArrayAsOutParam(propertyNames), ComSafeArrayAsOutParam(propertyDescriptions), ComSafeArrayAsOutParam(propertyTypes), ComSafeArrayAsOutParam(propertyFlags), ComSafeArrayAsOutParam(propertyDefaults))); RTPrintf(" properties=("); if (propertyNames.size() > 0) { for (size_t j = 0; j < propertyNames.size(); ++j) { RTPrintf("\n name='%ls' desc='%ls' type=", Bstr(propertyNames[j]).raw(), Bstr(propertyDescriptions[j]).raw()); switch (propertyTypes[j]) { case DataType_Int32: RTPrintf("int"); break; case DataType_Int8: RTPrintf("byte"); break; case DataType_String: RTPrintf("string"); break; } RTPrintf(" flags=%#04x", propertyFlags[j]); RTPrintf(" default='%ls'", Bstr(propertyDefaults[j]).raw()); if (j != propertyNames.size()-1) RTPrintf(", "); } } RTPrintf(")\n"); } return rc; }
// Configures the Direct3D device, and stores handles to it and the device context. void DX::DeviceResources::CreateDeviceResources() { UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) if (SdkLayersAvailable()) { // If the project is in a debug build, enable debugging via SDK Layers with this flag. creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } else { OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n"); } #endif // Determine DirectX hardware feature levels this app will support. static const D3D_FEATURE_LEVEL s_featureLevels[] = { D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1, }; UINT featLevelCount = 0; for (; featLevelCount < _countof(s_featureLevels); ++featLevelCount) { if (s_featureLevels[featLevelCount] < m_d3dMinFeatureLevel) break; } if (!featLevelCount) { throw std::out_of_range("minFeatureLevel too high"); } ComPtr<IDXGIAdapter1> adapter; GetHardwareAdapter(adapter.GetAddressOf()); // Create the Direct3D 11 API device object and a corresponding context. ComPtr<ID3D11Device> device; ComPtr<ID3D11DeviceContext> context; HRESULT hr = E_FAIL; if (adapter) { hr = D3D11CreateDevice( adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, 0, creationFlags, // Set debug and Direct2D compatibility flags. s_featureLevels, featLevelCount, D3D11_SDK_VERSION, device.GetAddressOf(), // Returns the Direct3D device created. &m_d3dFeatureLevel, // Returns feature level of device created. context.GetAddressOf() // Returns the device immediate context. ); } #if defined(NDEBUG) else { throw std::exception("No Direct3D hardware device found"); } #else if (FAILED(hr)) { // If the initialization fails, fall back to the WARP device. // For more information on WARP, see: // http://go.microsoft.com/fwlink/?LinkId=286690 hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device. 0, creationFlags, s_featureLevels, featLevelCount, D3D11_SDK_VERSION, device.GetAddressOf(), &m_d3dFeatureLevel, context.GetAddressOf() ); if (SUCCEEDED(hr)) { OutputDebugStringA("Direct3D Adapter - WARP\n"); } } #endif DX::ThrowIfFailed(hr); #ifndef NDEBUG ComPtr<ID3D11Debug> d3dDebug; if (SUCCEEDED(device.As(&d3dDebug))) { ComPtr<ID3D11InfoQueue> d3dInfoQueue; if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue))) { #ifdef _DEBUG d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); #endif D3D11_MESSAGE_ID hide[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS, }; D3D11_INFO_QUEUE_FILTER filter = {}; filter.DenyList.NumIDs = _countof(hide); filter.DenyList.pIDList = hide; d3dInfoQueue->AddStorageFilterEntries(&filter); } } #endif DX::ThrowIfFailed(device.As(&m_d3dDevice)); DX::ThrowIfFailed(context.As(&m_d3dContext)); }
/** * List USB filters. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listUsbFilters(const ComPtr<IVirtualBox> &pVirtualBox) { HRESULT rc; RTPrintf("Global USB Device Filters:\n\n"); ComPtr<IHost> host; CHECK_ERROR_RET(pVirtualBox, COMGETTER(Host)(host.asOutParam()), 1); SafeIfaceArray<IHostUSBDeviceFilter> coll; CHECK_ERROR_RET(host, COMGETTER(USBDeviceFilters)(ComSafeArrayAsOutParam(coll)), 1); if (coll.size() == 0) { RTPrintf("<none>\n\n"); } else { for (size_t index = 0; index < coll.size(); ++index) { ComPtr<IHostUSBDeviceFilter> flt = coll[index]; /* Query info. */ RTPrintf("Index: %zu\n", index); BOOL active = FALSE; CHECK_ERROR_RET(flt, COMGETTER(Active)(&active), 1); RTPrintf("Active: %s\n", active ? "yes" : "no"); USBDeviceFilterAction_T action; CHECK_ERROR_RET(flt, COMGETTER(Action)(&action), 1); const char *pszAction = "<invalid>"; switch (action) { case USBDeviceFilterAction_Ignore: pszAction = "Ignore"; break; case USBDeviceFilterAction_Hold: pszAction = "Hold"; break; default: break; } RTPrintf("Action: %s\n", pszAction); Bstr bstr; CHECK_ERROR_RET(flt, COMGETTER(Name)(bstr.asOutParam()), 1); RTPrintf("Name: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(VendorId)(bstr.asOutParam()), 1); RTPrintf("VendorId: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(ProductId)(bstr.asOutParam()), 1); RTPrintf("ProductId: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(Revision)(bstr.asOutParam()), 1); RTPrintf("Revision: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(Manufacturer)(bstr.asOutParam()), 1); RTPrintf("Manufacturer: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(Product)(bstr.asOutParam()), 1); RTPrintf("Product: %ls\n", bstr.raw()); CHECK_ERROR_RET(flt, COMGETTER(SerialNumber)(bstr.asOutParam()), 1); RTPrintf("Serial Number: %ls\n\n", bstr.raw()); } } return rc; }
// Load the sample assets. void D3D12ExecuteIndirect::LoadAssets() { // Create the root signatures. { CD3DX12_ROOT_PARAMETER rootParameters[GraphicsRootParametersCount]; rootParameters[Cbv].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_VERTEX); CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 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 compute signature. CD3DX12_DESCRIPTOR_RANGE ranges[2]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0); CD3DX12_ROOT_PARAMETER computeRootParameters[ComputeRootParametersCount]; computeRootParameters[SrvUavTable].InitAsDescriptorTable(2, ranges); computeRootParameters[RootConstants].InitAsConstants(4, 0); CD3DX12_ROOT_SIGNATURE_DESC computeRootSignatureDesc; computeRootSignatureDesc.Init(_countof(computeRootParameters), computeRootParameters); ThrowIfFailed(D3D12SerializeRootSignature(&computeRootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_computeRootSignature))); NAME_D3D12_OBJECT(m_computeRootSignature); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; ComPtr<ID3DBlob> computeShader; 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)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"compute.hlsl").c_str(), nullptr, nullptr, "CSMain", "cs_5_0", compileFlags, 0, &computeShader, &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 }, }; // 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 = CD3DX12_BLEND_DESC(D3D12_DEFAULT); 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); // Describe and create the compute pipeline state object (PSO). D3D12_COMPUTE_PIPELINE_STATE_DESC computePsoDesc = {}; computePsoDesc.pRootSignature = m_computeRootSignature.Get(); computePsoDesc.CS = CD3DX12_SHADER_BYTECODE(computeShader.Get()); ThrowIfFailed(m_device->CreateComputePipelineState(&computePsoDesc, IID_PPV_ARGS(&m_computeState))); NAME_D3D12_OBJECT(m_computeState); } // 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))); ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, m_computeCommandAllocators[m_frameIndex].Get(), m_computeState.Get(), IID_PPV_ARGS(&m_computeCommandList))); ThrowIfFailed(m_computeCommandList->Close()); NAME_D3D12_OBJECT(m_commandList); NAME_D3D12_OBJECT(m_computeCommandList); // Note: ComPtr's are CPU objects but these resources need to stay in scope until // the command list that references them has finished executing on the GPU. // We will flush the GPU at the end of this method to ensure the resources are not // prematurely destroyed. ComPtr<ID3D12Resource> vertexBufferUpload; ComPtr<ID3D12Resource> commandBufferUpload; // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, TriangleHalfWidth, TriangleDepth } }, { { TriangleHalfWidth, -TriangleHalfWidth, TriangleDepth } }, { { -TriangleHalfWidth, -TriangleHalfWidth, TriangleDepth } } }; 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(&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*>(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 = sizeof(triangleVertices); } // 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 constant buffers. { const UINT constantBufferDataSize = TriangleResourceCount * sizeof(SceneConstantBuffer); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(constantBufferDataSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_constantBuffer))); NAME_D3D12_OBJECT(m_constantBuffer); // Initialize the constant buffers for each of the triangles. for (UINT n = 0; n < TriangleCount; n++) { m_constantBufferData[n].velocity = XMFLOAT4(GetRandomFloat(0.01f, 0.02f), 0.0f, 0.0f, 0.0f); m_constantBufferData[n].offset = XMFLOAT4(GetRandomFloat(-5.0f, -1.5f), GetRandomFloat(-1.0f, 1.0f), GetRandomFloat(0.0f, 2.0f), 0.0f); m_constantBufferData[n].color = XMFLOAT4(GetRandomFloat(0.5f, 1.0f), GetRandomFloat(0.5f, 1.0f), GetRandomFloat(0.5f, 1.0f), 1.0f); XMStoreFloat4x4(&m_constantBufferData[n].projection, XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PIDIV4, m_aspectRatio, 0.01f, 20.0f))); } // Map the constant buffers. We don't unmap this until the app closes. // Keeping things mapped for the lifetime of the resource is okay. 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))); memcpy(m_pCbvDataBegin, &m_constantBufferData[0], TriangleCount * sizeof(SceneConstantBuffer)); // Create shader resource views (SRV) of the constant buffers for the // compute shader to read from. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.Format = DXGI_FORMAT_UNKNOWN; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Buffer.NumElements = TriangleCount; srvDesc.Buffer.StructureByteStride = sizeof(SceneConstantBuffer); srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; CD3DX12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle(m_cbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(), CbvSrvOffset, m_cbvSrvUavDescriptorSize); for (UINT frame = 0; frame < FrameCount; frame++) { srvDesc.Buffer.FirstElement = frame * TriangleCount; m_device->CreateShaderResourceView(m_constantBuffer.Get(), &srvDesc, cbvSrvHandle); cbvSrvHandle.Offset(CbvSrvUavDescriptorCountPerFrame, m_cbvSrvUavDescriptorSize); } } // Create the command signature used for indirect drawing. { // Each command consists of a CBV update and a DrawInstanced call. D3D12_INDIRECT_ARGUMENT_DESC argumentDescs[2] = {}; argumentDescs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW; argumentDescs[0].ConstantBufferView.RootParameterIndex = Cbv; argumentDescs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc = {}; commandSignatureDesc.pArgumentDescs = argumentDescs; commandSignatureDesc.NumArgumentDescs = _countof(argumentDescs); commandSignatureDesc.ByteStride = sizeof(IndirectCommand); ThrowIfFailed(m_device->CreateCommandSignature(&commandSignatureDesc, m_rootSignature.Get(), IID_PPV_ARGS(&m_commandSignature))); NAME_D3D12_OBJECT(m_commandSignature); } // Create the command buffers and UAVs to store the results of the compute work. { std::vector<IndirectCommand> commands; commands.resize(TriangleResourceCount); const UINT commandBufferSize = CommandSizePerFrame * FrameCount; D3D12_RESOURCE_DESC commandBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(commandBufferSize); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &commandBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_commandBuffer))); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(commandBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&commandBufferUpload))); NAME_D3D12_OBJECT(m_commandBuffer); D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = m_constantBuffer->GetGPUVirtualAddress(); UINT commandIndex = 0; for (UINT frame = 0; frame < FrameCount; frame++) { for (UINT n = 0; n < TriangleCount; n++) { commands[commandIndex].cbv = gpuAddress; commands[commandIndex].drawArguments.VertexCountPerInstance = 3; commands[commandIndex].drawArguments.InstanceCount = 1; commands[commandIndex].drawArguments.StartVertexLocation = 0; commands[commandIndex].drawArguments.StartInstanceLocation = 0; commandIndex++; gpuAddress += sizeof(SceneConstantBuffer); } } // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the command buffer. D3D12_SUBRESOURCE_DATA commandData = {}; commandData.pData = reinterpret_cast<UINT8*>(&commands[0]); commandData.RowPitch = commandBufferSize; commandData.SlicePitch = commandData.RowPitch; UpdateSubresources<1>(m_commandList.Get(), m_commandBuffer.Get(), commandBufferUpload.Get(), 0, 0, 1, &commandData); m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_commandBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); // Create SRVs for the command buffers. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.Format = DXGI_FORMAT_UNKNOWN; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Buffer.NumElements = TriangleCount; srvDesc.Buffer.StructureByteStride = sizeof(IndirectCommand); srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; CD3DX12_CPU_DESCRIPTOR_HANDLE commandsHandle(m_cbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(), CommandsOffset, m_cbvSrvUavDescriptorSize); for (UINT frame = 0; frame < FrameCount; frame++) { srvDesc.Buffer.FirstElement = frame * TriangleCount; m_device->CreateShaderResourceView(m_commandBuffer.Get(), &srvDesc, commandsHandle); commandsHandle.Offset(CbvSrvUavDescriptorCountPerFrame, m_cbvSrvUavDescriptorSize); } // Create the unordered access views (UAVs) that store the results of the compute work. CD3DX12_CPU_DESCRIPTOR_HANDLE processedCommandsHandle(m_cbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(), ProcessedCommandsOffset, m_cbvSrvUavDescriptorSize); for (UINT frame = 0; frame < FrameCount; frame++) { // Allocate a buffer large enough to hold all of the indirect commands // for a single frame as well as a UAV counter. commandBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(CommandBufferCounterOffset + sizeof(UINT), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &commandBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_processedCommandBuffers[frame]))); NAME_D3D12_OBJECT_INDEXED(m_processedCommandBuffers, frame); D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; uavDesc.Format = DXGI_FORMAT_UNKNOWN; uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; uavDesc.Buffer.FirstElement = 0; uavDesc.Buffer.NumElements = TriangleCount; uavDesc.Buffer.StructureByteStride = sizeof(IndirectCommand); uavDesc.Buffer.CounterOffsetInBytes = CommandBufferCounterOffset; uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; m_device->CreateUnorderedAccessView( m_processedCommandBuffers[frame].Get(), m_processedCommandBuffers[frame].Get(), &uavDesc, processedCommandsHandle); processedCommandsHandle.Offset(CbvSrvUavDescriptorCountPerFrame, m_cbvSrvUavDescriptorSize); } // Allocate a buffer that can be used to reset the UAV counters and initialize // it to 0. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sizeof(UINT)), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_processedCommandBufferCounterReset))); UINT8* pMappedCounterReset = nullptr; CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_processedCommandBufferCounterReset->Map(0, &readRange, reinterpret_cast<void**>(&pMappedCounterReset))); ZeroMemory(pMappedCounterReset, sizeof(UINT)); m_processedCommandBufferCounterReset->Unmap(0, nullptr); } // 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))); ThrowIfFailed(m_device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_computeFence))); 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(); } }