From 28dcc8089250905b6812322dbfc9a288a2fefd75 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 19 Apr 2023 15:19:04 +0100 Subject: [PATCH] Implement D3D12's CreateSampler2 and new sampler parameters --- .../D3D12PipelineStateViewer.cpp | 44 +++++++-- .../VulkanPipelineStateViewer.cpp | 19 +++- renderdoc/api/replay/d3d12_pipestate.h | 27 ++++-- renderdoc/api/replay/vk_pipestate.h | 22 +++-- renderdoc/driver/d3d12/d3d12_commands.cpp | 2 +- renderdoc/driver/d3d12/d3d12_common.cpp | 5 + renderdoc/driver/d3d12/d3d12_common.h | 5 +- renderdoc/driver/d3d12/d3d12_device.h | 2 +- .../driver/d3d12/d3d12_device_wrap11.cpp | 31 ++++++- renderdoc/driver/d3d12/d3d12_manager.cpp | 41 +++++++- renderdoc/driver/d3d12/d3d12_manager.h | 58 +++++++++++- renderdoc/driver/d3d12/d3d12_rendertext.cpp | 6 +- renderdoc/driver/d3d12/d3d12_replay.cpp | 59 ++++++++---- renderdoc/driver/d3d12/d3d12_replay.h | 2 +- renderdoc/driver/d3d12/d3d12_serialise.cpp | 50 +++++++++- renderdoc/driver/d3d12/d3d12_shader_cache.cpp | 93 ++++++++++++++++--- renderdoc/driver/d3d12/d3d12_shader_cache.h | 5 +- renderdoc/driver/d3d12/d3d12_shaderdebug.cpp | 25 +++-- renderdoc/driver/d3d12/d3d12_stringise.cpp | 13 +++ renderdoc/driver/vulkan/vk_replay.cpp | 9 +- renderdoc/replay/renderdoc_serialise.inl | 11 ++- 21 files changed, 436 insertions(+), 93 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 85be79f96..b374526e6 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -1314,11 +1314,20 @@ void D3D12PipelineStateViewer::setShaderState( if(shaderInput && !shaderInput->name.empty()) regname += lit(": ") + shaderInput->name; - QString borderColor = QFormatStr("%1, %2, %3, %4") - .arg(s.borderColor[0]) - .arg(s.borderColor[1]) - .arg(s.borderColor[2]) - .arg(s.borderColor[3]); + QString borderColor; + + if(s.borderColorType == CompType::Float) + borderColor = QFormatStr("%1, %2, %3, %4") + .arg(s.borderColorValue.floatValue[0]) + .arg(s.borderColorValue.floatValue[1]) + .arg(s.borderColorValue.floatValue[2]) + .arg(s.borderColorValue.floatValue[3]); + else + borderColor = QFormatStr("%1, %2, %3, %4") + .arg(s.borderColorValue.uintValue[0]) + .arg(s.borderColorValue.uintValue[1]) + .arg(s.borderColorValue.uintValue[2]) + .arg(s.borderColorValue.uintValue[3]); QString addressing; @@ -1353,6 +1362,9 @@ void D3D12PipelineStateViewer::setShaderState( if(s.UseBorder()) addressing += QFormatStr("<%1>").arg(borderColor); + if(s.unnormalized) + addressing += lit(" (Non-norm)"); + QString filter = ToQStr(s.filter); if(s.maxAnisotropy > 1) @@ -2927,11 +2939,20 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(shaderInput && !shaderInput->name.empty()) regname += lit(": ") + shaderInput->name; - QString borderColor = QFormatStr("%1, %2, %3, %4") - .arg(s.borderColor[0]) - .arg(s.borderColor[1]) - .arg(s.borderColor[2]) - .arg(s.borderColor[3]); + QString borderColor; + + if(s.borderColorType == CompType::Float) + borderColor = QFormatStr("%1, %2, %3, %4") + .arg(s.borderColorValue.floatValue[0]) + .arg(s.borderColorValue.floatValue[1]) + .arg(s.borderColorValue.floatValue[2]) + .arg(s.borderColorValue.floatValue[3]); + else + borderColor = QFormatStr("%1, %2, %3, %4") + .arg(s.borderColorValue.uintValue[0]) + .arg(s.borderColorValue.uintValue[1]) + .arg(s.borderColorValue.uintValue[2]) + .arg(s.borderColorValue.uintValue[3]); QString addressing; @@ -2966,6 +2987,9 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(s.UseBorder()) addressing += QFormatStr("<%1>").arg(borderColor); + if(s.unnormalized) + addressing += lit(" (Un-norm)"); + QString filter = ToQStr(s.filter); if(s.maxAnisotropy > 1) diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 493440d4e..ace7edaa1 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -1001,11 +1001,20 @@ QVariantList VulkanPipelineStateViewer::makeSampler(const QString &bindset, cons addressing += addPrefix + lit(": ") + addVal; if(descriptor.UseBorder()) - addressing += QFormatStr(" <%1, %2, %3, %4>") - .arg(descriptor.borderColor[0]) - .arg(descriptor.borderColor[1]) - .arg(descriptor.borderColor[2]) - .arg(descriptor.borderColor[3]); + { + if(descriptor.borderColorType == CompType::Float) + addressing += QFormatStr(" <%1, %2, %3, %4>") + .arg(descriptor.borderColorValue.floatValue[0]) + .arg(descriptor.borderColorValue.floatValue[1]) + .arg(descriptor.borderColorValue.floatValue[2]) + .arg(descriptor.borderColorValue.floatValue[3]); + else + addressing += QFormatStr(" <%1, %2, %3, %4>") + .arg(descriptor.borderColorValue.uintValue[0]) + .arg(descriptor.borderColorValue.uintValue[1]) + .arg(descriptor.borderColorValue.uintValue[2]) + .arg(descriptor.borderColorValue.uintValue[3]); + } if(descriptor.unnormalized) addressing += lit(" (Un-norm)"); diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index f09613ea5..da626a3b6 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -332,7 +332,9 @@ struct Sampler bool operator==(const Sampler &o) const { return bind == o.bind && tableIndex == o.tableIndex && addressU == o.addressU && - addressV == o.addressV && addressW == o.addressW && borderColor == o.borderColor && + addressV == o.addressV && addressW == o.addressW && + borderColorValue.uintValue == o.borderColorValue.uintValue && + borderColorType == o.borderColorType && unnormalized == o.unnormalized && compareFunction == o.compareFunction && filter == o.filter && maxAnisotropy == o.maxAnisotropy && maxLOD == o.maxLOD && minLOD == o.minLOD && mipLODBias == o.mipLODBias; @@ -349,8 +351,12 @@ struct Sampler return addressV < o.addressV; if(!(addressW == o.addressW)) return addressW < o.addressW; - if(!(borderColor == o.borderColor)) - return borderColor < o.borderColor; + if(!(borderColorValue.uintValue == o.borderColorValue.uintValue)) + return borderColorValue.uintValue < o.borderColorValue.uintValue; + if(!(borderColorType == o.borderColorType)) + return borderColorType < o.borderColorType; + if(!(unnormalized == o.unnormalized)) + return unnormalized < o.unnormalized; if(!(compareFunction == o.compareFunction)) return compareFunction < o.compareFunction; if(!(filter == o.filter)) @@ -376,11 +382,20 @@ struct Sampler AddressMode addressV = AddressMode::Wrap; DOCUMENT("The :class:`AddressMode` in the W direction."); AddressMode addressW = AddressMode::Wrap; - DOCUMENT(R"(The RGBA border color. + DOCUMENT(R"(For samplers - the RGBA border color value. Typically the float tuple inside will be used, +but the exact component type can be checked with :data:`borderColorType`. -:type: Tuple[float,float,float,float] +:type: PixelValue )"); - rdcfixedarray borderColor = {0.0f, 0.0f, 0.0f, 0.0f}; + PixelValue borderColorValue = {}; + DOCUMENT(R"(For samplers - the RGBA border color type. This determines how the data in +:data:`borderColorValue` will be interpreted. + +:type: CompType +)"); + CompType borderColorType = CompType::Float; + DOCUMENT("``True`` if unnormalized co-ordinates are used in this sampler."); + bool unnormalized = false; DOCUMENT("The :class:`CompareFunction` for comparison samplers."); CompareFunction compareFunction = CompareFunction::AlwaysTrue; DOCUMENT(R"(The filtering mode. diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 67e5bd03d..c44681d01 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -47,7 +47,8 @@ struct BindingElement filter == o.filter && addressU == o.addressU && addressV == o.addressV && addressW == o.addressW && mipBias == o.mipBias && maxAnisotropy == o.maxAnisotropy && compareFunction == o.compareFunction && minLOD == o.minLOD && maxLOD == o.maxLOD && - borderColor == o.borderColor && unnormalized == o.unnormalized && + borderColorValue.uintValue == o.borderColorValue.uintValue && + borderColorType == o.borderColorType && unnormalized == o.unnormalized && srgbBorder == o.srgbBorder && seamless == o.seamless; } bool operator<(const BindingElement &o) const @@ -100,8 +101,10 @@ struct BindingElement return minLOD < o.minLOD; if(!(maxLOD == o.maxLOD)) return maxLOD < o.maxLOD; - if(!(borderColor == o.borderColor)) - return borderColor < o.borderColor; + if(!(borderColorValue.uintValue == o.borderColorValue.uintValue)) + return borderColorValue.uintValue < o.borderColorValue.uintValue; + if(!(borderColorType == o.borderColorType)) + return borderColorType < o.borderColorType; if(!(unnormalized == o.unnormalized)) return unnormalized < o.unnormalized; if(!(srgbBorder == o.srgbBorder)) @@ -183,11 +186,18 @@ set's inline block data. float minLOD = 0.0f; DOCUMENT("For samplers - the maximum mip level that can be used."); float maxLOD = 0.0f; - DOCUMENT(R"(For samplers - the RGBA border color. + DOCUMENT(R"(For samplers - the RGBA border color value. Typically the float tuple inside will be used, +but the exact component type can be checked with :data:`borderColorType`. -:type: Tuple[float,float,float,float] +:type: PixelValue )"); - rdcfixedarray borderColor = {0.0f, 0.0f, 0.0f, 0.0f}; + PixelValue borderColorValue = {}; + DOCUMENT(R"(For samplers - the RGBA border color type. This determines how the data in +:data:`borderColorValue` will be interpreted. + +:type: CompType +)"); + CompType borderColorType = CompType::Float; DOCUMENT(R"(The swizzle applied to samplers. Primarily for ycbcr samplers applied before conversion but for non-ycbcr samplers can be used for implementations that require sampler swizzle information for border colors. diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index ff32ca7b8..fd36f30ac 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -686,6 +686,7 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::Device_CreateRenderTargetView: case D3D12Chunk::Device_CreateDepthStencilView: case D3D12Chunk::Device_CreateSampler: + case D3D12Chunk::Device_CreateSampler2: ret = m_pDevice->Serialise_DynamicDescriptorWrite(ser, NULL); break; case D3D12Chunk::Device_CopyDescriptors: @@ -947,7 +948,6 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::Device_CreateCommittedResource2: case D3D12Chunk::Device_CreatePlacedResource1: case D3D12Chunk::Device_CreateCommandQueue1: - case D3D12Chunk::Device_CreateSampler2: case D3D12Chunk::Device_CreateCommittedResource3: case D3D12Chunk::Device_CreatePlacedResource2: case D3D12Chunk::Device_CreateReservedResource1: diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index 50869bab5..f420ba539 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -239,6 +239,11 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver) if(ver == 0xD) return true; + // 0xE -> 0xF - Sampler descriptors are now serialised as D3D12_SAMPLER_DESC2 in a backwards + // compatible manner + if(ver == 0xE) + return true; + return false; } diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 959a524bb..9ddb7ee98 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -353,7 +353,7 @@ struct D3D12RootSignature D3D12_ROOT_SIGNATURE_FLAGS Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; rdcarray Parameters; - rdcarray StaticSamplers; + rdcarray StaticSamplers; }; DECLARE_REFLECTION_STRUCT(D3D12RootSignature); @@ -671,6 +671,7 @@ DECLARE_REFLECTION_ENUM(D3D12_SHADING_RATE_COMBINER); DECLARE_REFLECTION_ENUM(D3D12_ROOT_SIGNATURE_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_ROOT_PARAMETER_TYPE); DECLARE_REFLECTION_ENUM(D3D12_ROOT_DESCRIPTOR_FLAGS); +DECLARE_REFLECTION_ENUM(D3D12_SAMPLER_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_SHADER_VISIBILITY); DECLARE_REFLECTION_ENUM(D3D12_STATIC_BORDER_COLOR); DECLARE_REFLECTION_ENUM(D3D12_DESCRIPTOR_RANGE_TYPE); @@ -708,6 +709,7 @@ DECLARE_REFLECTION_STRUCT(D3D12_INDIRECT_ARGUMENT_DESC); DECLARE_REFLECTION_STRUCT(D3D12_COMMAND_SIGNATURE_DESC); DECLARE_REFLECTION_STRUCT(D3D12_QUERY_HEAP_DESC); DECLARE_REFLECTION_STRUCT(D3D12_SAMPLER_DESC); +DECLARE_REFLECTION_STRUCT(D3D12_SAMPLER_DESC2); DECLARE_REFLECTION_STRUCT(D3D12_CONSTANT_BUFFER_VIEW_DESC); DECLARE_REFLECTION_STRUCT(D3D12_BUFFER_SRV); DECLARE_REFLECTION_STRUCT(D3D12_TEX1D_SRV); @@ -776,6 +778,7 @@ DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_ENDING_ACCESS); DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_RENDER_TARGET_DESC); DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_DEPTH_STENCIL_DESC); DECLARE_REFLECTION_STRUCT(D3D12_STATIC_SAMPLER_DESC); +DECLARE_REFLECTION_STRUCT(D3D12_STATIC_SAMPLER_DESC1); DECLARE_REFLECTION_STRUCT(D3D12_DESCRIPTOR_RANGE1); DECLARE_REFLECTION_STRUCT(D3D12_ROOT_DESCRIPTOR_TABLE1); DECLARE_REFLECTION_STRUCT(D3D12_ROOT_CONSTANTS); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 219c04582..b9d298b0f 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -54,7 +54,7 @@ struct D3D12InitParams UINT SDKVersion = 0; // check if a frame capture section version is supported - static const uint64_t CurrentVersion = 0xE; + static const uint64_t CurrentVersion = 0xF; static bool IsSupportedVersion(uint64_t ver); }; diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap11.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap11.cpp index cd6d388a4..fe7f4a9dd 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap11.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap11.cpp @@ -27,7 +27,34 @@ #include "d3d12_command_queue.h" #include "d3d12_resources.h" -void WrappedID3D12Device::CreateSampler2(_In_ const D3D12_SAMPLER_DESC2 *pDesc, - _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +void WrappedID3D12Device::CreateSampler2(const D3D12_SAMPLER_DESC2 *pDesc, + D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) { + bool capframe = false; + + { + SCOPED_READLOCK(m_CapTransitionLock); + capframe = IsActiveCapturing(m_State); + } + + SERIALISE_TIME_CALL(m_pDevice11->CreateSampler2(pDesc, Unwrap(DestDescriptor))); + + // assume descriptors are volatile + if(capframe) + { + DynamicDescriptorWrite write; + write.desc.Init(pDesc); + write.dest = GetWrapped(DestDescriptor); + + { + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateSampler2); + Serialise_DynamicDescriptorWrite(ser, &write); + + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + } + + GetWrapped(DestDescriptor)->Init(pDesc); } diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 1ebf553f1..16e3c6cc2 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -30,14 +30,39 @@ #include "d3d12_device.h" #include "d3d12_resources.h" -void D3D12Descriptor::Init(const D3D12_SAMPLER_DESC *pDesc) +void D3D12Descriptor::Init(const D3D12_SAMPLER_DESC2 *pDesc) { if(pDesc) - data.samp.desc = *pDesc; + data.samp.desc.Init(*pDesc); else RDCEraseEl(data.samp.desc); } +void D3D12Descriptor::Init(const D3D12_SAMPLER_DESC *pDesc) +{ + if(!pDesc) + { + RDCEraseEl(data.samp.desc); + return; + } + + D3D12_SAMPLER_DESC2 desc; + desc.Filter = pDesc->Filter; + desc.Filter = pDesc->Filter; + desc.AddressU = pDesc->AddressU; + desc.AddressV = pDesc->AddressV; + desc.AddressW = pDesc->AddressW; + desc.ComparisonFunc = pDesc->ComparisonFunc; + desc.MipLODBias = pDesc->MipLODBias; + desc.MaxAnisotropy = pDesc->MaxAnisotropy; + memcpy(desc.UintBorderColor, pDesc->BorderColor, sizeof(desc.UintBorderColor)); + desc.MinLOD = pDesc->MinLOD; + desc.MaxLOD = pDesc->MaxLOD; + desc.Flags = D3D12_SAMPLER_FLAG_NONE; + + data.samp.desc.Init(desc); +} + void D3D12Descriptor::Init(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc) { data.nonsamp.type = D3D12DescriptorType::CBV; @@ -146,7 +171,17 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D { case D3D12DescriptorType::Sampler: { - dev->CreateSampler(&data.samp.desc, handle); + D3D12_SAMPLER_DESC2 desc = data.samp.desc.AsDesc(); + if(desc.Flags == D3D12_SAMPLER_FLAG_NONE) + { + D3D12_SAMPLER_DESC desc1; + memcpy(&desc1, &desc, sizeof(desc1)); + dev->CreateSampler(&desc1, handle); + } + else + { + dev->CreateSampler2(&desc, handle); + } break; } case D3D12DescriptorType::CBV: diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 81ee691ed..173e5e7d5 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -215,6 +215,59 @@ struct PortableHandle DECLARE_REFLECTION_STRUCT(PortableHandle); +struct D3D12_SAMPLER_DESC_SQUEEZED +{ + // this filter must be first and the same size, since we alias it for the descriptor type + D3D12_FILTER Filter; + + // we just save the enums in a byte since they'll never be larger + uint8_t AddressU; + uint8_t AddressV; + uint8_t AddressW; + uint8_t ComparisonFunc; + FLOAT MipLODBias; + UINT MaxAnisotropy; + // just copy as uint + FLOAT UintBorderColor[4]; + FLOAT MinLOD; + FLOAT MaxLOD; + D3D12_SAMPLER_FLAGS Flags; + + void Init(const D3D12_SAMPLER_DESC2 &desc) + { + Filter = desc.Filter; + AddressU = uint8_t(desc.AddressU); + AddressV = uint8_t(desc.AddressV); + AddressW = uint8_t(desc.AddressW); + ComparisonFunc = uint8_t(desc.ComparisonFunc); + MipLODBias = desc.MipLODBias; + MaxAnisotropy = desc.MaxAnisotropy; + memcpy(UintBorderColor, desc.UintBorderColor, sizeof(UintBorderColor)); + MinLOD = desc.MinLOD; + MaxLOD = desc.MaxLOD; + Flags = desc.Flags; + } + + D3D12_SAMPLER_DESC2 AsDesc() const + { + D3D12_SAMPLER_DESC2 desc = {}; + + desc.Filter = Filter; + desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE(AddressU); + desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE(AddressV); + desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE(AddressW); + desc.ComparisonFunc = D3D12_COMPARISON_FUNC(ComparisonFunc); + desc.MipLODBias = MipLODBias; + desc.MaxAnisotropy = MaxAnisotropy; + memcpy(desc.UintBorderColor, UintBorderColor, sizeof(UintBorderColor)); + desc.MinLOD = MinLOD; + desc.MaxLOD = MaxLOD; + desc.Flags = Flags; + + return desc; + } +}; + // the heap pointer & index are inside the data structs, because in the sampler case we don't need // to pad up for any alignment, and in the non-sampler case we declare the type before uint64/ptr // aligned elements come, so we don't get any padding waste. @@ -224,7 +277,7 @@ struct SamplerDescriptorData WrappedID3D12DescriptorHeap *heap; uint32_t idx; - D3D12_SAMPLER_DESC desc; + D3D12_SAMPLER_DESC_SQUEEZED desc; }; struct NonSamplerDescriptorData @@ -317,6 +370,7 @@ public: return handle; } + void Init(const D3D12_SAMPLER_DESC2 *pDesc); void Init(const D3D12_SAMPLER_DESC *pDesc); void Init(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc); void Init(ID3D12Resource *pResource, const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc); @@ -351,11 +405,11 @@ public: // Accessors for descriptor structs. The squeezed structs return only by value, others have const // reference returns - const D3D12_SAMPLER_DESC &GetSampler() const { return data.samp.desc; } const D3D12_RENDER_TARGET_VIEW_DESC &GetRTV() const { return data.nonsamp.rtv; } const D3D12_DEPTH_STENCIL_VIEW_DESC &GetDSV() const { return data.nonsamp.dsv; } const D3D12_CONSTANT_BUFFER_VIEW_DESC &GetCBV() const { return data.nonsamp.cbv; } // squeezed descriptors + D3D12_SAMPLER_DESC2 GetSampler() const { return data.samp.desc.AsDesc(); } D3D12_UNORDERED_ACCESS_VIEW_DESC GetUAV() const { return data.nonsamp.uav.AsDesc(); } D3D12_SHADER_RESOURCE_VIEW_DESC GetSRV() const { return data.nonsamp.srv.AsDesc(); } private: diff --git a/renderdoc/driver/d3d12/d3d12_rendertext.cpp b/renderdoc/driver/d3d12/d3d12_rendertext.cpp index 468d50444..a78706be7 100644 --- a/renderdoc/driver/d3d12/d3d12_rendertext.cpp +++ b/renderdoc/driver/d3d12/d3d12_rendertext.cpp @@ -325,13 +325,13 @@ D3D12TextRenderer::D3D12TextRenderer(WrappedID3D12Device *wrapper) D3D12ShaderCache *shaderCache = wrapper->GetShaderCache(); - const D3D12_STATIC_SAMPLER_DESC samplers[2] = { + const D3D12_STATIC_SAMPLER_DESC1 samplers[2] = { // point { D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.0f, 1, D3D12_COMPARISON_FUNC_ALWAYS, D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK, 0.0f, FLT_MAX, 0, 0, - D3D12_SHADER_VISIBILITY_PIXEL, + D3D12_SHADER_VISIBILITY_PIXEL, D3D12_SAMPLER_FLAG_NONE, }, // linear @@ -339,7 +339,7 @@ D3D12TextRenderer::D3D12TextRenderer(WrappedID3D12Device *wrapper) D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, 0.0f, 1, D3D12_COMPARISON_FUNC_ALWAYS, D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK, 0.0f, FLT_MAX, 1, 0, - D3D12_SHADER_VISIBILITY_PIXEL, + D3D12_SHADER_VISIBILITY_PIXEL, D3D12_SAMPLER_FLAG_NONE, }, }; diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 95e9e1357..bb6311817 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -985,13 +985,18 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor desc->GetHeap()->SetToViewCache(desc->GetHeapIndex(), view); } -void D3D12Replay::FillSampler(D3D12Pipe::Sampler &samp, const D3D12_SAMPLER_DESC &sampDesc) +void D3D12Replay::FillSampler(D3D12Pipe::Sampler &samp, const D3D12_SAMPLER_DESC2 &sampDesc) { samp.addressU = MakeAddressMode(sampDesc.AddressU); samp.addressV = MakeAddressMode(sampDesc.AddressV); samp.addressW = MakeAddressMode(sampDesc.AddressW); - samp.borderColor = sampDesc.BorderColor; + samp.borderColorValue.uintValue = sampDesc.UintBorderColor; + samp.borderColorType = + ((sampDesc.Flags & D3D12_SAMPLER_FLAG_UINT_BORDER_COLOR) != 0 ? CompType::UInt + : CompType::Float); + + samp.unnormalized = (sampDesc.Flags & D3D12_SAMPLER_FLAG_NON_NORMALIZED_COORDINATES) != 0; samp.compareFunction = MakeCompareFunc(sampDesc.ComparisonFunc); samp.filter = MakeFilter(sampDesc.Filter); @@ -1316,7 +1321,7 @@ void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::Roo if(desc) { - const D3D12_SAMPLER_DESC &sampDesc = desc->GetSampler(); + const D3D12_SAMPLER_DESC2 &sampDesc = desc->GetSampler(); FillSampler(samp, sampDesc); desc++; } @@ -1482,7 +1487,7 @@ void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::Roo desc += curUsage->descIndex; element->samplers.push_back(D3D12Pipe::Sampler()); D3D12Pipe::Sampler &samp = element->samplers.back(); - const D3D12_SAMPLER_DESC &sampDesc = desc->GetSampler(); + const D3D12_SAMPLER_DESC2 &sampDesc = desc->GetSampler(); FillSampler(samp, sampDesc); samp.tableIndex = curUsage->descIndex; element->dynamicallyUsedCount++; @@ -1539,7 +1544,7 @@ void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::Roo // Each static sampler gets its own RootElement for(size_t i = 0; i < sig->sig.StaticSamplers.size(); i++) { - D3D12_STATIC_SAMPLER_DESC &sampDesc = sig->sig.StaticSamplers[i]; + D3D12_STATIC_SAMPLER_DESC1 &sampDesc = sig->sig.StaticSamplers[i]; rootElements.resize_for_index(ridx); D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; @@ -1560,32 +1565,52 @@ void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::Roo samp.addressV = MakeAddressMode(sampDesc.AddressV); samp.addressW = MakeAddressMode(sampDesc.AddressW); + samp.borderColorType = CompType::Float; + if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK) { - samp.borderColor[0] = 0.0f; - samp.borderColor[1] = 0.0f; - samp.borderColor[2] = 0.0f; - samp.borderColor[3] = 0.0f; + samp.borderColorValue.floatValue[0] = 0.0f; + samp.borderColorValue.floatValue[1] = 0.0f; + samp.borderColorValue.floatValue[2] = 0.0f; + samp.borderColorValue.floatValue[3] = 0.0f; } else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK) { - samp.borderColor[0] = 0.0f; - samp.borderColor[1] = 0.0f; - samp.borderColor[2] = 0.0f; - samp.borderColor[3] = 1.0f; + samp.borderColorValue.floatValue[0] = 0.0f; + samp.borderColorValue.floatValue[1] = 0.0f; + samp.borderColorValue.floatValue[2] = 0.0f; + samp.borderColorValue.floatValue[3] = 1.0f; } else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE) { - samp.borderColor[0] = 1.0f; - samp.borderColor[1] = 1.0f; - samp.borderColor[2] = 1.0f; - samp.borderColor[3] = 1.0f; + samp.borderColorValue.floatValue[0] = 1.0f; + samp.borderColorValue.floatValue[1] = 1.0f; + samp.borderColorValue.floatValue[2] = 1.0f; + samp.borderColorValue.floatValue[3] = 1.0f; + } + else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT) + { + samp.borderColorValue.uintValue[0] = 0; + samp.borderColorValue.uintValue[1] = 0; + samp.borderColorValue.uintValue[2] = 0; + samp.borderColorValue.uintValue[3] = 1; + samp.borderColorType = CompType::UInt; + } + else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT) + { + samp.borderColorValue.uintValue[0] = 1; + samp.borderColorValue.uintValue[1] = 1; + samp.borderColorValue.uintValue[2] = 1; + samp.borderColorValue.uintValue[3] = 1; + samp.borderColorType = CompType::UInt; } else { RDCERR("Unexpected static border colour: %u", sampDesc.BorderColor); } + samp.unnormalized = (sampDesc.Flags & D3D12_SAMPLER_FLAG_NON_NORMALIZED_COORDINATES) != 0; + samp.compareFunction = MakeCompareFunc(sampDesc.ComparisonFunc); samp.filter = MakeFilter(sampDesc.Filter); samp.maxAnisotropy = 0; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 4305efd84..884e6dd9c 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -264,7 +264,7 @@ private: const ShaderBindpointMapping *mappings[(uint32_t)ShaderStage::Count], rdcarray &rootElements); void FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor *desc); - void FillSampler(D3D12Pipe::Sampler &view, const D3D12_SAMPLER_DESC &desc); + void FillSampler(D3D12Pipe::Sampler &view, const D3D12_SAMPLER_DESC2 &desc); bool CreateSOBuffers(); void ClearPostVSCache(); diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index 66d8ba563..e73189fb2 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -174,6 +174,25 @@ void DoSerialise(SerialiserType &ser, D3D12_STATIC_SAMPLER_DESC &el) SERIALISE_MEMBER(ShaderVisibility); } +template +void DoSerialise(SerialiserType &ser, D3D12_STATIC_SAMPLER_DESC1 &el) +{ + SERIALISE_MEMBER(Filter); + SERIALISE_MEMBER(AddressU); + SERIALISE_MEMBER(AddressV); + SERIALISE_MEMBER(AddressW); + SERIALISE_MEMBER(MipLODBias); + SERIALISE_MEMBER(MaxAnisotropy); + SERIALISE_MEMBER(ComparisonFunc); + SERIALISE_MEMBER(BorderColor); + SERIALISE_MEMBER(MinLOD); + SERIALISE_MEMBER(MaxLOD); + SERIALISE_MEMBER(ShaderRegister); + SERIALISE_MEMBER(RegisterSpace); + SERIALISE_MEMBER(ShaderVisibility); + SERIALISE_MEMBER(Flags); +} + template void DoSerialise(SerialiserType &ser, D3D12RootSignatureParameter &el) { @@ -363,7 +382,13 @@ void DoSerialise(SerialiserType &ser, D3D12Descriptor &el) { case D3D12DescriptorType::Sampler: { - ser.Serialise("Descriptor"_lit, el.data.samp.desc); + // special case because of squeezed descriptor + D3D12_SAMPLER_DESC2 desc; + if(ser.IsWriting() || ser.IsStructurising()) + desc = el.data.samp.desc.AsDesc(); + ser.Serialise("Descriptor"_lit, desc); + if(ser.IsReading() && !ser.IsStructurising()) + el.data.samp.desc.Init(desc); RDCASSERTEQUAL(el.GetType(), D3D12DescriptorType::Sampler); break; } @@ -1392,8 +1417,13 @@ void DoSerialise(SerialiserType &ser, D3D12_BOX &el) SERIALISE_MEMBER(back); } +// deliberately do not serialise D3D12_SAMPLER_DESC +// for ease of compatibility we serialise D3D12_SAMPLER_DESC2 here and use serialise versioning to +// detect old captures where the fields did not exist +// in descriptors where this is referenced, we unconditionally serialise the new version + template -void DoSerialise(SerialiserType &ser, D3D12_SAMPLER_DESC &el) +void DoSerialise(SerialiserType &ser, D3D12_SAMPLER_DESC2 &el) { SERIALISE_MEMBER(Filter).Important(); SERIALISE_MEMBER(AddressU); @@ -1402,9 +1432,21 @@ void DoSerialise(SerialiserType &ser, D3D12_SAMPLER_DESC &el) SERIALISE_MEMBER(MipLODBias); SERIALISE_MEMBER(MaxAnisotropy); SERIALISE_MEMBER(ComparisonFunc); - SERIALISE_MEMBER(BorderColor); + // serialise as floats since that is the most common case. It's also compatible with + // D3D12_SAMPLER_DESC + // since the flags come later in struct order, we can't do anything clever to serialise by that + // type + SERIALISE_MEMBER(FloatBorderColor); SERIALISE_MEMBER(MinLOD); SERIALISE_MEMBER(MaxLOD); + if(ser.VersionAtLeast(0xF)) + { + SERIALISE_MEMBER(Flags); + } + else + { + el.Flags = D3D12_SAMPLER_FLAG_NONE; + } } template @@ -1626,7 +1668,7 @@ INSTANTIATE_SERIALISE_TYPE(D3D12_DESCRIPTOR_HEAP_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_INDIRECT_ARGUMENT_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_COMMAND_SIGNATURE_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_QUERY_HEAP_DESC); -INSTANTIATE_SERIALISE_TYPE(D3D12_SAMPLER_DESC); +INSTANTIATE_SERIALISE_TYPE(D3D12_SAMPLER_DESC2); INSTANTIATE_SERIALISE_TYPE(D3D12_CONSTANT_BUFFER_VIEW_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_SHADER_RESOURCE_VIEW_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_RENDER_TARGET_VIEW_DESC); diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp index afeb6552e..40d05815d 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp @@ -602,10 +602,13 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz if(desc->NumStaticSamplers > 0) { - ret.StaticSamplers.assign(desc->pStaticSamplers, desc->NumStaticSamplers); + ret.StaticSamplers.resize(desc->NumStaticSamplers); for(size_t i = 0; i < ret.StaticSamplers.size(); i++) + { + ret.StaticSamplers[i] = Upconvert(desc->pStaticSamplers[i]); ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.StaticSamplers[i].RegisterSpace + 1); + } } SAFE_RELEASE(deser); @@ -626,8 +629,15 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz D3D12RootSignature ret; + uint32_t version = 12; const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *verdesc = NULL; - hr = deser->GetRootSignatureDescAtVersion(D3D_ROOT_SIGNATURE_VERSION_1_1, &verdesc); + hr = deser->GetRootSignatureDescAtVersion(D3D_ROOT_SIGNATURE_VERSION_1_2, &verdesc); + if(FAILED(hr)) + { + version = 11; + hr = deser->GetRootSignatureDescAtVersion(D3D_ROOT_SIGNATURE_VERSION_1_1, &verdesc); + } + if(FAILED(hr)) { SAFE_RELEASE(deser); @@ -660,10 +670,24 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz if(desc->NumStaticSamplers > 0) { - ret.StaticSamplers.assign(desc->pStaticSamplers, desc->NumStaticSamplers); + if(version >= 12) + { + ret.StaticSamplers.assign(verdesc->Desc_1_2.pStaticSamplers, + verdesc->Desc_1_2.NumStaticSamplers); - for(size_t i = 0; i < ret.StaticSamplers.size(); i++) - ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.StaticSamplers[i].RegisterSpace + 1); + for(size_t i = 0; i < ret.StaticSamplers.size(); i++) + ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.StaticSamplers[i].RegisterSpace + 1); + } + else + { + ret.StaticSamplers.resize(desc->NumStaticSamplers); + + for(size_t i = 0; i < ret.StaticSamplers.size(); i++) + { + ret.StaticSamplers[i] = Upconvert(desc->pStaticSamplers[i]); + ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.StaticSamplers[i].RegisterSpace + 1); + } + } } SAFE_RELEASE(deser); @@ -673,7 +697,7 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray ¶ms, D3D12_ROOT_SIGNATURE_FLAGS Flags, UINT NumStaticSamplers, - const D3D12_STATIC_SAMPLER_DESC *StaticSamplers) + const D3D12_STATIC_SAMPLER_DESC1 *StaticSamplers) { PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE serializeRootSig = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)GetProcAddress( @@ -693,10 +717,15 @@ ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray &p return NULL; } + rdcarray oldSamplers; + oldSamplers.resize(NumStaticSamplers); + for(size_t i = 0; i < oldSamplers.size(); i++) + oldSamplers[i] = Downconvert(StaticSamplers[i]); + D3D12_ROOT_SIGNATURE_DESC desc; desc.Flags = Flags; desc.NumStaticSamplers = NumStaticSamplers; - desc.pStaticSamplers = StaticSamplers; + desc.pStaticSamplers = oldSamplers.data(); desc.NumParameters = (UINT)params.size(); rdcarray params_1_0; @@ -776,18 +805,33 @@ ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray &p } D3D12_VERSIONED_ROOT_SIGNATURE_DESC verdesc; - verdesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + verdesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_2; - D3D12_ROOT_SIGNATURE_DESC1 &desc = verdesc.Desc_1_1; - desc.Flags = Flags; - desc.NumStaticSamplers = NumStaticSamplers; - desc.pStaticSamplers = StaticSamplers; - desc.NumParameters = (UINT)params.size(); - desc.pParameters = ¶ms[0]; + D3D12_ROOT_SIGNATURE_DESC2 &desc12 = verdesc.Desc_1_2; + desc12.Flags = Flags; + desc12.NumStaticSamplers = NumStaticSamplers; + desc12.pStaticSamplers = StaticSamplers; + desc12.NumParameters = (UINT)params.size(); + desc12.pParameters = ¶ms[0]; ID3DBlob *ret = NULL; ID3DBlob *errBlob = NULL; HRESULT hr = serializeRootSig(&verdesc, &ret, &errBlob); + SAFE_RELEASE(errBlob); + + if(SUCCEEDED(hr)) + return ret; + + // if it failed, try again at version 1.1 + verdesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + D3D12_ROOT_SIGNATURE_DESC1 &desc11 = verdesc.Desc_1_1; + rdcarray oldSamplers; + oldSamplers.resize(NumStaticSamplers); + for(size_t i = 0; i < oldSamplers.size(); i++) + oldSamplers[i] = Downconvert(StaticSamplers[i]); + desc11.pStaticSamplers = oldSamplers.data(); + + hr = serializeRootSig(&verdesc, &ret, &errBlob); if(FAILED(hr)) { @@ -859,3 +903,24 @@ void D3D12ShaderCache::LoadDXC() { GetDXC(); } + +D3D12_STATIC_SAMPLER_DESC1 D3D12ShaderCache::Upconvert(const D3D12_STATIC_SAMPLER_DESC &StaticSampler) +{ + D3D12_STATIC_SAMPLER_DESC1 ret; + memcpy(&ret, &StaticSampler, sizeof(StaticSampler)); + ret.Flags = D3D12_SAMPLER_FLAG_NONE; + return ret; +} + +D3D12_STATIC_SAMPLER_DESC D3D12ShaderCache::Downconvert(const D3D12_STATIC_SAMPLER_DESC1 &StaticSampler) +{ + D3D12_STATIC_SAMPLER_DESC ret; + memcpy(&ret, &StaticSampler, sizeof(ret)); + if(StaticSampler.Flags != 0) + RDCWARN("Downconverting sampler with advanced features set"); + if(ret.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT) + ret.BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT; + else if(ret.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT) + ret.BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT; + return ret; +} diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.h b/renderdoc/driver/d3d12/d3d12_shader_cache.h index 7c730831b..008ac8e6e 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.h +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.h @@ -45,7 +45,7 @@ public: ID3DBlob *MakeRootSig(const rdcarray ¶ms, D3D12_ROOT_SIGNATURE_FLAGS Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE, UINT NumStaticSamplers = 0, - const D3D12_STATIC_SAMPLER_DESC *StaticSamplers = NULL); + const D3D12_STATIC_SAMPLER_DESC1 *StaticSamplers = NULL); ID3DBlob *MakeRootSig(const D3D12RootSignature &rootsig); // must match the values in fixedcol.hlsl @@ -70,4 +70,7 @@ private: bool m_ShaderCacheDirty = false, m_CacheShaders = false; std::map m_ShaderCache; + + D3D12_STATIC_SAMPLER_DESC1 Upconvert(const D3D12_STATIC_SAMPLER_DESC &StaticSampler); + D3D12_STATIC_SAMPLER_DESC Downconvert(const D3D12_STATIC_SAMPLER_DESC1 &StaticSampler); }; diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index a9d420384..dafe65539 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -608,11 +608,11 @@ D3D12Descriptor D3D12DebugAPIWrapper::FindDescriptor(DXBCBytecode::OperandType t if(searchRangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) { - for(const D3D12_STATIC_SAMPLER_DESC &samp : pD3D12RootSig->sig.StaticSamplers) + for(const D3D12_STATIC_SAMPLER_DESC1 &samp : pD3D12RootSig->sig.StaticSamplers) { if(samp.RegisterSpace == slot.registerSpace && samp.ShaderRegister == slot.shaderRegister) { - D3D12_SAMPLER_DESC desc; + D3D12_SAMPLER_DESC2 desc; desc.Filter = samp.Filter; desc.AddressU = samp.AddressU; @@ -625,20 +625,29 @@ D3D12Descriptor D3D12DebugAPIWrapper::FindDescriptor(DXBCBytecode::OperandType t { default: case D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK: - desc.BorderColor[0] = desc.BorderColor[1] = desc.BorderColor[2] = - desc.BorderColor[3] = 0.0f; + desc.FloatBorderColor[0] = desc.FloatBorderColor[1] = desc.FloatBorderColor[2] = + desc.FloatBorderColor[3] = 0.0f; break; case D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK: - desc.BorderColor[0] = desc.BorderColor[1] = desc.BorderColor[2] = 0.0f; - desc.BorderColor[3] = 1.0f; + desc.FloatBorderColor[0] = desc.FloatBorderColor[1] = desc.FloatBorderColor[2] = 0.0f; + desc.FloatBorderColor[3] = 1.0f; break; case D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE: - desc.BorderColor[0] = desc.BorderColor[1] = desc.BorderColor[2] = - desc.BorderColor[3] = 1.0f; + desc.FloatBorderColor[0] = desc.FloatBorderColor[1] = desc.FloatBorderColor[2] = + desc.FloatBorderColor[3] = 1.0f; + break; + case D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT: + desc.UintBorderColor[0] = desc.UintBorderColor[1] = desc.UintBorderColor[2] = 0; + desc.UintBorderColor[3] = 1; + break; + case D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT: + desc.UintBorderColor[0] = desc.UintBorderColor[1] = desc.UintBorderColor[2] = + desc.UintBorderColor[3] = 1; break; } desc.MinLOD = samp.MinLOD; desc.MaxLOD = samp.MaxLOD; + desc.Flags = samp.Flags; descriptor.Init(&desc); return descriptor; diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index 3b290b690..51d7031f1 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -1269,3 +1269,16 @@ rdcstr DoStringise(const D3D12_DESCRIPTOR_RANGE_FLAGS &el) } END_BITFIELD_STRINGISE(); } + +template <> +rdcstr DoStringise(const D3D12_SAMPLER_FLAGS &el) +{ + BEGIN_BITFIELD_STRINGISE(D3D12_SAMPLER_FLAGS); + { + STRINGISE_BITFIELD_VALUE(D3D12_SAMPLER_FLAG_NONE) + + STRINGISE_BITFIELD_BIT(D3D12_SAMPLER_FLAG_UINT_BORDER_COLOR) + STRINGISE_BITFIELD_BIT(D3D12_SAMPLER_FLAG_NON_NORMALIZED_COORDINATES) + } + END_BITFIELD_STRINGISE(); +} diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index dfd1ce858..4df28800a 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2092,7 +2092,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) el.compareFunction = MakeCompareFunc(sampl.compareOp); el.minLOD = sampl.minLod; el.maxLOD = sampl.maxLod; - MakeBorderColor(sampl.borderColor, el.borderColor); + MakeBorderColor(sampl.borderColor, el.borderColorValue.floatValue); + el.borderColorType = CompType::Float; el.unnormalized = sampl.unnormalizedCoordinates; el.seamless = sampl.seamless; @@ -2119,12 +2120,12 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) { if(sampl.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT) { - for(int bord = 0; bord < 4; bord++) - el.borderColor[bord] = float(sampl.customBorderColor.int32[bord]); + el.borderColorValue.uintValue = sampl.customBorderColor.uint32; + el.borderColorType = CompType::UInt; } else { - el.borderColor = sampl.customBorderColor.float32; + el.borderColorValue.floatValue = sampl.customBorderColor.float32; } } } diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 69f037651..1ba30421c 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -1436,7 +1436,9 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::Sampler &el) SERIALISE_MEMBER(addressU); SERIALISE_MEMBER(addressV); SERIALISE_MEMBER(addressW); - SERIALISE_MEMBER(borderColor); + SERIALISE_MEMBER(borderColorValue); + SERIALISE_MEMBER(borderColorType); + SERIALISE_MEMBER(unnormalized); SERIALISE_MEMBER(compareFunction); SERIALISE_MEMBER(filter); SERIALISE_MEMBER(maxAnisotropy); @@ -1444,7 +1446,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::Sampler &el) SERIALISE_MEMBER(minLOD); SERIALISE_MEMBER(mipLODBias); - SIZE_CHECK(72); + SIZE_CHECK(76); } template @@ -1949,7 +1951,8 @@ void DoSerialise(SerialiserType &ser, VKPipe::BindingElement &el) SERIALISE_MEMBER(compareFunction); SERIALISE_MEMBER(minLOD); SERIALISE_MEMBER(maxLOD); - SERIALISE_MEMBER(borderColor); + SERIALISE_MEMBER(borderColorValue); + SERIALISE_MEMBER(borderColorType); SERIALISE_MEMBER(samplerSwizzle); SERIALISE_MEMBER(unnormalized); SERIALISE_MEMBER(inlineBlock); @@ -1963,7 +1966,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::BindingElement &el) SERIALISE_MEMBER(chromaFilter); SERIALISE_MEMBER(forceExplicitReconstruction); - SIZE_CHECK(184); + SIZE_CHECK(192); }; template