Branimir Karadžić hace 9 años
padre
commit
a2843d6cb2
Se han modificado 3 ficheros con 263 adiciones y 39 borrados
  1. 7 7
      src/shader.cpp
  2. 244 32
      src/shader_spirv.cpp
  3. 12 0
      src/shader_spirv.h

+ 7 - 7
src/shader.cpp

@@ -48,18 +48,18 @@ namespace bgfx
 			read(_reader, spirv, _err);
 			parse(spirv.shader, printAsm, _writer, _err);
 		}
-		else if (magic != BX_MAKEFOURCC('D', 'X', 'B', 'C') )
-		{
-			Dx9bc dx9bc;
-			read(_reader, dx9bc, _err);
-			parse(dx9bc.shader, printAsm, _writer, _err);
-		}
-		else
+		else if (magic == BX_MAKEFOURCC('D', 'X', 'B', 'C') )
 		{
 			DxbcContext dxbc;
 			read(_reader, dxbc, _err);
 			parse(dxbc.shader, printAsm, _writer, _err);
 		}
+		else
+		{
+			Dx9bc dx9bc;
+			read(_reader, dx9bc, _err);
+			parse(dx9bc.shader, printAsm, _writer, _err);
+		}
 	}
 
 	void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err)

+ 244 - 32
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]
 							);
@@ -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)

+ 12 - 0
src/shader_spirv.h

@@ -345,6 +345,8 @@ namespace bgfx
 		};
 	};
 
+	const char* getName(SpvOpcode::Enum _opcode);
+
 	struct SpvBuiltin
 	{
 		enum Enum
@@ -395,6 +397,8 @@ namespace bgfx
 		};
 	};
 
+	const char* getName(SpvBuiltin::Enum _enum);
+
 	struct SpvExecutionModel
 	{
 		enum Enum
@@ -456,6 +460,8 @@ namespace bgfx
 		};
 	};
 
+	const char* getName(SpvStorageClass::Enum _enum);
+
 	struct SpvResourceDim
 	{
 		enum Enum
@@ -486,6 +492,7 @@ namespace bgfx
 			GLSLPacked,
 			CPacked,
 			BuiltIn,
+			Unknown12,
 			NoPerspective,
 			Flat,
 			Patch,
@@ -500,6 +507,7 @@ namespace bgfx
 			NonWritable,
 			NonReadable,
 			Uniform,
+			Unknown27,
 			SaturatedConversion,
 			Stream,
 			Location,
@@ -522,6 +530,8 @@ namespace bgfx
 		};
 	};
 
+	const char* getName(SpvDecoration::Enum _enum);
+
 	struct SpvOperand
 	{
 		SpvOperand() { /* not pod */ }
@@ -540,6 +550,7 @@ namespace bgfx
 			Decoration,
 			Dim,
 			Dref,
+			ElementType,
 			ExecutionModel,
 			Function,
 			FunctionControl,
@@ -547,6 +558,7 @@ namespace bgfx
 			IdRep,
 			ImageFormat,
 			ImageOperands,
+			LinkageType,
 			LiteralNumber,
 			LiteralRep,
 			LiteralString,