瀏覽代碼

DXBC: Added immediate constant buffer support.

Branimir Karadžić 7 年之前
父節點
當前提交
d925e1a4b5
共有 2 個文件被更改,包括 183 次插入95 次删除
  1. 165 95
      src/shader_dxbc.cpp
  2. 18 0
      src/shader_dxbc.h

+ 165 - 95
src/shader_dxbc.cpp

@@ -550,6 +550,17 @@ namespace bgfx
 	};
 	BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcOperandType) == DxbcOperandType::Count);
 
+	static const char* s_dxbcCustomDataClass[] =
+	{
+		"Comment",
+		"DebugInfo",
+		"Opaque",
+		"dcl_immediateConstantBuffer",
+		"ShaderMessage",
+		"ClipPlaneConstantMappingsForDx9",
+	};
+	BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcCustomDataClass) == DxbcCustomDataClass::Count);
+
 #define DXBC_MAX_NAME_STRING 512
 
 	int32_t readString(bx::ReaderSeekerI* _reader, int64_t _offset, char* _out, uint32_t _max, bx::Error* _err)
@@ -1028,7 +1039,7 @@ namespace bgfx
 
 	int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction, bx::Error* _err)
 	{
-		uint32_t size = 0;
+		int32_t size = 0;
 
 		uint32_t token;
 		size += bx::read(_reader, token, _err);
@@ -1068,18 +1079,26 @@ namespace bgfx
 		_instruction.testNZ   = false;
 		_instruction.retType  = DxbcResourceReturnType::Unused;
 
+		_instruction.customDataClass = DxbcCustomDataClass::Comment;
+		_instruction.customData.clear();
+
 		switch (_instruction.opcode)
 		{
 			case DxbcOpcode::CUSTOMDATA:
 				{
+					_instruction.customDataClass = DxbcCustomDataClass::Enum( (token & UINT32_C(0xfffff800) ) >> 11);
+
 					_instruction.numOperands = 0;
-					size += bx::read(_reader, _instruction.length);
-					for (uint32_t ii = 0, num = (_instruction.length-2); ii < num; ++ii)
+					size += bx::read(_reader, _instruction.length, _err);
+					for (uint32_t ii = 0, num = (_instruction.length-2); ii < num && _err->isOk(); ++ii)
 					{
-						char temp[4];
-						size += bx::read(_reader, temp, 4, _err);
+						uint32_t temp;
+						size += bx::read(_reader, temp, _err);
+						if (_err->isOk() )
+						{
+							_instruction.customData.push_back(temp);
+						}
 					}
-
 				}
 				return size;
 
@@ -1315,10 +1334,22 @@ namespace bgfx
 			: 0
 			;
 
+		int32_t size =0;
+
 		switch (_instruction.opcode)
 		{
 			case DxbcOpcode::CUSTOMDATA:
-				return 0;
+				{
+					token &= UINT32_C(0x000007ff);
+					token |= _instruction.customDataClass << 11;
+
+					size += bx::write(_writer, token);
+
+					uint32_t len = uint32_t(_instruction.customData.size() );
+					size += bx::write(_writer, len/4+2, _err);
+					size += bx::write(_writer, _instruction.customData.data(), len, _err);
+				}
+				return size;
 
 			case DxbcOpcode::DCL_CONSTANT_BUFFER:
 				token |= _instruction.allowRefactoring ? UINT32_C(0x00000800) : 0;
@@ -1364,7 +1395,6 @@ namespace bgfx
 				break;
 		}
 
-		uint32_t size =0;
 		size += bx::write(_writer, token);
 
 		for (uint32_t ii = 0; _instruction.extended[ii] != DxbcInstruction::ExtendedType::Count; ++ii)
@@ -1444,31 +1474,88 @@ namespace bgfx
 		return size;
 	}
 
-	int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction)
+	int32_t toString(char* _out, int32_t _size, DxbcOperandMode::Enum _mode, uint8_t _modeBits)
 	{
 		int32_t size = 0;
 
-		size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-							, "%s%s%s"
-							, getName(_instruction.opcode)
-							, _instruction.saturate ? "_sat" : ""
-							, _instruction.testNZ   ? "_nz"  : ""
+		switch (_mode)
+		{
+		case DxbcOperandMode::Mask:
+			if (0xf > _modeBits
+			&&  0   < _modeBits)
+			{
+				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+							, ".%s%s%s%s"
+							, 0 == (_modeBits & 1) ? "" : "x"
+							, 0 == (_modeBits & 2) ? "" : "y"
+							, 0 == (_modeBits & 4) ? "" : "z"
+							, 0 == (_modeBits & 8) ? "" : "w"
 							);
+			}
+			break;
+
+		case DxbcOperandMode::Swizzle:
+			if (0xe4 != _modeBits)
+			{
+				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+							, ".%c%c%c%c"
+							, "xyzw"[(_modeBits   )&0x3]
+							, "xyzw"[(_modeBits>>2)&0x3]
+							, "xyzw"[(_modeBits>>4)&0x3]
+							, "xyzw"[(_modeBits>>6)&0x3]
+							);
+			}
+			break;
+
+		case DxbcOperandMode::Scalar:
+			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+						, ".%c"
+						, "xyzw"[_modeBits]
+						);
+			break;
+
+		default:
+			break;
+		}
+
+		return size;
+	}
+
+	int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction)
+	{
+		int32_t size = 0;
+
+		if (DxbcOpcode::CUSTOMDATA == _instruction.opcode)
+		{
+			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+						, "%s"
+						, s_dxbcCustomDataClass[_instruction.customDataClass]
+						);
+		}
+		else
+		{
+			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+						, "%s%s%s"
+						, getName(_instruction.opcode)
+						, _instruction.saturate ? "_sat" : ""
+						, _instruction.testNZ   ? "_nz"  : ""
+						);
+		}
 
 		if (DxbcResourceDim::Unknown != _instruction.srv)
 		{
 			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-								, " %s<%x>"
-								, s_dxbcSrvType[_instruction.srv]
-								, _instruction.value[0]
-								);
+						, " %s<%x>"
+						, s_dxbcSrvType[_instruction.srv]
+						, _instruction.value[0]
+						);
 		}
 		else if (0 < s_dxbcOpcodeInfo[_instruction.opcode].numValues)
 		{
 			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-								, " %d"
-								, _instruction.value[0]
-								);
+						, " %d"
+						, _instruction.value[0]
+						);
 		}
 
 		for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
