5a261a7fe8
- Bunch of fixes for issues found during SRP Lightweight and HD RP development - Fix indentation issues from generated Metal output - Metal Tessellation fixes - Improve ES2 support - Merge "fix issue with negation of (bool->int) result" #22 (https://github.com/Unity-Technologies/HLSLcc/pull/22) - Merge "Updated to support basic parsing of resources for Shader Model 5.1" #27 (https://github.com/Unity-Technologies/HLSLcc/pull/27) - Partial merge of "bugfix request" #37 (https://github.com/Unity-Technologies/HLSLcc/pull/37)
511 lines
14 KiB
C++
511 lines
14 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
#include <map>
|
|
#include <string>
|
|
#include "growing_array.h"
|
|
#include <stdint.h>
|
|
|
|
//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<std::string, REFLECT_RESOURCE_PRECISION> 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<struct ShaderVarType> 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<struct ShaderVarType>::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<uint32_t> pui32DefaultValues;
|
|
//Offset/Size in bytes.
|
|
uint32_t ui32StartOffset;
|
|
uint32_t ui32Size;
|
|
|
|
ShaderVarType sType;
|
|
};
|
|
|
|
struct ConstantBuffer
|
|
{
|
|
std::string name;
|
|
|
|
std::vector<ShaderVar> asVars;
|
|
|
|
uint32_t ui32TotalSizeInBytes;
|
|
|
|
uint32_t GetMemberCount(bool stripUnused) const
|
|
{
|
|
uint32_t res = 0;
|
|
std::vector<ShaderVar>::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<uint32_t> isIndexed; // Set of phases where this input/output is part of a index range.
|
|
std::map<uint32_t, uint32_t> indexStart; // If indexed, contains the start index for the range
|
|
std::map<uint32_t, uint32_t> 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<uint32_t>* arrayIndices,
|
|
int32_t* pi32Rebase,
|
|
uint32_t flags);
|
|
|
|
static std::string GetShaderVarIndexedFullName(const ShaderVarType* psShaderVar, const std::vector<uint32_t>& 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<InOutSignature> psInputSignatures;
|
|
std::vector<InOutSignature> psOutputSignatures;
|
|
std::vector<InOutSignature> psPatchConstantSignatures;
|
|
|
|
std::vector<ResourceBinding> psResourceBindings;
|
|
|
|
std::vector<ConstantBuffer> psConstantBuffers;
|
|
ConstantBuffer* psThisPointerConstBuffer;
|
|
|
|
std::vector<ClassType> psClassTypes;
|
|
std::vector<ClassInstance> psClassInstances;
|
|
|
|
//Func table ID to class name ID.
|
|
HLSLcc::growing_vector<uint32_t> aui32TableIDToTypeID;
|
|
|
|
HLSLcc::growing_vector<uint32_t> aui32ResourceMap[RGROUP_COUNT];
|
|
|
|
HLSLcc::growing_vector<ShaderVarType> sGroupSharedVarType;
|
|
|
|
TESSELLATOR_PARTITIONING eTessPartitioning;
|
|
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
|
|
uint32_t ui32TessInputControlPointCount;
|
|
uint32_t ui32TessOutputControlPointCount;
|
|
TESSELLATOR_DOMAIN eTessDomain;
|
|
bool bEarlyFragmentTests;
|
|
};
|