diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index 4021a9324..6489091ae 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -307,6 +307,12 @@ namespace wi::graphics Barrier(&barrier, 1, cmd); } + // Execute a global GPU memory barrier + void Barrier(CommandList cmd) + { + Barrier(GPUBarrier::Memory(), cmd); + } + struct GPULinearAllocator { GPUBuffer buffer; diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index c548f4e92..956d3e540 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -54,6 +54,7 @@ namespace dx12_internal #endif static PFN_D3D12_CREATE_DEVICE D3D12CreateDevice = nullptr; static PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER D3D12CreateVersionedRootSignatureDeserializer = nullptr; + static PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature = nullptr; #endif // PLATFORM_WINDOWS_DESKTOP // Engine -> Native converters @@ -2190,6 +2191,16 @@ std::mutex queue_locker; wi::platform::Exit(); } + D3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)wiGetProcAddress(dx12, "D3D12SerializeRootSignature"); + assert(D3D12SerializeRootSignature != nullptr); + if (D3D12SerializeRootSignature == nullptr) + { + std::stringstream ss(""); + ss << "Failed to load D3D12SerializeRootSignature! ERROR: " << std::hex << GetLastError(); + wi::helper::messageBox(ss.str(), "Error!"); + wi::platform::Exit(); + } + if (validationMode != ValidationMode::Disabled) { // Enable the debug layer. @@ -2855,6 +2866,42 @@ std::mutex queue_locker; wi::platform::Exit(); } + // Dummy rootsignature is created for validating multidraw command signatures (required): + ComPtr rootsig; + ComPtr serializedRootSig = nullptr; + ComPtr errorBlob = nullptr; + D3D12_ROOT_PARAMETER rootparam = {}; + rootparam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootparam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootparam.Constants.Num32BitValues = PUSH_CONSTANT_COUNT; + rootparam.Constants.ShaderRegister = 999; + D3D12_ROOT_SIGNATURE_DESC rootsig_desc = {}; + rootsig_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + rootsig_desc.NumParameters = 1; + rootsig_desc.pParameters = &rootparam; + dx12_check(D3D12SerializeRootSignature(&rootsig_desc, D3D_ROOT_SIGNATURE_VERSION_1, serializedRootSig.GetAddressOf(), errorBlob.GetAddressOf())); + dx12_check(device->CreateRootSignature(0, serializedRootSig->GetBufferPointer(), serializedRootSig->GetBufferSize(), PPV_ARGS(rootsig))); + + D3D12_INDIRECT_ARGUMENT_DESC drawInstancedCountArgs[2]; + drawInstancedCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT; + drawInstancedCountArgs[0].Constant.RootParameterIndex = 0; + drawInstancedCountArgs[0].Constant.Num32BitValuesToSet = 1; + drawInstancedCountArgs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + cmd_desc.ByteStride = sizeof(uint32_t) + sizeof(D3D12_DRAW_ARGUMENTS); + cmd_desc.NumArgumentDescs = arraysize(drawInstancedCountArgs); + cmd_desc.pArgumentDescs = drawInstancedCountArgs; + dx12_check(device->CreateCommandSignature(&cmd_desc, rootsig.Get(), PPV_ARGS(drawInstancedIndirectCountCommandSignature))); + + D3D12_INDIRECT_ARGUMENT_DESC drawIndexedInstancedCountArgs[2]; + drawIndexedInstancedCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT; + drawIndexedInstancedCountArgs[0].Constant.RootParameterIndex = 0; + drawIndexedInstancedCountArgs[0].Constant.Num32BitValuesToSet = 1; + drawIndexedInstancedCountArgs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; + cmd_desc.ByteStride = sizeof(uint32_t) + sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); + cmd_desc.NumArgumentDescs = arraysize(drawIndexedInstancedCountArgs); + cmd_desc.pArgumentDescs = drawIndexedInstancedCountArgs; + dx12_check(device->CreateCommandSignature(&cmd_desc, rootsig.Get(), PPV_ARGS(drawIndexedInstancedIndirectCountCommandSignature))); + if (CheckCapability(GraphicsDeviceCapability::MESH_SHADER)) { D3D12_INDIRECT_ARGUMENT_DESC dispatchMeshArgs[1]; @@ -2866,12 +2913,22 @@ std::mutex queue_locker; #endif // PLATFORM_XBOX cmd_desc.NumArgumentDescs = 1; cmd_desc.pArgumentDescs = dispatchMeshArgs; - hr = dx12_check(device->CreateCommandSignature(&cmd_desc, nullptr, PPV_ARGS(dispatchMeshIndirectCommandSignature))); - if (FAILED(hr)) - { - wilog_messagebox("ID3D12Device::CreateCommandSignature[dispatchMeshIndirect] failed! ERROR: %s", wi::helper::GetPlatformErrorString(hr).c_str()); - wi::platform::Exit(); - } + dx12_check(device->CreateCommandSignature(&cmd_desc, nullptr, PPV_ARGS(dispatchMeshIndirectCommandSignature))); + + D3D12_INDIRECT_ARGUMENT_DESC dispatchMeshCountArgs[2]; + dispatchMeshCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT; + dispatchMeshCountArgs[0].Constant.RootParameterIndex = 0; + dispatchMeshCountArgs[0].Constant.Num32BitValuesToSet = 1; +#ifdef PLATFORM_XBOX + wi::graphics::xbox::FillDispatchMeshIndirectArgumentDesc(dispatchMeshCountArgs[1], cmd_desc); +#else + dispatchMeshCountArgs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH; + cmd_desc.ByteStride = sizeof(D3D12_DISPATCH_MESH_ARGUMENTS); +#endif // PLATFORM_XBOX + cmd_desc.ByteStride += sizeof(uint32_t); + cmd_desc.NumArgumentDescs = arraysize(dispatchMeshCountArgs); + cmd_desc.pArgumentDescs = dispatchMeshCountArgs; + dx12_check(device->CreateCommandSignature(&cmd_desc, rootsig.Get(), PPV_ARGS(dispatchMeshIndirectCommandSignature))); } allocationhandler->descriptors_res.init(this, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 4096); @@ -6754,7 +6811,7 @@ std::mutex queue_locker; auto args_internal = to_internal(args); auto count_internal = to_internal(count); CommandList_DX12& commandlist = GetCommandList(cmd); - commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawInstancedIndirectCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); + commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawInstancedIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); } void GraphicsDevice_DX12::DrawIndexedInstancedIndirectCount(const GPUBuffer* args, uint64_t args_offset, const GPUBuffer* count, uint64_t count_offset, uint32_t max_count, CommandList cmd) { @@ -6762,7 +6819,7 @@ std::mutex queue_locker; auto args_internal = to_internal(args); auto count_internal = to_internal(count); CommandList_DX12& commandlist = GetCommandList(cmd); - commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawIndexedInstancedIndirectCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); + commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawIndexedInstancedIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); } void GraphicsDevice_DX12::Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ, CommandList cmd) { @@ -6796,7 +6853,7 @@ std::mutex queue_locker; auto args_internal = to_internal(args); auto count_internal = to_internal(count); CommandList_DX12& commandlist = GetCommandList(cmd); - commandlist.GetGraphicsCommandList()->ExecuteIndirect(dispatchMeshIndirectCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); + commandlist.GetGraphicsCommandList()->ExecuteIndirect(dispatchMeshIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset); } void GraphicsDevice_DX12::CopyResource(const GPUResource* pDst, const GPUResource* pSrc, CommandList cmd) { diff --git a/WickedEngine/wiGraphicsDevice_DX12.h b/WickedEngine/wiGraphicsDevice_DX12.h index 79279aa76..500e99518 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.h +++ b/WickedEngine/wiGraphicsDevice_DX12.h @@ -60,6 +60,10 @@ namespace wi::graphics Microsoft::WRL::ComPtr drawIndexedInstancedIndirectCommandSignature; Microsoft::WRL::ComPtr dispatchMeshIndirectCommandSignature; + Microsoft::WRL::ComPtr drawInstancedIndirectCountCommandSignature; + Microsoft::WRL::ComPtr drawIndexedInstancedIndirectCountCommandSignature; + Microsoft::WRL::ComPtr dispatchMeshIndirectCountCommandSignature; + wi::vector video_decode_profile_list; bool deviceRemoved = false; diff --git a/WickedEngine/wiPlatform.h b/WickedEngine/wiPlatform.h index 87498ae62..647d92ac6 100644 --- a/WickedEngine/wiPlatform.h +++ b/WickedEngine/wiPlatform.h @@ -18,6 +18,7 @@ #define PLATFORM_WINDOWS_DESKTOP #endif // WINAPI_FAMILY_GAMES #define wiLoadLibrary(name) LoadLibraryA(name) +#define wiFreeLibrary(handle) FreeLibrary(handle) #define wiGetProcAddress(handle,name) GetProcAddress(handle, name) #elif defined(__SCE__) #define PLATFORM_PS5 @@ -43,6 +44,7 @@ #if defined(PLATFORM_LINUX) || defined(PLATFORM_APPLE) #include #define wiLoadLibrary(name) dlopen(name, RTLD_LAZY) +#define wiFreeLibrary(handle) dlclose(handle) #define wiGetProcAddress(handle,name) dlsym(handle, name) typedef void* HMODULE; #endif // defined(PLATFORM_LINUX) || defined(PLATFORM_APPLE) diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 294bfd22f..a269157ac 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -11305,7 +11305,7 @@ void ComputeLuminance( cmd ); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(GPUBarrier::Memory(&res.luminance), cmd); } // Pass 2 : Reduce into 1x1 texture @@ -11633,7 +11633,7 @@ void Visibility_Prepare( { device->ClearUAV(res.primitiveID_resolved, 0, cmd); } - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); device->BindComputeShader(&shaders[msaa ? CSTYPE_VISIBILITY_RESOLVE_MSAA : CSTYPE_VISIBILITY_RESOLVE], cmd); @@ -11692,7 +11692,7 @@ void Visibility_Surface( device->ClearUAV(&res.texture_roughness, 0, cmd); device->ClearUAV(&res.texture_payload_0, 0, cmd); device->ClearUAV(&res.texture_payload_1, 0, cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); device->BindResource(&res.binned_tiles, 0, cmd); device->BindUAV(&output, 0, cmd); @@ -11747,7 +11747,7 @@ void Visibility_Surface_Reduced( device->ClearUAV(&res.texture_normals, 0, cmd); device->ClearUAV(&res.texture_roughness, 0, cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); device->BindResource(&res.binned_tiles, 0, cmd); device->BindUAV(&res.texture_normals, 1, cmd); @@ -11886,7 +11886,7 @@ void SurfelGI_Coverage( } device->ClearUAV(&res.result_halfres, 0, cmd); device->ClearUAV(&res.result, 0, cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); // Coverage: @@ -11978,18 +11978,11 @@ void SurfelGI( if (!scene.surfelgi.cleared) { scene.surfelgi.cleared = true; - GPUBarrier barriers[] = { - GPUBarrier::Image(&scene.surfelgi.momentsTexture, scene.surfelgi.momentsTexture.desc.layout, ResourceState::UNORDERED_ACCESS), - }; - device->Barrier(barriers, arraysize(barriers), cmd); + device->Barrier(GPUBarrier::Image(&scene.surfelgi.momentsTexture, scene.surfelgi.momentsTexture.desc.layout, ResourceState::UNORDERED_ACCESS), cmd); device->ClearUAV(&scene.surfelgi.momentsTexture, 0, cmd); device->ClearUAV(&scene.surfelgi.varianceBuffer, 0, cmd); - for (auto& x : barriers) - { - std::swap(x.image.layout_before, x.image.layout_after); - } - device->Barrier(barriers, arraysize(barriers), cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(GPUBarrier::Image(&scene.surfelgi.momentsTexture, ResourceState::UNORDERED_ACCESS, scene.surfelgi.momentsTexture.desc.layout), cmd); + device->Barrier(GPUBarrier::Memory(&scene.surfelgi.varianceBuffer), cmd); } // Grid reset: @@ -16822,7 +16815,7 @@ void VolumetricClouds_Capture( { device->ClearUAV(&scene.cloudmap, 0, cmd); device->ClearUAV(&scene.cloudmap_variance, 0, cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); } device->Dispatch( @@ -17219,7 +17212,7 @@ void Postprocess_FSR( device->ClearUAV(&temp, 0, cmd); device->ClearUAV(&output, 0, cmd); - device->Barrier(GPUBarrier::Memory(), cmd); + device->Barrier(cmd); device->Dispatch((desc.width + 15) / 16, (desc.height + 15) / 16, 1, cmd); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 880a6b912..a901ecd47 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 72; // minor bug fixes, alterations, refactors, updates - const int revision = 46; + const int revision = 47; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);