@@ -1495,11 +1582,11 @@ namespace bgfx
 			}
 
 			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-								, "%s%s%s"
-								, 0 == ii ? " " : ", "
-								, preOperand
-								, s_dxbcOperandType[operand.type]
-								);
+						, "%s%s%s"
+						, 0 == ii ? " " : ", "
+						, preOperand
+						, s_dxbcOperandType[operand.type]
+						);
 
 			switch (operand.type)
 			{
@@ -1509,35 +1596,39 @@ namespace bgfx
 				{
 					union { uint32_t i; float f; } cast = { operand.un.imm32[jj] };
 					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, "%s%f"
-										, 0 == jj ? "(" : ", "
-										, cast.f
-										);
+								, "%s%f"
+								, 0 == jj ? "(" : ", "
+								, cast.f
+								);
 				}
 
 				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-									, ")"
-									);
+							, ")"
+							);
 				break;
 
 			default:
 				break;
 			}
 
-			const uint32_t first = DxbcOperandAddrMode::RegImm32 == operand.addrMode[0] ? 0 : 1;
+			const uint32_t first = false
+				|| DxbcOperandType::ImmConstantBuffer == operand.type
+				|| DxbcOperandAddrMode::RegImm32      == operand.addrMode[0]
+				? 0 : 1
+				;
 			if (0 == first)
 			{
 				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-									, "["
-									);
+							, "["
+							);
 			}
 			else
 			{
 				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-									, "%d%s"
-									, operand.regIndex[0]
-									, array ? "[" : ""
-									);
+							, "%d%s"
+							, operand.regIndex[0]
+							, array ? "[" : ""
+							);
 			}
 
 			for (uint32_t jj = first, num = bx::uint32_min(operand.numAddrModes, BX_COUNTOF(operand.addrMode) ); jj < num; ++jj)
