diff options
Diffstat (limited to 'build/tools/HLSLcc/May_2014/src/reflect.c')
| -rw-r--r-- | build/tools/HLSLcc/May_2014/src/reflect.c | 1085 |
1 files changed, 1085 insertions, 0 deletions
diff --git a/build/tools/HLSLcc/May_2014/src/reflect.c b/build/tools/HLSLcc/May_2014/src/reflect.c new file mode 100644 index 0000000..297f19f --- /dev/null +++ b/build/tools/HLSLcc/May_2014/src/reflect.c @@ -0,0 +1,1085 @@ + +#include "internal_includes/reflect.h" +#include "internal_includes/debug.h" +#include "internal_includes/decode.h" +#include "internal_includes/hlslcc_malloc.h" +#include "bstrlib.h" +#include <stdlib.h> +#include <stdio.h> + +static void FormatVariableName(char* Name) +{ + /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/bb944006(v=vs.85).aspx + The uniform function parameters appear in the + constant table prepended with a dollar sign ($), + unlike the global variables. The dollar sign is + required to avoid name collisions between local + uniform inputs and global variables of the same name.*/ + + /* Leave $ThisPointer, $Element and $Globals as-is. + Otherwise remove $ character ($ is not a valid character for GLSL variable names). */ + if(Name[0] == '$') + { + if(strcmp(Name, "$Element") !=0 && + strcmp(Name, "$Globals") != 0 && + strcmp(Name, "$ThisPointer") != 0) + { + Name[0] = '_'; + } + } +} + +static void FormatConstantName(char* Name, char* cbName, int varIndex) +{ + _snprintf(Name, MAX_REFLECT_STRING_LENGTH, "%s_%d", cbName, varIndex); +} + +static void ReadStringFromTokenStream(const uint32_t* tokens, char* str) +{ + char* charTokens = (char*) tokens; + char nextCharacter = *charTokens++; + int length = 0; + + //Add each individual character until + //a terminator is found. + while(nextCharacter != 0) { + + str[length++] = nextCharacter; + + if(length > MAX_REFLECT_STRING_LENGTH) + { + str[length-1] = '\0'; + return; + } + + nextCharacter = *charTokens++; + } + + str[length] = '\0'; +} + +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 = D3D_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); + } +} + +static void ReadOutputSignatures(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->psOutputSignatures = psSignatures; + psShaderInfo->ui32NumOutputSignatures = ui32ElementCount; + + for(i=0; i<ui32ElementCount; ++i) + { + uint32_t ui32ComponentMasks; + InOutSignature* psCurrentSignature = psSignatures + i; + uint32_t ui32SemanticNameOffset; + + psCurrentSignature->ui32Stream = 0; + psCurrentSignature->eMinPrec = D3D_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++; + + 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 const uint32_t* ReadResourceBinding(const uint32_t* pui32FirstResourceToken, const uint32_t* pui32Tokens, ResourceBinding* psBinding) +{ + uint32_t ui32NameOffset = *pui32Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstResourceToken+ui32NameOffset), psBinding->Name); + FormatVariableName(psBinding->Name); + + psBinding->eType = *pui32Tokens++; + psBinding->ui32ReturnType = *pui32Tokens++; + psBinding->eDimension = (REFLECT_RESOURCE_DIMENSION)*pui32Tokens++; + psBinding->ui32NumSamples = *pui32Tokens++; + psBinding->ui32BindPoint = *pui32Tokens++; + psBinding->ui32BindCount = *pui32Tokens++; + psBinding->ui32Flags = *pui32Tokens++; + + return pui32Tokens; +} + +//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 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; + + 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); + FormatConstantName(psVar->Name, psBuffer->Name, i); + + 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; +} + +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 uint16_t* ReadClassType(const uint32_t* pui32FirstInterfaceToken, const uint16_t* pui16Tokens, ClassType* psClassType) +{ + const uint32_t* pui32Tokens = (const uint32_t*)pui16Tokens; + uint32_t ui32NameOffset = *pui32Tokens; + pui16Tokens+= 2; + + psClassType->ui16ID = *pui16Tokens++; + psClassType->ui16ConstBufStride = *pui16Tokens++; + psClassType->ui16Texture = *pui16Tokens++; + psClassType->ui16Sampler = *pui16Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken+ui32NameOffset), psClassType->Name); + + return pui16Tokens; +} + +static const uint16_t* ReadClassInstance(const uint32_t* pui32FirstInterfaceToken, const uint16_t* pui16Tokens, ClassInstance* psClassInstance) +{ + uint32_t ui32NameOffset = *pui16Tokens++ << 16; + ui32NameOffset |= *pui16Tokens++; + + psClassInstance->ui16ID = *pui16Tokens++; + psClassInstance->ui16ConstBuf = *pui16Tokens++; + psClassInstance->ui16ConstBufOffset = *pui16Tokens++; + psClassInstance->ui16Texture = *pui16Tokens++; + psClassInstance->ui16Sampler = *pui16Tokens++; + + ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken+ui32NameOffset), psClassInstance->Name); + + return pui16Tokens; +} + + +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; +} + +void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ConstantBuffer** ppsConstBuf) +{ + if(psShaderInfo->ui32MajorVersion > 3) + { + *ppsConstBuf = psShaderInfo->psConstantBuffers + psShaderInfo->aui32ResourceMap[eGroup][ui32BindPoint]; + } + else + { + ASSERT(psShaderInfo->ui32NumConstantBuffers == 1); + *ppsConstBuf = psShaderInfo->psConstantBuffers; + } +} + +int GetResourceFromBindingPoint(const ResourceGroup eGroup, uint32_t const ui32BindPoint, const ShaderInfo* psShaderInfo, ResourceBinding** ppsOutBinding) +{ + uint32_t i; + const uint32_t ui32NumBindings = psShaderInfo->ui32NumResourceBindings; + ResourceBinding* psBindings = psShaderInfo->psResourceBindings; + + for(i=0; i<ui32NumBindings; ++i) + { + if(ResourceTypeToResourceGroup(psBindings[i].eType) == eGroup) + { + if(ui32BindPoint >= psBindings[i].ui32BindPoint && ui32BindPoint < (psBindings[i].ui32BindPoint + psBindings[i].ui32BindCount)) + { + *ppsOutBinding = psBindings + i; + return 1; + } + } + } + return 0; +} + +int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderInfo* psShaderInfo, ShaderVar** ppsShaderVar) +{ + uint32_t i; + ConstantBuffer* psThisPointerConstBuffer = psShaderInfo->psThisPointerConstBuffer; + + const uint32_t ui32NumVars = psThisPointerConstBuffer->ui32NumVars; + + for(i=0; i<ui32NumVars; ++i) + { + if(ui32Offset >= psThisPointerConstBuffer->asVars[i].ui32StartOffset && + ui32Offset < (psThisPointerConstBuffer->asVars[i].ui32StartOffset + psThisPointerConstBuffer->asVars[i].ui32Size)) + { + *ppsShaderVar = &psThisPointerConstBuffer->asVars[i]; + return 1; + } + } + return 0; +} + +int GetInputSignatureFromRegister(const uint32_t ui32Register, const ShaderInfo* psShaderInfo, InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumInputSignatures; + + for(i=0; i<ui32NumVars; ++i) + { + InOutSignature* psInputSignatures = psShaderInfo->psInputSignatures; + if(ui32Register == psInputSignatures[i].ui32Register) + { + *ppsOut = psInputSignatures+i; + return 1; + } + } + return 0; +} + +int GetOutputSignatureFromRegister(const uint32_t ui32Register, + const uint32_t ui32CompMask, + const uint32_t ui32Stream, + ShaderInfo* psShaderInfo, + InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumOutputSignatures; + + for(i=0; i<ui32NumVars; ++i) + { + InOutSignature* psOutputSignatures = psShaderInfo->psOutputSignatures; + if(ui32Register == psOutputSignatures[i].ui32Register && + (ui32CompMask & psOutputSignatures[i].ui32Mask) && + ui32Stream == psOutputSignatures[i].ui32Stream) + { + *ppsOut = psOutputSignatures+i; + return 1; + } + } + return 0; +} + +int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, ShaderInfo* psShaderInfo, InOutSignature** ppsOut) +{ + uint32_t i; + const uint32_t ui32NumVars = psShaderInfo->ui32NumOutputSignatures; + + for(i=0; i<ui32NumVars; ++i) + { + InOutSignature* psOutputSignatures = psShaderInfo->psOutputSignatures; + if(eSystemValueType == psOutputSignatures[i].eSystemValueType && + ui32SemanticIndex == psOutputSignatures[i].ui32SemanticIndex) + { + *ppsOut = psOutputSignatures+i; + return 1; + } + } + return 0; +} + +static int IsOffsetInType(ShaderVarType* psType, + uint32_t parentOffset, + uint32_t offsetToFind, + const uint32_t* pui32Swizzle, + int32_t* pi32Index, + int32_t* pi32Rebase) +{ + uint32_t thisOffset = parentOffset + psType->Offset; + uint32_t thisSize = psType->Columns * psType->Rows * 4; + + if(psType->Elements) + { + thisSize *= psType->Elements; + } + + //Swizzle can point to another variable. In the example below + //cbUIUpdates.g_uMaxFaces would be cb1[2].z. The scalars are combined + //into vectors. psCBuf->ui32NumVars will be 3. + + // cbuffer cbUIUpdates + // { + // + // float g_fLifeSpan; // Offset: 0 Size: 4 + // float g_fLifeSpanVar; // Offset: 4 Size: 4 [unused] + // float g_fRadiusMin; // Offset: 8 Size: 4 [unused] + // float g_fRadiusMax; // Offset: 12 Size: 4 [unused] + // float g_fGrowTime; // Offset: 16 Size: 4 [unused] + // float g_fStepSize; // Offset: 20 Size: 4 + // float g_fTurnRate; // Offset: 24 Size: 4 + // float g_fTurnSpeed; // Offset: 28 Size: 4 [unused] + // float g_fLeafRate; // Offset: 32 Size: 4 + // float g_fShrinkTime; // Offset: 36 Size: 4 [unused] + // uint g_uMaxFaces; // Offset: 40 Size: 4 + // + // } + + // Name Type Format Dim Slot Elements + // ------------------------------ ---------- ------- ----------- ---- -------- + // cbUIUpdates cbuffer NA NA 1 1 + + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_Y) + { + offsetToFind += 4; + } + else + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_Z) + { + offsetToFind += 8; + } + else + if(pui32Swizzle[0] == OPERAND_4_COMPONENT_W) + { + offsetToFind += 12; + } + + if((offsetToFind >= thisOffset) && + offsetToFind < (thisOffset + thisSize)) + { + + if(psType->Class == SVC_MATRIX_ROWS || + psType->Class == SVC_MATRIX_COLUMNS) + { + //Matrices are treated as arrays of vectors. + pi32Index[0] = (offsetToFind - thisOffset) / 16; + } + //Check for array of vectors + else if(psType->Class == SVC_VECTOR && psType->Elements > 1) + { + pi32Index[0] = (offsetToFind - thisOffset) / 16; + } + else if(psType->Class == SVC_VECTOR && psType->Columns > 1) + { + //Check for vector starting at a non-vec4 offset. + + // cbuffer $Globals + // { + // + // float angle; // Offset: 0 Size: 4 + // float2 angle2; // Offset: 4 Size: 8 + // + // } + + //cb0[0].x = angle + //cb0[0].yzyy = angle2.xyxx + + //Rebase angle2 so that .y maps to .x, .z maps to .y + + pi32Rebase[0] = thisOffset % 16; + } + + return 1; + } + return 0; +} + +int GetShaderVarFromOffset(const uint32_t ui32Vec4Offset, + const uint32_t* pui32Swizzle, + ConstantBuffer* psCBuf, + ShaderVarType** ppsShaderVar, + int32_t* pi32Index, + int32_t* pi32Rebase) +{ + uint32_t i; + const uint32_t ui32BaseByteOffset = ui32Vec4Offset * 16; + + uint32_t ui32ByteOffset = ui32Vec4Offset * 16; + + const uint32_t ui32NumVars = psCBuf->ui32NumVars; + + for(i=0; i<ui32NumVars; ++i) + { + if(psCBuf->asVars[i].sType.Class == SVC_STRUCT) + { + uint32_t m = 0; + + for(m=0; m < psCBuf->asVars[i].sType.MemberCount; ++m) + { + ShaderVarType* psMember = psCBuf->asVars[i].sType.Members + m; + + ASSERT(psMember->Class != SVC_STRUCT); + + if(IsOffsetInType(psMember, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, pui32Swizzle, pi32Index, pi32Rebase)) + { + ppsShaderVar[0] = psMember; + return 1; + } + } + } + else + { + if(IsOffsetInType(&psCBuf->asVars[i].sType, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, pui32Swizzle, pi32Index, pi32Rebase)) + { + ppsShaderVar[0] = &psCBuf->asVars[i].sType; + return 1; + } + } + } + return 0; +} + +ResourceGroup ResourceTypeToResourceGroup(ResourceType eType) +{ + switch(eType) + { + case RTYPE_CBUFFER: + return RGROUP_CBUFFER; + + case RTYPE_SAMPLER: + return RGROUP_SAMPLER; + + case RTYPE_TEXTURE: + case RTYPE_BYTEADDRESS: + case RTYPE_STRUCTURED: + return RGROUP_TEXTURE; + + case RTYPE_UAV_RWTYPED: + case RTYPE_UAV_RWSTRUCTURED: + case RTYPE_UAV_RWBYTEADDRESS: + case RTYPE_UAV_APPEND_STRUCTURED: + case RTYPE_UAV_CONSUME_STRUCTURED: + case RTYPE_UAV_RWSTRUCTURED_WITH_COUNTER: + return RGROUP_UAV; + + case RTYPE_TBUFFER: + ASSERT(0); // Need to find out which group this belongs to + return RGROUP_TEXTURE; + } + + ASSERT(0); + return RGROUP_CBUFFER; +} + +void LoadShaderInfo(const uint32_t ui32MajorVersion, + const uint32_t ui32MinorVersion, + const ReflectionChunks* psChunks, + ShaderInfo* psInfo) +{ + const uint32_t* pui32Inputs = psChunks->pui32Inputs; + const uint32_t* pui32Inputs11 = psChunks->pui32Inputs11; + const uint32_t* pui32Resources = psChunks->pui32Resources; + const uint32_t* pui32Interfaces = psChunks->pui32Interfaces; + const uint32_t* pui32Outputs = psChunks->pui32Outputs; + const uint32_t* pui32Outputs11 = psChunks->pui32Outputs11; + const uint32_t* pui32OutputsWithStreams = psChunks->pui32OutputsWithStreams; + + psInfo->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED; + psInfo->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED; + + psInfo->ui32MajorVersion = ui32MajorVersion; + psInfo->ui32MinorVersion = ui32MinorVersion; + + + if(pui32Inputs) + ReadInputSignatures(pui32Inputs, psInfo, 0); + if(pui32Inputs11) + ReadInputSignatures(pui32Inputs11, psInfo, 1); + if(pui32Resources) + ReadResources(pui32Resources, psInfo); + if(pui32Interfaces) + ReadInterfaces(pui32Interfaces, psInfo); + if(pui32Outputs) + ReadOutputSignatures(pui32Outputs, psInfo, 0, 0); + if(pui32Outputs11) + ReadOutputSignatures(pui32Outputs11, psInfo, 1, 1); + if(pui32OutputsWithStreams) + ReadOutputSignatures(pui32OutputsWithStreams, psInfo, 0, 1); + + { + uint32_t i; + for(i=0; i<psInfo->ui32NumConstantBuffers;++i) + { + bstring cbufName = bfromcstr(&psInfo->psConstantBuffers[i].Name[0]); + bstring cbufThisPointer = bfromcstr("$ThisPointer"); + if(bstrcmp(cbufName, cbufThisPointer) == 0) + { + psInfo->psThisPointerConstBuffer = &psInfo->psConstantBuffers[i]; + } + } + } +} + +void FreeShaderInfo(ShaderInfo* psShaderInfo) +{ + //Free any default values for constants. + uint32_t cbuf; + for(cbuf=0; cbuf<psShaderInfo->ui32NumConstantBuffers; ++cbuf) + { + ConstantBuffer* psCBuf = &psShaderInfo->psConstantBuffers[cbuf]; + uint32_t var; + for(var=0; var < psCBuf->ui32NumVars; ++var) + { + ShaderVar* psVar = &psCBuf->asVars[var]; + if(psVar->haveDefaultValue) + { + hlslcc_free(psVar->pui32DefaultValues); + } + } + } + hlslcc_free(psShaderInfo->psInputSignatures); + hlslcc_free(psShaderInfo->psResourceBindings); + hlslcc_free(psShaderInfo->psConstantBuffers); + hlslcc_free(psShaderInfo->psClassTypes); + hlslcc_free(psShaderInfo->psClassInstances); + hlslcc_free(psShaderInfo->psOutputSignatures); + + psShaderInfo->ui32NumInputSignatures = 0; + psShaderInfo->ui32NumResourceBindings = 0; + psShaderInfo->ui32NumConstantBuffers = 0; + psShaderInfo->ui32NumClassTypes = 0; + psShaderInfo->ui32NumClassInstances = 0; + psShaderInfo->ui32NumOutputSignatures = 0; +} + +typedef struct ConstantTableD3D9_TAG +{ + uint32_t size; + uint32_t creator; + uint32_t version; + uint32_t constants; + uint32_t constantInfos; + uint32_t flags; + uint32_t target; +} ConstantTableD3D9; + +// These enums match those in d3dx9shader.h. +enum RegisterSet +{ + RS_BOOL, + RS_INT4, + RS_FLOAT4, + RS_SAMPLER, +}; + +enum TypeClass +{ + CLASS_SCALAR, + CLASS_VECTOR, + CLASS_MATRIX_ROWS, + CLASS_MATRIX_COLUMNS, + CLASS_OBJECT, + CLASS_STRUCT, +}; + +enum Type +{ + PT_VOID, + PT_BOOL, + PT_INT, + PT_FLOAT, + PT_STRING, + PT_TEXTURE, + PT_TEXTURE1D, + PT_TEXTURE2D, + PT_TEXTURE3D, + PT_TEXTURECUBE, + PT_SAMPLER, + PT_SAMPLER1D, + PT_SAMPLER2D, + PT_SAMPLER3D, + PT_SAMPLERCUBE, + PT_PIXELSHADER, + PT_VERTEXSHADER, + PT_PIXELFRAGMENT, + PT_VERTEXFRAGMENT, + PT_UNSUPPORTED, +}; +typedef struct ConstantInfoD3D9_TAG +{ + uint32_t name; + uint16_t registerSet; + uint16_t registerIndex; + uint16_t registerCount; + uint16_t reserved; + uint32_t typeInfo; + uint32_t defaultValue; +} ConstantInfoD3D9; + +typedef struct TypeInfoD3D9_TAG +{ + uint16_t typeClass; + uint16_t type; + uint16_t rows; + uint16_t columns; + uint16_t elements; + uint16_t structMembers; + uint32_t structMemberInfos; +} TypeInfoD3D9; + +typedef struct StructMemberInfoD3D9_TAG +{ + uint32_t name; + uint32_t typeInfo; +} StructMemberInfoD3D9; + +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)); + + 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_TEXTURE2D; + break; + case PT_SAMPLERCUBE: + res->eDimension = REFLECT_RESOURCE_DIMENSION_TEXTURECUBE; + break; + } + } + } + psConstantBuffer->ui32TotalSizeInBytes = ui32ConstantBufferSize; +} |