// Find the declaration of the texture described by psTextureOperand and // mark it as a shadow type. (e.g. accessed via sampler2DShadow rather than sampler2D) void MarkTextureAsShadow(ShaderInfo* psShaderInfo, Declaration* psDeclList, const uint32_t ui32DeclCount, const Operand* psTextureOperand) { ResourceBinding* psBinding = 0; int found; ASSERT(psTextureOperand->eType == OPERAND_TYPE_RESOURCE); found = GetResourceFromBindingPoint(RTYPE_TEXTURE, psTextureOperand->ui32RegisterNumber, psShaderInfo, &psBinding); if(found) { Declaration* psDecl = psDeclList; uint32_t i; for(i = 0; i < ui32DeclCount; ++i) { if(psDecl->eOpcode == OPCODE_DCL_RESOURCE) { if(psDecl->asOperands[0].eType == OPERAND_TYPE_RESOURCE && psDecl->asOperands[0].ui32RegisterNumber == psTextureOperand->ui32RegisterNumber) { psDecl->ui32IsShadowTex = 1; break; } } psDecl++; } } }
void TextureName(HLSLCrossCompilerContext* psContext, const uint32_t ui32RegisterNumber, const int bZCompare) { bstring glsl = *psContext->currentGLSLString; ResourceBinding* psBinding = 0; int found; found = GetResourceFromBindingPoint(RGROUP_TEXTURE, ui32RegisterNumber, &psContext->psShader->sInfo, &psBinding); if(bZCompare) { bcatcstr(glsl, "hlslcc_zcmp_"); } if(found) { int i = 0; char name[MAX_REFLECT_STRING_LENGTH]; uint32_t ui32ArrayOffset = ui32RegisterNumber - psBinding->ui32BindPoint; while(psBinding->Name[i] != '\0' && i < (MAX_REFLECT_STRING_LENGTH-1)) { name[i] = psBinding->Name[i]; //array syntax [X] becomes _0_ //Otherwise declarations could end up as: //uniform sampler2D SomeTextures[0]; //uniform sampler2D SomeTextures[1]; if(name[i] == '[' || name[i] == ']') name[i] = '_'; ++i; } name[i] = '\0'; if(ui32ArrayOffset) { bformata(glsl, "%s%d", name, ui32ArrayOffset); } else { bformata(glsl, "%s", name); } } else { bformata(glsl, "UnknownResource%d", ui32RegisterNumber); } }
const uint32_t* DecodeDeclaration(Shader* psShader, const uint32_t* pui32Token, Declaration* psDecl) { uint32_t ui32TokenLength = DecodeInstructionLength(*pui32Token); const uint32_t bExtended = DecodeIsOpcodeExtended(*pui32Token); const OPCODE_TYPE eOpcode = DecodeOpcodeType(*pui32Token); uint32_t ui32OperandOffset = 1; psDecl->eOpcode = eOpcode; psDecl->ui32IsShadowTex = 0; if(bExtended) { ui32OperandOffset = 2; } switch (eOpcode) { case OPCODE_DCL_RESOURCE: // DCL* opcodes have { psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token); psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_CONSTANT_BUFFER: // custom operand formats. { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_SAMPLER: { break; } case OPCODE_DCL_INDEX_RANGE: { psDecl->ui32NumOperands = 1; ui32OperandOffset += DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); psDecl->value.ui32IndexRange = pui32Token[ui32OperandOffset]; if(psDecl->asOperands[0].eType == OPERAND_TYPE_INPUT) { uint32_t i; const uint32_t indexRange = psDecl->value.ui32IndexRange; const uint32_t reg = psDecl->asOperands[0].ui32RegisterNumber; psShader->aIndexedInput[reg] = indexRange; psShader->aIndexedInputParents[reg] = reg; //-1 means don't declare this input because it falls in //the range of an already declared array. for(i=reg+1; i<reg+indexRange; ++i) { psShader->aIndexedInput[i] = -1; psShader->aIndexedInputParents[i] = reg; } } if(psDecl->asOperands[0].eType == OPERAND_TYPE_OUTPUT) { psShader->aIndexedOutput[psDecl->asOperands[0].ui32RegisterNumber] = psDecl->value.ui32IndexRange; } break; } case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: { psDecl->value.eOutputPrimitiveTopology = DecodeGSOutputPrimitiveTopology(*pui32Token); break; } case OPCODE_DCL_GS_INPUT_PRIMITIVE: { psDecl->value.eInputPrimitive = DecodeGSInputPrimitive(*pui32Token); break; } case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: { psDecl->value.ui32MaxOutputVertexCount = pui32Token[1]; break; } case OPCODE_DCL_TESS_PARTITIONING: { psDecl->value.eTessPartitioning = DecodeTessPartitioning(*pui32Token); break; } case OPCODE_DCL_TESS_DOMAIN: { psDecl->value.eTessDomain = DecodeTessDomain(*pui32Token); break; } case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: { psDecl->value.eTessOutPrim = DecodeTessOutPrim(*pui32Token); break; } case OPCODE_DCL_THREAD_GROUP: { psDecl->value.aui32WorkGroupSize[0] = pui32Token[1]; psDecl->value.aui32WorkGroupSize[1] = pui32Token[2]; psDecl->value.aui32WorkGroupSize[2] = pui32Token[3]; break; } case OPCODE_DCL_INPUT: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_INPUT_SIV: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); if(psShader->eShaderType == PIXEL_SHADER) { psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); } break; } case OPCODE_DCL_INPUT_PS: { psDecl->ui32NumOperands = 1; psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_INPUT_SGV: case OPCODE_DCL_INPUT_PS_SGV: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]); break; } case OPCODE_DCL_INPUT_PS_SIV: { psDecl->value.eInterpolation = DecodeInterpolationMode(*pui32Token); break; } case OPCODE_DCL_OUTPUT: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_OUTPUT_SGV: { break; } case OPCODE_DCL_OUTPUT_SIV: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); DecodeNameToken(pui32Token + 3, &psDecl->asOperands[0]); break; } case OPCODE_DCL_TEMPS: { psDecl->value.ui32NumTemps = *(pui32Token+ui32OperandOffset); break; } case OPCODE_DCL_INDEXABLE_TEMP: { break; } case OPCODE_DCL_GLOBAL_FLAGS: { psDecl->value.ui32GlobalFlags = DecodeGlobalFlags(*pui32Token); break; } case OPCODE_DCL_INTERFACE: { uint32_t func = 0, numClassesImplementingThisInterface, arrayLen, interfaceID; interfaceID = pui32Token[ui32OperandOffset]; ui32OperandOffset++; psDecl->ui32TableLength = pui32Token[ui32OperandOffset]; ui32OperandOffset++; numClassesImplementingThisInterface = DecodeInterfaceTableLength(*(pui32Token+ui32OperandOffset)); arrayLen = DecodeInterfaceArrayLength(*(pui32Token+ui32OperandOffset)); ui32OperandOffset++; psDecl->value.interface.ui32InterfaceID = interfaceID; psDecl->value.interface.ui32NumFuncTables = numClassesImplementingThisInterface; psDecl->value.interface.ui32ArraySize = arrayLen; psShader->funcPointer[interfaceID].ui32NumBodiesPerTable = psDecl->ui32TableLength; for(;func < numClassesImplementingThisInterface; ++func) { uint32_t ui32FuncTable = *(pui32Token+ui32OperandOffset); psShader->aui32FuncTableToFuncPointer[ui32FuncTable] = interfaceID; psShader->funcPointer[interfaceID].aui32FuncTables[func] = ui32FuncTable; ui32OperandOffset++; } break; } case OPCODE_DCL_FUNCTION_BODY: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_FUNCTION_TABLE: { uint32_t ui32Func; const uint32_t ui32FuncTableID = pui32Token[ui32OperandOffset++]; const uint32_t ui32NumFuncsInTable = pui32Token[ui32OperandOffset++]; for(ui32Func=0; ui32Func<ui32NumFuncsInTable;++ui32Func) { const uint32_t ui32FuncBodyID = pui32Token[ui32OperandOffset++]; psShader->aui32FuncBodyToFuncTable[ui32FuncBodyID] = ui32FuncTableID; psShader->funcTable[ui32FuncTableID].aui32FuncBodies[ui32Func] = ui32FuncBodyID; } // OpcodeToken0 is followed by a DWORD that represents the function table // identifier and another DWORD (TableLength) that gives the number of // functions in the table. // // This is followed by TableLength DWORDs which are function body indices. // break; } case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: { break; } case OPCODE_HS_DECLS: { break; } case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: { psDecl->value.ui32MaxOutputVertexCount = DecodeOutputControlPointCount(*pui32Token); break; } case OPCODE_HS_JOIN_PHASE: case OPCODE_HS_FORK_PHASE: case OPCODE_HS_CONTROL_POINT_PHASE: { break; } case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: { ASSERT(psShader->ui32ForkPhaseCount != 0);//Check for wrapping when we decrement. psDecl->value.aui32HullPhaseInstanceInfo[0] = psShader->ui32ForkPhaseCount-1; psDecl->value.aui32HullPhaseInstanceInfo[1] = pui32Token[1]; break; } case OPCODE_CUSTOMDATA: { ui32TokenLength = pui32Token[1]; { int iTupleSrc = 0, iTupleDest = 0; //const uint32_t ui32ConstCount = pui32Token[1] - 2; //const uint32_t ui32TupleCount = (ui32ConstCount / 4); CUSTOMDATA_CLASS eClass = DecodeCustomDataClass(pui32Token[0]); const uint32_t ui32NumVec4 = (ui32TokenLength - 2) / 4; uint32_t uIdx = 0; ICBVec4 const *pVec4Array = (void*) (pui32Token + 2); //The buffer will contain at least one value, but not more than 4096 scalars/1024 vec4's. ASSERT(ui32NumVec4 < MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE); /* must be a multiple of 4 */ ASSERT(((ui32TokenLength - 2) % 4) == 0); for (uIdx = 0; uIdx < ui32NumVec4; uIdx++) { psDecl->asImmediateConstBuffer[uIdx] = pVec4Array[uIdx]; } psDecl->ui32NumOperands = ui32NumVec4; } break; } case OPCODE_DCL_HS_MAX_TESSFACTOR: { psDecl->value.fMaxTessFactor = *((float*)&pui32Token[1]); break; } case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: { psDecl->ui32NumOperands = 1; psDecl->value.eResourceDimension = DecodeResourceDimension(*pui32Token); psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: { ResourceBinding* psBinding = NULL; ConstantBuffer* psBuffer = NULL; psDecl->ui32NumOperands = 1; psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); if(GetResourceFromBindingPoint(RTYPE_UAV_RWBYTEADDRESS, psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psBinding)) { GetConstantBufferFromBindingPoint(psBinding->ui32BindPoint, &psShader->sInfo, &psBuffer); psDecl->sUAV.ui32BufferSize = psBuffer->ui32TotalSizeInBytes; } break; } case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: { ResourceBinding* psBinding = NULL; ConstantBuffer* psBuffer = NULL; psDecl->ui32NumOperands = 1; psDecl->sUAV.ui32GloballyCoherentAccess = DecodeAccessCoherencyFlags(*pui32Token); DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); if(GetResourceFromBindingPoint(RTYPE_UAV_RWSTRUCTURED, psDecl->asOperands[0].ui32RegisterNumber, &psShader->sInfo, &psBinding)) { GetUAVBufferFromBindingPoint(psBinding->ui32BindPoint, &psShader->sInfo, &psBuffer); psDecl->sUAV.ui32BufferSize = psBuffer->ui32TotalSizeInBytes; } break; } case OPCODE_DCL_RESOURCE_STRUCTURED: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } case OPCODE_DCL_RESOURCE_RAW: { psDecl->ui32NumOperands = 1; DecodeOperand(pui32Token+ui32OperandOffset, &psDecl->asOperands[0]); break; } default: { //Reached end of declarations return 0; } } return pui32Token + ui32TokenLength; }