@@ -1546,82 +1637,61 @@ namespace bgfx
 				{
 				case DxbcOperandAddrMode::Imm32:
 					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, "%d"
-										, operand.regIndex[jj]
-										);
+								, "%d"
+								, operand.regIndex[jj]
+								);
 					break;
 
 				case DxbcOperandAddrMode::Reg:
 					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, "%s%d"
-										, s_dxbcOperandType[operand.subOperand[jj].type]
-										, operand.regIndex[jj]
-										);
+								, "%s%d"
+								, s_dxbcOperandType[operand.subOperand[jj].type]
+								, operand.subOperand[jj].regIndex
+								);
+					size += toString(&_out[size], bx::uint32_imax(0, _size-size)
+								, DxbcOperandMode::Enum(operand.subOperand[jj].mode)
+								, operand.subOperand[jj].modeBits
+								);
 					break;
 
 				case DxbcOperandAddrMode::RegImm32:
 					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, "%d + %s%d"
-										, operand.regIndex[jj]
-										, s_dxbcOperandType[operand.subOperand[jj].type]
-										, operand.subOperand[jj].regIndex
-										);
+								, "%d + %s%d"
+								, operand.regIndex[jj]
+								, s_dxbcOperandType[operand.subOperand[jj].type]
+								, operand.subOperand[jj].regIndex
+								);
+					size += toString(&_out[size], bx::uint32_imax(0, _size-size)
+								, DxbcOperandMode::Enum(operand.subOperand[jj].mode)
+								, operand.subOperand[jj].modeBits
+								);
 					break;
 
 				default:
+					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size), "???");
 					break;
 				}
 			}
 
 			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-								, "%s"
-								, array ? "]" : ""
-								);
+						, "%s"
+						, array ? "]" : ""
+						);
 
-			switch (operand.mode)
-			{
-			case DxbcOperandMode::Mask:
-				if (0xf > operand.modeBits
-				&&  0   < operand.modeBits)
-				{
-					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, ".%s%s%s%s"
-										, 0 == (operand.modeBits & 1) ? "" : "x"
-										, 0 == (operand.modeBits & 2) ? "" : "y"
-										, 0 == (operand.modeBits & 4) ? "" : "z"
-										, 0 == (operand.modeBits & 8) ? "" : "w"
-										);
-				}
-				break;
-
-			case DxbcOperandMode::Swizzle:
-				if (0xe4 != operand.modeBits)
-				{
-					size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-										, ".%c%c%c%c"
-										, "xyzw"[(operand.modeBits   )&0x3]
-										, "xyzw"[(operand.modeBits>>2)&0x3]
-										, "xyzw"[(operand.modeBits>>4)&0x3]
-										, "xyzw"[(operand.modeBits>>6)&0x3]
-										);
-				}
-				break;
+			size += toString(&_out[size], bx::uint32_imax(0, _size-size), operand.mode, operand.modeBits);
 
-			case DxbcOperandMode::Scalar:
-				size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-									, ".%c"
-									, "xyzw"[operand.modeBits]
-									);
-				break;
-
-			default:
-				break;
-			}
+			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+						, "%s"
+						, postOperand
+						);
+		}
 
+		if (_instruction.opcode == DxbcOpcode::DCL_CONSTANT_BUFFER
+		&&  _instruction.allowRefactoring)
+		{
 			size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
-								, "%s"
-								, postOperand
-								);
+						, ", dynamicIndexed"
+						);
 		}
 
 		return size;

+ 18 - 0
src/shader_dxbc.h

@@ -461,6 +461,21 @@ namespace bgfx
 		};
 	};
 
+	struct DxbcCustomDataClass
+	{
+		enum Enum
+		{
+			Comment,
+			DebugInfo,
+			Opaque,
+			ImmConstantBuffer,
+			ShaderMessage,
+			ClipPlaneConstantMappingsForDx9,
+
+			Count
+		};
+	};
+
 	struct DxbcSubOperand
 	{
 		DxbcSubOperand()
@@ -580,6 +595,9 @@ namespace bgfx
 		DxbcResourceReturnType::Enum resourceReturnTypes[4];
 
 		DxbcOperand operand[6];
+
+		DxbcCustomDataClass::Enum customDataClass;
+		stl::vector<uint32_t>     customData;
 	};
 
 	int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction, bx::Error* _err);