#pragma once #include #include #include #include #include "growing_array.h" #include //Reflection #define MAX_RESOURCE_BINDINGS 256 typedef enum _SHADER_VARIABLE_TYPE { SVT_VOID = 0, SVT_BOOL = 1, SVT_INT = 2, SVT_FLOAT = 3, SVT_STRING = 4, SVT_TEXTURE = 5, SVT_TEXTURE1D = 6, SVT_TEXTURE2D = 7, SVT_TEXTURE3D = 8, SVT_TEXTURECUBE = 9, SVT_SAMPLER = 10, SVT_PIXELSHADER = 15, SVT_VERTEXSHADER = 16, SVT_UINT = 19, SVT_UINT8 = 20, SVT_GEOMETRYSHADER = 21, SVT_RASTERIZER = 22, SVT_DEPTHSTENCIL = 23, SVT_BLEND = 24, SVT_BUFFER = 25, SVT_CBUFFER = 26, SVT_TBUFFER = 27, SVT_TEXTURE1DARRAY = 28, SVT_TEXTURE2DARRAY = 29, SVT_RENDERTARGETVIEW = 30, SVT_DEPTHSTENCILVIEW = 31, SVT_TEXTURE2DMS = 32, SVT_TEXTURE2DMSARRAY = 33, SVT_TEXTURECUBEARRAY = 34, SVT_HULLSHADER = 35, SVT_DOMAINSHADER = 36, SVT_INTERFACE_POINTER = 37, SVT_COMPUTESHADER = 38, SVT_DOUBLE = 39, SVT_RWTEXTURE1D = 40, SVT_RWTEXTURE1DARRAY = 41, SVT_RWTEXTURE2D = 42, SVT_RWTEXTURE2DARRAY = 43, SVT_RWTEXTURE3D = 44, SVT_RWBUFFER = 45, SVT_BYTEADDRESS_BUFFER = 46, SVT_RWBYTEADDRESS_BUFFER = 47, SVT_STRUCTURED_BUFFER = 48, SVT_RWSTRUCTURED_BUFFER = 49, SVT_APPEND_STRUCTURED_BUFFER = 50, SVT_CONSUME_STRUCTURED_BUFFER = 51, // Only used as a marker when analyzing register types SVT_FORCED_INT = 152, // Integer that can be either signed or unsigned. Only used as an intermediate step when doing data type analysis SVT_INT_AMBIGUOUS = 153, // Partial precision types. Used when doing type analysis SVT_FLOAT10 = 53, // Seems to be used in constant buffers SVT_FLOAT16 = 54, SVT_INT16 = 156, SVT_INT12 = 157, SVT_UINT16 = 158, SVT_FORCE_DWORD = 0x7fffffff } SHADER_VARIABLE_TYPE; typedef enum _SHADER_VARIABLE_CLASS { SVC_SCALAR = 0, SVC_VECTOR = (SVC_SCALAR + 1), SVC_MATRIX_ROWS = (SVC_VECTOR + 1), SVC_MATRIX_COLUMNS = (SVC_MATRIX_ROWS + 1), SVC_OBJECT = (SVC_MATRIX_COLUMNS + 1), SVC_STRUCT = (SVC_OBJECT + 1), SVC_INTERFACE_CLASS = (SVC_STRUCT + 1), SVC_INTERFACE_POINTER = (SVC_INTERFACE_CLASS + 1), SVC_FORCE_DWORD = 0x7fffffff } SHADER_VARIABLE_CLASS; /////////////////////////////////////// // Types enum TESSELLATOR_PARTITIONING { TESSELLATOR_PARTITIONING_UNDEFINED = 0, TESSELLATOR_PARTITIONING_INTEGER = 1, TESSELLATOR_PARTITIONING_POW2 = 2, TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4 }; enum TESSELLATOR_OUTPUT_PRIMITIVE { TESSELLATOR_OUTPUT_UNDEFINED = 0, TESSELLATOR_OUTPUT_POINT = 1, TESSELLATOR_OUTPUT_LINE = 2, TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4 }; typedef enum TESSELLATOR_DOMAIN { TESSELLATOR_DOMAIN_UNDEFINED = 0, TESSELLATOR_DOMAIN_ISOLINE = 1, TESSELLATOR_DOMAIN_TRI = 2, TESSELLATOR_DOMAIN_QUAD = 3 } TESSELLATOR_DOMAIN; enum SPECIAL_NAME { NAME_UNDEFINED = 0, NAME_POSITION = 1, NAME_CLIP_DISTANCE = 2, NAME_CULL_DISTANCE = 3, NAME_RENDER_TARGET_ARRAY_INDEX = 4, NAME_VIEWPORT_ARRAY_INDEX = 5, NAME_VERTEX_ID = 6, NAME_PRIMITIVE_ID = 7, NAME_INSTANCE_ID = 8, NAME_IS_FRONT_FACE = 9, NAME_SAMPLE_INDEX = 10, // The following are added for D3D11 NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR = 11, NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR = 12, NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR = 13, NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR = 14, NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR = 15, NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR = 16, NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR = 17, NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR = 18, NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR = 19, NAME_FINAL_TRI_INSIDE_TESSFACTOR = 20, NAME_FINAL_LINE_DETAIL_TESSFACTOR = 21, NAME_FINAL_LINE_DENSITY_TESSFACTOR = 22, }; enum INOUT_COMPONENT_TYPE { INOUT_COMPONENT_UNKNOWN = 0, INOUT_COMPONENT_UINT32 = 1, INOUT_COMPONENT_SINT32 = 2, INOUT_COMPONENT_FLOAT32 = 3 }; enum MIN_PRECISION { MIN_PRECISION_DEFAULT = 0, MIN_PRECISION_FLOAT_16 = 1, MIN_PRECISION_FLOAT_2_8 = 2, MIN_PRECISION_RESERVED = 3, MIN_PRECISION_SINT_16 = 4, MIN_PRECISION_UINT_16 = 5, MIN_PRECISION_ANY_16 = 0xf0, MIN_PRECISION_ANY_10 = 0xf1 }; enum ResourceType { RTYPE_CBUFFER,//0 RTYPE_TBUFFER,//1 RTYPE_TEXTURE,//2 RTYPE_SAMPLER,//3 RTYPE_UAV_RWTYPED,//4 RTYPE_STRUCTURED,//5 RTYPE_UAV_RWSTRUCTURED,//6 RTYPE_BYTEADDRESS,//7 RTYPE_UAV_RWBYTEADDRESS,//8 RTYPE_UAV_APPEND_STRUCTURED,//9 RTYPE_UAV_CONSUME_STRUCTURED,//10 RTYPE_UAV_RWSTRUCTURED_WITH_COUNTER,//11 RTYPE_COUNT, }; enum ResourceGroup { RGROUP_CBUFFER, RGROUP_TEXTURE, RGROUP_SAMPLER, RGROUP_UAV, RGROUP_COUNT, }; enum REFLECT_RESOURCE_DIMENSION { REFLECT_RESOURCE_DIMENSION_UNKNOWN = 0, REFLECT_RESOURCE_DIMENSION_BUFFER = 1, REFLECT_RESOURCE_DIMENSION_TEXTURE1D = 2, REFLECT_RESOURCE_DIMENSION_TEXTURE1DARRAY = 3, REFLECT_RESOURCE_DIMENSION_TEXTURE2D = 4, REFLECT_RESOURCE_DIMENSION_TEXTURE2DARRAY = 5, REFLECT_RESOURCE_DIMENSION_TEXTURE2DMS = 6, REFLECT_RESOURCE_DIMENSION_TEXTURE2DMSARRAY = 7, REFLECT_RESOURCE_DIMENSION_TEXTURE3D = 8, REFLECT_RESOURCE_DIMENSION_TEXTURECUBE = 9, REFLECT_RESOURCE_DIMENSION_TEXTURECUBEARRAY = 10, REFLECT_RESOURCE_DIMENSION_BUFFEREX = 11, }; enum REFLECT_RESOURCE_PRECISION { REFLECT_RESOURCE_PRECISION_UNKNOWN = 0, REFLECT_RESOURCE_PRECISION_LOWP = 1, REFLECT_RESOURCE_PRECISION_MEDIUMP = 2, REFLECT_RESOURCE_PRECISION_HIGHP = 3, }; enum RESOURCE_RETURN_TYPE { RETURN_TYPE_UNORM = 1, RETURN_TYPE_SNORM = 2, RETURN_TYPE_SINT = 3, RETURN_TYPE_UINT = 4, RETURN_TYPE_FLOAT = 5, RETURN_TYPE_MIXED = 6, RETURN_TYPE_DOUBLE = 7, RETURN_TYPE_CONTINUED = 8, RETURN_TYPE_UNUSED = 9, }; typedef std::map HLSLccSamplerPrecisionInfo; struct ResourceBinding { std::string name; ResourceType eType; uint32_t ui32BindPoint; uint32_t ui32BindCount; uint32_t ui32Flags; uint32_t ui32Space; uint32_t ui32RangeID; REFLECT_RESOURCE_DIMENSION eDimension; RESOURCE_RETURN_TYPE ui32ReturnType; uint32_t ui32NumSamples; REFLECT_RESOURCE_PRECISION ePrecision; int m_SamplerMode; // (SB_SAMPLER_MODE) For samplers, this is the sampler mode this sampler is declared with SHADER_VARIABLE_TYPE GetDataType() const { switch (ePrecision) { case REFLECT_RESOURCE_PRECISION_LOWP: switch (ui32ReturnType) { case RETURN_TYPE_UNORM: case RETURN_TYPE_SNORM: case RETURN_TYPE_FLOAT: return SVT_FLOAT10; case RETURN_TYPE_SINT: return SVT_INT16; case RETURN_TYPE_UINT: return SVT_UINT16; default: // ASSERT(0); return SVT_FLOAT10; } case REFLECT_RESOURCE_PRECISION_MEDIUMP: switch (ui32ReturnType) { case RETURN_TYPE_UNORM: case RETURN_TYPE_SNORM: case RETURN_TYPE_FLOAT: return SVT_FLOAT16; case RETURN_TYPE_SINT: return SVT_INT16; case RETURN_TYPE_UINT: return SVT_UINT16; default: // ASSERT(0); return SVT_FLOAT16; } default: switch (ui32ReturnType) { case RETURN_TYPE_UNORM: case RETURN_TYPE_SNORM: case RETURN_TYPE_FLOAT: return SVT_FLOAT; case RETURN_TYPE_SINT: return SVT_INT; case RETURN_TYPE_UINT: return SVT_UINT; case RETURN_TYPE_DOUBLE: return SVT_DOUBLE; default: // ASSERT(0); return SVT_FLOAT; } } } }; struct ShaderVarType { ShaderVarType() : Class(), Type(), Rows(), Columns(), Elements(), MemberCount(), Offset(), ParentCount(), Parent(), m_IsUsed(false) {} SHADER_VARIABLE_CLASS Class; SHADER_VARIABLE_TYPE Type; uint32_t Rows; uint32_t Columns; uint32_t Elements; uint32_t MemberCount; uint32_t Offset; std::string name; uint32_t ParentCount; struct ShaderVarType * Parent; //Includes all parent names. std::string fullName; std::vector Members; bool m_IsUsed; // If not set, is not used in the shader code uint32_t GetMemberCount() const { if (Class == SVC_STRUCT) { uint32_t res = 0; std::vector::const_iterator itr; for (itr = Members.begin(); itr != Members.end(); itr++) { res += itr->GetMemberCount(); } return res; } else return 1; } }; struct ShaderVar { std::string name; int haveDefaultValue; std::vector pui32DefaultValues; //Offset/Size in bytes. uint32_t ui32StartOffset; uint32_t ui32Size; ShaderVarType sType; }; struct ConstantBuffer { std::string name; std::vector asVars; uint32_t ui32TotalSizeInBytes; uint32_t GetMemberCount(bool stripUnused) const { uint32_t res = 0; std::vector::const_iterator itr; for (itr = asVars.begin(); itr != asVars.end(); itr++) { if (stripUnused && !itr->sType.m_IsUsed) continue; res += itr->sType.GetMemberCount(); } return res; } }; struct ClassType { std::string name; uint16_t ui16ID; uint16_t ui16ConstBufStride; uint16_t ui16Texture; uint16_t ui16Sampler; }; struct ClassInstance { std::string name; uint16_t ui16ID; uint16_t ui16ConstBuf; uint16_t ui16ConstBufOffset; uint16_t ui16Texture; uint16_t ui16Sampler; }; class Operand; class ShaderInfo { public: struct InOutSignature { std::string semanticName; uint32_t ui32SemanticIndex; SPECIAL_NAME eSystemValueType; INOUT_COMPONENT_TYPE eComponentType; uint32_t ui32Register; uint32_t ui32Mask; uint32_t ui32ReadWriteMask; int iRebase; // If mask does not start from zero, this indicates the offset that needs to be subtracted from each swizzle uint32_t ui32Stream; MIN_PRECISION eMinPrec; std::set isIndexed; // Set of phases where this input/output is part of a index range. std::map indexStart; // If indexed, contains the start index for the range std::map index; // If indexed, contains the current index relative to the index start. }; ShaderInfo() : ui32MajorVersion(), ui32MinorVersion(), psResourceBindings(), psConstantBuffers(), psThisPointerConstBuffer(), psClassTypes(), psClassInstances() {} SHADER_VARIABLE_TYPE GetTextureDataType(uint32_t regNo); int GetResourceFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ResourceBinding** ppsOutBinding) const; void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ConstantBuffer** ppsConstBuf) const; int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderVar** ppsShaderVar) const; int GetInputSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32Mask, const InOutSignature** ppsOut, bool allowNull = false) const; int GetPatchConstantSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32Mask, const InOutSignature** ppsOut, bool allowNull = false) const; int GetOutputSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32CompMask, const uint32_t ui32Stream, const InOutSignature** ppsOut, bool allowNull = false) const; int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, const InOutSignature** ppsOut) const; static ResourceGroup ResourceTypeToResourceGroup(ResourceType); static uint32_t GetCBVarSize(const ShaderVarType* psType, bool matrixAsVectors, bool wholeArraySize = false); static int GetShaderVarFromOffset(const uint32_t ui32Vec4Offset, const uint32_t(&pui32Swizzle)[4], const ConstantBuffer* psCBuf, const ShaderVarType** ppsShaderVar, bool* isArray, std::vector* arrayIndices, int32_t* pi32Rebase, uint32_t flags); static std::string GetShaderVarIndexedFullName(const ShaderVarType* psShaderVar, const std::vector& indices, const std::string& dynamicIndex, bool revertDynamicIndexCalc, bool matrixAsVectors); // Apply shader precision information to resource bindings void AddSamplerPrecisions(HLSLccSamplerPrecisionInfo &info); uint32_t ui32MajorVersion; uint32_t ui32MinorVersion; std::vector psInputSignatures; std::vector psOutputSignatures; std::vector psPatchConstantSignatures; std::vector psResourceBindings; std::vector psConstantBuffers; ConstantBuffer* psThisPointerConstBuffer; std::vector psClassTypes; std::vector psClassInstances; //Func table ID to class name ID. HLSLcc::growing_vector aui32TableIDToTypeID; HLSLcc::growing_vector aui32ResourceMap[RGROUP_COUNT]; HLSLcc::growing_vector sGroupSharedVarType; TESSELLATOR_PARTITIONING eTessPartitioning; TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim; uint32_t ui32TessInputControlPointCount; uint32_t ui32TessOutputControlPointCount; TESSELLATOR_DOMAIN eTessDomain; bool bEarlyFragmentTests; };