public static ShaderProgramChunk Parse(BytecodeReader reader) { var program = new ShaderProgramChunk { Version = ShaderVersion.ParseShex(reader), // Length Token (LenTok) // Always follows VerTok // [31:00] Unsigned integer count of number of DWORDs in program code, including version and length tokens. // So the minimum value is 0x00000002 (if an empty program is ever valid). Length = reader.ReadUInt32() }; while (!reader.EndOfBuffer) { // Opcode Format (OpcodeToken0) // // [10:00] D3D10_SB_OPCODE_TYPE // if( [10:00] == D3D10_SB_OPCODE_CUSTOMDATA ) // { // Token starts a custom-data block. See "Custom-Data Block Format". // } // else // standard opcode token // { // [23:11] Opcode-Specific Controls // [30:24] Instruction length in DWORDs including the opcode token. // [31] 0 normally. 1 if extended operand definition, meaning next DWORD // contains extended opcode token. // } var opcodeHeaderReader = reader.CopyAtCurrentPosition(); var opcodeToken0 = opcodeHeaderReader.ReadUInt32(); var opcodeHeader = new OpcodeHeader { OpcodeType = opcodeToken0.DecodeValue <OpcodeType>(0, 10), Length = opcodeToken0.DecodeValue(24, 30), IsExtended = (opcodeToken0.DecodeValue(31, 31) == 1) }; OpcodeToken opcodeToken; if (opcodeHeader.OpcodeType == OpcodeType.CustomData) { opcodeToken = CustomDataToken.Parse(reader, opcodeToken0); } else if (opcodeHeader.OpcodeType.IsDeclaration()) { opcodeToken = DeclarationToken.Parse(reader, opcodeHeader.OpcodeType); } else // Not custom data or declaration, so must be instruction. { opcodeToken = InstructionToken.Parse(reader, opcodeHeader); } opcodeToken.Header = opcodeHeader; program.Tokens.Add(opcodeToken); } program.LinkControlFlowInstructions(); return(program); }
internal void WriteDeclarationAnnotations(DeclarationToken token) { var opcodeType = token.Header.OpcodeType; switch (opcodeType) { case OpcodeType.DclTessDomain: { var dcl = token as TessellatorDomainDeclarationToken; Output.AppendFormat("[domain(\"{0}\")]\n", dcl.Domain.GetAttributeName()); break; } case OpcodeType.DclMaxOutputVertexCount: { var dcl = token as GeometryShaderMaxOutputVertexCountDeclarationToken; Output.AppendFormat("[maxvertexcount({0})]\n", dcl.MaxPrimitives); break; } case OpcodeType.DclThreadGroup: { var dcl = token as ThreadGroupDeclarationToken; Output.AppendFormat("[numthreads({0}, {1}, {2})]\n", dcl.Dimensions[0], dcl.Dimensions[1], dcl.Dimensions[2]); break; } case OpcodeType.DclThreadGroupSharedMemoryStructured: { var dcl = token as StructuredThreadGroupSharedMemoryDeclarationToken; Output.AppendLine("groupshared struct {"); for (int i = 0; i < dcl.StructByteStride; i += 4) { Output.AppendLine($"\tfloat4 m{i / 4};"); } Output.AppendLine($"}} {dcl.Operand.OperandType.GetDescription()}{dcl.Operand.Indices[0].Value}[{dcl.StructCount}];"); break; } case OpcodeType.DclThreadGroupSharedMemoryRaw: { var dcl = token as RawThreadGroupSharedMemoryDeclarationToken; if (dcl.ElementCount != 4) { throw new ArgumentException($"Can't handle dcl_tgsm_raw with element count of {dcl.ElementCount}"); } Output.AppendLine($"groupshared float {dcl.Operand.OperandType.GetDescription()}{dcl.Operand.Indices[0].Value};"); break; } default: break; } }
internal void WriteDeclarationParameter(DeclarationToken token) { switch (token.Header.OpcodeType) { case OpcodeType.DclInput: { break; } } }
void InitOutputDeclaration(DeclarationToken token) { var key = token.Operand.OperandType.GetDescription(); switch (token.Operand.OperandType) { case OperandType.OutputDepth: { var register = new Register("depth"); AddRegister(key, register); OutputRegisters.Add(register); break; } case OperandType.OutputCoverageMask: { var register = new Register("coverageMask"); AddRegister(key, register); OutputRegisters.Add(register); break; } case OperandType.OutputDepthGreaterEqual: { var register = new Register("depthGE"); AddRegister(key, register); OutputRegisters.Add(register); break; } case OperandType.OutputDepthLessEqual: { var register = new Register("depthLE"); AddRegister(key, register); OutputRegisters.Add(register); break; } case OperandType.StencilRef: { var register = new Register("oStencilRef"); AddRegister(key, register); OutputRegisters.Add(register); break; } case OperandType.Output: break; default: throw new NotImplementedException($"{token}"); } }
private void WriteDeclrations(DeclarationToken decl) { if (decl is TempRegisterDeclarationToken temps) { WriteIndent(); Write("float4 "); for (int i = 0; i < temps.TempCount; i++) { WriteFormat("r{0}", i); if (i < temps.TempCount - 1) { Write(", "); } } Write(";"); WriteLineFormat(" // {0}", decl.ToString()); } else { WriteIndent(); WriteLineFormat("// Not implemented [{0}]: {1}", decl.Header.OpcodeType, decl.ToString()); } }
internal void WriteDeclarationVariables(DeclarationToken token) { }
internal void LogDeclaration(DeclarationToken token) { DebugLog(token); }
void InitInputDeclaration(DeclarationToken token) { var key = token.Operand.OperandType.GetDescription(); switch (token.Operand.OperandType) { case OperandType.InputCoverageMask: { var register = new Register("coverage"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.OutputDepth: { var register = new Register("depth"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.OutputCoverageMask: { var register = new Register("coverageMask"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputThreadGroupID: { var register = new Register("threadGroupID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputThreadID: { var register = new Register("threadID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputThreadIDInGroup: { var register = new Register("threadIDInGroup"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputThreadIDInGroupFlattened: { var register = new Register("threadIDInGroupFlattened"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputPrimitiveID: { var register = new Register("inputPrimitiveID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputForkInstanceID: { var register = new Register("forkInstanceID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputGSInstanceID: { var register = new Register("gsInstanceID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.InputDomainPoint: { var register = new Register("domain"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.OutputControlPointID: { var register = new Register("outputControlPointID"); AddRegister(key, register); InputRegisters.Add(register); break; } case OperandType.Input: { // TODO break; } case OperandType.InputControlPoint: { // TODO break; } case OperandType.OutputControlPoint: { // TODO break; } case OperandType.InputPatchConstant: { // TODO break; } case OperandType.InnerCoverage: { // TODO break; } case OperandType.StencilRef: { // TODO break; } default: throw new NotImplementedException($"{token}"); } }