Make shaderc output independent of backend enums (#2411)

* Fix typo in SPIR-V id

* Use backend-agnostic shaderc output

...as opposed to directly storing and comparing against Vulkan and WebGPU enums. This is backwards-compatible with existing code and shaders.

* Remove comments and Undefined value
This commit is contained in:
pezcode 2021-02-28 21:38:12 +01:00 committed by GitHub
parent 39cdaace39
commit 302c978b1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 216 additions and 45 deletions

View File

@ -635,7 +635,7 @@ project "shaderc"
path.join(BGFX_DIR, "tools/shaderc/**.cpp"),
path.join(BGFX_DIR, "tools/shaderc/**.h"),
path.join(BGFX_DIR, "src/vertexlayout.**"),
path.join(BGFX_DIR, "src/shader_spirv.**"),
path.join(BGFX_DIR, "src/shader**"),
}
configuration { "mingw-*" }

View File

@ -20,6 +20,7 @@
#include "renderer_nvn.cpp"
#include "renderer_vk.cpp"
#include "renderer_webgpu.cpp"
#include "shader.cpp"
#include "shader_dx9bc.cpp"
#include "shader_dxbc.cpp"
#include "shader_spirv.cpp"

View File

@ -5067,13 +5067,20 @@ VK_DESTROY
uint16_t regCount;
bx::read(&reader, regCount);
if (!isShaderVerLess(magic, 8) )
const bool hasTexData = !isShaderVerLess(magic, 8);
uint8_t texComponent = 0;
uint8_t texDimension = 0;
if (hasTexData)
{
uint16_t texInfo = 0;
bx::read(&reader, texInfo);
bx::read(&reader, texComponent);
bx::read(&reader, texDimension);
}
const char* kind = "invalid";
BX_UNUSED(num);
BX_UNUSED(texComponent);
if (UINT16_MAX != regIndex)
{
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
@ -5088,7 +5095,7 @@ VK_DESTROY
else if (UniformType::End == (~kUniformMask & type) )
{
// regCount is used for descriptor type
const bool isBuffer = regCount == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
const bool isBuffer = idToDescriptorType(regCount) == DescriptorType::StorageBuffer;
const uint16_t stage = regIndex - (isBuffer ? 16 : 32) - (fragment ? 48 : 0); // regIndex is used for buffer binding index
m_bindInfo[stage].type = isBuffer ? BindType::Buffer : BindType::Image;
@ -5129,13 +5136,14 @@ VK_DESTROY
}
}
BX_TRACE("\t%s: %s (%s), num %2d, r.index %3d, r.count %2d"
BX_TRACE("\t%s: %s (%s), r.index %3d, r.count %2d, r.texComponent %1d, r.texDimension %1d"
, kind
, name
, getUniformTypeName(UniformType::Enum(type&~kUniformMask) )
, num
, regIndex
, regCount
, texComponent
, texDimension
);
BX_UNUSED(kind);
}

View File

