Implement D3D12's CreateSampler2 and new sampler parameters

This commit is contained in:
baldurk committed 2023-05-19 14:54:39 +01:00
1 parent d3edbc5dd1
commit 28dcc80892
21 files changed
+436 -93

No files matched your search

@@ -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)
@@ -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)");
+21 -6
View File
@@ -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<float, 4> 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.
+16 -6
View File
@@ -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<float, 4> 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.
+1 -1
View File
@@ -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:
+5
View File
@@ -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;
}
+4 -1
View File
@@ -353,7 +353,7 @@ struct D3D12RootSignature
D3D12_ROOT_SIGNATURE_FLAGS Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
rdcarray<D3D12RootSignatureParameter> Parameters;
rdcarray<D3D12_STATIC_SAMPLER_DESC> StaticSamplers;
rdcarray<D3D12_STATIC_SAMPLER_DESC1> 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);
+1 -1
View File
@@ -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);
};
+29 -2
View File
@@ -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);
}
+38 -3
View File
@@ -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:
+56 -2
View File
@@ -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:
+3 -3
View File
@@ -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,
},
};
+42 -17
View File
@@ -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;
+1 -1
View File
@@ -264,7 +264,7 @@ private:
const ShaderBindpointMapping *mappings[(uint32_t)ShaderStage::Count],
rdcarray<D3D12Pipe::RootSignatureRange> &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();
+46 -4
View File
@@ -174,6 +174,25 @@ void DoSerialise(SerialiserType &ser, D3D12_STATIC_SAMPLER_DESC &el)
SERIALISE_MEMBER(ShaderVisibility);
}
template <class SerialiserType>
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 <class SerialiserType>
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 <class SerialiserType>
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 <class SerialiserType>
@@ -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);
+79 -14
View File
@@ -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<D3D12_ROOT_PARAMETER1> &params,
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<D3D12_ROOT_PARAMETER1> &p
return NULL;
}
rdcarray<D3D12_STATIC_SAMPLER_DESC> 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<D3D12_ROOT_PARAMETER> params_1_0;
@@ -776,18 +805,33 @@ ID3DBlob *D3D12ShaderCache::MakeRootSig(const rdcarray<D3D12_ROOT_PARAMETER1> &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 = &params[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 = &params[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<D3D12_STATIC_SAMPLER_DESC> 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;
}
+4 -1
View File
@@ -45,7 +45,7 @@ public:
ID3DBlob *MakeRootSig(const rdcarray<D3D12_ROOT_PARAMETER1> &params,
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<uint32_t, ID3DBlob *> m_ShaderCache;
D3D12_STATIC_SAMPLER_DESC1 Upconvert(const D3D12_STATIC_SAMPLER_DESC &StaticSampler);
D3D12_STATIC_SAMPLER_DESC Downconvert(const D3D12_STATIC_SAMPLER_DESC1 &StaticSampler);
};
+17 -8
View File
@@ -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;
@@ -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();
}
+5 -4
View File
@@ -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;
}
}
}
+7 -4
View File
@@ -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 <typename SerialiserType>
@@ -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 <typename SerialiserType>