summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/shader_spirv.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/shader_spirv.cpp')
-rw-r--r--3rdparty/bgfx/src/shader_spirv.cpp278
1 files changed, 245 insertions, 33 deletions
diff --git a/3rdparty/bgfx/src/shader_spirv.cpp b/3rdparty/bgfx/src/shader_spirv.cpp
index 2fec1c0b0e4..7226f90fe78 100644
--- a/3rdparty/bgfx/src/shader_spirv.cpp
+++ b/3rdparty/bgfx/src/shader_spirv.cpp
@@ -8,15 +8,6 @@
namespace bgfx
{
- struct SpvOpcodeInfo
- {
- bool hasType;
- bool hasResult;
- SpvOperand::Enum operands[8];
- };
-
- static const SpvOpcodeInfo s_spvOpcodeInfo[] =
- {
#define SPV_OPERAND_1(_a0) SpvOperand::_a0
#define SPV_OPERAND_2(_a0, _a1) SPV_OPERAND_1(_a0), SPV_OPERAND_1(_a1)
#define SPV_OPERAND_3(_a0, _a1, _a2) SPV_OPERAND_1(_a0), SPV_OPERAND_2(_a1, _a2)
@@ -33,6 +24,23 @@ namespace bgfx
# define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__)(__VA_ARGS__) }
#endif // BX_COMPILER_MSVC
#define _ Count
+
+ bool isDebug(SpvOpcode::Enum _opcode)
+ {
+ return (SpvOpcode::SourceContinued <= _opcode && SpvOpcode::Line >= _opcode)
+ || SpvOpcode::NoLine == _opcode
+ ;
+ }
+
+ struct SpvOpcodeInfo
+ {
+ bool hasType;
+ bool hasResult;
+ SpvOperand::Enum operands[8];
+ };
+
+ static const SpvOpcodeInfo s_spvOpcodeInfo[] =
+ {
{ false, false, /* Nop, // 0 */ SPV_OPERAND(_) },
{ true, true, /* Undef, // 1 */ SPV_OPERAND(_) },
{ false, false, /* SourceContinued, // 2 */ SPV_OPERAND(_) },
@@ -61,10 +69,10 @@ namespace bgfx
{ false, true, /* TypeImage, // 25 */ SPV_OPERAND(SampledType, Dim, LiteralNumber, LiteralNumber, LiteralNumber, LiteralNumber, ImageFormat, AccessQualifier) },
{ false, true, /* TypeSampler, // 26 */ SPV_OPERAND(LiteralNumber) },
{ false, true, /* TypeSampledImage, // 27 */ SPV_OPERAND(LiteralNumber) },
- { false, true, /* TypeArray, // 28 */ SPV_OPERAND(LiteralNumber) },
- { false, true, /* TypeRuntimeArray, // 29 */ SPV_OPERAND(_) },
- { false, true, /* TypeStruct, // 30 */ SPV_OPERAND(_) },
- { false, true, /* TypeOpaque, // 31 */ SPV_OPERAND(_) },
+ { false, true, /* TypeArray, // 28 */ SPV_OPERAND(ElementType, LiteralNumber) },
+ { false, true, /* TypeRuntimeArray, // 29 */ SPV_OPERAND(ElementType) },
+ { false, true, /* TypeStruct, // 30 */ SPV_OPERAND(IdRep) },
+ { false, true, /* TypeOpaque, // 31 */ SPV_OPERAND(LiteralString) },
{ false, true, /* TypePointer, // 32 */ SPV_OPERAND(StorageClass, Id) },
{ false, true, /* TypeFunction, // 33 */ SPV_OPERAND(Id, Id, Id, Id, Id) },
{ false, true, /* TypeEvent, // 34 */ SPV_OPERAND(_) },
@@ -354,8 +362,6 @@ namespace bgfx
{ true, true, /* AtomicFlagTestAndSet, // 318 */ SPV_OPERAND(_) },
{ false, false, /* AtomicFlagClear, // 319 */ SPV_OPERAND(_) },
{ true, true, /* ImageSparseRead, // 320 */ SPV_OPERAND(_) },
-#undef _
-#undef SPV_OPERAND
};
BX_STATIC_ASSERT(BX_COUNTOF(s_spvOpcodeInfo) == SpvOpcode::Count);
@@ -682,18 +688,136 @@ namespace bgfx
"AtomicFlagTestAndSet",
"AtomicFlagClear",
"ImageSparseRead",
+ "",
};
- BX_STATIC_ASSERT(BX_COUNTOF(s_spvOpcode) == SpvOpcode::Count);
+ BX_STATIC_ASSERT(BX_COUNTOF(s_spvOpcode)-1 == SpvOpcode::Count);
const char* getName(SpvOpcode::Enum _opcode)
{
- BX_WARN(_opcode < SpvOpcode::Count, "Unknown opcode id %d.", _opcode);
- return _opcode < SpvOpcode::Count
+ BX_WARN(_opcode <= SpvOpcode::Count, "Unknown opcode id %d.", _opcode);
+ return _opcode <= SpvOpcode::Count
? s_spvOpcode[_opcode]
: "?SpvOpcode?"
;
}
+ struct SpvDecorationInfo
+ {
+ SpvOperand::Enum operands[2];
+ };
+
+ static const SpvDecorationInfo s_spvDecorationInfo[] =
+ {
+ { /* RelaxedPrecision */ SPV_OPERAND(_) },
+ { /* SpecId */ SPV_OPERAND(LiteralNumber) },
+ { /* Block */ SPV_OPERAND(_) },
+ { /* BufferBlock */ SPV_OPERAND(_) },
+ { /* RowMajor */ SPV_OPERAND(_) },
+ { /* ColMajor */ SPV_OPERAND(_) },
+ { /* ArrayStride */ SPV_OPERAND(LiteralNumber) },
+ { /* MatrixStride */ SPV_OPERAND(LiteralNumber) },
+ { /* GLSLShared */ SPV_OPERAND(_) },
+ { /* GLSLPacked */ SPV_OPERAND(_) },
+ { /* CPacked */ SPV_OPERAND(_) },
+ { /* BuiltIn */ SPV_OPERAND(LiteralNumber) },
+ { /* Unknown12 */ SPV_OPERAND(_) },
+ { /* NoPerspective */ SPV_OPERAND(_) },
+ { /* Flat */ SPV_OPERAND(_) },
+ { /* Patch */ SPV_OPERAND(_) },
+ { /* Centroid */ SPV_OPERAND(_) },
+ { /* Sample */ SPV_OPERAND(_) },
+ { /* Invariant */ SPV_OPERAND(_) },
+ { /* Restrict */ SPV_OPERAND(_) },
+ { /* Aliased */ SPV_OPERAND(_) },
+ { /* Volatile */ SPV_OPERAND(_) },
+ { /* Constant */ SPV_OPERAND(_) },
+ { /* Coherent */ SPV_OPERAND(_) },
+ { /* NonWritable */ SPV_OPERAND(_) },
+ { /* NonReadable */ SPV_OPERAND(_) },
+ { /* Uniform */ SPV_OPERAND(_) },
+ { /* Unknown27 */ SPV_OPERAND(_) },
+ { /* SaturatedConversion */ SPV_OPERAND(_) },
+ { /* Stream */ SPV_OPERAND(LiteralNumber) },
+ { /* Location */ SPV_OPERAND(LiteralNumber) },
+ { /* Component */ SPV_OPERAND(LiteralNumber) },
+ { /* Index */ SPV_OPERAND(LiteralNumber) },
+ { /* Binding */ SPV_OPERAND(LiteralNumber) },
+ { /* DescriptorSet */ SPV_OPERAND(LiteralNumber) },
+ { /* Offset */ SPV_OPERAND(LiteralNumber) },
+ { /* XfbBuffer */ SPV_OPERAND(LiteralNumber) },
+ { /* XfbStride */ SPV_OPERAND(LiteralNumber) },
+ { /* FuncParamAttr */ SPV_OPERAND(_) },
+ { /* FPRoundingMode */ SPV_OPERAND(_) },
+ { /* FPFastMathMode */ SPV_OPERAND(_) },
+ { /* LinkageAttributes */ SPV_OPERAND(LiteralString, LinkageType) },
+ { /* NoContraction */ SPV_OPERAND(_) },
+ { /* InputAttachmentIndex */ SPV_OPERAND(LiteralNumber) },
+ { /* Alignment */ SPV_OPERAND(LiteralNumber) },
+ };
+
+ static const char* s_spvDecoration[] =
+ {
+ "RelaxedPrecision",
+ "SpecId",
+ "Block",
+ "BufferBlock",
+ "RowMajor",
+ "ColMajor",
+ "ArrayStride",
+ "MatrixStride",
+ "GLSLShared",
+ "GLSLPacked",
+ "CPacked",
+ "BuiltIn",
+ "Unknown12",
+ "NoPerspective",
+ "Flat",
+ "Patch",
+ "Centroid",
+ "Sample",
+ "Invariant",
+ "Restrict",
+ "Aliased",
+ "Volatile",
+ "Constant",
+ "Coherent",
+ "NonWritable",
+ "NonReadable",
+ "Uniform",
+ "Unknown27",
+ "SaturatedConversion",
+ "Stream",
+ "Location",
+ "Component",
+ "Index",
+ "Binding",
+ "DescriptorSet",
+ "Offset",
+ "XfbBuffer",
+ "XfbStride",
+ "FuncParamAttr",
+ "FPRoundingMode",
+ "FPFastMathMode",
+ "LinkageAttributes",
+ "NoContraction",
+ "InputAttachmentIndex",
+ "Alignment",
+ ""
+ };
+ BX_STATIC_ASSERT(BX_COUNTOF(s_spvDecoration)-1 == SpvDecoration::Count);
+
+ const char* getName(SpvDecoration::Enum _enum)
+ {
+ BX_CHECK(_enum <= SpvDecoration::Count, "Unknown decoration id %d.", _enum);
+ return _enum <= SpvDecoration::Count
+ ? s_spvDecoration[_enum]
+ : "?SpvDecoration?"
+ ;
+ }
+
+#undef _
+#undef SPV_OPERAND
+
static const char* s_spvStorageClass[] =
{
"UniformConstant",
@@ -708,18 +832,75 @@ namespace bgfx
"PushConstant",
"AtomicCounter",
"Image",
+ ""
};
- BX_STATIC_ASSERT(BX_COUNTOF(s_spvStorageClass) == SpvStorageClass::Count);
+ BX_STATIC_ASSERT(BX_COUNTOF(s_spvStorageClass)-1 == SpvStorageClass::Count);
const char* getName(SpvStorageClass::Enum _enum)
{
- BX_CHECK(_enum < SpvStorageClass::Count, "Unknown storage class id %d.", _enum);
- return _enum < SpvStorageClass::Count
+ BX_CHECK(_enum <= SpvStorageClass::Count, "Unknown storage class id %d.", _enum);
+ return _enum <= SpvStorageClass::Count
? s_spvStorageClass[_enum]
: "?SpvStorageClass?"
;
}
+ static const char* s_spvBuiltin[] =
+ {
+ "Position",
+ "PointSize",
+ "ClipDistance",
+ "CullDistance",
+ "VertexId",
+ "InstanceId",
+ "PrimitiveId",
+ "InvocationId",
+ "Layer",
+ "ViewportIndex",
+ "TessLevelOuter",
+ "TessLevelInner",
+ "TessCoord",
+ "PatchVertices",
+ "FragCoord",
+ "PointCoord",
+ "FrontFacing",
+ "SampleId",
+ "SamplePosition",
+ "SampleMask",
+ "FragDepth",
+ "HelperInvocation",
+ "NumWorkgroups",
+ "WorkgroupSize",
+ "WorkgroupId",
+ "LocalInvocationId",
+ "GlobalInvocationId",
+ "LocalInvocationIndex",
+ "WorkDim",
+ "GlobalSize",
+ "EnqueuedWorkgroupSize",
+ "GlobalOffset",
+ "GlobalLinearId",
+ "SubgroupSize",
+ "SubgroupMaxSize",
+ "NumSubgroups",
+ "NumEnqueuedSubgroups",
+ "SubgroupId",
+ "SubgroupLocalInvocationId",
+ "VertexIndex",
+ "InstanceIndex",
+ "",
+ };
+ BX_STATIC_ASSERT(BX_COUNTOF(s_spvBuiltin)-1 == SpvBuiltin::Count);
+
+ const char* getName(SpvBuiltin::Enum _enum)
+ {
+ BX_CHECK(_enum <= SpvBuiltin::Count, "Unknown builtin id %d.", _enum);
+ return _enum <= SpvBuiltin::Count
+ ? s_spvBuiltin[_enum]
+ : "?SpvBuiltin?"
+ ;
+ }
+
int32_t read(bx::ReaderI* _reader, SpvOperand& _operand, bx::Error* _err)
{
int32_t size = 0;
@@ -775,11 +956,19 @@ namespace bgfx
{
size += read(_reader, _instruction.type, _err);
}
+ else
+ {
+ _instruction.type = UINT32_MAX;
+ }
if (info.hasResult)
{
size += read(_reader, _instruction.result, _err);
}
+ else
+ {
+ _instruction.result = UINT32_MAX;
+ }
uint16_t currOp = 0;
switch (_instruction.opcode)
@@ -826,10 +1015,21 @@ namespace bgfx
if (_instruction.hasResult)
{
- size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
- , " %%%d = "
- , _instruction.result
- );
+ if (_instruction.hasType)
+ {
+ size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+ , " r%d.t%d = "
+ , _instruction.result
+ , _instruction.type
+ );
+ }
+ else
+ {
+ size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+ , " r%d = "
+ , _instruction.result
+ );
+ }
}
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
@@ -850,6 +1050,14 @@ namespace bgfx
);
break;
+ case SpvOperand::Decoration:
+ size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+ , "%s%s"
+ , 0 == ii ? " " : ", "
+ , getName(SpvDecoration::Enum(operand.data[0]) )
+ );
+ break;
+
case SpvOperand::FunctionControl:
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
, "%s0x%08x"
@@ -900,7 +1108,7 @@ namespace bgfx
default:
size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
- , "%s%%%d"
+ , "%sr%d"
, 0 == ii ? " " : ", "
, operand.data[0]
);
@@ -961,7 +1169,7 @@ namespace bgfx
return size;
}
- void parse(const SpvShader& _src, SpirvParseFn _fn, void* _userData, bx::Error* _err)
+ void parse(const SpvShader& _src, SpvParseFn _fn, void* _userData, bx::Error* _err)
{
BX_ERROR_SCOPE(_err);
@@ -978,12 +1186,16 @@ namespace bgfx
return;
}
- BX_CHECK(size/4 == instruction.length, "read %d, expected %d, %s"
- , size/4
- , instruction.length
- , getName(instruction.opcode)
- );
- BX_UNUSED(size);
+ if (size/4 != instruction.length)
+ {
+ BX_TRACE("read %d, expected %d, %s"
+ , size/4
+ , instruction.length
+ , getName(instruction.opcode)
+ );
+ BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, "SPIR-V: Invalid instruction.");
+ return;
+ }
bool cont = _fn(token * sizeof(uint32_t), instruction, _userData);
if (!cont)