@ -2542,7 +2542,7 @@ namespace bgfx { namespace webgpu
else if (UniformType::End == (~kUniformMask & type))
{
// regCount is used for descriptor type
const bool buffer = regCount == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
const bool buffer = idToDescriptorType(regCount) == DescriptorType::StorageBuffer;
const bool readonly = (type & kUniformReadOnlyBit) != 0;
const uint8_t stage = regIndex - (buffer ? 16 : 32) - (fragment ? 48 : 0);
@ -2583,28 +2583,36 @@ namespace bgfx { namespace webgpu
m_bindInfo[stage].m_binding = regIndex;
m_bindInfo[stage].m_uniform = info->m_handle;
auto textureComponentToSampleType = [](wgpu::TextureComponentType componentType)
auto textureDimensionToWgpu = [](TextureDimension::Enum dimension)
{
switch (dimension)
{
case TextureDimension::Dimension1D: return wgpu::TextureViewDimension::e1D;
case TextureDimension::Dimension2D: return wgpu::TextureViewDimension::e2D;
case TextureDimension::Dimension2DArray: return wgpu::TextureViewDimension::e2DArray;
case TextureDimension::DimensionCube: return wgpu::TextureViewDimension::eCube;
case TextureDimension::DimensionCubeArray: return wgpu::TextureViewDimension::eCubeArray;
case TextureDimension::Dimension3D: return wgpu::TextureViewDimension::e3D;
default: return wgpu::TextureViewDimension::Undefined;
}
};
auto textureComponentToWgpuSampleType = [](TextureComponentType::Enum componentType)
{
switch (componentType)
{
case wgpu::TextureComponentType::Float:
return wgpu::TextureSampleType::Float;
case wgpu::TextureComponentType::Sint:
return wgpu::TextureSampleType::Sint;
case wgpu::TextureComponentType::Uint:
return wgpu::TextureSampleType::Uint;
case wgpu::TextureComponentType::DepthComparison:
return wgpu::TextureSampleType::UnfilterableFloat;
default:
return wgpu::TextureSampleType::Float;
case TextureComponentType::Float: return wgpu::TextureSampleType::Float;
case TextureComponentType::Int: return wgpu::TextureSampleType::Sint;
case TextureComponentType::Uint: return wgpu::TextureSampleType::Uint;
default: return wgpu::TextureSampleType::Float;
}
};
m_textures[m_numSamplers] = wgpu::BindGroupLayoutEntry();
m_textures[m_numSamplers].binding = regIndex;
m_textures[m_numSamplers].visibility = shaderStage;
m_textures[m_numSamplers].texture.viewDimension = wgpu::TextureViewDimension(texDimension);
m_textures[m_numSamplers].texture.sampleType = textureComponentToSampleType(wgpu::TextureComponentType(texComponent));
m_textures[m_numSamplers].texture.viewDimension = textureDimensionToWgpu(idToTextureDimension(texDimension));
m_textures[m_numSamplers].texture.sampleType = textureComponentToWgpuSampleType(idToTextureComponentType(texComponent));
const bool comparisonSampler = (type & kUniformCompareBit) != 0;

View File

@ -10,6 +10,109 @@
namespace bgfx
{
struct DescriptorTypeToId
{
DescriptorType::Enum type;
uint16_t id;
};
static DescriptorTypeToId s_descriptorTypeToId[] =
{
// NOTICE:
// DescriptorType must be in order how it appears in DescriptorType::Enum! id is
// unique and should not be changed if new DescriptorTypes are added.
{ DescriptorType::StorageBuffer, 0x0007 },
{ DescriptorType::StorageImage, 0x0003 },
};
BX_STATIC_ASSERT(BX_COUNTOF(s_descriptorTypeToId) == DescriptorType::Count);
DescriptorType::Enum idToDescriptorType(uint16_t _id)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(s_descriptorTypeToId); ++ii)
{
if (s_descriptorTypeToId[ii].id == _id)
{
return s_descriptorTypeToId[ii].type;
}
}
return DescriptorType::Count;
}
uint16_t descriptorTypeToId(DescriptorType::Enum _type)
{
return s_descriptorTypeToId[_type].id;
}
struct TextureComponentTypeToId
{
TextureComponentType::Enum type;
uint8_t id;
};
static TextureComponentTypeToId s_textureComponentTypeToId[] =
{
// see comment in s_descriptorTypeToId
{ TextureComponentType::Float, 0x00 },
{ TextureComponentType::Int, 0x01 },
{ TextureComponentType::Uint, 0x02 },
};
BX_STATIC_ASSERT(BX_COUNTOF(s_textureComponentTypeToId) == TextureComponentType::Count);
TextureComponentType::Enum idToTextureComponentType(uint8_t _id)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(s_textureComponentTypeToId); ++ii)
{
if (s_textureComponentTypeToId[ii].id == _id)
{
return s_textureComponentTypeToId[ii].type;
}
}
return TextureComponentType::Count;
}
uint8_t textureComponentTypeToId(TextureComponentType::Enum _type)
{
return s_textureComponentTypeToId[_type].id;
}
struct TextureDimensionToId
{
TextureDimension::Enum dimension;
uint8_t id;
};
static TextureDimensionToId s_textureDimensionToId[] =
{
// see comment in s_descriptorTypeToId
{ TextureDimension::Dimension1D, 0x01 },
{ TextureDimension::Dimension2D, 0x02 },
{ TextureDimension::Dimension2DArray, 0x03 },
{ TextureDimension::DimensionCube, 0x04 },
{ TextureDimension::DimensionCubeArray, 0x05 },
{ TextureDimension::Dimension3D, 0x06 },
};
BX_STATIC_ASSERT(BX_COUNTOF(s_textureDimensionToId) == TextureDimension::Count);
TextureDimension::Enum idToTextureDimension(uint8_t _id)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(s_textureDimensionToId); ++ii)
{
if (s_textureDimensionToId[ii].id == _id)
{
return s_textureDimensionToId[ii].dimension;
}
}
return TextureDimension::Count;
}
uint8_t textureDimensionToId(TextureDimension::Enum _dim)
{
return s_textureDimensionToId[_dim].id;
}
static bool printAsm(uint32_t _offset, const DxbcInstruction& _instruction, void* _userData)
{
BX_UNUSED(_offset);

View File

@ -10,6 +10,53 @@
namespace bgfx
{
struct DescriptorType
{
enum Enum
{
StorageBuffer,
StorageImage,
Count
};
};
DescriptorType::Enum idToDescriptorType(uint16_t _id);
uint16_t descriptorTypeToId(DescriptorType::Enum _type);
struct TextureComponentType
{
enum Enum
{
Float,
Int,
Uint,
Count
};
};
TextureComponentType::Enum idToTextureComponentType(uint8_t _id);
uint8_t textureComponentTypeToId(TextureComponentType::Enum _type);
struct TextureDimension
{
enum Enum
{
Dimension1D,
Dimension2D,
Dimension2DArray,
DimensionCube,
DimensionCubeArray,
Dimension3D,
Count
};
};
TextureDimension::Enum idToTextureDimension(uint8_t _id);
uint8_t textureDimensionToId(TextureDimension::Enum _dim);
///
void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err = NULL);

View File

@ -104,7 +104,7 @@ namespace bgfx
{ ShadingLang::HLSL, 500, "s_5_0" },
{ ShadingLang::Metal, 1000, "metal" },
{ ShadingLang::PSSL, 1000, "pssl" },
{ ShadingLang::SpirV, 1331, "spirv13-11" },
{ ShadingLang::SpirV, 1311, "spirv13-11" },
{ ShadingLang::SpirV, 1411, "spirv14-11" },
{ ShadingLang::SpirV, 1512, "spirv15-12" },
{ ShadingLang::SpirV, 1010, "spirv10-10" },

View File

@ -56,6 +56,7 @@ namespace bgfx
#include <tinystl/vector.h>
namespace stl = tinystl;
#include "../../src/shader.h"
#include "../../src/shader_spirv.h"
#include "../../3rdparty/khronos/vulkan-local/vulkan.h"
@ -179,39 +180,42 @@ namespace bgfx { namespace spirv
return true;
}
wgpu::TextureComponentType SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType spirvBaseType)
bgfx::TextureComponentType::Enum SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType _type)
{
switch (spirvBaseType)
switch (_type)
{
case spirv_cross::SPIRType::Float:
return wgpu::TextureComponentType::Float;
return bgfx::TextureComponentType::Float;
case spirv_cross::SPIRType::Int:
return wgpu::TextureComponentType::Sint;
return bgfx::TextureComponentType::Int;
case spirv_cross::SPIRType::UInt:
return wgpu::TextureComponentType::Uint;
return bgfx::TextureComponentType::Uint;
default:
return wgpu::TextureComponentType::Float;
return bgfx::TextureComponentType::Float;
}
}
wgpu::TextureViewDimension SpirvDimToTextureViewDimension(spv::Dim dim, bool arrayed)
bgfx::TextureDimension::Enum SpirvDimToTextureViewDimension(spv::Dim _dim, bool _arrayed)
{
switch (dim)
switch (_dim)
{
case spv::Dim::Dim1D:
return wgpu::TextureViewDimension::e1D;
return bgfx::TextureDimension::Dimension1D;
case spv::Dim::Dim2D:
return arrayed
? wgpu::TextureViewDimension::e2DArray
: wgpu::TextureViewDimension::e2D;
return _arrayed
? bgfx::TextureDimension::Dimension2DArray
: bgfx::TextureDimension::Dimension2D
;
case spv::Dim::Dim3D:
return wgpu::TextureViewDimension::e3D;
return bgfx::TextureDimension::Dimension3D;
case spv::Dim::DimCube:
return arrayed
? wgpu::TextureViewDimension::CubeArray
: wgpu::TextureViewDimension::Cube;
return _arrayed
? bgfx::TextureDimension::DimensionCubeArray
: bgfx::TextureDimension::DimensionCube
;
default:
return wgpu::TextureViewDimension::Undefined;
BX_ASSERT(false, "Unknown texture dimension %d", _dim);
return bgfx::TextureDimension::Dimension2D;
}
}
@ -1077,8 +1081,8 @@ namespace bgfx { namespace spirv
| (isCompareSampler ? kUniformCompareBit : 0)
);
un.texComponent = uint8_t(SpirvCrossBaseTypeToFormatType(componentType) );
un.texDimension = uint8_t(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) );
un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType) );
un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) );
un.regIndex = binding_index;
un.regCount = 0; // unused
@ -1110,11 +1114,11 @@ namespace bgfx { namespace spirv
un.name = uniform_name;
un.type = type;
un.texComponent = uint8_t(SpirvCrossBaseTypeToFormatType(componentType) );
un.texDimension = uint8_t(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) );
un.texComponent = textureComponentTypeToId(SpirvCrossBaseTypeToFormatType(componentType) );
un.texDimension = textureDimensionToId(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed) );
un.regIndex = binding_index;
un.regCount = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; // for descriptor type
un.regCount = descriptorTypeToId(DescriptorType::StorageImage);
uniforms.push_back(un);
}
@ -1138,7 +1142,7 @@ namespace bgfx { namespace spirv
uniform.name = name;
uniform.type = type;
uniform.regIndex = binding_index;
uniform.regCount = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
uniform.regCount = descriptorTypeToId(DescriptorType::StorageBuffer);
break;
}
}