From 4185fcb6cda8be2db0b67ae344a6445444681ae1 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 14 Aug 2015 17:03:16 +0200 Subject: [PATCH 1/5] d3d12: Do not output scale if there is no rtt available Fix crash in Disgaea 3 --- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 05367e9f94..46729ee55e 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -817,7 +817,8 @@ void D3D12GSRender::Flip() } else { - commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); + if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) + commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ)); resourceToFlip = m_rtts.m_currentlyBoundRenderTargets[0]; } @@ -890,11 +891,11 @@ void D3D12GSRender::Flip() vbv.SizeInBytes = 16 * sizeof(float); commandList->IASetVertexBuffers(0, 1, &vbv); commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - commandList->DrawInstanced(4, 1, 0, 0); + if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) + commandList->DrawInstanced(4, 1, 0, 0); commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); - if (isFlipSurfaceInLocalMemory(m_surface_color_target)) + if (isFlipSurfaceInLocalMemory(m_surface_color_target) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); check(commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList); From befe93784f6d3ab09e43caa78abc910f8287f2e0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 12 Aug 2015 16:46:32 +0200 Subject: [PATCH 2/5] d3d12: Do not create/submit an extra command list for texture upload/rtt state change --- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 17 ++++++++--------- rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 15 +++++++++++---- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 9 +-------- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 14 +++----------- 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 46729ee55e..8e06c9348a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -431,12 +431,12 @@ void D3D12GSRender::Clear(u32 cmd) { assert(cmd == NV4097_CLEAR_SURFACE); - PrepareRenderTargets(); - ID3D12GraphicsCommandList *commandList; check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList))); getCurrentResourceStorage().m_inflightCommandList.push_back(commandList); + PrepareRenderTargets(commandList); + /* if (m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); @@ -509,7 +509,11 @@ void D3D12GSRender::Clear(u32 cmd) void D3D12GSRender::Draw() { - PrepareRenderTargets(); + ID3D12GraphicsCommandList *commandList; + m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList)); + getCurrentResourceStorage().m_inflightCommandList.push_back(commandList); + + PrepareRenderTargets(commandList); // Init vertex count // TODO: Very hackish, clean this @@ -536,11 +540,6 @@ void D3D12GSRender::Draw() } } - ID3D12GraphicsCommandList *commandList; - m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList)); - getCurrentResourceStorage().m_inflightCommandList.push_back(commandList); - - std::chrono::time_point startVertexTime = std::chrono::system_clock::now(); if (m_indexed_array.m_count || m_draw_array_count) { @@ -588,7 +587,7 @@ void D3D12GSRender::Draw() if (m_PSO->second > 0) { std::chrono::time_point startTextureTime = std::chrono::system_clock::now(); - size_t usedTexture = UploadTextures(); + size_t usedTexture = UploadTextures(commandList); // Fill empty slots for (; usedTexture < m_PSO->second; usedTexture++) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 87cdbabe62..14e0c405f1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -402,12 +402,19 @@ private: void FillVertexShaderConstantsBuffer(); void FillPixelShaderConstantsBuffer(); /** - * Upload textures to Data heap if necessary and create necessary descriptor in the per frame storage struct. - * returns the number of texture uploaded + * Fetch all textures recorded in the state in the render target cache and in the texture cache. + * If a texture is not cached, populate cmdlist with uploads command. + * Create necessary resource view/sampler descriptors in the per frame storage struct. + * returns the number of texture uploaded. */ - size_t UploadTextures(); + size_t UploadTextures(ID3D12GraphicsCommandList *cmdlist); - void PrepareRenderTargets(); + /** + * Creates render target if necessary. + * Populate cmdlist with render target state change (from RTT to generic read for previous rtt, + * from generic to rtt for rtt in cache). + */ + void PrepareRenderTargets(ID3D12GraphicsCommandList *cmdlist); protected: virtual void OnInit() override; virtual void OnInitThread() override; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index f131d0b102..dc2684c3a9 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -12,7 +12,7 @@ #include "D3D12.h" #include "D3D12GSRender.h" -void D3D12GSRender::PrepareRenderTargets() +void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) { // FBO location has changed, previous data might be copied u32 address_a = m_set_context_dma_color_a ? GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000) : 0; @@ -21,10 +21,6 @@ void D3D12GSRender::PrepareRenderTargets() u32 address_d = m_set_context_dma_color_d ? GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000) : 0; u32 address_z = m_set_context_dma_z ? GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000) : 0; - ID3D12GraphicsCommandList *copycmdlist; - check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(©cmdlist))); - getCurrentResourceStorage().m_inflightCommandList.push_back(copycmdlist); - // Make previous RTTs sampleable for (unsigned i = 0; i < 4; i++) { @@ -141,9 +137,6 @@ void D3D12GSRender::PrepareRenderTargets() } depthStencilViewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; m_device->CreateDepthStencilView(ds, &depthStencilViewDesc, m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); - - check(copycmdlist->Close()); - m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)©cmdlist); } ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, size_t slot, u32 address, diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 2038ec5b52..2ca3963d90 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -726,7 +726,7 @@ size_t getTextureSize(const RSXTexture &texture) } } -size_t D3D12GSRender::UploadTextures() +size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist) { std::lock_guard lock(mut); size_t usedTexture = 0; @@ -758,15 +758,7 @@ size_t D3D12GSRender::UploadTextures() } else { - // Upload at each iteration to take advantage of overlapping transfer - ID3D12GraphicsCommandList *commandList; - check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_textureUploadCommandAllocator, nullptr, IID_PPV_ARGS(&commandList))); - - vramTexture = uploadSingleTexture(m_textures[i], m_device, commandList, m_textureUploadData); - - check(commandList->Close()); - m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList); - getCurrentResourceStorage().m_inflightCommandList.push_back(commandList); + vramTexture = uploadSingleTexture(m_textures[i], m_device, cmdlist, m_textureUploadData); m_texturesCache[texaddr] = vramTexture; u32 s = (u32)align(getTextureSize(m_textures[i]), 4096); @@ -897,4 +889,4 @@ size_t D3D12GSRender::UploadTextures() return usedTexture; } -#endif +#endif \ No newline at end of file From 9cb88b3a8dab5ce7a1ffcba37361677550d8c9ca Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 14 Aug 2015 21:38:40 +0200 Subject: [PATCH 3/5] d3d12: Use ThrowIfFailed instead of check to be inline with DX12 Samples --- rpcs3/Emu/RSX/D3D12/D3D12.h | 10 ++-- rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 14 +++--- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 66 +++++++++++++-------------- rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 4 +- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 6 +-- rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp | 12 ++--- 6 files changed, 57 insertions(+), 55 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12.h b/rpcs3/Emu/RSX/D3D12/D3D12.h index a139297b1c..e5f250eb67 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12.h @@ -11,11 +11,13 @@ #define SAFE_RELEASE(x) if (x) x->Release(); -inline -void check(HRESULT hr) +// From DX12 D3D11On12 Sample (MIT Licensed) +inline void ThrowIfFailed(HRESULT hr) { - if (hr != 0) - abort(); + if (FAILED(hr)) + { + throw; + } } /** diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index bfa2364f89..52ff6a0895 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -205,7 +205,7 @@ ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVerte size_t heapOffset = vertexIndexHeap.alloc(subBufferSize); ID3D12Resource *vertexBuffer; - check(device->CreatePlacedResource( + ThrowIfFailed(device->CreatePlacedResource( vertexIndexHeap.m_heap, heapOffset, &getBufferResourceDesc(subBufferSize), @@ -214,7 +214,7 @@ ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVerte IID_PPV_ARGS(&vertexBuffer) )); void *bufferMap; - check(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); + ThrowIfFailed(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); memset(bufferMap, -1, subBufferSize); #pragma omp parallel for for (int vertex = 0; vertex < vbf.elementCount; vertex++) @@ -405,7 +405,7 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); ID3D12Resource *indexBuffer; - check(m_device->CreatePlacedResource( + ThrowIfFailed(m_device->CreatePlacedResource( m_vertexIndexData.m_heap, heapOffset, &getBufferResourceDesc(subBufferSize), @@ -415,7 +415,7 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) )); void *bufferMap; - check(indexBuffer->Map(0, nullptr, (void**)&bufferMap)); + ThrowIfFailed(indexBuffer->Map(0, nullptr, (void**)&bufferMap)); if (indexed_draw && !forcedIndexBuffer) streamBuffer(bufferMap, m_indexed_array.m_data.data(), subBufferSize); else if (indexed_draw && forcedIndexBuffer) @@ -499,7 +499,7 @@ void D3D12GSRender::setScaleOffset() D3D12_RANGE range = { heapOffset, heapOffset + 256 }; void *scaleOffsetMap; - check(m_constantsData.m_heap->Map(0, &range, &scaleOffsetMap)); + ThrowIfFailed(m_constantsData.m_heap->Map(0, &range, &scaleOffsetMap)); streamToBuffer((char*)scaleOffsetMap + heapOffset, scaleOffsetMat, 16 * sizeof(float)); int isAlphaTested = m_set_alpha_test; memcpy((char*)scaleOffsetMap + heapOffset + 16 * sizeof(float), &isAlphaTested, sizeof(int)); @@ -531,7 +531,7 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer() D3D12_RANGE range = { heapOffset, heapOffset + bufferSize }; void *constantsBufferMap; - check(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap)); + ThrowIfFailed(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap)); for (const auto &vertexConstants : m_vertexConstants) { float data[4] = { @@ -568,7 +568,7 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer() size_t offset = 0; void *constantsBufferMap; - check(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap)); + ThrowIfFailed(m_constantsData.m_heap->Map(0, &range, &constantsBufferMap)); for (size_t offsetInFP : fragmentOffset) { u32 vector[4]; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 8e06c9348a..e4359c28c1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -119,31 +119,31 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device) // Create a global command allocator device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator)); device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_textureUploadCommandAllocator)); - check(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&m_downloadCommandAllocator))); + ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&m_downloadCommandAllocator))); D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc = {}; descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; descriptorHeapDesc.NumDescriptors = 10000; // For safety descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - check(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_constantsBufferDescriptorsHeap))); + ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_constantsBufferDescriptorsHeap))); descriptorHeapDesc = {}; descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; descriptorHeapDesc.NumDescriptors = 10000; // For safety descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - check(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_scaleOffsetDescriptorHeap))); + ThrowIfFailed(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_scaleOffsetDescriptorHeap))); D3D12_DESCRIPTOR_HEAP_DESC textureDescriptorDesc = {}; textureDescriptorDesc.NumDescriptors = 10000; // For safety textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; textureDescriptorDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_textureDescriptorsHeap))); + ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_textureDescriptorsHeap))); textureDescriptorDesc.NumDescriptors = 2048; // For safety textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0]))); - check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1]))); + ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[0]))); + ThrowIfFailed(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap[1]))); } void D3D12GSRender::ResourceStorage::Release() @@ -221,13 +221,13 @@ D3D12GSRender::D3D12GSRender() } Microsoft::WRL::ComPtr dxgiFactory; - check(CreateDXGIFactory(IID_PPV_ARGS(&dxgiFactory))); + ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&dxgiFactory))); // Create adapter IDXGIAdapter* adaptater = nullptr; switch (Ini.GSD3DAdaptater.GetValue()) { case 0: // WARP - check(dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&adaptater))); + ThrowIfFailed(dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&adaptater))); break; case 1: // Default dxgiFactory->EnumAdapters(0, &adaptater); @@ -236,14 +236,14 @@ D3D12GSRender::D3D12GSRender() dxgiFactory->EnumAdapters(Ini.GSD3DAdaptater.GetValue() - 2,&adaptater); break; } - check(wrapD3D12CreateDevice(adaptater, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); + ThrowIfFailed(wrapD3D12CreateDevice(adaptater, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device))); // Queues D3D12_COMMAND_QUEUE_DESC copyQueueDesc = {}, graphicQueueDesc = {}; copyQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; graphicQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - check(m_device->CreateCommandQueue(©QueueDesc, IID_PPV_ARGS(&m_commandQueueCopy))); - check(m_device->CreateCommandQueue(&graphicQueueDesc, IID_PPV_ARGS(&m_commandQueueGraphic))); + ThrowIfFailed(m_device->CreateCommandQueue(©QueueDesc, IID_PPV_ARGS(&m_commandQueueCopy))); + ThrowIfFailed(m_device->CreateCommandQueue(&graphicQueueDesc, IID_PPV_ARGS(&m_commandQueueGraphic))); g_descriptorStrideSRVCBVUAV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); g_descriptorStrideDSV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); @@ -266,7 +266,7 @@ D3D12GSRender::D3D12GSRender() swapChain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; swapChain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - check(dxgiFactory->CreateSwapChain(m_commandQueueGraphic, &swapChain, (IDXGISwapChain**)&m_swapChain)); + ThrowIfFailed(dxgiFactory->CreateSwapChain(m_commandQueueGraphic, &swapChain, (IDXGISwapChain**)&m_swapChain)); m_swapChain->GetBuffer(0, IID_PPV_ARGS(&m_backBuffer[0])); m_swapChain->GetBuffer(1, IID_PPV_ARGS(&m_backBuffer[1])); @@ -326,7 +326,7 @@ D3D12GSRender::D3D12GSRender() Microsoft::WRL::ComPtr rootSignatureBlob; Microsoft::WRL::ComPtr errorBlob; - check(wrapD3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); + ThrowIfFailed(wrapD3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob)); m_device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), @@ -344,7 +344,7 @@ D3D12GSRender::D3D12GSRender() D3D12_HEAP_PROPERTIES hp = {}; hp.Type = D3D12_HEAP_TYPE_DEFAULT; - check( + ThrowIfFailed( m_device->CreateCommittedResource( &hp, D3D12_HEAP_FLAG_NONE, @@ -432,7 +432,7 @@ void D3D12GSRender::Clear(u32 cmd) assert(cmd == NV4097_CLEAR_SURFACE); ID3D12GraphicsCommandList *commandList; - check(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList))); + ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList))); getCurrentResourceStorage().m_inflightCommandList.push_back(commandList); PrepareRenderTargets(commandList); @@ -503,7 +503,7 @@ void D3D12GSRender::Clear(u32 cmd) } } - check(commandList->Close()); + ThrowIfFailed(commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**) &commandList); } @@ -716,7 +716,7 @@ void D3D12GSRender::Draw() else commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, (UINT)m_renderingInfo.m_baseVertex, 0); - check(commandList->Close()); + ThrowIfFailed(commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList); m_indexed_array.Reset(); } @@ -771,7 +771,7 @@ void D3D12GSRender::Flip() assert(m_textureUploadData.canAlloc(textureSize)); size_t heapOffset = m_textureUploadData.alloc(textureSize); - check(m_device->CreatePlacedResource( + ThrowIfFailed(m_device->CreatePlacedResource( m_textureUploadData.m_heap, heapOffset, &getBufferResourceDesc(textureSize), @@ -782,13 +782,13 @@ void D3D12GSRender::Flip() m_textureUploadData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, textureSize, stagingTexture)); void *dstBuffer; - check(stagingTexture->Map(0, nullptr, &dstBuffer)); + ThrowIfFailed(stagingTexture->Map(0, nullptr, &dstBuffer)); for (unsigned row = 0; row < h; row++) memcpy((char*)dstBuffer + row * rowPitch, (char*)src_buffer + row * w * 4, w * 4); stagingTexture->Unmap(0, nullptr); } - check( + ThrowIfFailed( m_device->CreateCommittedResource( &heapProp, D3D12_HEAP_FLAG_NONE, @@ -896,10 +896,10 @@ void D3D12GSRender::Flip() commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); if (isFlipSurfaceInLocalMemory(m_surface_color_target) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); - check(commandList->Close()); + ThrowIfFailed(commandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&commandList); - check(m_swapChain->Present(Ini.GSVSyncEnable.GetValue() ? 1 : 0, 0)); + ThrowIfFailed(m_swapChain->Present(Ini.GSVSyncEnable.GetValue() ? 1 : 0, 0)); // Add an event signaling queue completion ResourceStorage &storage = getNonCurrentResourceStorage(); @@ -996,7 +996,7 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra size_t heapOffset = m_readbackResources.alloc(sizeInByte); resdesc = getBufferResourceDesc(sizeInByte); - check( + ThrowIfFailed( m_device->CreatePlacedResource( m_readbackResources.m_heap, heapOffset, @@ -1030,7 +1030,7 @@ static void copyToCellRamAndRelease(void *dstAddress, ID3D12Resource *res, size_t dstPitch, size_t srcPitch, size_t width, size_t height) { void *srcBuffer; - check(res->Map(0, nullptr, &srcBuffer)); + ThrowIfFailed(res->Map(0, nullptr, &srcBuffer)); for (unsigned row = 0; row < height; row++) memcpy((char*)dstAddress + row * dstPitch, (char*)srcBuffer + row * srcPitch, srcPitch); res->Unmap(0, nullptr); @@ -1050,7 +1050,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) ID3D12Fence *fence; - check( + ThrowIfFailed( m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)) ); HANDLE handle = CreateEvent(0, FALSE, FALSE, 0); @@ -1076,7 +1076,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) assert(m_UAVHeap.canAlloc(sizeInByte)); size_t heapOffset = m_UAVHeap.alloc(sizeInByte); - check( + ThrowIfFailed( m_device->CreatePlacedResource( m_UAVHeap.m_heap, heapOffset, @@ -1093,7 +1093,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) heapOffset = m_readbackResources.alloc(sizeInByte); resdesc = getBufferResourceDesc(sizeInByte); - check( + ThrowIfFailed( m_device->CreatePlacedResource( m_readbackResources.m_heap, heapOffset, @@ -1105,7 +1105,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) ); m_readbackResources.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, sizeInByte, writeDest)); - check( + ThrowIfFailed( m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&convertCommandList)) ); @@ -1113,7 +1113,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) descriptorHeapDesc.NumDescriptors = 2; descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - check( + ThrowIfFailed( m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&descriptorHeap)) ); D3D12_CPU_DESCRIPTOR_HANDLE Handle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); @@ -1164,14 +1164,14 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) convertCommandList->ResourceBarrier(2, barriers); convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(depthConverted, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); - check(convertCommandList->Close()); + ThrowIfFailed(convertCommandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&convertCommandList); } ID3D12GraphicsCommandList *downloadCommandList; if (needTransfer) { - check( + ThrowIfFailed( m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator, nullptr, IID_PPV_ARGS(&downloadCommandList)) ); } @@ -1237,7 +1237,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) } if (needTransfer) { - check(downloadCommandList->Close()); + ThrowIfFailed(downloadCommandList->Close()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&downloadCommandList); } @@ -1259,7 +1259,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) auto ptr = vm::get_ptr(address); char *ptrAsChar = (char*)ptr; unsigned char *writeDestPtr; - check(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); + ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); // TODO : this should be done by the gpu for (unsigned row = 0; row < m_surface_clip_h; row++) { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 14e0c405f1..52ace0b516 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -82,7 +82,7 @@ struct InitHeap heapDesc.SizeInBytes = heapSize; heapDesc.Properties.Type = type; heapDesc.Flags = flags; - check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&result))); + ThrowIfFailed(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&result))); return result; } }; @@ -95,7 +95,7 @@ struct InitHeap ID3D12Resource *result; D3D12_HEAP_PROPERTIES heapProperties = {}; heapProperties.Type = type; - check(device->CreateCommittedResource(&heapProperties, + ThrowIfFailed(device->CreateCommittedResource(&heapProperties, flags, &getBufferResourceDesc(heapSize), D3D12_RESOURCE_STATE_GENERIC_READ, diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 2ca3963d90..cd5941d4db 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -555,7 +555,7 @@ ID3D12Resource *uploadSingleTexture( assert(textureBuffersHeap.canAlloc(textureSize)); size_t heapOffset = textureBuffersHeap.alloc(textureSize); - check(device->CreatePlacedResource( + ThrowIfFailed(device->CreatePlacedResource( textureBuffersHeap.m_heap, heapOffset, &getBufferResourceDesc(textureSize), @@ -567,7 +567,7 @@ ID3D12Resource *uploadSingleTexture( auto pixels = vm::get_ptr(texaddr); void *textureData; - check(Texture->Map(0, nullptr, (void**)&textureData)); + ThrowIfFailed(Texture->Map(0, nullptr, (void**)&textureData)); std::vector mipInfos; switch (format) @@ -616,7 +616,7 @@ ID3D12Resource *uploadSingleTexture( D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - check(device->CreateCommittedResource( + ThrowIfFailed(device->CreateCommittedResource( &heapProp, D3D12_HEAP_FLAG_NONE, &texturedesc, diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp index 1e51d30ab1..5c69464a82 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.cpp @@ -185,7 +185,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - check(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO))); + ThrowIfFailed(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO))); float quadVertex[16] = { @@ -197,7 +197,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_UPLOAD; - check( + ThrowIfFailed( device->CreateCommittedResource( &heapProp, D3D12_HEAP_FLAG_NONE, @@ -217,11 +217,11 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - check( + ThrowIfFailed( device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_textureDescriptorHeap)) ); heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - check( + ThrowIfFailed( device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap)) ); } @@ -229,7 +229,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device) void D3D12GSRender::initConvertShader() { const auto &p = compileF32toU8CS(); - check( + ThrowIfFailed( m_device->CreateRootSignature(0, p.second->GetBufferPointer(), p.second->GetBufferSize(), IID_PPV_ARGS(&m_convertRootSignature)) ); @@ -238,7 +238,7 @@ void D3D12GSRender::initConvertShader() computePipelineStateDesc.CS.pShaderBytecode = p.first->GetBufferPointer(); computePipelineStateDesc.pRootSignature = m_convertRootSignature; - check( + ThrowIfFailed( m_device->CreateComputePipelineState(&computePipelineStateDesc, IID_PPV_ARGS(&m_convertPSO)) ); From 09cc127dd9d5a6e31acb1f41a2b6062da107e5ac Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 14 Aug 2015 23:29:48 +0200 Subject: [PATCH 4/5] d3d12: Use ComPtr<> instead of manually releasing some structures --- rpcs3/Emu/RSX/D3D12/D3D12.h | 3 ++ rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 4 +- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 45 +++++++------------ rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 22 ++++----- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 10 ++--- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 11 ++--- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 24 +++++----- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 2 +- 8 files changed, 55 insertions(+), 66 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12.h b/rpcs3/Emu/RSX/D3D12/D3D12.h index e5f250eb67..d3f8f0cb94 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12.h @@ -3,12 +3,15 @@ #include #include +#include #include "utilities/Log.h" #include "Emu/Memory/vm.h" #include "Emu/RSX/GCM.h" #pragma comment (lib, "dxgi.lib") +using namespace Microsoft::WRL; + #define SAFE_RELEASE(x) if (x) x->Release(); // From DX12 D3D11On12 Sample (MIT Licensed) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 52ff6a0895..19f84955c4 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -279,7 +279,7 @@ std::vector D3D12GSRender::UploadVertexBuffers(bool in { std::vector result; const std::vector &vertexBufferFormat = FormatVertexData(m_vertex_data); - m_IASet = getIALayout(m_device, vertexBufferFormat, m_vertex_data); + m_IASet = getIALayout(m_device.Get(), vertexBufferFormat, m_vertex_data); const u32 data_offset = indexed_draw ? 0 : m_draw_array_first; @@ -302,7 +302,7 @@ std::vector D3D12GSRender::UploadVertexBuffers(bool in vertexBuffer = It->second; else { - vertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device, m_vertexIndexData); + vertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device.Get(), m_vertexIndexData); m_vertexCache[key] = vertexBuffer; } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index e4359c28c1..ad2f77973b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -242,8 +242,7 @@ D3D12GSRender::D3D12GSRender() D3D12_COMMAND_QUEUE_DESC copyQueueDesc = {}, graphicQueueDesc = {}; copyQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; graphicQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - ThrowIfFailed(m_device->CreateCommandQueue(©QueueDesc, IID_PPV_ARGS(&m_commandQueueCopy))); - ThrowIfFailed(m_device->CreateCommandQueue(&graphicQueueDesc, IID_PPV_ARGS(&m_commandQueueGraphic))); + ThrowIfFailed(m_device->CreateCommandQueue(&graphicQueueDesc, IID_PPV_ARGS(m_commandQueueGraphic.GetAddressOf()))); g_descriptorStrideSRVCBVUAV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); g_descriptorStrideDSV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); @@ -266,7 +265,7 @@ D3D12GSRender::D3D12GSRender() swapChain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; swapChain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - ThrowIfFailed(dxgiFactory->CreateSwapChain(m_commandQueueGraphic, &swapChain, (IDXGISwapChain**)&m_swapChain)); + ThrowIfFailed(dxgiFactory->CreateSwapChain(m_commandQueueGraphic.Get(), &swapChain, (IDXGISwapChain**)m_swapChain.GetAddressOf())); m_swapChain->GetBuffer(0, IID_PPV_ARGS(&m_backBuffer[0])); m_swapChain->GetBuffer(1, IID_PPV_ARGS(&m_backBuffer[1])); @@ -277,9 +276,9 @@ D3D12GSRender::D3D12GSRender() rttDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rttDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_backbufferAsRendertarget[0])); - m_device->CreateRenderTargetView(m_backBuffer[0], &rttDesc, m_backbufferAsRendertarget[0]->GetCPUDescriptorHandleForHeapStart()); + m_device->CreateRenderTargetView(m_backBuffer[0].Get(), &rttDesc, m_backbufferAsRendertarget[0]->GetCPUDescriptorHandleForHeapStart()); m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_backbufferAsRendertarget[1])); - m_device->CreateRenderTargetView(m_backBuffer[1], &rttDesc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); + m_device->CreateRenderTargetView(m_backBuffer[1].Get(), &rttDesc, m_backbufferAsRendertarget[1]->GetCPUDescriptorHandleForHeapStart()); // Common root signatures for (unsigned textureCount = 0; textureCount < 17; textureCount++) @@ -331,16 +330,16 @@ D3D12GSRender::D3D12GSRender() m_device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), - IID_PPV_ARGS(&m_rootSignatures[textureCount])); + IID_PPV_ARGS(m_rootSignatures[textureCount].GetAddressOf())); } - m_perFrameStorage[0].Init(m_device); + m_perFrameStorage[0].Init(m_device.Get()); m_perFrameStorage[0].Reset(); - m_perFrameStorage[1].Init(m_device); + m_perFrameStorage[1].Init(m_device.Get()); m_perFrameStorage[1].Reset(); initConvertShader(); - m_outputScalingPass.Init(m_device); + m_outputScalingPass.Init(m_device.Get()); D3D12_HEAP_PROPERTIES hp = {}; hp.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -354,14 +353,14 @@ D3D12GSRender::D3D12GSRender() IID_PPV_ARGS(&m_dummyTexture)) ); - m_readbackResources.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); - m_UAVHeap.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES); + m_readbackResources.Init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); + m_UAVHeap.Init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES); - m_rtts.Init(m_device); + m_rtts.Init(m_device.Get()); - m_constantsData.Init(m_device, 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); - m_vertexIndexData.Init(m_device, 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); - m_textureUploadData.Init(m_device, 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); + m_constantsData.Init(m_device.Get(), 1024 * 1024 * 64, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_NONE); + m_vertexIndexData.Init(m_device.Get(), 1024 * 1024 * 384, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); + m_textureUploadData.Init(m_device.Get(), 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS); } D3D12GSRender::~D3D12GSRender() @@ -378,22 +377,12 @@ D3D12GSRender::~D3D12GSRender() m_convertRootSignature->Release(); m_perFrameStorage[0].Release(); m_perFrameStorage[1].Release(); - m_commandQueueGraphic->Release(); - m_commandQueueCopy->Release(); - m_backbufferAsRendertarget[0]->Release(); - m_backBuffer[0]->Release(); - m_backbufferAsRendertarget[1]->Release(); - m_backBuffer[1]->Release(); m_rtts.Release(); - for (unsigned i = 0; i < 17; i++) - m_rootSignatures[i]->Release(); for (auto &tmp : m_texToClean) tmp->Release(); for (auto &tmp : m_texturesCache) tmp.second->Release(); - m_swapChain->Release(); m_outputScalingPass.Release(); - m_device->Release(); unloadD3D12FunctionPointers(); } @@ -559,7 +548,7 @@ void D3D12GSRender::Draw() return; } - commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second]); + commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second].Get()); commandList->OMSetStencilRef(m_stencil_func_ref); // Constants @@ -821,7 +810,7 @@ void D3D12GSRender::Flip() resourceToFlip = m_rtts.m_currentlyBoundRenderTargets[0]; } - commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()], D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); + commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); D3D12_VIEWPORT viewport = { @@ -893,7 +882,7 @@ void D3D12GSRender::Flip() if (m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) commandList->DrawInstanced(4, 1, 0, 0); - commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); + commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); if (isFlipSurfaceInLocalMemory(m_surface_color_target) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) commandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); ThrowIfFailed(commandList->Close()); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 52ace0b516..ab2da2268e 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -230,6 +230,17 @@ struct GarbageCollectionThread class D3D12GSRender : public GSRender { private: + /** D3D12 structures. + * Note: they should be declared in reverse order of destruction + */ + ComPtr m_device; + ComPtr m_commandQueueGraphic; + ComPtr m_swapChain; + ComPtr m_backBuffer[2]; + ComPtr m_backbufferAsRendertarget[2]; + // m_rootSignatures[N] is RS with N texture/sample + ComPtr m_rootSignatures[17]; + /** * Mutex protecting m_texturesCache and m_Textoclean access * Memory protection fault catch can be generated by any thread and @@ -253,8 +264,6 @@ private: PipelineStateObjectCache m_cachePSO; std::pair *m_PSO; - // m_rootSignatures[N] is RS with N texture/sample - ID3D12RootSignature *m_rootSignatures[17]; struct { @@ -346,22 +355,15 @@ private: RenderTargets m_rtts; std::vector m_IASet; - ID3D12Device* m_device; + size_t g_descriptorStrideSRVCBVUAV; size_t g_descriptorStrideDSV; size_t g_descriptorStrideRTV; size_t g_descriptorStrideSamplers; - ID3D12CommandQueue *m_commandQueueCopy; - ID3D12CommandQueue *m_commandQueueGraphic; // Used to fill unused texture slot ID3D12Resource *m_dummyTexture; - struct IDXGISwapChain3 *m_swapChain; - //BackBuffers - ID3D12Resource* m_backBuffer[2]; - ID3D12DescriptorHeap *m_backbufferAsRendertarget[2]; - size_t m_lastWidth, m_lastHeight, m_lastDepth; public: GSFrameBase2 *m_frame; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index a02f5f9c76..43515d4ec8 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -10,8 +10,9 @@ #define TO_STRING(x) #x void Shader::Compile(const std::string &code, SHADER_TYPE st) -{ HRESULT hr; - Microsoft::WRL::ComPtr errorBlob; +{ + HRESULT hr; + ComPtr errorBlob; switch (st) { case SHADER_TYPE::SHADER_TYPE_VERTEX: @@ -27,9 +28,6 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st) } } - - - bool D3D12GSRender::LoadProgram() { if (!m_cur_fragment_prog) @@ -287,7 +285,7 @@ bool D3D12GSRender::LoadProgram() prop.IASet = m_IASet; - m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device, m_rootSignatures)); + m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device.Get(), m_rootSignatures)); return m_PSO != nullptr; } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 4fe0e4734e..38566e5ecc 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -1,15 +1,12 @@ #pragma once #if defined (DX12_SUPPORT) -#include -#include +#include "D3D12.h" #include "../Common/ProgramStateCache.h" #include "D3D12VertexProgramDecompiler.h" #include "D3D12FragmentProgramDecompiler.h" #include "Utilities/File.h" - - struct D3D12PipelineProperties { D3D12_PRIMITIVE_TOPOLOGY_TYPE Topology; @@ -66,7 +63,7 @@ public: ~Shader() {} u32 id; - Microsoft::WRL::ComPtr bytecode; + ComPtr bytecode; std::vector FragmentConstantOffsetCache; size_t m_textureCount; @@ -86,7 +83,7 @@ struct D3D12Traits typedef Shader FragmentProgramData; typedef std::pair PipelineData; typedef D3D12PipelineProperties PipelineProperties; - typedef std::pair ExtraData; + typedef std::pair *> ExtraData; static void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID) @@ -145,7 +142,7 @@ struct D3D12Traits graphicPipelineStateDesc.PS.BytecodeLength = fragmentProgramData.bytecode->GetBufferSize(); graphicPipelineStateDesc.PS.pShaderBytecode = fragmentProgramData.bytecode->GetBufferPointer(); - graphicPipelineStateDesc.pRootSignature = extraData.second[fragmentProgramData.m_textureCount]; + graphicPipelineStateDesc.pRootSignature = extraData.second[fragmentProgramData.m_textureCount].Get(); result->second = fragmentProgramData.m_textureCount; graphicPipelineStateDesc.BlendState = pipelineProperties.Blend; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index dc2684c3a9..bc8132a272 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -59,66 +59,66 @@ void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) { case CELL_GCM_SURFACE_TARGET_0: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_1: { - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 0, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_MRT1: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); } break; case CELL_GCM_SURFACE_TARGET_MRT2: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle); break; } case CELL_GCM_SURFACE_TARGET_MRT3: { - ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttA = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 0, address_a, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttA, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttB = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 1, address_b, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttB, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttC = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 2, address_c, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttC, &rttViewDesc, Handle); Handle.ptr += g_RTTIncrement; - ID3D12Resource *rttD = m_rtts.bindAddressAsRenderTargets(m_device, copycmdlist, 3, address_d, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, + ID3D12Resource *rttD = m_rtts.bindAddressAsRenderTargets(m_device.Get(), copycmdlist, 3, address_d, m_surface_clip_w, m_surface_clip_h, m_surface_color_format, m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); m_device->CreateRenderTargetView(rttD, &rttViewDesc, Handle); break; } } - ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device, copycmdlist, address_z, m_surface_clip_w, m_surface_clip_h, m_surface_depth_format, 1., 0); + ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device.Get(), copycmdlist, address_z, m_surface_clip_w, m_surface_clip_h, m_surface_depth_format, 1., 0); D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {}; switch (m_surface_depth_format) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index cd5941d4db..d6d5cb9ee4 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -758,7 +758,7 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist) } else { - vramTexture = uploadSingleTexture(m_textures[i], m_device, cmdlist, m_textureUploadData); + vramTexture = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData); m_texturesCache[texaddr] = vramTexture; u32 s = (u32)align(getTextureSize(m_textures[i]), 4096); From 3b0afe92e3c63af32c3bc51735f3ad114931db56 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 14 Aug 2015 23:02:46 +0200 Subject: [PATCH 5/5] d3d12: Add a dummy D3D12Lib struct that load/unload d3d12.dll It allows to unload the lib after everything else has been released, it fixes a crash when leaving an app with d3d12 backend. --- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 14 +++++++++++--- rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 11 ++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index ad2f77973b..244852862b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -203,8 +203,18 @@ bool D3D12GSRender::invalidateTexture(u32 addr) return handled; } +D3D12DLLManagement::D3D12DLLManagement() +{ + loadD3D12FunctionPointers(); +} + +D3D12DLLManagement::~D3D12DLLManagement() +{ + unloadD3D12FunctionPointers(); +} + D3D12GSRender::D3D12GSRender() - : GSRender(), m_PSO(nullptr) + : GSRender(), m_D3D12Lib(), m_PSO(nullptr) { gfxHandler = [this](u32 addr) { bool result = invalidateTexture(addr); @@ -212,7 +222,6 @@ D3D12GSRender::D3D12GSRender() LOG_WARNING(RSX, "Reporting Cell writing to %x", addr); return result; }; - loadD3D12FunctionPointers(); if (Ini.GSDebugOutputEnable.GetValue()) { Microsoft::WRL::ComPtr debugInterface; @@ -383,7 +392,6 @@ D3D12GSRender::~D3D12GSRender() for (auto &tmp : m_texturesCache) tmp.second->Release(); m_outputScalingPass.Release(); - unloadD3D12FunctionPointers(); } void D3D12GSRender::Close() diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index ab2da2268e..b81df5eac2 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -227,12 +227,22 @@ struct GarbageCollectionThread void waitForCompletion(); }; +/** + * Structure used to load/unload D3D12 lib. + */ +struct D3D12DLLManagement +{ + D3D12DLLManagement(); + ~D3D12DLLManagement(); +}; + class D3D12GSRender : public GSRender { private: /** D3D12 structures. * Note: they should be declared in reverse order of destruction */ + D3D12DLLManagement m_D3D12Lib; ComPtr m_device; ComPtr m_commandQueueGraphic; ComPtr m_swapChain; @@ -240,7 +250,6 @@ private: ComPtr m_backbufferAsRendertarget[2]; // m_rootSignatures[N] is RS with N texture/sample ComPtr m_rootSignatures[17]; - /** * Mutex protecting m_texturesCache and m_Textoclean access * Memory protection fault catch can be generated by any thread and