//Read D3D11_SHADER_TYPE_DESC static void ReadShaderVariableType(const uint32_t ui32MajorVersion, const uint32_t* pui32FirstConstBufToken, const uint32_t* pui32tokens, ShaderVarType* varType) { const uint16_t* pui16Tokens = (const uint16_t*) pui32tokens; uint16_t ui32MemberCount; uint32_t ui32MemberOffset; const uint32_t* pui32MemberTokens; uint32_t i; varType->Class = (SHADER_VARIABLE_CLASS)pui16Tokens[0]; varType->Type = (SHADER_VARIABLE_TYPE)pui16Tokens[1]; varType->Rows = pui16Tokens[2]; varType->Columns = pui16Tokens[3]; varType->Elements = pui16Tokens[4]; varType->MemberCount = ui32MemberCount = pui16Tokens[5]; varType->Members = 0; if(varType->ParentCount) { ASSERT( (strlen(varType->Parent->FullName) + 1 + strlen(varType->Name) + 1 + 2) < MAX_REFLECT_STRING_LENGTH); strcpy(varType->FullName, varType->Parent->FullName); strcat(varType->FullName, "."); strcat(varType->FullName, varType->Name); } if(ui32MemberCount) { varType->Members = (ShaderVarType*)hlslcc_malloc(sizeof(ShaderVarType)*ui32MemberCount); ui32MemberOffset = pui32tokens[3]; pui32MemberTokens = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberOffset); for(i=0; i< ui32MemberCount; ++i) { uint32_t ui32NameOffset = *pui32MemberTokens++; uint32_t ui32MemberTypeOffset = *pui32MemberTokens++; varType->Members[i].Parent = varType; varType->Members[i].ParentCount = varType->ParentCount + 1; varType->Members[i].Offset = *pui32MemberTokens++; ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), varType->Members[i].Name); ReadShaderVariableType(ui32MajorVersion, pui32FirstConstBufToken, (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberTypeOffset), &varType->Members[i]); } } }
static void ReadPatchConstantSignatures(const uint32_t* pui32Tokens, ShaderInfo* psShaderInfo, const int minPrec, const int streams) { uint32_t i; InOutSignature* psSignatures; const uint32_t* pui32FirstSignatureToken = pui32Tokens; const uint32_t ui32ElementCount = *pui32Tokens++; const uint32_t ui32Key = *pui32Tokens++; psSignatures = hlslcc_malloc(sizeof(InOutSignature) * ui32ElementCount); psShaderInfo->psPatchConstantSignatures = psSignatures; psShaderInfo->ui32NumPatchConstantSignatures = ui32ElementCount; for(i=0; i<ui32ElementCount; ++i) { uint32_t ui32ComponentMasks; InOutSignature* psCurrentSignature = psSignatures + i; uint32_t ui32SemanticNameOffset; psCurrentSignature->ui32Stream = 0; psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT; if(streams) psCurrentSignature->ui32Stream = *pui32Tokens++; ui32SemanticNameOffset = *pui32Tokens++; psCurrentSignature->ui32SemanticIndex = *pui32Tokens++; psCurrentSignature->eSystemValueType = (SPECIAL_NAME)*pui32Tokens++; psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *pui32Tokens++; psCurrentSignature->ui32Register = *pui32Tokens++; // Massage some special inputs/outputs to match the types of GLSL counterparts if (psCurrentSignature->eSystemValueType == NAME_RENDER_TARGET_ARRAY_INDEX) { psCurrentSignature->eComponentType = INOUT_COMPONENT_SINT32; } ui32ComponentMasks = *pui32Tokens++; psCurrentSignature->ui32Mask = ui32ComponentMasks & 0x7F; //Shows which components are NEVER written. psCurrentSignature->ui32ReadWriteMask = (ui32ComponentMasks & 0x7F00) >> 8; if(minPrec) psCurrentSignature->eMinPrec = *pui32Tokens++; ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken+ui32SemanticNameOffset), psCurrentSignature->SemanticName); } }
static void ReadInputSignatures(const uint32_t* pui32Tokens, ShaderInfo* psShaderInfo, const int extended) { uint32_t i; InOutSignature* psSignatures; const uint32_t* pui32FirstSignatureToken = pui32Tokens; const uint32_t ui32ElementCount = *pui32Tokens++; const uint32_t ui32Key = *pui32Tokens++; psSignatures = hlslcc_malloc(sizeof(InOutSignature) * ui32ElementCount); psShaderInfo->psInputSignatures = psSignatures; psShaderInfo->ui32NumInputSignatures = ui32ElementCount; for(i=0; i<ui32ElementCount; ++i) { uint32_t ui32ComponentMasks; InOutSignature* psCurrentSignature = psSignatures + i; uint32_t ui32SemanticNameOffset; psCurrentSignature->ui32Stream = 0; psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT; if(extended) psCurrentSignature->ui32Stream = *pui32Tokens++; ui32SemanticNameOffset = *pui32Tokens++; psCurrentSignature->ui32SemanticIndex = *pui32Tokens++; psCurrentSignature->eSystemValueType = (SPECIAL_NAME) *pui32Tokens++; psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *pui32Tokens++; psCurrentSignature->ui32Register = *pui32Tokens++; ui32ComponentMasks = *pui32Tokens++; psCurrentSignature->ui32Mask = ui32ComponentMasks & 0x7F; //Shows which components are read psCurrentSignature->ui32ReadWriteMask = (ui32ComponentMasks & 0x7F00) >> 8; if(extended) psCurrentSignature->eMinPrec = *pui32Tokens++; ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken+ui32SemanticNameOffset), psCurrentSignature->SemanticName); } }
HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename, unsigned int flags, GLLang language, const GlExtensions *extensions, GLSLCrossDependencyData* dependencies, GLSLShader* result) { FILE* shaderFile; int length; size_t readLength; char* shader; int success = 0; shaderFile = fopen(filename, "rb"); if(!shaderFile) { return 0; } fseek(shaderFile, 0, SEEK_END); length = ftell(shaderFile); fseek(shaderFile, 0, SEEK_SET); shader = (char*)hlslcc_malloc(length+1); readLength = fread(shader, 1, length, shaderFile); fclose(shaderFile); shaderFile = 0; shader[readLength] = '\0'; success = TranslateHLSLFromMem(shader, flags, language, extensions, dependencies, result); hlslcc_free(shader); return success; }
static void ReadInterfaces(const uint32_t* pui32Tokens, ShaderInfo* psShaderInfo) { uint32_t i; uint32_t ui32StartSlot; const uint32_t* pui32FirstInterfaceToken = pui32Tokens; const uint32_t ui32ClassInstanceCount = *pui32Tokens++; const uint32_t ui32ClassTypeCount = *pui32Tokens++; const uint32_t ui32InterfaceSlotRecordCount = *pui32Tokens++; const uint32_t ui32InterfaceSlotCount = *pui32Tokens++; const uint32_t ui32ClassInstanceOffset = *pui32Tokens++; const uint32_t ui32ClassTypeOffset = *pui32Tokens++; const uint32_t ui32InterfaceSlotOffset = *pui32Tokens++; const uint16_t* pui16ClassTypes = (const uint16_t*)((const char*)pui32FirstInterfaceToken + ui32ClassTypeOffset); const uint16_t* pui16ClassInstances = (const uint16_t*)((const char*)pui32FirstInterfaceToken + ui32ClassInstanceOffset); const uint32_t* pui32InterfaceSlots = (const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32InterfaceSlotOffset); const uint32_t* pui32InterfaceSlotTokens = pui32InterfaceSlots; ClassType* psClassTypes; ClassInstance* psClassInstances; psClassTypes = hlslcc_malloc(sizeof(ClassType) * ui32ClassTypeCount); for(i=0; i<ui32ClassTypeCount; ++i) { pui16ClassTypes = ReadClassType(pui32FirstInterfaceToken, pui16ClassTypes, psClassTypes+i); psClassTypes[i].ui16ID = (uint16_t)i; } psClassInstances = hlslcc_malloc(sizeof(ClassInstance) * ui32ClassInstanceCount); for(i=0; i<ui32ClassInstanceCount; ++i) { pui16ClassInstances = ReadClassInstance(pui32FirstInterfaceToken, pui16ClassInstances, psClassInstances+i); } //Slots map function table to $ThisPointer cbuffer variable index ui32StartSlot = 0; for(i=0; i<ui32InterfaceSlotRecordCount; ++i) { uint32_t k; const uint32_t ui32SlotSpan = *pui32InterfaceSlotTokens++; const uint32_t ui32Count = *pui32InterfaceSlotTokens++; const uint32_t ui32TypeIDOffset = *pui32InterfaceSlotTokens++; const uint32_t ui32TableIDOffset = *pui32InterfaceSlotTokens++; const uint16_t* pui16TypeID = (const uint16_t*)((const char*)pui32FirstInterfaceToken+ui32TypeIDOffset); const uint32_t* pui32TableID = (const uint32_t*)((const char*)pui32FirstInterfaceToken+ui32TableIDOffset); for(k=0; k < ui32Count; ++k) { psShaderInfo->aui32TableIDToTypeID[*pui32TableID++] = *pui16TypeID++; } ui32StartSlot += ui32SlotSpan; } psShaderInfo->ui32NumClassInstances = ui32ClassInstanceCount; psShaderInfo->psClassInstances = psClassInstances; psShaderInfo->ui32NumClassTypes = ui32ClassTypeCount; psShaderInfo->psClassTypes = psClassTypes; }
static void ReadResources(const uint32_t* pui32Tokens,//in ShaderInfo* psShaderInfo)//out { ResourceBinding* psResBindings; ConstantBuffer* psConstantBuffers; const uint32_t* pui32ConstantBuffers; const uint32_t* pui32ResourceBindings; const uint32_t* pui32FirstToken = pui32Tokens; uint32_t i; const uint32_t ui32NumConstantBuffers = *pui32Tokens++; const uint32_t ui32ConstantBufferOffset = *pui32Tokens++; uint32_t ui32NumResourceBindings = *pui32Tokens++; uint32_t ui32ResourceBindingOffset = *pui32Tokens++; uint32_t ui32ShaderModel = *pui32Tokens++; uint32_t ui32CompileFlags = *pui32Tokens++;//D3DCompile flags? http://msdn.microsoft.com/en-us/library/gg615083(v=vs.85).aspx //Resources pui32ResourceBindings = (const uint32_t*)((const char*)pui32FirstToken + ui32ResourceBindingOffset); psResBindings = hlslcc_malloc(sizeof(ResourceBinding)*ui32NumResourceBindings); psShaderInfo->ui32NumResourceBindings = ui32NumResourceBindings; psShaderInfo->psResourceBindings = psResBindings; for(i=0; i < ui32NumResourceBindings; ++i) { pui32ResourceBindings = ReadResourceBinding(pui32FirstToken, pui32ResourceBindings, psResBindings+i); ASSERT(psResBindings[i].ui32BindPoint < MAX_RESOURCE_BINDINGS); } //Constant buffers pui32ConstantBuffers = (const uint32_t*)((const char*)pui32FirstToken + ui32ConstantBufferOffset); psConstantBuffers = hlslcc_malloc(sizeof(ConstantBuffer) * ui32NumConstantBuffers); psShaderInfo->ui32NumConstantBuffers = ui32NumConstantBuffers; psShaderInfo->psConstantBuffers = psConstantBuffers; for(i=0; i < ui32NumConstantBuffers; ++i) { pui32ConstantBuffers = ReadConstantBuffer(psShaderInfo, pui32FirstToken, pui32ConstantBuffers, psConstantBuffers+i); } //Map resource bindings to constant buffers if(psShaderInfo->ui32NumConstantBuffers) { for(i=0; i < ui32NumResourceBindings; ++i) { ResourceGroup eRGroup; uint32_t cbufIndex = 0; eRGroup = ResourceTypeToResourceGroup(psResBindings[i].eType); //Find the constant buffer whose name matches the resource at the given resource binding point for(cbufIndex=0; cbufIndex < psShaderInfo->ui32NumConstantBuffers; cbufIndex++) { if(strcmp(psConstantBuffers[cbufIndex].Name, psResBindings[i].Name) == 0) { psShaderInfo->aui32ResourceMap[eRGroup][psResBindings[i].ui32BindPoint] = cbufIndex; } } } } }
static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo, const uint32_t* pui32FirstConstBufToken, const uint32_t* pui32Tokens, ConstantBuffer* psBuffer) { uint32_t i; uint32_t ui32NameOffset = *pui32Tokens++; uint32_t ui32VarCount = *pui32Tokens++; uint32_t ui32VarOffset = *pui32Tokens++; const uint32_t* pui32VarToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32VarOffset); ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), psBuffer->Name); FormatVariableName(psBuffer->Name); psBuffer->ui32NumVars = ui32VarCount; psBuffer->asVars = hlslcc_malloc(psBuffer->ui32NumVars * sizeof(ShaderVar)); for(i=0; i<ui32VarCount; ++i) { //D3D11_SHADER_VARIABLE_DESC ShaderVar * const psVar = &psBuffer->asVars[i]; uint32_t ui32Flags; uint32_t ui32TypeOffset; uint32_t ui32DefaultValueOffset; ui32NameOffset = *pui32VarToken++; ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken+ui32NameOffset), psVar->Name); FormatVariableName(psVar->Name); psVar->ui32StartOffset = *pui32VarToken++; psVar->ui32Size = *pui32VarToken++; ui32Flags = *pui32VarToken++; ui32TypeOffset = *pui32VarToken++; strcpy(psVar->sType.Name, psVar->Name); strcpy(psVar->sType.FullName, psVar->Name); psVar->sType.Parent = 0; psVar->sType.ParentCount = 0; psVar->sType.Offset = 0; ReadShaderVariableType(psShaderInfo->ui32MajorVersion, pui32FirstConstBufToken, (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32TypeOffset), &psVar->sType); ui32DefaultValueOffset = *pui32VarToken++; if (psShaderInfo->ui32MajorVersion >= 5) { uint32_t StartTexture = *pui32VarToken++; uint32_t TextureSize = *pui32VarToken++; uint32_t StartSampler = *pui32VarToken++; uint32_t SamplerSize = *pui32VarToken++; } psVar->haveDefaultValue = 0; if(ui32DefaultValueOffset) { uint32_t i = 0; const uint32_t ui32NumDefaultValues = psVar->ui32Size / 4; const uint32_t* pui32DefaultValToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32DefaultValueOffset); //Always a sequence of 4-bytes at the moment. //bool const becomes 0 or 0xFFFFFFFF int, int & float are 4-bytes. ASSERT(psVar->ui32Size%4 == 0); psVar->haveDefaultValue = 1; psVar->pui32DefaultValues = hlslcc_malloc(psVar->ui32Size); for(i=0; i<ui32NumDefaultValues; ++i) { psVar->pui32DefaultValues[i] = pui32DefaultValToken[i]; } } } { uint32_t ui32Flags; uint32_t ui32BufferType; psBuffer->ui32TotalSizeInBytes = *pui32Tokens++; ui32Flags = *pui32Tokens++; ui32BufferType = *pui32Tokens++; } return pui32Tokens; }
void LoadD3D9ConstantTable(const char* data, ShaderInfo* psInfo) { ConstantTableD3D9* ctab; uint32_t constNum; ConstantInfoD3D9* cinfos; ConstantBuffer* psConstantBuffer; uint32_t ui32ConstantBufferSize = 0; uint32_t numResourceBindingsNeeded = 0; ShaderVar* var; ctab = (ConstantTableD3D9*)data; cinfos = (ConstantInfoD3D9*) (data + ctab->constantInfos); psInfo->ui32NumConstantBuffers++; //Only 1 Constant Table in d3d9 ASSERT(psInfo->ui32NumConstantBuffers==1); psConstantBuffer = hlslcc_malloc(sizeof(ConstantBuffer)); psInfo->psConstantBuffers = psConstantBuffer; psConstantBuffer->ui32NumVars = 0; strcpy(psConstantBuffer->Name, "$Globals"); //Determine how many resource bindings to create for(constNum = 0; constNum < ctab->constants; ++constNum) { if(cinfos[constNum].registerSet == RS_SAMPLER) { ++numResourceBindingsNeeded; } } psInfo->psResourceBindings = hlslcc_malloc(numResourceBindingsNeeded*sizeof(ResourceBinding)); psConstantBuffer->asVars = hlslcc_malloc((ctab->constants - numResourceBindingsNeeded) * sizeof(ShaderVar)); var = &psConstantBuffer->asVars[0]; for(constNum = 0; constNum < ctab->constants; ++constNum) { TypeInfoD3D9* typeInfo = (TypeInfoD3D9*) (data + cinfos[constNum].typeInfo); if(cinfos[constNum].registerSet != RS_SAMPLER) { strcpy(var->Name, data + cinfos[constNum].name); FormatVariableName(var->Name); var->ui32Size = cinfos[constNum].registerCount * 16; var->ui32StartOffset = cinfos[constNum].registerIndex * 16; var->haveDefaultValue = 0; if(ui32ConstantBufferSize < (var->ui32Size + var->ui32StartOffset)) { ui32ConstantBufferSize = var->ui32Size + var->ui32StartOffset; } var->sType.Rows = typeInfo->rows; var->sType.Columns = typeInfo->columns; var->sType.Elements = typeInfo->elements; var->sType.MemberCount = typeInfo->structMembers; var->sType.Members = 0; var->sType.Offset = 0; strcpy(var->sType.FullName, var->Name); var->sType.Parent = 0; var->sType.ParentCount = 0; switch(typeInfo->typeClass) { case CLASS_SCALAR: { var->sType.Class = SVC_SCALAR; break; } case CLASS_VECTOR: { var->sType.Class = SVC_VECTOR; break; } case CLASS_MATRIX_ROWS: { var->sType.Class = SVC_MATRIX_ROWS; break; } case CLASS_MATRIX_COLUMNS: { var->sType.Class = SVC_MATRIX_COLUMNS; break; } case CLASS_OBJECT: { var->sType.Class = SVC_OBJECT; break; } case CLASS_STRUCT: { var->sType.Class = SVC_STRUCT; break; } } switch(cinfos[constNum].registerSet) { case RS_BOOL: { var->sType.Type = SVT_BOOL; break; } case RS_INT4: { var->sType.Type = SVT_INT; break; } case RS_FLOAT4: { var->sType.Type = SVT_FLOAT; break; } } var++; psConstantBuffer->ui32NumVars++; } else { //Create a resource if it is sampler in order to replicate the d3d10+ //method of separating samplers from general constants. uint32_t ui32ResourceIndex = psInfo->ui32NumResourceBindings++; ResourceBinding* res = &psInfo->psResourceBindings[ui32ResourceIndex]; strcpy(res->Name, data + cinfos[constNum].name); FormatVariableName(res->Name); res->ui32BindPoint = cinfos[constNum].registerIndex; res->ui32BindCount = cinfos[constNum].registerCount; res->ui32Flags = 0; res->ui32NumSamples = 1; res->ui32ReturnType = 0; res->eType = RTYPE_TEXTURE; switch(typeInfo->type) { case PT_SAMPLER: case PT_SAMPLER1D: res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE1D; break; case PT_SAMPLER2D: res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE2D; break; case PT_SAMPLER3D: res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURE3D; break; case PT_SAMPLERCUBE: res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURECUBE; break; } } } psConstantBuffer->ui32TotalSizeInBytes = ui32ConstantBufferSize; }