|
|
|
@@ -1432,6 +1432,10 @@ namespace dx12_internal
|
|
|
|
|
wi::allocator::shared_ptr<void> rootsig_desc_lifetime_extender;
|
|
|
|
|
RootSignatureOptimizer rootsig_optimizer;
|
|
|
|
|
|
|
|
|
|
Microsoft::WRL::ComPtr<ID3D12CommandSignature> drawInstancedIndirectCountCommandSignature;
|
|
|
|
|
Microsoft::WRL::ComPtr<ID3D12CommandSignature> drawIndexedInstancedIndirectCountCommandSignature;
|
|
|
|
|
Microsoft::WRL::ComPtr<ID3D12CommandSignature> dispatchMeshIndirectCountCommandSignature;
|
|
|
|
|
|
|
|
|
|
struct PSO_STREAM
|
|
|
|
|
{
|
|
|
|
|
struct PSO_STREAM1
|
|
|
|
@@ -2866,42 +2870,6 @@ 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];
|
|
|
|
@@ -2914,21 +2882,6 @@ std::mutex queue_locker;
|
|
|
|
|
cmd_desc.NumArgumentDescs = 1;
|
|
|
|
|
cmd_desc.pArgumentDescs = dispatchMeshArgs;
|
|
|
|
|
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);
|
|
|
|
@@ -3963,6 +3916,76 @@ std::mutex queue_locker;
|
|
|
|
|
hr = dx12_check(device->CreatePipelineState(&streamDesc, PPV_ARGS(internal_state->resource)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stage == ShaderStage::VS)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lck(multidraw_signature_locker);
|
|
|
|
|
MultiDrawSignature& cached = multidraw_signatures[internal_state->rootSignature.Get()];
|
|
|
|
|
|
|
|
|
|
if (cached.drawInstancedIndirectCountCommandSignature)
|
|
|
|
|
{
|
|
|
|
|
internal_state->drawInstancedIndirectCountCommandSignature = cached.drawInstancedIndirectCountCommandSignature;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
D3D12_COMMAND_SIGNATURE_DESC cmd_desc = {};
|
|
|
|
|
D3D12_INDIRECT_ARGUMENT_DESC drawInstancedCountArgs[2] = {};
|
|
|
|
|
drawInstancedCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
|
|
|
|
|
drawInstancedCountArgs[0].Constant.RootParameterIndex = internal_state->rootsig_optimizer.PUSH;
|
|
|
|
|
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, internal_state->rootSignature.Get(), PPV_ARGS(internal_state->drawInstancedIndirectCountCommandSignature)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cached.drawIndexedInstancedIndirectCountCommandSignature)
|
|
|
|
|
{
|
|
|
|
|
internal_state->drawIndexedInstancedIndirectCountCommandSignature = cached.drawIndexedInstancedIndirectCountCommandSignature;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
D3D12_COMMAND_SIGNATURE_DESC cmd_desc = {};
|
|
|
|
|
D3D12_INDIRECT_ARGUMENT_DESC drawIndexedInstancedCountArgs[2] = {};
|
|
|
|
|
drawIndexedInstancedCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
|
|
|
|
|
drawIndexedInstancedCountArgs[0].Constant.RootParameterIndex = internal_state->rootsig_optimizer.PUSH;
|
|
|
|
|
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, internal_state->rootSignature.Get(), PPV_ARGS(internal_state->drawIndexedInstancedIndirectCountCommandSignature)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (stage == ShaderStage::MS)
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lck(multidraw_signature_locker);
|
|
|
|
|
MultiDrawSignature& cached = multidraw_signatures[internal_state->rootSignature.Get()];
|
|
|
|
|
|
|
|
|
|
if (cached.dispatchMeshIndirectCountCommandSignature)
|
|
|
|
|
{
|
|
|
|
|
internal_state->dispatchMeshIndirectCountCommandSignature = cached.dispatchMeshIndirectCountCommandSignature;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
D3D12_COMMAND_SIGNATURE_DESC cmd_desc = {};
|
|
|
|
|
D3D12_INDIRECT_ARGUMENT_DESC dispatchMeshCountArgs[2] = {};
|
|
|
|
|
dispatchMeshCountArgs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
|
|
|
|
|
dispatchMeshCountArgs[0].Constant.RootParameterIndex = internal_state->rootsig_optimizer.PUSH;
|
|
|
|
|
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, internal_state->rootSignature.Get(), PPV_ARGS(internal_state->dispatchMeshIndirectCountCommandSignature)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SUCCEEDED(hr);
|
|
|
|
|
}
|
|
|
|
|
bool GraphicsDevice_DX12::CreateSampler(const SamplerDesc* desc, Sampler* sampler) const
|
|
|
|
@@ -4059,6 +4082,8 @@ std::mutex queue_locker;
|
|
|
|
|
internal_state->rootSignature = shader_internal->rootSignature;
|
|
|
|
|
internal_state->rootsig_desc = shader_internal->rootsig_desc;
|
|
|
|
|
internal_state->rootsig_desc_lifetime_extender = pso->desc.vs->internal_state;
|
|
|
|
|
internal_state->drawInstancedIndirectCountCommandSignature = shader_internal->drawInstancedIndirectCountCommandSignature;
|
|
|
|
|
internal_state->drawIndexedInstancedIndirectCountCommandSignature = shader_internal->drawIndexedInstancedIndirectCountCommandSignature;
|
|
|
|
|
stream.stream1.ROOTSIG = internal_state->rootSignature.Get();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -4120,6 +4145,7 @@ std::mutex queue_locker;
|
|
|
|
|
internal_state->rootSignature = shader_internal->rootSignature;
|
|
|
|
|
internal_state->rootsig_desc = shader_internal->rootsig_desc;
|
|
|
|
|
internal_state->rootsig_desc_lifetime_extender = pso->desc.ms->internal_state;
|
|
|
|
|
internal_state->dispatchMeshIndirectCountCommandSignature = shader_internal->dispatchMeshIndirectCountCommandSignature;
|
|
|
|
|
stream.stream1.ROOTSIG = internal_state->rootSignature.Get();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -5758,6 +5784,7 @@ std::mutex queue_locker;
|
|
|
|
|
|
|
|
|
|
void GraphicsDevice_DX12::ClearPipelineStateCache()
|
|
|
|
|
{
|
|
|
|
|
multidraw_signatures.clear();
|
|
|
|
|
pipelines_global.clear();
|
|
|
|
|
|
|
|
|
|
for (auto& x : commandlists)
|
|
|
|
@@ -6808,18 +6835,20 @@ std::mutex queue_locker;
|
|
|
|
|
void GraphicsDevice_DX12::DrawInstancedIndirectCount(const GPUBuffer* args, uint64_t args_offset, const GPUBuffer* count, uint64_t count_offset, uint32_t max_count, CommandList cmd)
|
|
|
|
|
{
|
|
|
|
|
predraw(cmd);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
auto pso_internal = to_internal(commandlist.active_pso);
|
|
|
|
|
auto args_internal = to_internal(args);
|
|
|
|
|
auto count_internal = to_internal(count);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawInstancedIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(pso_internal->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)
|
|
|
|
|
{
|
|
|
|
|
predraw(cmd);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
auto pso_internal = to_internal(commandlist.active_pso);
|
|
|
|
|
auto args_internal = to_internal(args);
|
|
|
|
|
auto count_internal = to_internal(count);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(drawIndexedInstancedIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(pso_internal->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)
|
|
|
|
|
{
|
|
|
|
@@ -6850,10 +6879,11 @@ std::mutex queue_locker;
|
|
|
|
|
void GraphicsDevice_DX12::DispatchMeshIndirectCount(const GPUBuffer* args, uint64_t args_offset, const GPUBuffer* count, uint64_t count_offset, uint32_t max_count, CommandList cmd)
|
|
|
|
|
{
|
|
|
|
|
predraw(cmd);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
auto pso_internal = to_internal(commandlist.active_pso);
|
|
|
|
|
auto args_internal = to_internal(args);
|
|
|
|
|
auto count_internal = to_internal(count);
|
|
|
|
|
CommandList_DX12& commandlist = GetCommandList(cmd);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(dispatchMeshIndirectCountCommandSignature.Get(), max_count, args_internal->resource.Get(), args_offset, count_internal->resource.Get(), count_offset);
|
|
|
|
|
commandlist.GetGraphicsCommandList()->ExecuteIndirect(pso_internal->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)
|
|
|
|
|
{
|
|
|
|
|