From 0812448a8fc9615a14e4a03841484baced4367c8 Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Mon, 17 Nov 2025 10:30:35 -0800 Subject: [PATCH 01/11] Applied enhanced barriers to multithread sample --- .../src/D3D12Multithreading.cpp | 172 ++++++++++++++++++ .../src/D3D12Multithreading.h | 2 +- .../src/D3D12Multithreading.sln | 25 ++- .../src/D3D12Multithreading.vcxproj | 99 ++++++++++ .../D3D12Multithreading/src/FrameResource.cpp | 72 +++++++- .../D3D12Multithreading/src/FrameResource.h | 5 +- 6 files changed, 362 insertions(+), 13 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index f28999d41..103fd12fd 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -56,6 +56,14 @@ void D3D12Multithreading::LoadPipeline() UINT dxgiFactoryFlags = 0; #if defined(_DEBUG) + + // Check to see if a copy of WinPixGpuCapturer.dll has already been injected into the application. + // This may happen if the application is launched through the PIX UI. + if (GetModuleHandle(L"WinPixGpuCapturer.dll") == 0) + { + LoadLibrary(L"C:\\Program Files\\Microsoft PIX\\2505.30\\WinPixGpuCapturer.dll"); + } + // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. { @@ -96,6 +104,15 @@ void D3D12Multithreading::LoadPipeline() )); } +#if defined(USE_ENHANCED_BARRIERS) + D3D12_FEATURE_DATA_D3D12_OPTIONS12 options12 = {}; + ThrowIfFailed(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options12, sizeof(options12))); + if (options12.EnhancedBarriersSupported != TRUE) + { + ThrowIfFailed(E_FAIL); + } +#endif // defined(USE_ENHANCED_BARRIERS) + // Describe and create the command queue. D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; @@ -270,7 +287,11 @@ void D3D12Multithreading::LoadAssets() } // Create temporary command list for initial GPU setup. +#if defined(USE_ENHANCED_BARRIERS) + ComPtr commandList; +#else ComPtr commandList; +#endif // defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList))); // Create render target views (RTVs). @@ -325,6 +346,18 @@ void D3D12Multithreading::LoadAssets() // Create the vertex buffer. { +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_vertexBuffer))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -332,6 +365,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_vertexBuffer); @@ -354,7 +388,24 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy vertex buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_BUFFER_BARRIER BufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_ALL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_CONSTANT_BUFFER, // AccessAfter + m_vertexBuffer.Get() + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); +#endif // defined(USE_ENHANCED_BARRIERS) PIXEndEvent(commandList.Get()); } @@ -367,6 +418,18 @@ void D3D12Multithreading::LoadAssets() // Create the index buffer. { +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_indexBuffer))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -374,6 +437,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_indexBuffer))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_indexBuffer); @@ -396,7 +460,25 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy index buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_indexBuffer.Get(), m_indexBufferUpload.Get(), 0, 0, 1, &indexData); + +#if defined(USE_ENHANCED_BARRIERS) + D3D12_BUFFER_BARRIER BufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_INDEX_INPUT, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_INDEX_BUFFER, // AccessAfter + m_indexBuffer.Get() + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)); +#endif // defined(USE_ENHANCED_BARRIERS) PIXEndEvent(commandList.Get()); } @@ -440,6 +522,32 @@ void D3D12Multithreading::LoadAssets() { // Describe and create a Texture2D. const SampleAssets::TextureResource &tex = SampleAssets::Textures[i]; + +#if defined(USE_ENHANCED_BARRIERS) + CD3DX12_RESOURCE_DESC1 texDesc( + D3D12_RESOURCE_DIMENSION_TEXTURE2D, + 0, + tex.Width, + tex.Height, + 1, + static_cast(tex.MipLevels), + tex.Format, + 1, + 0, + D3D12_TEXTURE_LAYOUT_UNKNOWN, + D3D12_RESOURCE_FLAG_NONE); + + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &texDesc, + D3D12_BARRIER_LAYOUT_COPY_DEST, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_textures[i]))); +#else CD3DX12_RESOURCE_DESC texDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -460,6 +568,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_textures[i]))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT_INDEXED(m_textures, i); @@ -482,7 +591,28 @@ void D3D12Multithreading::LoadAssets() textureData.SlicePitch = tex.Data->Size; UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_ALL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_textures[i].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); +#endif // defined(USE_ENHANCED_BARRIERS) } // Describe and create an SRV. @@ -914,8 +1044,29 @@ void D3D12Multithreading::BeginFrame() { m_pCurrentFrameResource->Init(); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Indicate that the back buffer will be used as a render target. m_pCurrentFrameResource->m_commandLists[CommandListPre]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); +#endif // defined(USE_ENHANCED_BARRIERS) // Clear the render target and depth stencil. const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -940,8 +1091,29 @@ void D3D12Multithreading::EndFrame() { m_pCurrentFrameResource->Finish(); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Indicate that the back buffer will now be used to present. m_pCurrentFrameResource->m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); +#endif // defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_pCurrentFrameResource->m_commandLists[CommandListPost]->Close()); } diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h index 5cb0061a7..5caec2668 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h @@ -78,7 +78,7 @@ class D3D12Multithreading : public DXSample CD3DX12_VIEWPORT m_viewport; CD3DX12_RECT m_scissorRect; ComPtr m_swapChain; - ComPtr m_device; + ComPtr m_device; ComPtr m_renderTargets[FrameCount]; ComPtr m_depthStencil; ComPtr m_commandAllocator; diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln index 463a097ec..47ed51675 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln @@ -1,22 +1,31 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30621.155.26403.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36623.8 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12Multithreading", "D3D12Multithreading.vcxproj", "{3FC193D0-7E4E-4918-8431-D67391EE4145}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 + Debug (Enhanced Barriers)|x64 = Debug (Enhanced Barriers)|x64 + Debug (Legacy Barriers)|x64 = Debug (Legacy Barriers)|x64 + Release (Enhanced Barriers)|x64 = Release (Enhanced Barriers)|x64 + Release (Legacy Barriers)|x64 = Release (Legacy Barriers)|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.ActiveCfg = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.Build.0 = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.ActiveCfg = Release|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.Build.0 = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.ActiveCfg = Debug (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.Build.0 = Debug (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.ActiveCfg = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.Build.0 = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.ActiveCfg = Release (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.Build.0 = Release (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.ActiveCfg = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A6E9CE1E-E505-4D05-A426-17CD475BE895} + EndGlobalSection EndGlobal diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj index 3a802ce89..eabd6f346 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj @@ -2,10 +2,18 @@ + + Debug (Enhanced Barriers) + x64 + Debug x64 + + Release (Enhanced Barriers) + x64 + Release x64 @@ -25,6 +33,12 @@ v142 Unicode + + Application + true + v142 + Unicode + Application false @@ -32,25 +46,52 @@ true Unicode + + Application + false + v142 + true + Unicode + + + + + + + true bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Legacy_Barriers + + + true + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Enhanced_Barriers false bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Legacy_Barriers + + + false + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Enhanced_Barriers @@ -80,6 +121,34 @@ true + + + Use + Level3 + Disabled + USE_ENHANCED_BARRIERS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + false + false + + + %(AdditionalIncludeDirectories) + 4267 + + + true + d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) + d3d12.dll + + + true + + + copy %(Identity) "$(OutDir)" > NUL + $(OutDir)\%(Identity) + true + + Level3 @@ -108,6 +177,34 @@ true + + + Level3 + Use + MaxSpeed + true + true + USE_ENHANCED_BARRIERS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + 4267 + + + true + true + true + d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) + d3d12.dll + + + true + + + copy %(Identity) "$(OutDir)" > NUL + $(OutDir)\%(Identity) + true + + @@ -128,7 +225,9 @@ Create + Create Create + Create diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index 9c498aa02..683ea3338 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -13,7 +13,7 @@ #include "FrameResource.h" #include "SquidRoom.h" -FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex) : +FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex) : m_fenceValue(0), m_pipelineState(pPso), m_pipelineStateShadowMap(pShadowMapPso) @@ -49,6 +49,20 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I } // Describe and create the shadow map texture. +#if defined(USE_ENHANCED_BARRIERS) + CD3DX12_RESOURCE_DESC1 shadowTexDesc( + D3D12_RESOURCE_DIMENSION_TEXTURE2D, + 0, + static_cast(pViewport->Width), + static_cast(pViewport->Height), + 1, + 1, + DXGI_FORMAT_R32_TYPELESS, + 1, + 0, + D3D12_TEXTURE_LAYOUT_UNKNOWN, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); +#else CD3DX12_RESOURCE_DESC shadowTexDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -61,12 +75,25 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); +#endif D3D12_CLEAR_VALUE clearValue; // Performance tip: Tell the runtime at resource creation the desired clear value. clearValue.Format = DXGI_FORMAT_D32_FLOAT; clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &shadowTexDesc, + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, + &clearValue, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_shadowTexture))); +#else ThrowIfFailed(pDevice->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -74,6 +101,7 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(&m_shadowTexture))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_shadowTexture); @@ -254,13 +282,55 @@ void FrameResource::Init() void FrameResource::SwapBarriers() { +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_commandLists[CommandListMid]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Transition the shadow map from writeable to readable. m_commandLists[CommandListMid]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); +#endif // defined(USE_ENHANCED_BARRIERS) } void FrameResource::Finish() { +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); +#endif // defined(USE_ENHANCED_BARRIERS) } // Sets up the descriptor tables for the worker command list to use diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h index 845c9cc03..517f0872a 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h @@ -25,8 +25,7 @@ class FrameResource ID3D12CommandList* m_batchSubmit[NumContexts * 2 + CommandListCount]; ComPtr m_commandAllocators[CommandListCount]; - ComPtr m_commandLists[CommandListCount]; - + ComPtr m_commandLists[CommandListCount]; ComPtr m_shadowCommandAllocators[NumContexts]; ComPtr m_shadowCommandLists[NumContexts]; @@ -50,7 +49,7 @@ class FrameResource D3D12_GPU_DESCRIPTOR_HANDLE m_sceneCbvHandle; public: - FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex); + FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex); ~FrameResource(); void Bind(ID3D12GraphicsCommandList* pCommandList, BOOL scenePass, D3D12_CPU_DESCRIPTOR_HANDLE* pRtvHandle, D3D12_CPU_DESCRIPTOR_HANDLE* pDsvHandle); From 71104e686b6ffc11615e4d5d95de6966ddadea7c Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Mon, 17 Nov 2025 13:48:31 -0800 Subject: [PATCH 02/11] Save All Syncs --- .../src/D3D12Multithreading.cpp | 172 ++++++++++++++++++ .../src/D3D12Multithreading.h | 2 +- .../src/D3D12Multithreading.sln | 25 ++- .../src/D3D12Multithreading.vcxproj | 99 ++++++++++ .../D3D12Multithreading/src/FrameResource.cpp | 72 +++++++- .../D3D12Multithreading/src/FrameResource.h | 5 +- 6 files changed, 362 insertions(+), 13 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index f28999d41..143b93291 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -56,6 +56,14 @@ void D3D12Multithreading::LoadPipeline() UINT dxgiFactoryFlags = 0; #if defined(_DEBUG) + + // Check to see if a copy of WinPixGpuCapturer.dll has already been injected into the application. + // This may happen if the application is launched through the PIX UI. + if (GetModuleHandle(L"WinPixGpuCapturer.dll") == 0) + { + LoadLibrary(L"C:\\Program Files\\Microsoft PIX\\2505.30\\WinPixGpuCapturer.dll"); + } + // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. { @@ -96,6 +104,15 @@ void D3D12Multithreading::LoadPipeline() )); } +#if defined(USE_ENHANCED_BARRIERS) + D3D12_FEATURE_DATA_D3D12_OPTIONS12 options12 = {}; + ThrowIfFailed(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options12, sizeof(options12))); + if (options12.EnhancedBarriersSupported != TRUE) + { + ThrowIfFailed(E_FAIL); + } +#endif // defined(USE_ENHANCED_BARRIERS) + // Describe and create the command queue. D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; @@ -270,7 +287,11 @@ void D3D12Multithreading::LoadAssets() } // Create temporary command list for initial GPU setup. +#if defined(USE_ENHANCED_BARRIERS) + ComPtr commandList; +#else ComPtr commandList; +#endif // defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList))); // Create render target views (RTVs). @@ -325,6 +346,18 @@ void D3D12Multithreading::LoadAssets() // Create the vertex buffer. { +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_vertexBuffer))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -332,6 +365,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_vertexBuffer); @@ -354,7 +388,24 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy vertex buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_BUFFER_BARRIER BufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter + m_vertexBuffer.Get() + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); +#endif // defined(USE_ENHANCED_BARRIERS) PIXEndEvent(commandList.Get()); } @@ -367,6 +418,18 @@ void D3D12Multithreading::LoadAssets() // Create the index buffer. { +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_indexBuffer))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -374,6 +437,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_indexBuffer))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_indexBuffer); @@ -396,7 +460,25 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy index buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_indexBuffer.Get(), m_indexBufferUpload.Get(), 0, 0, 1, &indexData); + +#if defined(USE_ENHANCED_BARRIERS) + D3D12_BUFFER_BARRIER BufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_INDEX_INPUT, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_INDEX_BUFFER, // AccessAfter + m_indexBuffer.Get() + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)); +#endif // defined(USE_ENHANCED_BARRIERS) PIXEndEvent(commandList.Get()); } @@ -440,6 +522,32 @@ void D3D12Multithreading::LoadAssets() { // Describe and create a Texture2D. const SampleAssets::TextureResource &tex = SampleAssets::Textures[i]; + +#if defined(USE_ENHANCED_BARRIERS) + CD3DX12_RESOURCE_DESC1 texDesc( + D3D12_RESOURCE_DIMENSION_TEXTURE2D, + 0, + tex.Width, + tex.Height, + 1, + static_cast(tex.MipLevels), + tex.Format, + 1, + 0, + D3D12_TEXTURE_LAYOUT_UNKNOWN, + D3D12_RESOURCE_FLAG_NONE); + + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &texDesc, + D3D12_BARRIER_LAYOUT_COPY_DEST, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_textures[i]))); +#else CD3DX12_RESOURCE_DESC texDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -460,6 +568,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_textures[i]))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT_INDEXED(m_textures, i); @@ -482,7 +591,28 @@ void D3D12Multithreading::LoadAssets() textureData.SlicePitch = tex.Data->Size; UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_textures[i].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); +#endif // defined(USE_ENHANCED_BARRIERS) } // Describe and create an SRV. @@ -914,8 +1044,29 @@ void D3D12Multithreading::BeginFrame() { m_pCurrentFrameResource->Init(); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_NONE, // SyncBefore + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Indicate that the back buffer will be used as a render target. m_pCurrentFrameResource->m_commandLists[CommandListPre]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); +#endif // defined(USE_ENHANCED_BARRIERS) // Clear the render target and depth stencil. const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -940,8 +1091,29 @@ void D3D12Multithreading::EndFrame() { m_pCurrentFrameResource->Finish(); +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore + D3D12_BARRIER_SYNC_NONE, // SyncAfter + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Indicate that the back buffer will now be used to present. m_pCurrentFrameResource->m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); +#endif // defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_pCurrentFrameResource->m_commandLists[CommandListPost]->Close()); } diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h index 5cb0061a7..5caec2668 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h @@ -78,7 +78,7 @@ class D3D12Multithreading : public DXSample CD3DX12_VIEWPORT m_viewport; CD3DX12_RECT m_scissorRect; ComPtr m_swapChain; - ComPtr m_device; + ComPtr m_device; ComPtr m_renderTargets[FrameCount]; ComPtr m_depthStencil; ComPtr m_commandAllocator; diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln index 463a097ec..47ed51675 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln @@ -1,22 +1,31 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30621.155.26403.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36623.8 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12Multithreading", "D3D12Multithreading.vcxproj", "{3FC193D0-7E4E-4918-8431-D67391EE4145}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 + Debug (Enhanced Barriers)|x64 = Debug (Enhanced Barriers)|x64 + Debug (Legacy Barriers)|x64 = Debug (Legacy Barriers)|x64 + Release (Enhanced Barriers)|x64 = Release (Enhanced Barriers)|x64 + Release (Legacy Barriers)|x64 = Release (Legacy Barriers)|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.ActiveCfg = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.Build.0 = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.ActiveCfg = Release|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.Build.0 = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.ActiveCfg = Debug (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.Build.0 = Debug (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.ActiveCfg = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.Build.0 = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.ActiveCfg = Release (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.Build.0 = Release (Enhanced Barriers)|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.ActiveCfg = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A6E9CE1E-E505-4D05-A426-17CD475BE895} + EndGlobalSection EndGlobal diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj index 3a802ce89..eabd6f346 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj @@ -2,10 +2,18 @@ + + Debug (Enhanced Barriers) + x64 + Debug x64 + + Release (Enhanced Barriers) + x64 + Release x64 @@ -25,6 +33,12 @@ v142 Unicode + + Application + true + v142 + Unicode + Application false @@ -32,25 +46,52 @@ true Unicode + + Application + false + v142 + true + Unicode + + + + + + + true bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Legacy_Barriers + + + true + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Enhanced_Barriers false bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Legacy_Barriers + + + false + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + $(ProjectName)_Enhanced_Barriers @@ -80,6 +121,34 @@ true + + + Use + Level3 + Disabled + USE_ENHANCED_BARRIERS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + false + false + + + %(AdditionalIncludeDirectories) + 4267 + + + true + d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) + d3d12.dll + + + true + + + copy %(Identity) "$(OutDir)" > NUL + $(OutDir)\%(Identity) + true + + Level3 @@ -108,6 +177,34 @@ true + + + Level3 + Use + MaxSpeed + true + true + USE_ENHANCED_BARRIERS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + 4267 + + + true + true + true + d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) + d3d12.dll + + + true + + + copy %(Identity) "$(OutDir)" > NUL + $(OutDir)\%(Identity) + true + + @@ -128,7 +225,9 @@ Create + Create Create + Create diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index 9c498aa02..683ea3338 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -13,7 +13,7 @@ #include "FrameResource.h" #include "SquidRoom.h" -FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex) : +FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex) : m_fenceValue(0), m_pipelineState(pPso), m_pipelineStateShadowMap(pShadowMapPso) @@ -49,6 +49,20 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I } // Describe and create the shadow map texture. +#if defined(USE_ENHANCED_BARRIERS) + CD3DX12_RESOURCE_DESC1 shadowTexDesc( + D3D12_RESOURCE_DIMENSION_TEXTURE2D, + 0, + static_cast(pViewport->Width), + static_cast(pViewport->Height), + 1, + 1, + DXGI_FORMAT_R32_TYPELESS, + 1, + 0, + D3D12_TEXTURE_LAYOUT_UNKNOWN, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); +#else CD3DX12_RESOURCE_DESC shadowTexDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -61,12 +75,25 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); +#endif D3D12_CLEAR_VALUE clearValue; // Performance tip: Tell the runtime at resource creation the desired clear value. clearValue.Format = DXGI_FORMAT_D32_FLOAT; clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &shadowTexDesc, + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, + &clearValue, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_shadowTexture))); +#else ThrowIfFailed(pDevice->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -74,6 +101,7 @@ FrameResource::FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, I D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(&m_shadowTexture))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_shadowTexture); @@ -254,13 +282,55 @@ void FrameResource::Init() void FrameResource::SwapBarriers() { +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_commandLists[CommandListMid]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else // Transition the shadow map from writeable to readable. m_commandLists[CommandListMid]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); +#endif // defined(USE_ENHANCED_BARRIERS) } void FrameResource::Finish() { +#if defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BufBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + + m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); +#else m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); +#endif // defined(USE_ENHANCED_BARRIERS) } // Sets up the descriptor tables for the worker command list to use diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h index 845c9cc03..517f0872a 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h @@ -25,8 +25,7 @@ class FrameResource ID3D12CommandList* m_batchSubmit[NumContexts * 2 + CommandListCount]; ComPtr m_commandAllocators[CommandListCount]; - ComPtr m_commandLists[CommandListCount]; - + ComPtr m_commandLists[CommandListCount]; ComPtr m_shadowCommandAllocators[NumContexts]; ComPtr m_shadowCommandLists[NumContexts]; @@ -50,7 +49,7 @@ class FrameResource D3D12_GPU_DESCRIPTOR_HANDLE m_sceneCbvHandle; public: - FrameResource(ID3D12Device* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex); + FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, ID3D12PipelineState* pShadowMapPso, ID3D12DescriptorHeap* pDsvHeap, ID3D12DescriptorHeap* pCbvSrvHeap, D3D12_VIEWPORT* pViewport, UINT frameResourceIndex); ~FrameResource(); void Bind(ID3D12GraphicsCommandList* pCommandList, BOOL scenePass, D3D12_CPU_DESCRIPTOR_HANDLE* pRtvHandle, D3D12_CPU_DESCRIPTOR_HANDLE* pDsvHandle); From 351464c2bc146a679fb771bcbc66a2eb36fd24ca Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Mon, 17 Nov 2025 14:44:25 -0800 Subject: [PATCH 03/11] Test syncs --- .../src/D3D12Multithreading.cpp | 117 +++++++++++++----- .../D3D12Multithreading/src/FrameResource.cpp | 51 +++++--- 2 files changed, 122 insertions(+), 46 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index 143b93291..fe8afb687 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -287,11 +287,7 @@ void D3D12Multithreading::LoadAssets() } // Create temporary command list for initial GPU setup. -#if defined(USE_ENHANCED_BARRIERS) ComPtr commandList; -#else - ComPtr commandList; -#endif // defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList))); // Create render target views (RTVs). @@ -307,7 +303,12 @@ void D3D12Multithreading::LoadAssets() // Create the depth stencil. { +#if defined(USE_ENHANCED_BARRIERS) + CD3DX12_RESOURCE_DESC1 shadowTextureDesc( +#else CD3DX12_RESOURCE_DESC shadowTextureDesc( + +#endif // defined(USE_ENHANCED_BARRIERS) D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, static_cast(m_viewport.Width), @@ -325,6 +326,18 @@ void D3D12Multithreading::LoadAssets() clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &shadowTextureDesc, + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, + &clearValue, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_depthStencil))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, @@ -332,6 +345,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(&m_depthStencil))); +#endif // defined(USE_ENHANCED_BARRIERS) NAME_D3D12_OBJECT(m_depthStencil); @@ -370,6 +384,18 @@ void D3D12Multithreading::LoadAssets() NAME_D3D12_OBJECT(m_vertexBuffer); { +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_vertexBufferUpload))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, @@ -377,6 +403,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBufferUpload))); +#endif // defined(USE_ENHANCED_BARRIERS) // Copy data to the upload heap and then schedule a copy // from the upload heap to the vertex buffer. @@ -389,18 +416,18 @@ void D3D12Multithreading::LoadAssets() UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData); #if defined(USE_ENHANCED_BARRIERS) - D3D12_BUFFER_BARRIER BufBarriers[] = + D3D12_BUFFER_BARRIER VertexBufBarriers[] = { CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter m_vertexBuffer.Get() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; + D3D12_BARRIER_GROUP VertexBufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(VertexBufBarriers), VertexBufBarriers)}; commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); #else @@ -442,6 +469,19 @@ void D3D12Multithreading::LoadAssets() NAME_D3D12_OBJECT(m_indexBuffer); { + +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_indexBufferUpload))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, @@ -449,7 +489,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_indexBufferUpload))); - +#endif // defined(USE_ENHANCED_BARRIERS) // Copy data to the upload heap and then schedule a copy // from the upload heap to the index buffer. D3D12_SUBRESOURCE_DATA indexData = {}; @@ -575,6 +615,18 @@ void D3D12Multithreading::LoadAssets() { const UINT subresourceCount = texDesc.DepthOrArraySize * texDesc.MipLevels; UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_textures[i].Get(), 0, subresourceCount); +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(uploadBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_textureUploads[i]))); +#else ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, @@ -582,6 +634,7 @@ void D3D12Multithreading::LoadAssets() D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_textureUploads[i]))); +#endif // defined(USE_ENHANCED_BARRIERS) // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. @@ -592,13 +645,13 @@ void D3D12Multithreading::LoadAssets() UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData); #if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BufBarriers[] = + D3D12_TEXTURE_BARRIER TexturesBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_textures[i].Get(), @@ -607,9 +660,9 @@ void D3D12Multithreading::LoadAssets() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + D3D12_BARRIER_GROUP TextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(TexturesBarriers), TexturesBarriers) }; - commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + commandList->Barrier(_countof(TextureBarrierGroups), TextureBarrierGroups); #else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); #endif // defined(USE_ENHANCED_BARRIERS) @@ -1045,13 +1098,13 @@ void D3D12Multithreading::BeginFrame() m_pCurrentFrameResource->Init(); #if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BufBarriers[] = + D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_NONE, // SyncBefore - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter m_renderTargets[m_frameIndex].Get(), @@ -1060,9 +1113,9 @@ void D3D12Multithreading::BeginFrame() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + D3D12_BARRIER_GROUP BeginFrameBarriersGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BeginFrameBarriers), BeginFrameBarriers) }; - m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BeginFrameBarriersGroups), BeginFrameBarriersGroups); #else // Indicate that the back buffer will be used as a render target. m_pCurrentFrameResource->m_commandLists[CommandListPre]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); @@ -1092,13 +1145,13 @@ void D3D12Multithreading::EndFrame() m_pCurrentFrameResource->Finish(); #if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BufBarriers[] = + D3D12_TEXTURE_BARRIER EndFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore - D3D12_BARRIER_SYNC_NONE, // SyncAfter - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter m_renderTargets[m_frameIndex].Get(), @@ -1107,9 +1160,9 @@ void D3D12Multithreading::EndFrame() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + D3D12_BARRIER_GROUP EndFrameBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(EndFrameBarriers), EndFrameBarriers) }; - m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(EndFrameBarrierGroups), EndFrameBarrierGroups); #else // Indicate that the back buffer will now be used to present. m_pCurrentFrameResource->m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index 683ea3338..5f063c2ff 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -149,6 +149,28 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, // Create the constant buffers. const UINT constantBufferSize = (sizeof(SceneConstantBuffer) + (D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1)) & ~(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1); // must be a multiple 256 bytes +#if defined(USE_ENHANCED_BARRIERS) + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_shadowConstantBuffer))); + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_sceneConstantBuffer))); +#else ThrowIfFailed(pDevice->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, @@ -163,6 +185,7 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_sceneConstantBuffer))); +#endif // defined(USE_ENHANCED_BARRIERS) // Map the constant buffers and cache their heap pointers. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. @@ -283,13 +306,13 @@ void FrameResource::Init() void FrameResource::SwapBarriers() { #if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BufBarriers[] = + D3D12_TEXTURE_BARRIER ShadowTextureBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_shadowTexture.Get(), @@ -298,9 +321,9 @@ void FrameResource::SwapBarriers() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + D3D12_BARRIER_GROUP ShadowTextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(ShadowTextureBarriers), ShadowTextureBarriers) }; - m_commandLists[CommandListMid]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + m_commandLists[CommandListMid]->Barrier(_countof(ShadowTextureBarrierGroups), ShadowTextureBarrierGroups); #else // Transition the shadow map from writeable to readable. m_commandLists[CommandListMid]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); @@ -310,13 +333,13 @@ void FrameResource::SwapBarriers() void FrameResource::Finish() { #if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BufBarriers[] = + D3D12_TEXTURE_BARRIER FinishTexBarrier[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter + D3D12_BARRIER_SYNC_ALL, // SyncBefore + D3D12_BARRIER_SYNC_ALL, // SyncAfter + D3D12_BARRIER_ACCESS_COMMON, // AccessBefore + D3D12_BARRIER_ACCESS_COMMON, // AccessAfter D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter m_shadowTexture.Get(), @@ -325,9 +348,9 @@ void FrameResource::Finish() ) }; - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + D3D12_BARRIER_GROUP FinishTexBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(FinishTexBarrier), FinishTexBarrier) }; - m_commandLists[CommandListPost]->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + m_commandLists[CommandListPost]->Barrier(_countof(FinishTexBarrierGroups), FinishTexBarrierGroups); #else m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); #endif // defined(USE_ENHANCED_BARRIERS) From 03ccdb98bc04d2c615692b124bb63e1c2fb85716 Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Mon, 17 Nov 2025 14:45:08 -0800 Subject: [PATCH 04/11] Nit --- Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index fe8afb687..f6313378e 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -429,7 +429,7 @@ void D3D12Multithreading::LoadAssets() D3D12_BARRIER_GROUP VertexBufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(VertexBufBarriers), VertexBufBarriers)}; - commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + commandList->Barrier(_countof(VertexBufBarrierGroups), VertexBufBarrierGroups); #else commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); #endif // defined(USE_ENHANCED_BARRIERS) From 885346e56f50c096c9c3091d663ce88b3eb8f659 Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Tue, 18 Nov 2025 15:05:31 -0800 Subject: [PATCH 05/11] Establish syncs --- .../src/D3D12Multithreading.cpp | 32 +++++++++---------- .../D3D12Multithreading/src/FrameResource.cpp | 18 +++++------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index f6313378e..a43224852 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -419,10 +419,10 @@ void D3D12Multithreading::LoadAssets() D3D12_BUFFER_BARRIER VertexBufBarriers[] = { CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter m_vertexBuffer.Get() ) }; @@ -648,10 +648,10 @@ void D3D12Multithreading::LoadAssets() D3D12_TEXTURE_BARRIER TexturesBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_textures[i].Get(), @@ -1101,10 +1101,10 @@ void D3D12Multithreading::BeginFrame() D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_NONE, // SyncBefore + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter m_renderTargets[m_frameIndex].Get(), @@ -1148,10 +1148,10 @@ void D3D12Multithreading::EndFrame() D3D12_TEXTURE_BARRIER EndFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore + D3D12_BARRIER_SYNC_NONE, // SyncAfter + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter m_renderTargets[m_frameIndex].Get(), diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index 5f063c2ff..b8a3f57e0 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -75,7 +75,7 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); -#endif +#endif // defined(USE_ENHANCED_BARRIERS) D3D12_CLEAR_VALUE clearValue; // Performance tip: Tell the runtime at resource creation the desired clear value. clearValue.Format = DXGI_FORMAT_D32_FLOAT; @@ -309,10 +309,10 @@ void FrameResource::SwapBarriers() D3D12_TEXTURE_BARRIER ShadowTextureBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_shadowTexture.Get(), @@ -336,10 +336,10 @@ void FrameResource::Finish() D3D12_TEXTURE_BARRIER FinishTexBarrier[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_ALL, // SyncBefore - D3D12_BARRIER_SYNC_ALL, // SyncAfter - D3D12_BARRIER_ACCESS_COMMON, // AccessBefore - D3D12_BARRIER_ACCESS_COMMON, // AccessAfter + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter m_shadowTexture.Get(), From be3ac942cdefd959704c7faf8da8cfcbedcf443c Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Wed, 19 Nov 2025 16:10:34 -0800 Subject: [PATCH 06/11] Nits and readme updates --- Samples/Desktop/D3D12Multithreading/readme.md | 4 +- .../src/D3D12Multithreading.cpp | 61 ++++++++----------- .../src/D3D12Multithreading.sln | 4 +- .../D3D12Multithreading/src/FrameResource.cpp | 16 ++--- .../D3D12Multithreading/src/FrameResource.h | 1 + 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/readme.md b/Samples/Desktop/D3D12Multithreading/readme.md index c74a861c1..cd0944ff5 100644 --- a/Samples/Desktop/D3D12Multithreading/readme.md +++ b/Samples/Desktop/D3D12Multithreading/readme.md @@ -18,4 +18,6 @@ extendedZipContent: This sample demonstrates the use of multiple threads with Direct3D 12. An app can use multithreading to improve efficiency by building command lists on multiple threads asynchronously. The majority of the CPU cost is associated with command list building, not command list execution. Apps must ensure they never concurrently call methods on the same command list or command allocator. ### Optional features -This sample has been updated to build against the Windows 10 Anniversary Update SDK. In this SDK a new revision of Root Signatures is available for Direct3D 12 apps to use. Root Signature 1.1 allows for apps to declare when descriptors in a descriptor heap won't change or the data descriptors point to won't change. This allows the option for drivers to make optimizations that might be possible knowing that something (like a descriptor or the memory it points to) is static for some period of time. \ No newline at end of file +This sample has been updated to build against the Windows 10 Anniversary Update SDK. In this SDK a new revision of Root Signatures is available for Direct3D 12 apps to use. Root Signature 1.1 allows for apps to declare when descriptors in a descriptor heap won't change or the data descriptors point to won't change. This allows the option for drivers to make optimizations that might be possible knowing that something (like a descriptor or the memory it points to) is static for some period of time. + +This sample can be built with with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index a43224852..48f2a8d59 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -56,14 +56,6 @@ void D3D12Multithreading::LoadPipeline() UINT dxgiFactoryFlags = 0; #if defined(_DEBUG) - - // Check to see if a copy of WinPixGpuCapturer.dll has already been injected into the application. - // This may happen if the application is launched through the PIX UI. - if (GetModuleHandle(L"WinPixGpuCapturer.dll") == 0) - { - LoadLibrary(L"C:\\Program Files\\Microsoft PIX\\2505.30\\WinPixGpuCapturer.dll"); - } - // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. { @@ -307,7 +299,6 @@ void D3D12Multithreading::LoadAssets() CD3DX12_RESOURCE_DESC1 shadowTextureDesc( #else CD3DX12_RESOURCE_DESC shadowTextureDesc( - #endif // defined(USE_ENHANCED_BARRIERS) D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -419,10 +410,10 @@ void D3D12Multithreading::LoadAssets() D3D12_BUFFER_BARRIER VertexBufBarriers[] = { CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter m_vertexBuffer.Get() ) }; @@ -507,7 +498,7 @@ void D3D12Multithreading::LoadAssets() CD3DX12_BUFFER_BARRIER( D3D12_BARRIER_SYNC_COPY, // SyncBefore D3D12_BARRIER_SYNC_INDEX_INPUT, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore D3D12_BARRIER_ACCESS_INDEX_BUFFER, // AccessAfter m_indexBuffer.Get() ) @@ -648,14 +639,14 @@ void D3D12Multithreading::LoadAssets() D3D12_TEXTURE_BARRIER TexturesBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter - D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore - D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_textures[i].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources D3D12_TEXTURE_BARRIER_FLAG_NONE ) }; @@ -1101,14 +1092,14 @@ void D3D12Multithreading::BeginFrame() D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_NONE, // SyncBefore - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter - D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore - D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter + D3D12_BARRIER_SYNC_NONE, // SyncBefore + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter m_renderTargets[m_frameIndex].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources D3D12_TEXTURE_BARRIER_FLAG_NONE ) }; @@ -1148,14 +1139,14 @@ void D3D12Multithreading::EndFrame() D3D12_TEXTURE_BARRIER EndFrameBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore - D3D12_BARRIER_SYNC_NONE, // SyncAfter - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter - D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore - D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore + D3D12_BARRIER_SYNC_NONE, // SyncAfter + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter m_renderTargets[m_frameIndex].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources D3D12_TEXTURE_BARRIER_FLAG_NONE ) }; diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln index 47ed51675..b5cfd1131 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.14.36623.8 d17.14 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30621.155.26403.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12Multithreading", "D3D12Multithreading.vcxproj", "{3FC193D0-7E4E-4918-8431-D67391EE4145}" EndProject diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index b8a3f57e0..e2cd38a1e 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -309,10 +309,10 @@ void FrameResource::SwapBarriers() D3D12_TEXTURE_BARRIER ShadowTextureBarriers[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter m_shadowTexture.Get(), @@ -336,10 +336,10 @@ void FrameResource::Finish() D3D12_TEXTURE_BARRIER FinishTexBarrier[] = { CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter m_shadowTexture.Get(), diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h index 517f0872a..37dd09fb4 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.h +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.h @@ -26,6 +26,7 @@ class FrameResource ComPtr m_commandAllocators[CommandListCount]; ComPtr m_commandLists[CommandListCount]; + ComPtr m_shadowCommandAllocators[NumContexts]; ComPtr m_shadowCommandLists[NumContexts]; From d4e00bc8c5779ed1dd1974ba8ec5fee08cbfe0cd Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Wed, 19 Nov 2025 16:14:55 -0800 Subject: [PATCH 07/11] Nit --- Samples/Desktop/D3D12Multithreading/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/Desktop/D3D12Multithreading/readme.md b/Samples/Desktop/D3D12Multithreading/readme.md index cd0944ff5..a32a03bdc 100644 --- a/Samples/Desktop/D3D12Multithreading/readme.md +++ b/Samples/Desktop/D3D12Multithreading/readme.md @@ -20,4 +20,4 @@ This sample demonstrates the use of multiple threads with Direct3D 12. An app ca ### Optional features This sample has been updated to build against the Windows 10 Anniversary Update SDK. In this SDK a new revision of Root Signatures is available for Direct3D 12 apps to use. Root Signature 1.1 allows for apps to declare when descriptors in a descriptor heap won't change or the data descriptors point to won't change. This allows the option for drivers to make optimizations that might be possible knowing that something (like a descriptor or the memory it points to) is static for some period of time. -This sample can be built with with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file +This sample can be built with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it, choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file From b249ae3996d1ca2c7ed7c68ec42c48c248d7141f Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Wed, 19 Nov 2025 16:19:08 -0800 Subject: [PATCH 08/11] Nit --- Samples/Desktop/D3D12Multithreading/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/Desktop/D3D12Multithreading/readme.md b/Samples/Desktop/D3D12Multithreading/readme.md index a32a03bdc..5beac83b4 100644 --- a/Samples/Desktop/D3D12Multithreading/readme.md +++ b/Samples/Desktop/D3D12Multithreading/readme.md @@ -20,4 +20,4 @@ This sample demonstrates the use of multiple threads with Direct3D 12. An app ca ### Optional features This sample has been updated to build against the Windows 10 Anniversary Update SDK. In this SDK a new revision of Root Signatures is available for Direct3D 12 apps to use. Root Signature 1.1 allows for apps to declare when descriptors in a descriptor heap won't change or the data descriptors point to won't change. This allows the option for drivers to make optimizations that might be possible knowing that something (like a descriptor or the memory it points to) is static for some period of time. -This sample can be built with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it, choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file +This sample can be built with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it, choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file From 0377599b7c707e197cda8bba184544541c66cbbc Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Thu, 20 Nov 2025 13:11:32 -0800 Subject: [PATCH 09/11] Using runtime branching instead of precompiled --- .../src/D3D12Multithreading.cpp | 495 +++++++++--------- .../src/D3D12Multithreading.h | 4 + .../src/D3D12Multithreading.sln | 18 +- .../src/D3D12Multithreading.vcxproj | 99 ---- .../D3D12Multithreading/src/FrameResource.cpp | 224 ++++---- 5 files changed, 370 insertions(+), 470 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index 48f2a8d59..c924d25f1 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -14,6 +14,7 @@ #include "FrameResource.h" D3D12Multithreading* D3D12Multithreading::s_app = nullptr; +bool D3D12Multithreading::s_bIsEnhancedBarriersEnabled = false; extern "C" { __declspec(dllexport) extern const UINT D3D12SDKVersion = 618; } extern "C" { __declspec(dllexport) extern const char* D3D12SDKPath = u8".\\D3D12\\"; } @@ -96,14 +97,9 @@ void D3D12Multithreading::LoadPipeline() )); } -#if defined(USE_ENHANCED_BARRIERS) D3D12_FEATURE_DATA_D3D12_OPTIONS12 options12 = {}; ThrowIfFailed(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options12, sizeof(options12))); - if (options12.EnhancedBarriersSupported != TRUE) - { - ThrowIfFailed(E_FAIL); - } -#endif // defined(USE_ENHANCED_BARRIERS) + s_bIsEnhancedBarriersEnabled = static_cast(options12.EnhancedBarriersSupported); // Describe and create the command queue. D3D12_COMMAND_QUEUE_DESC queueDesc = {}; @@ -295,11 +291,7 @@ void D3D12Multithreading::LoadAssets() // Create the depth stencil. { -#if defined(USE_ENHANCED_BARRIERS) - CD3DX12_RESOURCE_DESC1 shadowTextureDesc( -#else CD3DX12_RESOURCE_DESC shadowTextureDesc( -#endif // defined(USE_ENHANCED_BARRIERS) D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, static_cast(m_viewport.Width), @@ -317,26 +309,29 @@ void D3D12Multithreading::LoadAssets() clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; -#if defined(USE_ENHANCED_BARRIERS) - ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &shadowTextureDesc, - D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, - &clearValue, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_depthStencil))); -#else - ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &shadowTextureDesc, - D3D12_RESOURCE_STATE_DEPTH_WRITE, - &clearValue, - IID_PPV_ARGS(&m_depthStencil))); -#endif // defined(USE_ENHANCED_BARRIERS) + if (s_bIsEnhancedBarriersEnabled) + { + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1(shadowTextureDesc), + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, + &clearValue, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_depthStencil))); + } + else + { + ThrowIfFailed(m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &shadowTextureDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &clearValue, + IID_PPV_ARGS(&m_depthStencil))); + } NAME_D3D12_OBJECT(m_depthStencil); @@ -351,33 +346,10 @@ void D3D12Multithreading::LoadAssets() // Create the vertex buffer. { -#if defined(USE_ENHANCED_BARRIERS) - ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), - D3D12_BARRIER_LAYOUT_UNDEFINED, - nullptr, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_vertexBuffer))); -#else - ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize), - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&m_vertexBuffer))); -#endif // defined(USE_ENHANCED_BARRIERS) - - NAME_D3D12_OBJECT(m_vertexBuffer); - + if (s_bIsEnhancedBarriersEnabled) { -#if defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), D3D12_BARRIER_LAYOUT_UNDEFINED, @@ -385,16 +357,45 @@ void D3D12Multithreading::LoadAssets() nullptr, 0, nullptr, - IID_PPV_ARGS(&m_vertexBufferUpload))); -#else + IID_PPV_ARGS(&m_vertexBuffer))); + } + else + { ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize), - D3D12_RESOURCE_STATE_GENERIC_READ, + D3D12_RESOURCE_STATE_COPY_DEST, nullptr, - IID_PPV_ARGS(&m_vertexBufferUpload))); -#endif // defined(USE_ENHANCED_BARRIERS) + IID_PPV_ARGS(&m_vertexBuffer))); + } + + NAME_D3D12_OBJECT(m_vertexBuffer); + + { + if (s_bIsEnhancedBarriersEnabled) + { + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::VertexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_vertexBufferUpload))); + } + else + { + ThrowIfFailed(m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_vertexBufferUpload))); + } // Copy data to the upload heap and then schedule a copy // from the upload heap to the vertex buffer. @@ -406,25 +407,26 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy vertex buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData); -#if defined(USE_ENHANCED_BARRIERS) - D3D12_BUFFER_BARRIER VertexBufBarriers[] = - { - CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter - m_vertexBuffer.Get() - ) - }; - - D3D12_BARRIER_GROUP VertexBufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(VertexBufBarriers), VertexBufBarriers)}; - - commandList->Barrier(_countof(VertexBufBarrierGroups), VertexBufBarrierGroups); -#else - commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); -#endif // defined(USE_ENHANCED_BARRIERS) + if (s_bIsEnhancedBarriersEnabled) + { + D3D12_BUFFER_BARRIER VertexBufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_VERTEX_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_VERTEX_BUFFER, // AccessAfter + m_vertexBuffer.Get() + ) + }; + D3D12_BARRIER_GROUP VertexBufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(VertexBufBarriers), VertexBufBarriers) }; + commandList->Barrier(_countof(VertexBufBarrierGroups), VertexBufBarrierGroups); + } + else + { + commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); + } PIXEndEvent(commandList.Get()); } @@ -436,34 +438,10 @@ void D3D12Multithreading::LoadAssets() // Create the index buffer. { -#if defined(USE_ENHANCED_BARRIERS) - ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), - D3D12_BARRIER_LAYOUT_UNDEFINED, - nullptr, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_indexBuffer))); -#else - ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize), - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&m_indexBuffer))); -#endif // defined(USE_ENHANCED_BARRIERS) - - NAME_D3D12_OBJECT(m_indexBuffer); - + if (s_bIsEnhancedBarriersEnabled) { - -#if defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), D3D12_BARRIER_LAYOUT_UNDEFINED, @@ -471,16 +449,46 @@ void D3D12Multithreading::LoadAssets() nullptr, 0, nullptr, - IID_PPV_ARGS(&m_indexBufferUpload))); -#else + IID_PPV_ARGS(&m_indexBuffer))); + } + else + { ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize), - D3D12_RESOURCE_STATE_GENERIC_READ, + D3D12_RESOURCE_STATE_COPY_DEST, nullptr, - IID_PPV_ARGS(&m_indexBufferUpload))); -#endif // defined(USE_ENHANCED_BARRIERS) + IID_PPV_ARGS(&m_indexBuffer))); + } + + NAME_D3D12_OBJECT(m_indexBuffer); + + { + if (s_bIsEnhancedBarriersEnabled) + { + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(SampleAssets::IndexDataSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_indexBufferUpload))); + } + else + { + ThrowIfFailed(m_device->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_indexBufferUpload))); + } + // Copy data to the upload heap and then schedule a copy // from the upload heap to the index buffer. D3D12_SUBRESOURCE_DATA indexData = {}; @@ -491,25 +499,25 @@ void D3D12Multithreading::LoadAssets() PIXBeginEvent(commandList.Get(), 0, L"Copy index buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_indexBuffer.Get(), m_indexBufferUpload.Get(), 0, 0, 1, &indexData); - -#if defined(USE_ENHANCED_BARRIERS) - D3D12_BUFFER_BARRIER BufBarriers[] = + if (s_bIsEnhancedBarriersEnabled) { - CD3DX12_BUFFER_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_INDEX_INPUT, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_INDEX_BUFFER, // AccessAfter - m_indexBuffer.Get() - ) - }; - - D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers)}; - - commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); -#else - commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)); -#endif // defined(USE_ENHANCED_BARRIERS) + D3D12_BUFFER_BARRIER BufBarriers[] = + { + CD3DX12_BUFFER_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_INDEX_INPUT, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_INDEX_BUFFER, // AccessAfter + m_indexBuffer.Get() + ) + }; + D3D12_BARRIER_GROUP BufBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BufBarriers), BufBarriers) }; + commandList->Barrier(_countof(BufBarrierGroups), BufBarrierGroups); + } + else + { + commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)); + } PIXEndEvent(commandList.Get()); } @@ -553,32 +561,6 @@ void D3D12Multithreading::LoadAssets() { // Describe and create a Texture2D. const SampleAssets::TextureResource &tex = SampleAssets::Textures[i]; - -#if defined(USE_ENHANCED_BARRIERS) - CD3DX12_RESOURCE_DESC1 texDesc( - D3D12_RESOURCE_DIMENSION_TEXTURE2D, - 0, - tex.Width, - tex.Height, - 1, - static_cast(tex.MipLevels), - tex.Format, - 1, - 0, - D3D12_TEXTURE_LAYOUT_UNKNOWN, - D3D12_RESOURCE_FLAG_NONE); - - ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &texDesc, - D3D12_BARRIER_LAYOUT_COPY_DEST, - nullptr, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_textures[i]))); -#else CD3DX12_RESOURCE_DESC texDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -592,40 +574,59 @@ void D3D12Multithreading::LoadAssets() D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE); - ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &texDesc, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&m_textures[i]))); -#endif // defined(USE_ENHANCED_BARRIERS) - - NAME_D3D12_OBJECT_INDEXED(m_textures, i); - + if (s_bIsEnhancedBarriersEnabled) { - const UINT subresourceCount = texDesc.DepthOrArraySize * texDesc.MipLevels; - UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_textures[i].Get(), 0, subresourceCount); -#if defined(USE_ENHANCED_BARRIERS) ThrowIfFailed(m_device->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC1::Buffer(uploadBufferSize), - D3D12_BARRIER_LAYOUT_UNDEFINED, + &CD3DX12_RESOURCE_DESC1(texDesc), + D3D12_BARRIER_LAYOUT_COPY_DEST, nullptr, nullptr, 0, nullptr, - IID_PPV_ARGS(&m_textureUploads[i]))); -#else + IID_PPV_ARGS(&m_textures[i]))); + } + else + { ThrowIfFailed(m_device->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize), - D3D12_RESOURCE_STATE_GENERIC_READ, + &texDesc, + D3D12_RESOURCE_STATE_COPY_DEST, nullptr, - IID_PPV_ARGS(&m_textureUploads[i]))); -#endif // defined(USE_ENHANCED_BARRIERS) + IID_PPV_ARGS(&m_textures[i]))); + } + + NAME_D3D12_OBJECT_INDEXED(m_textures, i); + + { + const UINT subresourceCount = texDesc.DepthOrArraySize * texDesc.MipLevels; + UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_textures[i].Get(), 0, subresourceCount); + + if (s_bIsEnhancedBarriersEnabled) + { + ThrowIfFailed(m_device->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(uploadBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_textureUploads[i]))); + } + else + { + 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(&m_textureUploads[i]))); + } // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. @@ -635,28 +636,30 @@ void D3D12Multithreading::LoadAssets() textureData.SlicePitch = tex.Data->Size; UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData); -#if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER TexturesBarriers[] = - { - CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_COPY, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter - D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore - D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter - m_textures[i].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources - D3D12_TEXTURE_BARRIER_FLAG_NONE - ) - }; - - D3D12_BARRIER_GROUP TextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(TexturesBarriers), TexturesBarriers) }; - commandList->Barrier(_countof(TextureBarrierGroups), TextureBarrierGroups); -#else - commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); -#endif // defined(USE_ENHANCED_BARRIERS) + if (s_bIsEnhancedBarriersEnabled) + { + D3D12_TEXTURE_BARRIER TexturesBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_COPY, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_COPY_DEST, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_COPY_DEST, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_textures[i].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + D3D12_BARRIER_GROUP TextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(TexturesBarriers), TexturesBarriers) }; + commandList->Barrier(_countof(TextureBarrierGroups), TextureBarrierGroups); + } + else + { + commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + } } // Describe and create an SRV. @@ -1088,29 +1091,32 @@ void D3D12Multithreading::BeginFrame() { m_pCurrentFrameResource->Init(); -#if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = + if (s_bIsEnhancedBarriersEnabled) { - CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_NONE, // SyncBefore - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter - D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore - D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter - m_renderTargets[m_frameIndex].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources - D3D12_TEXTURE_BARRIER_FLAG_NONE - ) - }; - - D3D12_BARRIER_GROUP BeginFrameBarriersGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BeginFrameBarriers), BeginFrameBarriers) }; - - m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BeginFrameBarriersGroups), BeginFrameBarriersGroups); -#else - // Indicate that the back buffer will be used as a render target. - m_pCurrentFrameResource->m_commandLists[CommandListPre]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); -#endif // defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_NONE, // SyncBefore + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessBefore + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessAfter + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutBefore + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + + D3D12_BARRIER_GROUP BeginFrameBarriersGroups[] = { CD3DX12_BARRIER_GROUP(_countof(BeginFrameBarriers), BeginFrameBarriers) }; + + m_pCurrentFrameResource->m_commandLists[CommandListPre]->Barrier(_countof(BeginFrameBarriersGroups), BeginFrameBarriersGroups); + } + else + { + // Indicate that the back buffer will be used as a render target. + m_pCurrentFrameResource->m_commandLists[CommandListPre]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); + } // Clear the render target and depth stencil. const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1135,29 +1141,30 @@ void D3D12Multithreading::EndFrame() { m_pCurrentFrameResource->Finish(); -#if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER EndFrameBarriers[] = + if (s_bIsEnhancedBarriersEnabled) { - CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore - D3D12_BARRIER_SYNC_NONE, // SyncAfter - D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore - D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter - D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore - D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter - m_renderTargets[m_frameIndex].Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources - D3D12_TEXTURE_BARRIER_FLAG_NONE - ) - }; - - D3D12_BARRIER_GROUP EndFrameBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(EndFrameBarriers), EndFrameBarriers) }; - - m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(EndFrameBarrierGroups), EndFrameBarrierGroups); -#else - // Indicate that the back buffer will now be used to present. - m_pCurrentFrameResource->m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); -#endif // defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER EndFrameBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore + D3D12_BARRIER_SYNC_NONE, // SyncAfter + D3D12_BARRIER_ACCESS_RENDER_TARGET, // AccessBefore + D3D12_BARRIER_ACCESS_NO_ACCESS, // AccessAfter + D3D12_BARRIER_LAYOUT_RENDER_TARGET, // LayoutBefore + D3D12_BARRIER_LAYOUT_PRESENT, // LayoutAfter + m_renderTargets[m_frameIndex].Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + D3D12_BARRIER_GROUP EndFrameBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(EndFrameBarriers), EndFrameBarriers) }; + m_pCurrentFrameResource->m_commandLists[CommandListPost]->Barrier(_countof(EndFrameBarrierGroups), EndFrameBarrierGroups); + } + else + { + // Indicate that the back buffer will now be used to present. + m_pCurrentFrameResource->m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); + } ThrowIfFailed(m_pCurrentFrameResource->m_commandLists[CommandListPost]->Close()); } diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h index 5caec2668..929fd501e 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.h @@ -57,6 +57,8 @@ class D3D12Multithreading : public DXSample static D3D12Multithreading* Get() { return s_app; } + static bool IsEnhancedBarriersEnabled() { return s_bIsEnhancedBarriersEnabled; } + virtual void OnInit(); virtual void OnUpdate(); virtual void OnRender(); @@ -128,6 +130,8 @@ class D3D12Multithreading : public DXSample FrameResource* m_pCurrentFrameResource; int m_currentFrameResourceIndex; + static bool s_bIsEnhancedBarriersEnabled; + struct ThreadParameter { int threadIndex; diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln index b5cfd1131..2e3ab4995 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln @@ -7,20 +7,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12Multithreading", "D3D1 EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug (Enhanced Barriers)|x64 = Debug (Enhanced Barriers)|x64 - Debug (Legacy Barriers)|x64 = Debug (Legacy Barriers)|x64 - Release (Enhanced Barriers)|x64 = Release (Enhanced Barriers)|x64 - Release (Legacy Barriers)|x64 = Release (Legacy Barriers)|x64 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.ActiveCfg = Debug (Enhanced Barriers)|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Enhanced Barriers)|x64.Build.0 = Debug (Enhanced Barriers)|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.ActiveCfg = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug (Legacy Barriers)|x64.Build.0 = Debug|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.ActiveCfg = Release (Enhanced Barriers)|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Enhanced Barriers)|x64.Build.0 = Release (Enhanced Barriers)|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.ActiveCfg = Release|x64 - {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release (Legacy Barriers)|x64.Build.0 = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.ActiveCfg = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Debug|x64.Build.0 = Debug|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.ActiveCfg = Release|x64 + {3FC193D0-7E4E-4918-8431-D67391EE4145}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj index eabd6f346..3a802ce89 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.vcxproj @@ -2,18 +2,10 @@ - - Debug (Enhanced Barriers) - x64 - Debug x64 - - Release (Enhanced Barriers) - x64 - Release x64 @@ -33,12 +25,6 @@ v142 Unicode - - Application - true - v142 - Unicode - Application false @@ -46,52 +32,25 @@ true Unicode - - Application - false - v142 - true - Unicode - - - - - - - true bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ - $(ProjectName)_Legacy_Barriers - - - true - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - $(ProjectName)_Enhanced_Barriers false bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ - $(ProjectName)_Legacy_Barriers - - - false - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - $(ProjectName)_Enhanced_Barriers @@ -121,34 +80,6 @@ true - - - Use - Level3 - Disabled - USE_ENHANCED_BARRIERS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - false - false - - - %(AdditionalIncludeDirectories) - 4267 - - - true - d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) - d3d12.dll - - - true - - - copy %(Identity) "$(OutDir)" > NUL - $(OutDir)\%(Identity) - true - - Level3 @@ -177,34 +108,6 @@ true - - - Level3 - Use - MaxSpeed - true - true - USE_ENHANCED_BARRIERS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - %(AdditionalIncludeDirectories) - 4267 - - - true - true - true - d3d12.lib;dxgi.lib;d3dcompiler.lib;dxguid.lib;%(AdditionalDependencies) - d3d12.dll - - - true - - - copy %(Identity) "$(OutDir)" > NUL - $(OutDir)\%(Identity) - true - - @@ -225,9 +128,7 @@ Create - Create Create - Create diff --git a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp index e2cd38a1e..8d2c3faf0 100644 --- a/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/FrameResource.cpp @@ -49,20 +49,6 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, } // Describe and create the shadow map texture. -#if defined(USE_ENHANCED_BARRIERS) - CD3DX12_RESOURCE_DESC1 shadowTexDesc( - D3D12_RESOURCE_DIMENSION_TEXTURE2D, - 0, - static_cast(pViewport->Width), - static_cast(pViewport->Height), - 1, - 1, - DXGI_FORMAT_R32_TYPELESS, - 1, - 0, - D3D12_TEXTURE_LAYOUT_UNKNOWN, - D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); -#else CD3DX12_RESOURCE_DESC shadowTexDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, @@ -75,33 +61,35 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); -#endif // defined(USE_ENHANCED_BARRIERS) D3D12_CLEAR_VALUE clearValue; // Performance tip: Tell the runtime at resource creation the desired clear value. clearValue.Format = DXGI_FORMAT_D32_FLOAT; clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; -#if defined(USE_ENHANCED_BARRIERS) - ThrowIfFailed(pDevice->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &shadowTexDesc, - D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, - &clearValue, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_shadowTexture))); -#else - ThrowIfFailed(pDevice->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &shadowTexDesc, - D3D12_RESOURCE_STATE_DEPTH_WRITE, - &clearValue, - IID_PPV_ARGS(&m_shadowTexture))); -#endif // defined(USE_ENHANCED_BARRIERS) + if (D3D12Multithreading::IsEnhancedBarriersEnabled()) + { + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1(shadowTexDesc), + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, + &clearValue, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_shadowTexture))); + } + else + { + ThrowIfFailed(pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), + D3D12_HEAP_FLAG_NONE, + &shadowTexDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &clearValue, + IID_PPV_ARGS(&m_shadowTexture))); + } NAME_D3D12_OBJECT(m_shadowTexture); @@ -149,43 +137,47 @@ FrameResource::FrameResource(ID3D12Device10* pDevice, ID3D12PipelineState* pPso, // Create the constant buffers. const UINT constantBufferSize = (sizeof(SceneConstantBuffer) + (D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1)) & ~(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1); // must be a multiple 256 bytes -#if defined(USE_ENHANCED_BARRIERS) - ThrowIfFailed(pDevice->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), - D3D12_BARRIER_LAYOUT_UNDEFINED, - nullptr, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_shadowConstantBuffer))); - ThrowIfFailed(pDevice->CreateCommittedResource3( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), - D3D12_BARRIER_LAYOUT_UNDEFINED, - nullptr, - nullptr, - 0, - nullptr, - IID_PPV_ARGS(&m_sceneConstantBuffer))); -#else - ThrowIfFailed(pDevice->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(constantBufferSize), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&m_shadowConstantBuffer))); - ThrowIfFailed(pDevice->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(constantBufferSize), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&m_sceneConstantBuffer))); -#endif // defined(USE_ENHANCED_BARRIERS) + + if (D3D12Multithreading::IsEnhancedBarriersEnabled()) + { + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_shadowConstantBuffer))); + ThrowIfFailed(pDevice->CreateCommittedResource3( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC1::Buffer(constantBufferSize), + D3D12_BARRIER_LAYOUT_UNDEFINED, + nullptr, + nullptr, + 0, + nullptr, + IID_PPV_ARGS(&m_sceneConstantBuffer))); + } + else + { + ThrowIfFailed(pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(constantBufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_shadowConstantBuffer))); + ThrowIfFailed(pDevice->CreateCommittedResource( + &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), + D3D12_HEAP_FLAG_NONE, + &CD3DX12_RESOURCE_DESC::Buffer(constantBufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&m_sceneConstantBuffer))); + } // Map the constant buffers and cache their heap pointers. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. @@ -305,55 +297,57 @@ void FrameResource::Init() void FrameResource::SwapBarriers() { -#if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER ShadowTextureBarriers[] = + if (D3D12Multithreading::IsEnhancedBarriersEnabled()) { - CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter - D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore - D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter - m_shadowTexture.Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources - D3D12_TEXTURE_BARRIER_FLAG_NONE - ) - }; - - D3D12_BARRIER_GROUP ShadowTextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(ShadowTextureBarriers), ShadowTextureBarriers) }; - - m_commandLists[CommandListMid]->Barrier(_countof(ShadowTextureBarrierGroups), ShadowTextureBarrierGroups); -#else - // Transition the shadow map from writeable to readable. - m_commandLists[CommandListMid]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); -#endif // defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER ShadowTextureBarriers[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncBefore + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncAfter + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessBefore + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessAfter + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutBefore + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + D3D12_BARRIER_GROUP ShadowTextureBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(ShadowTextureBarriers), ShadowTextureBarriers) }; + m_commandLists[CommandListMid]->Barrier(_countof(ShadowTextureBarrierGroups), ShadowTextureBarrierGroups); + } + else + { + // Transition the shadow map from writeable to readable. + m_commandLists[CommandListMid]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + } } void FrameResource::Finish() { -#if defined(USE_ENHANCED_BARRIERS) - D3D12_TEXTURE_BARRIER FinishTexBarrier[] = + if (D3D12Multithreading::IsEnhancedBarriersEnabled()) { - CD3DX12_TEXTURE_BARRIER( - D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore - D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter - D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore - D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter - D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore - D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter - m_shadowTexture.Get(), - CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources - D3D12_TEXTURE_BARRIER_FLAG_NONE - ) - }; - - D3D12_BARRIER_GROUP FinishTexBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(FinishTexBarrier), FinishTexBarrier) }; - - m_commandLists[CommandListPost]->Barrier(_countof(FinishTexBarrierGroups), FinishTexBarrierGroups); -#else - m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); -#endif // defined(USE_ENHANCED_BARRIERS) + D3D12_TEXTURE_BARRIER FinishTexBarrier[] = + { + CD3DX12_TEXTURE_BARRIER( + D3D12_BARRIER_SYNC_PIXEL_SHADING, // SyncBefore + D3D12_BARRIER_SYNC_DEPTH_STENCIL, // SyncAfter + D3D12_BARRIER_ACCESS_SHADER_RESOURCE, // AccessBefore + D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE, // AccessAfter + D3D12_BARRIER_LAYOUT_SHADER_RESOURCE, // LayoutBefore + D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE, // LayoutAfter + m_shadowTexture.Get(), + CD3DX12_BARRIER_SUBRESOURCE_RANGE(0xffffffff), // All subresources + D3D12_TEXTURE_BARRIER_FLAG_NONE + ) + }; + D3D12_BARRIER_GROUP FinishTexBarrierGroups[] = { CD3DX12_BARRIER_GROUP(_countof(FinishTexBarrier), FinishTexBarrier) }; + m_commandLists[CommandListPost]->Barrier(_countof(FinishTexBarrierGroups), FinishTexBarrierGroups); + } + else + { + m_commandLists[CommandListPost]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_shadowTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE)); + } } // Sets up the descriptor tables for the worker command list to use From 837ee5520b9f2f83d67790037ec8507c074f6d1a Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Thu, 20 Nov 2025 13:17:29 -0800 Subject: [PATCH 10/11] Nit --- Samples/Desktop/D3D12Multithreading/readme.md | 2 +- .../Desktop/D3D12Multithreading/src/D3D12Multithreading.sln | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Samples/Desktop/D3D12Multithreading/readme.md b/Samples/Desktop/D3D12Multithreading/readme.md index 5beac83b4..1447e4bf9 100644 --- a/Samples/Desktop/D3D12Multithreading/readme.md +++ b/Samples/Desktop/D3D12Multithreading/readme.md @@ -20,4 +20,4 @@ This sample demonstrates the use of multiple threads with Direct3D 12. An app ca ### Optional features This sample has been updated to build against the Windows 10 Anniversary Update SDK. In this SDK a new revision of Root Signatures is available for Direct3D 12 apps to use. Root Signature 1.1 allows for apps to declare when descriptors in a descriptor heap won't change or the data descriptors point to won't change. This allows the option for drivers to make optimizations that might be possible knowing that something (like a descriptor or the memory it points to) is static for some period of time. -This sample can be built with Enhanced Barriers. Make sure to have the latest driver installed and that your GPU supports this feature. To enable it, choose ` (Enhanced Barriers)` option under the configuration dropdown. ` (Legacy Barriers)` are also available if running on older hardware. \ No newline at end of file +This sample is built with Enhanced Barriers. The sample will use Enhanced Barriers if the hardware supports it. If not, Legacy Barriers will be used instead. \ No newline at end of file diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln index 2e3ab4995..463a097ec 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.sln @@ -19,7 +19,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A6E9CE1E-E505-4D05-A426-17CD475BE895} - EndGlobalSection EndGlobal From 7d0505759e718292f0aed22ccb50c5e554a75c8e Mon Sep 17 00:00:00 2001 From: Alexandre Cardoso Date: Fri, 21 Nov 2025 12:32:03 -0800 Subject: [PATCH 11/11] Added comments --- .../D3D12Multithreading/src/D3D12Multithreading.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp index c924d25f1..e0a37d919 100644 --- a/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp +++ b/Samples/Desktop/D3D12Multithreading/src/D3D12Multithreading.cpp @@ -1095,6 +1095,11 @@ void D3D12Multithreading::BeginFrame() { D3D12_TEXTURE_BARRIER BeginFrameBarriers[] = { + // Using SYNC_NONE and ACCESS_NO_ACCESS with Enhanced Barrier to avoid unnecessary sync/flush. + // Using them explicitly tells the GPU it is okay to immediately transition + // the layout without waiting for preceding work to complete. + // In this case, the legacy barrier would flush and finish any preceding work that may potentially be reading from the RT + // resource (in this case there is none) CD3DX12_TEXTURE_BARRIER( D3D12_BARRIER_SYNC_NONE, // SyncBefore D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncAfter @@ -1145,6 +1150,8 @@ void D3D12Multithreading::EndFrame() { D3D12_TEXTURE_BARRIER EndFrameBarriers[] = { + // Using SYNC_NONE and ACCESS_NO_ACCESS with Enhanced Barrier means subsequent + // commands are unblocked without having to wait for the barrier to complete. CD3DX12_TEXTURE_BARRIER( D3D12_BARRIER_SYNC_RENDER_TARGET, // SyncBefore D3D12_BARRIER_SYNC_NONE, // SyncAfter