dx12 multidraw counters support and some other thing

This commit is contained in:
Turánszki János
2026-02-24 18:10:21 +01:00
parent b6d683680f
commit 7dcc39ad95
6 changed files with 89 additions and 27 deletions
+6
View File
@@ -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;
+66 -9
View File
@@ -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<ID3D12RootSignature> rootsig;
ComPtr<ID3DBlob> serializedRootSig = nullptr;
ComPtr<ID3DBlob> 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)
{
+4
View File
@@ -60,6 +60,10 @@ namespace wi::graphics
Microsoft::WRL::ComPtr<ID3D12CommandSignature> drawIndexedInstancedIndirectCommandSignature;
Microsoft::WRL::ComPtr<ID3D12CommandSignature> dispatchMeshIndirectCommandSignature;
Microsoft::WRL::ComPtr<ID3D12CommandSignature> drawInstancedIndirectCountCommandSignature;
Microsoft::WRL::ComPtr<ID3D12CommandSignature> drawIndexedInstancedIndirectCountCommandSignature;
Microsoft::WRL::ComPtr<ID3D12CommandSignature> dispatchMeshIndirectCountCommandSignature;
wi::vector<GUID> video_decode_profile_list;
bool deviceRemoved = false;
+2
View File
@@ -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 <dlfcn.h>
#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)
+10 -17
View File
@@ -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);
+1 -1
View File
@@ -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);