From 5f0e1253cca20e757d2fdb91eb344ae32faf91aa Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 18 Nov 2025 12:08:54 +0100 Subject: [PATCH] Refactor DX12 Root Signature creation to support offline construction Fix running D3D12 on integrated AMD GPU --- Source/Engine/Core/Types/StringBuilder.h | 5 + .../DirectX/DX12/GPUContextDX12.cpp | 1 + .../DirectX/DX12/GPUDeviceDX12.cpp | 480 ++++++++++++------ .../DirectX/DX12/GPUDeviceDX12.h | 5 - .../DirectX/DX12/RootSignatureDX12.h | 33 ++ 5 files changed, 354 insertions(+), 170 deletions(-) create mode 100644 Source/Engine/GraphicsDevice/DirectX/DX12/RootSignatureDX12.h diff --git a/Source/Engine/Core/Types/StringBuilder.h b/Source/Engine/Core/Types/StringBuilder.h index 925111cc3..620ac8a13 100644 --- a/Source/Engine/Core/Types/StringBuilder.h +++ b/Source/Engine/Core/Types/StringBuilder.h @@ -215,6 +215,11 @@ public: return String(_data.Get(), _data.Count()); } + StringAnsi ToStringAnsi() const + { + return StringAnsi(_data.Get(), _data.Count()); + } + StringView ToStringView() const; }; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index b33f94d61..13769f2dd 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -29,6 +29,7 @@ #include "GPUVertexLayoutDX12.h" #include "CommandQueueDX12.h" #include "DescriptorHeapDX12.h" +#include "RootSignatureDX12.h" #include "Engine/Graphics/RenderTask.h" #include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h" #include "Engine/Debug/Exceptions/NotImplementedException.h" diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index 88334be60..62070ecda 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -12,6 +12,9 @@ #include "GPUSamplerDX12.h" #include "GPUVertexLayoutDX12.h" #include "GPUSwapChainDX12.h" +#include "RootSignatureDX12.h" +#include "UploadBufferDX12.h" +#include "CommandQueueDX12.h" #include "Engine/Engine/Engine.h" #include "Engine/Engine/CommandLine.h" #include "Engine/Graphics/RenderTask.h" @@ -21,20 +24,23 @@ #include "Engine/Profiler/ProfilerMemory.h" #include "Engine/Core/Log.h" #include "Engine/Core/Config/PlatformSettings.h" -#include "UploadBufferDX12.h" -#include "CommandQueueDX12.h" +#include "Engine/Core/Types/StringBuilder.h" #include "Engine/Core/Utilities.h" #include "Engine/Threading/Threading.h" #include "CommandSignatureDX12.h" static bool CheckDX12Support(IDXGIAdapter* adapter) { +#if PLATFORM_XBOX_SCARLETT || PLATFORM_XBOX_ONE + return true; +#else // Try to create device if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { return true; } return false; +#endif } GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements, bool explicitOffsets) @@ -55,6 +61,310 @@ GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& } } +RootSignatureDX12::RootSignatureDX12() +{ + // Clear structures + Platform::MemoryClear(this, sizeof(*this)); + + // Descriptor tables + { + // SRVs + D3D12_DESCRIPTOR_RANGE& range = _ranges[0]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range.NumDescriptors = GPU_MAX_SR_BINDED; + range.BaseShaderRegister = 0; + range.RegisterSpace = 0; + range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + } + { + // UAVs + D3D12_DESCRIPTOR_RANGE& range = _ranges[1]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + range.NumDescriptors = GPU_MAX_UA_BINDED; + range.BaseShaderRegister = 0; + range.RegisterSpace = 0; + range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + } + { + // Samplers + D3D12_DESCRIPTOR_RANGE& range = _ranges[2]; + range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + range.NumDescriptors = GPU_MAX_SAMPLER_BINDED - GPU_STATIC_SAMPLERS_COUNT; + range.BaseShaderRegister = GPU_STATIC_SAMPLERS_COUNT; + range.RegisterSpace = 0; + range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + } + + // Root parameters + for (int32 i = 0; i < GPU_MAX_CB_BINDED; i++) + { + // CBs + D3D12_ROOT_PARAMETER& param = _parameters[DX12_ROOT_SIGNATURE_CB + i]; + param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + param.Descriptor.ShaderRegister = i; + param.Descriptor.RegisterSpace = 0; + } + { + // SRVs + D3D12_ROOT_PARAMETER& param = _parameters[DX12_ROOT_SIGNATURE_SR]; + param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + param.DescriptorTable.NumDescriptorRanges = 1; + param.DescriptorTable.pDescriptorRanges = &_ranges[0]; + } + { + // UAVs + D3D12_ROOT_PARAMETER& param = _parameters[DX12_ROOT_SIGNATURE_UA]; + param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + param.DescriptorTable.NumDescriptorRanges = 1; + param.DescriptorTable.pDescriptorRanges = &_ranges[1]; + } + { + // Samplers + D3D12_ROOT_PARAMETER& param = _parameters[DX12_ROOT_SIGNATURE_SAMPLER]; + param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + param.DescriptorTable.NumDescriptorRanges = 1; + param.DescriptorTable.pDescriptorRanges = &_ranges[2]; + } + + // Static samplers + static_assert(GPU_STATIC_SAMPLERS_COUNT == ARRAY_COUNT(_staticSamplers), "Update static samplers setup."); + // Linear Clamp + InitSampler(0, D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP); + // Point Clamp + InitSampler(1, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP); + // Linear Wrap + InitSampler(2, D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_WRAP); + // Point Wrap + InitSampler(3, D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP); + // Shadow + InitSampler(4, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_COMPARISON_FUNC_LESS_EQUAL); + // Shadow PCF + InitSampler(5, D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_COMPARISON_FUNC_LESS_EQUAL); + + // Init + _desc.NumParameters = ARRAY_COUNT(_parameters); + _desc.pParameters = _parameters; + _desc.NumStaticSamplers = ARRAY_COUNT(_staticSamplers); + _desc.pStaticSamplers = _staticSamplers; + _desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; +} + +void RootSignatureDX12::InitSampler(int32 i, D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE address, D3D12_COMPARISON_FUNC comparisonFunc) +{ + auto& sampler = _staticSamplers[i]; + sampler.Filter = filter; + sampler.AddressU = address; + sampler.AddressV = address; + sampler.AddressW = address; + sampler.MipLODBias = 0.0f; + sampler.MaxAnisotropy = 1; + sampler.ComparisonFunc = comparisonFunc; + sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; + sampler.MinLOD = 0; + sampler.MaxLOD = D3D12_FLOAT32_MAX; + sampler.ShaderRegister = i; + sampler.RegisterSpace = 0; + sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; +} + +ComPtr RootSignatureDX12::Serialize() const +{ + ComPtr signature; + ComPtr error; + VALIDATE_DIRECTX_CALL(D3D12SerializeRootSignature(&_desc, D3D_ROOT_SIGNATURE_VERSION_1_0, &signature, &error)); + if (error.Get()) + { + LOG(Error, "D3D12SerializeRootSignature failed with error: {}", String((const char*)error->GetBufferPointer())); + } + return signature; +} + +#if USE_EDITOR + +const Char* GetRootSignatureShaderVisibility(D3D12_SHADER_VISIBILITY visibility) +{ + switch (visibility) + { + case D3D12_SHADER_VISIBILITY_VERTEX: + return TEXT(", visibility=SHADER_VISIBILITY_VERTEX"); + case D3D12_SHADER_VISIBILITY_HULL: + return TEXT(", visibility=SHADER_VISIBILITY_HULL"); + case D3D12_SHADER_VISIBILITY_DOMAIN: + return TEXT(", visibility=SHADER_VISIBILITY_DOMAIN"); + case D3D12_SHADER_VISIBILITY_GEOMETRY: + return TEXT(", visibility=SHADER_VISIBILITY_GEOMETRY"); + case D3D12_SHADER_VISIBILITY_PIXEL: + return TEXT(", visibility=SHADER_VISIBILITY_PIXEL"); + case D3D12_SHADER_VISIBILITY_AMPLIFICATION: + return TEXT(", visibility=SHADER_VISIBILITY_AMPLIFICATION"); + case D3D12_SHADER_VISIBILITY_MESH: + return TEXT(", visibility=SHADER_VISIBILITY_MESH"); + case D3D12_SHADER_VISIBILITY_ALL: + default: + return TEXT(""); // Default + } +} + +const Char* GetRootSignatureSamplerFilter(D3D12_FILTER filter) +{ + switch (filter) + { + case D3D12_FILTER_MIN_MAG_MIP_POINT: + return TEXT("FILTER_MIN_MAG_MIP_POINT"); + case D3D12_FILTER_MIN_MAG_MIP_LINEAR: + return TEXT("FILTER_MIN_MAG_MIP_LINEAR"); + case D3D12_FILTER_ANISOTROPIC: + return TEXT("FILTER_ANISOTROPIC"); + case D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT: + return TEXT("FILTER_COMPARISON_MIN_MAG_MIP_POINT"); + case D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: + return TEXT("FILTER_COMPARISON_MIN_MAG_MIP_LINEAR"); + default: + CRASH; // Not implemented + } +} + +const Char* GetRootSignatureSamplerAddress(D3D12_TEXTURE_ADDRESS_MODE address) +{ + switch (address) + { + case D3D12_TEXTURE_ADDRESS_MODE_WRAP: + return TEXT("TEXTURE_ADDRESS_WRAP"); + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR: + return TEXT("TEXTURE_ADDRESS_MIRROR"); + case D3D12_TEXTURE_ADDRESS_MODE_CLAMP: + return TEXT("TEXTURE_ADDRESS_CLAMP"); + case D3D12_TEXTURE_ADDRESS_MODE_BORDER: + return TEXT("TEXTURE_ADDRESS_BORDER"); + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE: + return TEXT("TEXTURE_ADDRESS_MIRROR_ONCE"); + default: + return TEXT(""); + } +} + +const Char* GetRootSignatureSamplerComparisonFunc(D3D12_COMPARISON_FUNC func) +{ + switch (func) + { + case D3D12_COMPARISON_FUNC_NEVER: + return TEXT("COMPARISON_NEVER"); + case D3D12_COMPARISON_FUNC_LESS: + return TEXT("COMPARISON_LESS"); + case D3D12_COMPARISON_FUNC_EQUAL: + return TEXT("COMPARISON_EQUAL"); + case D3D12_COMPARISON_FUNC_LESS_EQUAL: + return TEXT("COMPARISON_LESS_EQUAL"); + case D3D12_COMPARISON_FUNC_GREATER: + return TEXT("COMPARISON_GREATER"); + case D3D12_COMPARISON_FUNC_NOT_EQUAL: + return TEXT("COMPARISON_NOT_EQUAL"); + case D3D12_COMPARISON_FUNC_GREATER_EQUAL: + return TEXT("COMPARISON_GREATER_EQUAL"); + case D3D12_COMPARISON_FUNC_ALWAYS: + default: + return TEXT("COMPARISON_ALWAYS"); + } +} + +void RootSignatureDX12::ToString(StringBuilder& sb, bool singleLine) const +{ + // Flags + sb.Append(TEXT("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT)")); + + // Parameters + const Char newLine = singleLine ? ' ' : '\n'; + for (const D3D12_ROOT_PARAMETER& param : _parameters) + { + const Char* visibility = GetRootSignatureShaderVisibility(param.ShaderVisibility); + switch (param.ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + sb.AppendFormat(TEXT(",{}DescriptorTable("), newLine); + for (uint32 rangeIndex = 0; rangeIndex < param.DescriptorTable.NumDescriptorRanges; rangeIndex++) + { + if (rangeIndex) + sb.Append(TEXT(", ")); + const D3D12_DESCRIPTOR_RANGE& range = param.DescriptorTable.pDescriptorRanges[rangeIndex]; + switch (range.RangeType) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + sb.AppendFormat(TEXT("SRV(t{}"), range.BaseShaderRegister); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + sb.AppendFormat(TEXT("UAV(u{}"), range.BaseShaderRegister); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + sb.AppendFormat(TEXT("CBV(b{}"), range.BaseShaderRegister); + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: + sb.AppendFormat(TEXT("Sampler(s{}"), range.BaseShaderRegister); + break; + } + if (range.NumDescriptors != 1) + { + if (range.NumDescriptors == UINT_MAX) + sb.Append(TEXT(", numDescriptors=unbounded")); + else + sb.AppendFormat(TEXT(", numDescriptors={}"), range.NumDescriptors); + } + if (range.OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + sb.AppendFormat(TEXT(", offset={}"), range.OffsetInDescriptorsFromTableStart); + sb.Append(')'); + } + sb.AppendFormat(TEXT("{})"), visibility); + break; + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + sb.AppendFormat(TEXT(",{}RootConstants(num32BitConstants={}, b{}{})"), newLine, param.Constants.Num32BitValues, param.Constants.ShaderRegister, visibility); + break; + case D3D12_ROOT_PARAMETER_TYPE_CBV: + sb.AppendFormat(TEXT(",{}CBV(b{}{})"), newLine, param.Descriptor.ShaderRegister, visibility); + break; + case D3D12_ROOT_PARAMETER_TYPE_SRV: + sb.AppendFormat(TEXT(",{}SRV(t{}{})"), newLine, param.Descriptor.ShaderRegister, visibility); + break; + case D3D12_ROOT_PARAMETER_TYPE_UAV: + sb.AppendFormat(TEXT(",{}UAV(u{}{})"), newLine, param.Descriptor.ShaderRegister, visibility); + break; + } + } + + // Static Samplers + for (const D3D12_STATIC_SAMPLER_DESC& sampler : _staticSamplers) + { + const Char* visibility = GetRootSignatureShaderVisibility(sampler.ShaderVisibility); + sb.AppendFormat(TEXT(",{}StaticSampler(s{}"), newLine, sampler.ShaderRegister); + sb.AppendFormat(TEXT(", filter={}"), GetRootSignatureSamplerFilter(sampler.Filter)); + sb.AppendFormat(TEXT(", addressU={}"), GetRootSignatureSamplerAddress(sampler.AddressU)); + sb.AppendFormat(TEXT(", addressV={}"), GetRootSignatureSamplerAddress(sampler.AddressV)); + sb.AppendFormat(TEXT(", addressW={}"), GetRootSignatureSamplerAddress(sampler.AddressW)); + sb.AppendFormat(TEXT(", comparisonFunc={}"), GetRootSignatureSamplerComparisonFunc(sampler.ComparisonFunc)); + sb.AppendFormat(TEXT(", maxAnisotropy={}"), sampler.MaxAnisotropy); + sb.Append(TEXT(", borderColor=STATIC_BORDER_COLOR_OPAQUE_BLACK")); + sb.AppendFormat(TEXT("{})"), visibility); + } +} + +String RootSignatureDX12::ToString() const +{ + StringBuilder sb; + ToString(sb); + return sb.ToString(); +} + +StringAnsi RootSignatureDX12::ToStringAnsi() const +{ + StringBuilder sb; + ToString(sb); + return sb.ToStringAnsi(); +} + +#endif + GPUDevice* GPUDeviceDX12::Create() { #if PLATFORM_XBOX_SCARLETT || PLATFORM_XBOX_ONE @@ -561,170 +871,10 @@ bool GPUDeviceDX12::Init() } // Create root signature - // TODO: maybe create set of different root signatures? for UAVs, for compute, for simple drawing, for post fx? { - // Descriptor tables - D3D12_DESCRIPTOR_RANGE r[3]; // SRV+UAV+Sampler - { - D3D12_DESCRIPTOR_RANGE& range = r[0]; - range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - range.NumDescriptors = GPU_MAX_SR_BINDED; - range.BaseShaderRegister = 0; - range.RegisterSpace = 0; - range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - } - { - D3D12_DESCRIPTOR_RANGE& range = r[1]; - range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - range.NumDescriptors = GPU_MAX_UA_BINDED; - range.BaseShaderRegister = 0; - range.RegisterSpace = 0; - range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - } - { - D3D12_DESCRIPTOR_RANGE& range = r[2]; - range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; - range.NumDescriptors = GPU_MAX_SAMPLER_BINDED - GPU_STATIC_SAMPLERS_COUNT; - range.BaseShaderRegister = GPU_STATIC_SAMPLERS_COUNT; - range.RegisterSpace = 0; - range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - } - - // Root parameters - D3D12_ROOT_PARAMETER rootParameters[GPU_MAX_CB_BINDED + 3]; - for (int32 i = 0; i < GPU_MAX_CB_BINDED; i++) - { - // CB - D3D12_ROOT_PARAMETER& rootParam = rootParameters[DX12_ROOT_SIGNATURE_CB + i]; - rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; - rootParam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParam.Descriptor.ShaderRegister = i; - rootParam.Descriptor.RegisterSpace = 0; - } - { - // SRVs - D3D12_ROOT_PARAMETER& rootParam = rootParameters[DX12_ROOT_SIGNATURE_SR]; - rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParam.DescriptorTable.NumDescriptorRanges = 1; - rootParam.DescriptorTable.pDescriptorRanges = &r[0]; - } - { - // UAVs - D3D12_ROOT_PARAMETER& rootParam = rootParameters[DX12_ROOT_SIGNATURE_UA]; - rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParam.DescriptorTable.NumDescriptorRanges = 1; - rootParam.DescriptorTable.pDescriptorRanges = &r[1]; - } - { - // Samplers - D3D12_ROOT_PARAMETER& rootParam = rootParameters[DX12_ROOT_SIGNATURE_SAMPLER]; - rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParam.DescriptorTable.NumDescriptorRanges = 1; - rootParam.DescriptorTable.pDescriptorRanges = &r[2]; - } - - // Static samplers - D3D12_STATIC_SAMPLER_DESC staticSamplers[6]; - static_assert(GPU_STATIC_SAMPLERS_COUNT == ARRAY_COUNT(staticSamplers), "Update static samplers setup."); - // Linear Clamp - staticSamplers[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - staticSamplers[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[0].MipLODBias = 0.0f; - staticSamplers[0].MaxAnisotropy = 1; - staticSamplers[0].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[0].MinLOD = 0; - staticSamplers[0].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[0].ShaderRegister = 0; - staticSamplers[0].RegisterSpace = 0; - staticSamplers[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - // Point Clamp - staticSamplers[1].Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - staticSamplers[1].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[1].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[1].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[1].MipLODBias = 0.0f; - staticSamplers[1].MaxAnisotropy = 1; - staticSamplers[1].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[1].MinLOD = 0; - staticSamplers[1].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[1].ShaderRegister = 1; - staticSamplers[1].RegisterSpace = 0; - staticSamplers[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - // Linear Wrap - staticSamplers[2].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - staticSamplers[2].AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[2].AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[2].AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[2].MipLODBias = 0.0f; - staticSamplers[2].MaxAnisotropy = 1; - staticSamplers[2].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[2].MinLOD = 0; - staticSamplers[2].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[2].ShaderRegister = 2; - staticSamplers[2].RegisterSpace = 0; - staticSamplers[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - // Point Wrap - staticSamplers[3].Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; - staticSamplers[3].AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[3].AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[3].AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - staticSamplers[3].MipLODBias = 0.0f; - staticSamplers[3].MaxAnisotropy = 1; - staticSamplers[3].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[3].MinLOD = 0; - staticSamplers[3].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[3].ShaderRegister = 3; - staticSamplers[3].RegisterSpace = 0; - staticSamplers[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - // Shadow - staticSamplers[4].Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT; - staticSamplers[4].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[4].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[4].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[4].MipLODBias = 0.0f; - staticSamplers[4].MaxAnisotropy = 1; - staticSamplers[4].ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; - staticSamplers[4].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[4].MinLOD = 0; - staticSamplers[4].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[4].ShaderRegister = 4; - staticSamplers[4].RegisterSpace = 0; - staticSamplers[4].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - // Shadow PCF - staticSamplers[5].Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; - staticSamplers[5].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[5].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[5].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - staticSamplers[5].MipLODBias = 0.0f; - staticSamplers[5].MaxAnisotropy = 1; - staticSamplers[5].ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; - staticSamplers[5].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; - staticSamplers[5].MinLOD = 0; - staticSamplers[5].MaxLOD = D3D12_FLOAT32_MAX; - staticSamplers[5].ShaderRegister = 5; - staticSamplers[5].RegisterSpace = 0; - staticSamplers[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - - // Init - D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc; - rootSignatureDesc.NumParameters = ARRAY_COUNT(rootParameters); - rootSignatureDesc.pParameters = rootParameters; - rootSignatureDesc.NumStaticSamplers = ARRAY_COUNT(staticSamplers); - rootSignatureDesc.pStaticSamplers = staticSamplers; - rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - - // Serialize - ComPtr signature; - ComPtr error; - VALIDATE_DIRECTX_CALL(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); - - // Create - VALIDATE_DIRECTX_CALL(_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&_rootSignature))); + RootSignatureDX12 signature; + ComPtr signatureBlob = signature.Serialize(); + VALIDATE_DIRECTX_CALL(_device->CreateRootSignature(0, signatureBlob->GetBufferPointer(), signatureBlob->GetBufferSize(), IID_PPV_ARGS(&_rootSignature))); } if (TimestampQueryHeap.Init()) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h index 064ed9a01..bb5d53458 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.h @@ -18,11 +18,6 @@ #define DX12_BACK_BUFFER_COUNT 2 #endif -#define DX12_ROOT_SIGNATURE_CB 0 -#define DX12_ROOT_SIGNATURE_SR (GPU_MAX_CB_BINDED+0) -#define DX12_ROOT_SIGNATURE_UA (GPU_MAX_CB_BINDED+1) -#define DX12_ROOT_SIGNATURE_SAMPLER (GPU_MAX_CB_BINDED+2) - class Engine; class WindowsWindow; class GPUContextDX12; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/RootSignatureDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/RootSignatureDX12.h new file mode 100644 index 000000000..156b6ae04 --- /dev/null +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/RootSignatureDX12.h @@ -0,0 +1,33 @@ +// Copyright (c) Wojciech Figat. All rights reserved. + +#pragma once + +#include "Engine/Graphics/Config.h" +#include "../IncludeDirectXHeaders.h" + +#define DX12_ROOT_SIGNATURE_CB 0 +#define DX12_ROOT_SIGNATURE_SR (GPU_MAX_CB_BINDED+0) +#define DX12_ROOT_SIGNATURE_UA (GPU_MAX_CB_BINDED+1) +#define DX12_ROOT_SIGNATURE_SAMPLER (GPU_MAX_CB_BINDED+2) + +struct RootSignatureDX12 +{ +private: + D3D12_ROOT_SIGNATURE_DESC _desc; + D3D12_DESCRIPTOR_RANGE _ranges[3]; + D3D12_ROOT_PARAMETER _parameters[GPU_MAX_CB_BINDED + 3]; + D3D12_STATIC_SAMPLER_DESC _staticSamplers[6]; + +public: + RootSignatureDX12(); + + ComPtr Serialize() const; +#if USE_EDITOR + void ToString(class StringBuilder& sb, bool singleLine = false) const; + String ToString() const; + StringAnsi ToStringAnsi() const; +#endif + +private: + void InitSampler(int32 i, D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE address, D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL); +};