Fix UsedSRsMask/UsedUAsMask when binding arrays to the shader

This commit is contained in:
2022-03-22 12:55:13 +01:00
parent d58584e1fd
commit c10cdc3d90
12 changed files with 250 additions and 265 deletions
@@ -151,7 +151,8 @@ namespace
case D3D_SIT_TEXTURE:
case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
for (UINT shift = 0; shift < resDesc.BindCount; shift++)
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
break;
// Unordered Access
@@ -161,7 +162,8 @@ namespace
case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
bindings.UsedUAsMask |= 1 << resDesc.BindPoint;
for (UINT shift = 0; shift < resDesc.BindCount; shift++)
bindings.UsedUAsMask |= 1 << (resDesc.BindPoint + shift);
break;
}
}
@@ -381,13 +381,19 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
// Shader Resource
case D3D_SIT_TEXTURE:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
header.SrDimensions[resDesc.BindPoint] = resDesc.Dimension;
for (UINT shift = 0; shift < resDesc.BindCount; shift++)
{
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
header.SrDimensions[resDesc.BindPoint + shift] = resDesc.Dimension;
}
break;
case D3D_SIT_STRUCTURED:
case D3D_SIT_BYTEADDRESS:
bindings.UsedSRsMask |= 1 << resDesc.BindPoint;
header.SrDimensions[resDesc.BindPoint] = D3D_SRV_DIMENSION_BUFFER;
for (UINT shift = 0; shift < resDesc.BindCount; shift++)
{
bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift);
header.SrDimensions[resDesc.BindPoint + shift] = D3D_SRV_DIMENSION_BUFFER;
}
break;
// Unordered Access
@@ -397,30 +403,10 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
case D3D_SIT_UAV_APPEND_STRUCTURED:
case D3D_SIT_UAV_CONSUME_STRUCTURED:
case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
bindings.UsedUAsMask |= 1 << resDesc.BindPoint;
switch (resDesc.Dimension)
for (UINT shift = 0; shift < resDesc.BindCount; shift++)
{
case D3D_SRV_DIMENSION_BUFFER:
header.UaDimensions[resDesc.BindPoint] = 1; // D3D12_UAV_DIMENSION_BUFFER;
break;
case D3D_SRV_DIMENSION_TEXTURE1D:
header.UaDimensions[resDesc.BindPoint] = 2; // D3D12_UAV_DIMENSION_TEXTURE1D;
break;
case D3D_SRV_DIMENSION_TEXTURE1DARRAY:
header.UaDimensions[resDesc.BindPoint] = 3; // D3D12_UAV_DIMENSION_TEXTURE1DARRAY;
break;
case D3D_SRV_DIMENSION_TEXTURE2D:
header.UaDimensions[resDesc.BindPoint] = 4; // D3D12_UAV_DIMENSION_TEXTURE2D;
break;
case D3D_SRV_DIMENSION_TEXTURE2DARRAY:
header.UaDimensions[resDesc.BindPoint] = 5; // D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
break;
case D3D_SRV_DIMENSION_TEXTURE3D:
header.UaDimensions[resDesc.BindPoint] = 8; // D3D12_UAV_DIMENSION_TEXTURE3D;
break;
default:
LOG(Error, "Unknown UAV resource {2} of type {0} at slot {1}", resDesc.Dimension, resDesc.BindPoint, String(resDesc.Name));
return true;
bindings.UsedUAsMask |= 1 << (resDesc.BindPoint + shift);
header.SrDimensions[resDesc.BindPoint + shift] = (byte)resDesc.Dimension; // D3D_SRV_DIMENSION matches D3D12_UAV_DIMENSION
}
break;
}
@@ -33,7 +33,6 @@ namespace
class Includer : public glslang::TShader::Includer
{
private:
ShaderCompilationContext* _context;
IncludeResult* include(const char* headerName, const char* includerName, int depth) const
@@ -46,14 +45,12 @@ private:
}
public:
Includer(ShaderCompilationContext* context)
{
_context = context;
}
public:
// [glslang::TShader::Include]
IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override
{
@@ -210,6 +207,7 @@ struct Descriptor
int32 Slot;
int32 Binding;
int32 Size;
int32 Count;
SpirvShaderResourceBindingType BindingType;
VkDescriptorType DescriptorType;
SpirvShaderResourceType ResourceType;
@@ -229,7 +227,7 @@ SpirvShaderResourceType GetTextureType(const glslang::TSampler& sampler)
case glslang::EsdCube:
return SpirvShaderResourceType::TextureCube;
default:
CRASH;
CRASH;
return SpirvShaderResourceType::Unknown;
}
}
@@ -244,23 +242,13 @@ bool IsUavType(const glslang::TType& type)
class DescriptorsCollector
{
public:
int32 Images;
int32 Buffers;
int32 DescriptorsCount;
int32 Images = 0;
int32 Buffers = 0;
int32 TexelBuffers = 0;
int32 DescriptorsCount = 0;
Descriptor Descriptors[SpirvShaderDescriptorInfo::MaxDescriptors];
public:
DescriptorsCollector()
{
Images = 0;
Buffers = 0;
DescriptorsCount = 0;
}
public:
Descriptor* Add(glslang::TVarEntryInfo& ent)
{
const glslang::TType& type = ent.symbol->getType();
@@ -374,28 +362,6 @@ public:
}
}
// Get the output info about shader uniforms usage
switch (descriptorType)
{
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Images++;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
Buffers++;
break;
default:
LOG(Warning, "Invalid descriptor type {0} for symbol {1}.", (int32)descriptorType, String(name));
return nullptr;
}
const auto index = DescriptorsCount++;
auto& descriptor = Descriptors[index];
descriptor.Binding = index;
@@ -405,6 +371,32 @@ public:
descriptor.DescriptorType = descriptorType;
descriptor.ResourceType = resourceType;
descriptor.Name = name;
descriptor.Count = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
// Get the output info about shader uniforms usage
switch (descriptorType)
{
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Images += descriptor.Count;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
Buffers += descriptor.Count;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
TexelBuffers += descriptor.Count;
break;
default:
LOG(Warning, "Invalid descriptor type {0} for symbol {1}.", (int32)descriptorType, String(name));
return nullptr;
}
return &descriptor;
}
};
@@ -412,12 +404,10 @@ public:
class MyIoMapResolver : public glslang::TDefaultIoResolverBase
{
private:
int32 _set;
DescriptorsCollector* _collector;
public:
MyIoMapResolver(int32 set, DescriptorsCollector* collector, const glslang::TIntermediate& intermediate)
: TDefaultIoResolverBase(intermediate)
, _set(set)
@@ -426,7 +416,6 @@ public:
}
public:
// [glslang::TDefaultIoResolverBase]
bool validateBinding(EShLanguage stage, glslang::TVarEntryInfo& ent) override
{
@@ -455,7 +444,9 @@ public:
// Add resource
const auto descriptor = _collector->Add(ent);
if (descriptor)
return ent.newBinding = reserveSlot(_set, descriptor->Binding);
{
return ent.newBinding = reserveSlot(_set, descriptor->Binding, descriptor->Count);
}
return ent.newBinding;
}
@@ -686,6 +677,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Process all descriptors
header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images;
header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers;
header.DescriptorInfo.TexelBufferViewsCount = descriptorsCollector.TexelBuffers;
for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++)
{
auto& descriptor = descriptorsCollector.Descriptors[i];
@@ -697,6 +689,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
d.BindingType = descriptor.BindingType;
d.DescriptorType = descriptor.DescriptorType;
d.ResourceType = descriptor.ResourceType;
d.Count = descriptor.Count;
switch (descriptor.BindingType)
{
@@ -732,6 +725,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat
// Mark as used and cache some data
cc.IsUsed = true;
cc.Size = descriptor.Size;
break;
}
}
}