reformat upstream code to latest coding convention ( 281bc7d8cfdb )

This commit is contained in:
Antti Tapaninen 2018-12-22 15:45:19 -08:00
Родитель 467d0a193a
Коммит cb9809a23c
54 изменённых файлов: 28277 добавлений и 28040 удалений

Просмотреть файл

@ -10,398 +10,399 @@
//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,
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,
// 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,
// 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
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
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
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
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_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,
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 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 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,
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 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,
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,
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,
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;
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
std::string name;
ResourceType eType;
uint32_t ui32BindPoint;
uint32_t ui32BindCount;
uint32_t ui32Flags;
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;
}
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;
}
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;
}
}
}
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)
{}
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;
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;
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
std::vector<struct ShaderVarType> Members;
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;
}
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;
std::string name;
int haveDefaultValue;
std::vector<uint32_t> pui32DefaultValues;
//Offset/Size in bytes.
uint32_t ui32StartOffset;
uint32_t ui32Size;
ShaderVarType sType;
ShaderVarType sType;
};
struct ConstantBuffer
{
std::string name;
std::string name;
std::vector<ShaderVar> asVars;
std::vector<ShaderVar> asVars;
uint32_t ui32TotalSizeInBytes;
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;
}
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;
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;
std::string name;
uint16_t ui16ID;
uint16_t ui16ConstBuf;
uint16_t ui16ConstBufOffset;
uint16_t ui16Texture;
uint16_t ui16Sampler;
};
class Operand;
@ -410,100 +411,98 @@ 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;
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
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;
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.
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()
{}
ShaderInfo() :
ui32MajorVersion(),
ui32MinorVersion(),
psResourceBindings(),
psConstantBuffers(),
psThisPointerConstBuffer(),
psClassTypes(),
psClassInstances()
{}
SHADER_VARIABLE_TYPE GetTextureDataType(uint32_t regNo);
SHADER_VARIABLE_TYPE GetTextureDataType(uint32_t regNo);
int GetResourceFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ResourceBinding** ppsOutBinding) const;
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;
void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ConstantBuffer** ppsConstBuf) const;
int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderVar** ppsShaderVar) 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 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;
int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, const InOutSignature** ppsOut) const;
static ResourceGroup ResourceTypeToResourceGroup(ResourceType);
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 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);
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);
// Apply shader precision information to resource bindings
void AddSamplerPrecisions(HLSLccSamplerPrecisionInfo &info);
uint32_t ui32MajorVersion;
uint32_t ui32MinorVersion;
uint32_t ui32MajorVersion;
uint32_t ui32MinorVersion;
std::vector<InOutSignature> psInputSignatures;
std::vector<InOutSignature> psOutputSignatures;
std::vector<InOutSignature> psPatchConstantSignatures;
std::vector<InOutSignature> psInputSignatures;
std::vector<InOutSignature> psOutputSignatures;
std::vector<InOutSignature> psPatchConstantSignatures;
std::vector<ResourceBinding> psResourceBindings;
std::vector<ResourceBinding> psResourceBindings;
std::vector<ConstantBuffer> psConstantBuffers;
ConstantBuffer* psThisPointerConstBuffer;
std::vector<ConstantBuffer> psConstantBuffers;
ConstantBuffer* psThisPointerConstBuffer;
std::vector<ClassType> psClassTypes;
std::vector<ClassInstance> psClassInstances;
std::vector<ClassType> psClassTypes;
std::vector<ClassInstance> psClassInstances;
//Func table ID to class name ID.
HLSLcc::growing_vector<uint32_t> aui32TableIDToTypeID;
//Func table ID to class name ID.
HLSLcc::growing_vector<uint32_t> aui32TableIDToTypeID;
HLSLcc::growing_vector<uint32_t> aui32ResourceMap[RGROUP_COUNT];
HLSLcc::growing_vector<uint32_t> aui32ResourceMap[RGROUP_COUNT];
HLSLcc::growing_vector<ShaderVarType> sGroupSharedVarType;
HLSLcc::growing_vector<ShaderVarType> sGroupSharedVarType;
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t ui32TessInputControlPointCount;
uint32_t ui32TessOutputControlPointCount;
TESSELLATOR_DOMAIN eTessDomain;
bool bEarlyFragmentTests;
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t ui32TessInputControlPointCount;
uint32_t ui32TessOutputControlPointCount;
TESSELLATOR_DOMAIN eTessDomain;
bool bEarlyFragmentTests;
};

Просмотреть файл

@ -2,46 +2,44 @@
namespace HLSLcc
{
// A vector that automatically grows when written to, fills the intermediate ones with default value.
// Reading from an index returns the default value if attempting to access out of bounds.
template <class T> class growing_vector
{
public:
growing_vector() : data() {}
// A vector that automatically grows when written to, fills the intermediate ones with default value.
// Reading from an index returns the default value if attempting to access out of bounds.
template<class T> class growing_vector
{
public:
growing_vector() : data() {}
std::vector<T> data;
std::vector<T> data;
T & operator[](std::size_t idx)
{
if (idx >= data.size())
data.resize((idx + 1) * 2);
return data[idx];
}
T & operator[](std::size_t idx)
{
if (idx >= data.size())
data.resize((idx + 1) * 2);
return data[idx];
}
const T & operator[](std::size_t idx) const
{
static T defaultValue = T();
if (idx >= data.size())
return defaultValue;
return data[idx];
}
const T & operator[](std::size_t idx) const
{
static T defaultValue = T();
if (idx >= data.size())
return defaultValue;
return data[idx];
}
};
};
// Same but with bool specialization
template<> class growing_vector<bool>
{
public:
growing_vector() : data() {}
// Same but with bool specialization
template <> class growing_vector<bool>
{
public:
growing_vector() : data() {}
std::vector<bool> data;
std::vector<bool> data;
std::vector<bool>::reference operator[](std::size_t idx)
{
if (idx >= data.size())
data.resize((idx + 1) * 2, false);
return data[idx];
}
};
};
std::vector<bool>::reference operator[](std::size_t idx)
{
if (idx >= data.size())
data.resize((idx + 1) * 2, false);
return data[idx];
}
};
}

Просмотреть файл

@ -6,7 +6,7 @@
#include <map>
#include <algorithm>
#if defined (_WIN32) && defined(HLSLCC_DYNLIB)
#if defined(_WIN32) && defined(HLSLCC_DYNLIB)
#define HLSLCC_APIENTRY __stdcall
#if defined(libHLSLcc_EXPORTS)
#define HLSLCC_API __declspec(dllexport)
@ -24,9 +24,9 @@
typedef enum
{
LANG_DEFAULT,// Depends on the HLSL shader model.
LANG_ES_100, LANG_ES_FIRST=LANG_ES_100,
LANG_ES_100, LANG_ES_FIRST = LANG_ES_100,
LANG_ES_300,
LANG_ES_310, LANG_ES_LAST = LANG_ES_310,
LANG_ES_310, LANG_ES_LAST = LANG_ES_310,
LANG_120, LANG_GL_FIRST = LANG_120,
LANG_130,
LANG_140,
@ -37,15 +37,16 @@ typedef enum
LANG_420,
LANG_430,
LANG_440, LANG_GL_LAST = LANG_440,
LANG_METAL,
LANG_METAL,
} GLLang;
typedef struct GlExtensions {
uint32_t ARB_explicit_attrib_location : 1;
uint32_t ARB_explicit_uniform_location : 1;
uint32_t ARB_shading_language_420pack : 1;
uint32_t OVR_multiview : 1;
uint32_t EXT_shader_framebuffer_fetch : 1;
typedef struct GlExtensions
{
uint32_t ARB_explicit_attrib_location : 1;
uint32_t ARB_explicit_uniform_location : 1;
uint32_t ARB_shading_language_420pack : 1;
uint32_t OVR_multiview : 1;
uint32_t EXT_shader_framebuffer_fetch : 1;
} GlExtensions;
#include "ShaderInfo.h"
@ -65,11 +66,11 @@ typedef enum INTERPOLATION_MODE
INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
} INTERPOLATION_MODE;
#define PS_FLAG_VERTEX_SHADER 0x1
#define PS_FLAG_HULL_SHADER 0x2
#define PS_FLAG_DOMAIN_SHADER 0x4
#define PS_FLAG_VERTEX_SHADER 0x1
#define PS_FLAG_HULL_SHADER 0x2
#define PS_FLAG_DOMAIN_SHADER 0x4
#define PS_FLAG_GEOMETRY_SHADER 0x8
#define PS_FLAG_PIXEL_SHADER 0x10
#define PS_FLAG_PIXEL_SHADER 0x10
#define TO_FLAG_NONE 0x0
#define TO_FLAG_INTEGER 0x1
@ -99,42 +100,42 @@ typedef enum INTERPOLATION_MODE
typedef enum
{
INVALID_SHADER = -1,
PIXEL_SHADER,
VERTEX_SHADER,
GEOMETRY_SHADER,
HULL_SHADER,
DOMAIN_SHADER,
COMPUTE_SHADER,
INVALID_SHADER = -1,
PIXEL_SHADER,
VERTEX_SHADER,
GEOMETRY_SHADER,
HULL_SHADER,
DOMAIN_SHADER,
COMPUTE_SHADER,
} SHADER_TYPE;
// Enum for texture dimension reflection data
// Enum for texture dimension reflection data
typedef enum
{
TD_FLOAT = 0,
TD_INT,
TD_2D,
TD_3D,
TD_CUBE,
TD_2DSHADOW,
TD_2DARRAY,
TD_CUBEARRAY
TD_FLOAT = 0,
TD_INT,
TD_2D,
TD_3D,
TD_CUBE,
TD_2DSHADOW,
TD_2DARRAY,
TD_CUBEARRAY
} HLSLCC_TEX_DIMENSION;
// The prefix for all temporary variables used by the generated code.
// Using a texture or uniform name like this will cause conflicts
#define HLSLCC_TEMP_PREFIX "u_xlat"
typedef std::vector<std::pair<std::string, std::string>> MemberDefinitions;
typedef std::vector<std::pair<std::string, std::string> > MemberDefinitions;
// We store struct definition contents inside a vector of strings
struct StructDefinition
{
StructDefinition() : m_Members(), m_Dependencies(), m_IsPrinted(false) {}
StructDefinition() : m_Members(), m_Dependencies(), m_IsPrinted(false) {}
MemberDefinitions m_Members; // A vector of strings with the struct members
std::vector<std::string> m_Dependencies; // A vector of struct names this struct depends on.
bool m_IsPrinted; // Has this struct been printed out yet?
MemberDefinitions m_Members; // A vector of strings with the struct members
std::vector<std::string> m_Dependencies; // A vector of struct names this struct depends on.
bool m_IsPrinted; // Has this struct been printed out yet?
};
typedef std::map<std::string, StructDefinition> StructDefinitions;
@ -146,65 +147,65 @@ typedef std::map<std::string, std::string> FunctionDefinitions;
// (because both UAVs and textures use the same slots in Metal, also constant buffers and other buffers etc)
class BindingSlotAllocator
{
typedef std::map<uint32_t, uint32_t> SlotMap;
SlotMap m_Allocations;
uint32_t m_ShaderStageAllocations;
typedef std::map<uint32_t, uint32_t> SlotMap;
SlotMap m_Allocations;
uint32_t m_ShaderStageAllocations;
public:
BindingSlotAllocator() : m_Allocations(), m_ShaderStageAllocations(0)
{
for(int i = MAX_RESOURCE_BINDINGS-1; i >= 0; i --)
m_FreeSlots.push_back(i);
}
BindingSlotAllocator() : m_Allocations(), m_ShaderStageAllocations(0)
{
for (int i = MAX_RESOURCE_BINDINGS - 1; i >= 0; i--)
m_FreeSlots.push_back(i);
}
enum BindType
{
ConstantBuffer = 0,
RWBuffer,
Texture,
UAV
};
enum BindType
{
ConstantBuffer = 0,
RWBuffer,
Texture,
UAV
};
uint32_t GetBindingSlot(uint32_t regNo, BindType type)
{
// The key is regNumber with the bindtype stored to highest 16 bits
uint32_t key = (m_ShaderStageAllocations + regNo) | (uint32_t(type) << 16);
SlotMap::iterator itr = m_Allocations.find(key);
if(itr == m_Allocations.end())
{
uint32_t slot = m_FreeSlots.back();
m_FreeSlots.pop_back();
m_Allocations.insert(std::make_pair(key, slot));
return slot;
}
return itr->second;
}
uint32_t GetBindingSlot(uint32_t regNo, BindType type)
{
// The key is regNumber with the bindtype stored to highest 16 bits
uint32_t key = (m_ShaderStageAllocations + regNo) | (uint32_t(type) << 16);
SlotMap::iterator itr = m_Allocations.find(key);
if (itr == m_Allocations.end())
{
uint32_t slot = m_FreeSlots.back();
m_FreeSlots.pop_back();
m_Allocations.insert(std::make_pair(key, slot));
return slot;
}
return itr->second;
}
// Func for reserving binding slots with the original reg number.
// Used for fragment shader UAVs (SetRandomWriteTarget etc).
void ReserveBindingSlot(uint32_t regNo, BindType type)
{
uint32_t key = regNo | (uint32_t(type) << 16);
m_Allocations.insert(std::make_pair(key, regNo));
// Func for reserving binding slots with the original reg number.
// Used for fragment shader UAVs (SetRandomWriteTarget etc).
void ReserveBindingSlot(uint32_t regNo, BindType type)
{
uint32_t key = regNo | (uint32_t(type) << 16);
m_Allocations.insert(std::make_pair(key, regNo));
// Remove regNo from free slots
for (int i = m_FreeSlots.size() - 1; i >= 0; i--)
{
if (m_FreeSlots[i] == regNo)
{
m_FreeSlots.erase(m_FreeSlots.begin() + i);
return;
}
}
}
// Remove regNo from free slots
for (int i = m_FreeSlots.size() - 1; i >= 0; i--)
{
if (m_FreeSlots[i] == regNo)
{
m_FreeSlots.erase(m_FreeSlots.begin() + i);
return;
}
}
}
uint32_t SaveTotalShaderStageAllocationsCount()
{
m_ShaderStageAllocations = m_Allocations.size();
return m_ShaderStageAllocations;
}
uint32_t SaveTotalShaderStageAllocationsCount()
{
m_ShaderStageAllocations = m_Allocations.size();
return m_ShaderStageAllocations;
}
private:
std::vector<uint32_t> m_FreeSlots;
std::vector<uint32_t> m_FreeSlots;
};
//The shader stages (Vertex, Pixel et al) do not depend on each other
@ -220,156 +221,155 @@ private:
class GLSLCrossDependencyData
{
public:
// A container for a single Vulkan resource binding (<set, binding> pair)
typedef std::pair<uint32_t, uint32_t> VulkanResourceBinding;
// A container for a single Vulkan resource binding (<set, binding> pair)
typedef std::pair<uint32_t, uint32_t> VulkanResourceBinding;
private:
//Required if PixelInterpDependency is true
std::vector<INTERPOLATION_MODE> pixelInterpolation;
// Map of varying locations, indexed by varying names.
typedef std::map<std::string, uint32_t> VaryingLocations;
//Required if PixelInterpDependency is true
std::vector<INTERPOLATION_MODE> pixelInterpolation;
static const int MAX_NAMESPACES = 6; // Max namespaces: vert input, hull input, domain input, geom input, ps input, (ps output)
// Map of varying locations, indexed by varying names.
typedef std::map<std::string, uint32_t> VaryingLocations;
VaryingLocations varyingLocationsMap[MAX_NAMESPACES];
uint32_t nextAvailableVaryingLocation[MAX_NAMESPACES];
static const int MAX_NAMESPACES = 6; // Max namespaces: vert input, hull input, domain input, geom input, ps input, (ps output)
typedef std::map<std::string, VulkanResourceBinding> VulkanResourceBindings;
VulkanResourceBindings m_VulkanResourceBindings;
uint32_t m_NextAvailableVulkanResourceBinding[8]; // one per set.
VaryingLocations varyingLocationsMap[MAX_NAMESPACES];
uint32_t nextAvailableVaryingLocation[MAX_NAMESPACES];
inline int GetVaryingNamespace(SHADER_TYPE eShaderType, bool isInput)
{
switch (eShaderType)
{
case VERTEX_SHADER:
return isInput ? 0 : 1;
typedef std::map<std::string, VulkanResourceBinding> VulkanResourceBindings;
VulkanResourceBindings m_VulkanResourceBindings;
uint32_t m_NextAvailableVulkanResourceBinding[8]; // one per set.
case HULL_SHADER:
return isInput ? 1 : 2;
inline int GetVaryingNamespace(SHADER_TYPE eShaderType, bool isInput)
{
switch (eShaderType)
{
case VERTEX_SHADER:
return isInput ? 0 : 1;
case DOMAIN_SHADER:
return isInput ? 2 : 3;
case HULL_SHADER:
return isInput ? 1 : 2;
case GEOMETRY_SHADER:
// The input depends on whether there's a tessellation shader before us
if (isInput)
{
return ui32ProgramStages & PS_FLAG_DOMAIN_SHADER ? 3 : 1;
}
return 4;
case DOMAIN_SHADER:
return isInput ? 2 : 3;
case PIXEL_SHADER:
// The inputs can come from geom shader, domain shader or directly from vertex shader
if (isInput)
{
if (ui32ProgramStages & PS_FLAG_GEOMETRY_SHADER)
{
return 4;
}
else if (ui32ProgramStages & PS_FLAG_DOMAIN_SHADER)
{
return 3;
}
else
{
return 1;
}
}
return 5; // This value never really used
default:
return 0;
}
}
case GEOMETRY_SHADER:
// The input depends on whether there's a tessellation shader before us
if (isInput)
{
return ui32ProgramStages & PS_FLAG_DOMAIN_SHADER ? 3 : 1;
}
return 4;
typedef std::map<std::string, uint32_t> SpecializationConstantMap;
SpecializationConstantMap m_SpecConstantMap;
uint32_t m_NextSpecID;
case PIXEL_SHADER:
// The inputs can come from geom shader, domain shader or directly from vertex shader
if (isInput)
{
if (ui32ProgramStages & PS_FLAG_GEOMETRY_SHADER)
{
return 4;
}
else if (ui32ProgramStages & PS_FLAG_DOMAIN_SHADER)
{
return 3;
}
else
{
return 1;
}
}
return 5; // This value never really used
default:
return 0;
}
}
typedef std::map<std::string, uint32_t> SpecializationConstantMap;
SpecializationConstantMap m_SpecConstantMap;
uint32_t m_NextSpecID;
public:
GLSLCrossDependencyData()
: eTessPartitioning(),
eTessOutPrim(),
fMaxTessFactor(64.0),
numPatchesInThreadGroup(0),
hasControlPoint(false),
hasPatchConstant(false),
ui32ProgramStages(0),
m_ExtBlendModes(),
m_NextSpecID(0)
{
memset(nextAvailableVaryingLocation, 0, sizeof(nextAvailableVaryingLocation));
memset(m_NextAvailableVulkanResourceBinding, 0, sizeof(m_NextAvailableVulkanResourceBinding));
}
GLSLCrossDependencyData()
: eTessPartitioning(),
eTessOutPrim(),
fMaxTessFactor(64.0),
numPatchesInThreadGroup(0),
hasControlPoint(false),
hasPatchConstant(false),
ui32ProgramStages(0),
m_ExtBlendModes(),
m_NextSpecID(0)
{
memset(nextAvailableVaryingLocation, 0, sizeof(nextAvailableVaryingLocation));
memset(m_NextAvailableVulkanResourceBinding, 0, sizeof(m_NextAvailableVulkanResourceBinding));
}
// Retrieve the location for a varying with a given name.
// If the name doesn't already have an allocated location, allocate one
// and store it into the map.
inline uint32_t GetVaryingLocation(const std::string &name, SHADER_TYPE eShaderType, bool isInput)
{
int nspace = GetVaryingNamespace(eShaderType, isInput);
VaryingLocations::iterator itr = varyingLocationsMap[nspace].find(name);
if (itr != varyingLocationsMap[nspace].end())
return itr->second;
// Retrieve the location for a varying with a given name.
// If the name doesn't already have an allocated location, allocate one
// and store it into the map.
inline uint32_t GetVaryingLocation(const std::string &name, SHADER_TYPE eShaderType, bool isInput)
{
int nspace = GetVaryingNamespace(eShaderType, isInput);
VaryingLocations::iterator itr = varyingLocationsMap[nspace].find(name);
if (itr != varyingLocationsMap[nspace].end())
return itr->second;
uint32_t newKey = nextAvailableVaryingLocation[nspace];
nextAvailableVaryingLocation[nspace]++;
varyingLocationsMap[nspace].insert(std::make_pair(name, newKey));
return newKey;
}
uint32_t newKey = nextAvailableVaryingLocation[nspace];
nextAvailableVaryingLocation[nspace]++;
varyingLocationsMap[nspace].insert(std::make_pair(name, newKey));
return newKey;
}
// Retrieve the binding for a resource (texture, constant buffer, image) with a given name
// If not found, allocate a new one (in set 0) and return that
// The returned value is a pair of <set, binding>
// If the name contains "hlslcc_set_X_bind_Y", those values (from the first found occurence in the name)
// will be used instead, and all occurences of that string will be removed from name, so name parameter can be modified
// if allocRoomForCounter is true, the following binding number in the same set will be allocated with name + '_counter'
inline std::pair<uint32_t, uint32_t> GetVulkanResourceBinding(std::string &name, bool allocRoomForCounter = false, uint32_t preferredSet = 0)
{
// scan for the special marker
const char *marker = "Xhlslcc_set_%d_bind_%dX";
uint32_t Set = 0, Binding = 0;
size_t startLoc = name.find("Xhlslcc");
if ((startLoc != std::string::npos) && (sscanf(name.c_str() + startLoc, marker, &Set, &Binding) == 2))
{
// Get rid of all markers
while ((startLoc = name.find("Xhlslcc")) != std::string::npos)
{
size_t endLoc = name.find('X', startLoc + 1);
if (endLoc == std::string::npos)
break;
name.erase(startLoc, endLoc - startLoc + 1);
}
// Add to map
VulkanResourceBinding newBind = std::make_pair(Set, Binding);
m_VulkanResourceBindings.insert(std::make_pair(name, newBind));
if (allocRoomForCounter)
{
VulkanResourceBinding counterBind = std::make_pair(Set, Binding + 1);
m_VulkanResourceBindings.insert(std::make_pair(name + "_counter", counterBind));
}
// Retrieve the binding for a resource (texture, constant buffer, image) with a given name
// If not found, allocate a new one (in set 0) and return that
// The returned value is a pair of <set, binding>
// If the name contains "hlslcc_set_X_bind_Y", those values (from the first found occurence in the name)
// will be used instead, and all occurences of that string will be removed from name, so name parameter can be modified
// if allocRoomForCounter is true, the following binding number in the same set will be allocated with name + '_counter'
inline std::pair<uint32_t, uint32_t> GetVulkanResourceBinding(std::string &name, bool allocRoomForCounter = false, uint32_t preferredSet = 0)
{
// scan for the special marker
const char *marker = "Xhlslcc_set_%d_bind_%dX";
uint32_t Set = 0, Binding = 0;
size_t startLoc = name.find("Xhlslcc");
if ((startLoc != std::string::npos) && (sscanf(name.c_str() + startLoc, marker, &Set, &Binding) == 2))
{
// Get rid of all markers
while ((startLoc = name.find("Xhlslcc")) != std::string::npos)
{
size_t endLoc = name.find('X', startLoc + 1);
if (endLoc == std::string::npos)
break;
name.erase(startLoc, endLoc - startLoc + 1);
}
// Add to map
VulkanResourceBinding newBind = std::make_pair(Set, Binding);
m_VulkanResourceBindings.insert(std::make_pair(name, newBind));
if (allocRoomForCounter)
{
VulkanResourceBinding counterBind = std::make_pair(Set, Binding+1);
m_VulkanResourceBindings.insert(std::make_pair(name + "_counter", counterBind));
}
return newBind;
}
return newBind;
}
VulkanResourceBindings::iterator itr = m_VulkanResourceBindings.find(name);
if (itr != m_VulkanResourceBindings.end())
return itr->second;
VulkanResourceBindings::iterator itr = m_VulkanResourceBindings.find(name);
if (itr != m_VulkanResourceBindings.end())
return itr->second;
// Allocate a new one
VulkanResourceBinding newBind = std::make_pair(preferredSet, m_NextAvailableVulkanResourceBinding[preferredSet]);
m_NextAvailableVulkanResourceBinding[preferredSet]++;
m_VulkanResourceBindings.insert(std::make_pair(name, newBind));
if (allocRoomForCounter)
{
VulkanResourceBinding counterBind = std::make_pair(preferredSet, m_NextAvailableVulkanResourceBinding[preferredSet]);
m_NextAvailableVulkanResourceBinding[preferredSet]++;
m_VulkanResourceBindings.insert(std::make_pair(name + "_counter", counterBind));
}
return newBind;
}
// Allocate a new one
VulkanResourceBinding newBind = std::make_pair(preferredSet, m_NextAvailableVulkanResourceBinding[preferredSet]);
m_NextAvailableVulkanResourceBinding[preferredSet]++;
m_VulkanResourceBindings.insert(std::make_pair(name, newBind));
if (allocRoomForCounter)
{
VulkanResourceBinding counterBind = std::make_pair(preferredSet, m_NextAvailableVulkanResourceBinding[preferredSet]);
m_NextAvailableVulkanResourceBinding[preferredSet]++;
m_VulkanResourceBindings.insert(std::make_pair(name + "_counter", counterBind));
}
return newBind;
}
//dcl_tessellator_partitioning and dcl_tessellator_output_primitive appear in hull shader for D3D,
//but they appear on inputs inside domain shaders for GL.
@ -383,74 +383,75 @@ public:
bool hasControlPoint;
bool hasPatchConstant;
// Bitfield for the shader stages this program is going to include (see PS_FLAG_*).
// Needed so we can construct proper shader input and output names
uint32_t ui32ProgramStages;
// Bitfield for the shader stages this program is going to include (see PS_FLAG_*).
// Needed so we can construct proper shader input and output names
uint32_t ui32ProgramStages;
std::vector<std::string> m_ExtBlendModes; // The blend modes (from KHR_blend_equation_advanced) requested for this shader. See ext spec for list.
inline INTERPOLATION_MODE GetInterpolationMode(uint32_t regNo)
{
if (regNo >= pixelInterpolation.size())
return INTERPOLATION_UNDEFINED;
else
return pixelInterpolation[regNo];
}
std::vector<std::string> m_ExtBlendModes; // The blend modes (from KHR_blend_equation_advanced) requested for this shader. See ext spec for list.
inline void SetInterpolationMode(uint32_t regNo, INTERPOLATION_MODE mode)
{
if (regNo >= pixelInterpolation.size())
pixelInterpolation.resize((regNo + 1) * 2, INTERPOLATION_UNDEFINED);
inline INTERPOLATION_MODE GetInterpolationMode(uint32_t regNo)
{
if (regNo >= pixelInterpolation.size())
return INTERPOLATION_UNDEFINED;
else
return pixelInterpolation[regNo];
}
pixelInterpolation[regNo] = mode;
}
inline void SetInterpolationMode(uint32_t regNo, INTERPOLATION_MODE mode)
{
if (regNo >= pixelInterpolation.size())
pixelInterpolation.resize((regNo + 1) * 2, INTERPOLATION_UNDEFINED);
struct CompareFirst
{
CompareFirst(std::string val) : m_Val (val) {}
bool operator()(const std::pair<std::string, std::string>& elem) const
{
return m_Val == elem.first;
}
private:
std::string m_Val;
};
pixelInterpolation[regNo] = mode;
}
inline bool IsMemberDeclared(const std::string &name)
{
if (std::find_if(m_SharedFunctionMembers.begin(), m_SharedFunctionMembers.end(), CompareFirst(name)) != m_SharedFunctionMembers.end())
return true;
return false;
}
struct CompareFirst
{
CompareFirst(std::string val) : m_Val(val) {}
bool operator()(const std::pair<std::string, std::string>& elem) const
{
return m_Val == elem.first;
}
MemberDefinitions m_SharedFunctionMembers;
BindingSlotAllocator m_SharedTextureSlots, m_SharedSamplerSlots;
BindingSlotAllocator m_SharedBufferSlots;
private:
std::string m_Val;
};
inline void ClearCrossDependencyData()
{
pixelInterpolation.clear();
for (int i = 0; i < MAX_NAMESPACES; i++)
{
varyingLocationsMap[i].clear();
nextAvailableVaryingLocation[i] = 0;
}
m_NextSpecID = kArraySizeConstantID + 1;
m_SpecConstantMap.clear();
m_SharedFunctionMembers.clear();
}
inline bool IsMemberDeclared(const std::string &name)
{
if (std::find_if(m_SharedFunctionMembers.begin(), m_SharedFunctionMembers.end(), CompareFirst(name)) != m_SharedFunctionMembers.end())
return true;
return false;
}
// Retrieve or allocate a layout slot for Vulkan specialization constant
inline uint32_t GetSpecializationConstantSlot(const std::string &name)
{
SpecializationConstantMap::iterator itr = m_SpecConstantMap.find(name);
if (itr != m_SpecConstantMap.end())
return itr->second;
MemberDefinitions m_SharedFunctionMembers;
BindingSlotAllocator m_SharedTextureSlots, m_SharedSamplerSlots;
BindingSlotAllocator m_SharedBufferSlots;
m_SpecConstantMap.insert(std::make_pair(std::string(name), m_NextSpecID));
inline void ClearCrossDependencyData()
{
pixelInterpolation.clear();
for (int i = 0; i < MAX_NAMESPACES; i++)
{
varyingLocationsMap[i].clear();
nextAvailableVaryingLocation[i] = 0;
}
m_NextSpecID = kArraySizeConstantID + 1;
m_SpecConstantMap.clear();
m_SharedFunctionMembers.clear();
}
return m_NextSpecID++;
}
// Retrieve or allocate a layout slot for Vulkan specialization constant
inline uint32_t GetSpecializationConstantSlot(const std::string &name)
{
SpecializationConstantMap::iterator itr = m_SpecConstantMap.find(name);
if (itr != m_SpecConstantMap.end())
return itr->second;
m_SpecConstantMap.insert(std::make_pair(std::string(name), m_NextSpecID));
return m_NextSpecID++;
}
};
struct GLSLShader
@ -466,28 +467,28 @@ struct GLSLShader
class HLSLccReflection
{
public:
HLSLccReflection() {}
virtual ~HLSLccReflection() {}
HLSLccReflection() {}
virtual ~HLSLccReflection() {}
// Called on errors or diagnostic messages
virtual void OnDiagnostics(const std::string &error, int line, bool isError) {}
// Called on errors or diagnostic messages
virtual void OnDiagnostics(const std::string &error, int line, bool isError) {}
virtual void OnInputBinding(const std::string &name, int bindIndex) {}
virtual void OnInputBinding(const std::string &name, int bindIndex) {}
// Returns false if this constant buffer is not needed for this shader. This info can be used for pruning unused
// constant buffers and vars from compute shaders where we need broader context than a single kernel to know
// if something can be dropped, as the constant buffers are shared between all kernels in a .compute file.
virtual bool OnConstantBuffer(const std::string &name, size_t bufferSize, size_t memberCount) { return true; }
// Returns false if this constant buffer is not needed for this shader. This info can be used for pruning unused
// constant buffers and vars from compute shaders where we need broader context than a single kernel to know
// if something can be dropped, as the constant buffers are shared between all kernels in a .compute file.
virtual bool OnConstantBuffer(const std::string &name, size_t bufferSize, size_t memberCount) { return true; }
// Returns false if this constant var is not needed for this shader. See above.
virtual bool OnConstant(const std::string &name, int bindIndex, SHADER_VARIABLE_TYPE cType, int rows, int cols, bool isMatrix, int arraySize) { return true; }
// Returns false if this constant var is not needed for this shader. See above.
virtual bool OnConstant(const std::string &name, int bindIndex, SHADER_VARIABLE_TYPE cType, int rows, int cols, bool isMatrix, int arraySize) { return true; }
virtual void OnConstantBufferBinding(const std::string &name, int bindIndex) {}
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, bool multisampled, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
virtual void OnBufferBinding(const std::string &name, int bindIndex, bool isUAV) {}
virtual void OnThreadGroupSize(unsigned int xSize, unsigned int ySize, unsigned int zSize) {}
virtual void OnTessellationInfo(uint32_t tessPartitionMode, uint32_t tessOutputWindingOrder, uint32_t tessMaxFactor, uint32_t tessNumPatchesInThreadGroup) {}
virtual void OnTessellationKernelInfo(uint32_t patchKernelBufferCount) {}
virtual void OnConstantBufferBinding(const std::string &name, int bindIndex) {}
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, bool multisampled, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
virtual void OnBufferBinding(const std::string &name, int bindIndex, bool isUAV) {}
virtual void OnThreadGroupSize(unsigned int xSize, unsigned int ySize, unsigned int zSize) {}
virtual void OnTessellationInfo(uint32_t tessPartitionMode, uint32_t tessOutputWindingOrder, uint32_t tessMaxFactor, uint32_t tessNumPatchesInThreadGroup) {}
virtual void OnTessellationKernelInfo(uint32_t patchKernelBufferCount) {}
};
@ -562,7 +563,7 @@ static const unsigned int HLSLCC_FLAG_VULKAN_BINDINGS = 0x40000;
static const unsigned int HLSLCC_FLAG_METAL_SHADOW_SAMPLER_LINEAR = 0x80000;
// If set, avoid emit atomic counter (ARB_shader_atomic_counters) and use atomic functions provided by ARB_shader_storage_buffer_object instead.
static const unsigned int HLSLCC_FLAG_AVOID_SHADER_ATOMIC_COUNTERS = 0x100000;
static const unsigned int HLSLCC_FLAG_AVOID_SHADER_ATOMIC_COUNTERS = 0x100000;
// If set, and generating Vulkan shaders, attempts to detect static branching and transforms them into specialization constants
static const unsigned int HLSLCC_FLAG_VULKAN_SPECIALIZATION_CONSTANTS = 0x200000;
@ -588,27 +589,26 @@ extern "C" {
#endif
HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename,
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result
);
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result
);
HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromMem(const char* shader,
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result);
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result);
#ifdef __cplusplus
}
#endif
#endif

Просмотреть файл

@ -1,5 +1,3 @@
extern "C" {
#include "hlslcc.h"
}

Просмотреть файл

@ -5,11 +5,11 @@
*
* Copyright (c) 2005-2011 Paul Hsieh
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
@ -17,7 +17,7 @@
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@ -191,7 +191,7 @@
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
*/
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)))) && !defined(_PSTDINT_H_INCLUDED)
#include <stdint.h>
#define _PSTDINT_H_INCLUDED
# ifndef PRINTF_INT64_MODIFIER
@ -242,47 +242,47 @@
* these duplicated definitions from Open Watcom's stdint.h file for now.
*/
# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
# if !defined (INT64_C)
# if defined(__WATCOMC__) && __WATCOMC__ >= 1250
# if !defined(INT64_C)
# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
# endif
# if !defined (UINT64_C)
# if !defined(UINT64_C)
# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
# endif
# if !defined (INT32_C)
# if !defined(INT32_C)
# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
# endif
# if !defined (UINT32_C)
# if !defined(UINT32_C)
# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
# endif
# if !defined (INT16_C)
# if !defined(INT16_C)
# define INT16_C(x) (x)
# endif
# if !defined (UINT16_C)
# if !defined(UINT16_C)
# define UINT16_C(x) (x)
# endif
# if !defined (INT8_C)
# if !defined(INT8_C)
# define INT8_C(x) (x)
# endif
# if !defined (UINT8_C)
# if !defined(UINT8_C)
# define UINT8_C(x) (x)
# endif
# if !defined (UINT64_MAX)
# if !defined(UINT64_MAX)
# define UINT64_MAX 18446744073709551615ULL
# endif
# if !defined (INT64_MAX)
# if !defined(INT64_MAX)
# define INT64_MAX 9223372036854775807LL
# endif
# if !defined (UINT32_MAX)
# if !defined(UINT32_MAX)
# define UINT32_MAX 4294967295UL
# endif
# if !defined (INT32_MAX)
# if !defined(INT32_MAX)
# define INT32_MAX 2147483647L
# endif
# if !defined (INTMAX_MAX)
# if !defined(INTMAX_MAX)
# define INTMAX_MAX INT64_MAX
# endif
# if !defined (INTMAX_MIN)
# if !defined(INTMAX_MIN)
# define INTMAX_MIN INT64_MIN
# endif
# endif
@ -305,8 +305,8 @@
# define UINT8_MAX 0xff
#endif
#ifndef uint8_t
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
typedef unsigned char uint8_t;
# if (UCHAR_MAX == UINT8_MAX) || defined(S_SPLINT_S)
typedef unsigned char uint8_t;
# define UINT8_C(v) ((uint8_t) v)
# else
# error "Platform not supported"
@ -320,8 +320,8 @@
# define INT8_MIN INT8_C(0x80)
#endif
#ifndef int8_t
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
typedef signed char int8_t;
# if (SCHAR_MAX == INT8_MAX) || defined(S_SPLINT_S)
typedef signed char int8_t;
# define INT8_C(v) ((int8_t) v)
# else
# error "Platform not supported"
@ -332,14 +332,14 @@
# define UINT16_MAX 0xffff
#endif
#ifndef uint16_t
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
typedef unsigned int uint16_t;
#if (UINT_MAX == UINT16_MAX) || defined(S_SPLINT_S)
typedef unsigned int uint16_t;
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER ""
# endif
# define UINT16_C(v) ((uint16_t) (v))
#elif (USHRT_MAX == UINT16_MAX)
typedef unsigned short uint16_t;
typedef unsigned short uint16_t;
# define UINT16_C(v) ((uint16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER "h"
@ -356,14 +356,14 @@
# define INT16_MIN INT16_C(0x8000)
#endif
#ifndef int16_t
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
typedef signed int int16_t;
#if (INT_MAX == INT16_MAX) || defined(S_SPLINT_S)
typedef signed int int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER ""
# endif
#elif (SHRT_MAX == INT16_MAX)
typedef signed short int16_t;
typedef signed short int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER "h"
@ -377,20 +377,20 @@
# define UINT32_MAX (0xffffffffUL)
#endif
#ifndef uint32_t
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
typedef unsigned long uint32_t;
#if (ULONG_MAX == UINT32_MAX) || defined(S_SPLINT_S)
typedef unsigned long uint32_t;
# define UINT32_C(v) v ## UL
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER "l"
# endif
#elif (UINT_MAX == UINT32_MAX)
typedef unsigned int uint32_t;
typedef unsigned int uint32_t;
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
# define UINT32_C(v) v ## U
#elif (USHRT_MAX == UINT32_MAX)
typedef unsigned short uint32_t;
typedef unsigned short uint32_t;
# define UINT32_C(v) ((unsigned short) (v))
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
@ -407,20 +407,20 @@
# define INT32_MIN INT32_C(0x80000000)
#endif
#ifndef int32_t
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
typedef signed long int32_t;
#if (LONG_MAX == INT32_MAX) || defined(S_SPLINT_S)
typedef signed long int32_t;
# define INT32_C(v) v ## L
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER "l"
# endif
#elif (INT_MAX == INT32_MAX)
typedef signed int int32_t;
typedef signed int int32_t;
# define INT32_C(v) v
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
#elif (SHRT_MAX == INT32_MAX)
typedef signed short int32_t;
typedef signed short int32_t;
# define INT32_C(v) ((short) (v))
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
@ -438,11 +438,11 @@
*/
#undef stdint_int64_defined
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined(S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined(S_SPLINT_S)
# define stdint_int64_defined
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
@ -451,29 +451,29 @@
# endif
#endif
#if !defined (stdint_int64_defined)
#if !defined(stdint_int64_defined)
# if defined(__GNUC__)
# define stdint_int64_defined
__extension__ typedef long long int64_t;
__extension__ typedef unsigned long long uint64_t;
__extension__ typedef long long int64_t;
__extension__ typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
# elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) || defined(S_SPLINT_S)
# define stdint_int64_defined
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
# define stdint_int64_defined
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# define UINT64_C(v) v ## UI64
# define INT64_C(v) v ## I64
# ifndef PRINTF_INT64_MODIFIER
@ -482,20 +482,20 @@
# endif
#endif
#if !defined (LONG_LONG_MAX) && defined (INT64_C)
#if !defined(LONG_LONG_MAX) && defined(INT64_C)
# define LONG_LONG_MAX INT64_C (9223372036854775807)
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
#endif
#if !defined (INT64_MAX) && defined (INT64_C)
#if !defined(INT64_MAX) && defined(INT64_C)
# define INT64_MAX INT64_C (9223372036854775807)
#endif
#if !defined (INT64_MIN) && defined (INT64_C)
#if !defined(INT64_MIN) && defined(INT64_C)
# define INT64_MIN INT64_C (-9223372036854775808)
#endif
#if !defined (UINT64_MAX) && defined (INT64_C)
#if !defined(UINT64_MAX) && defined(INT64_C)
# define UINT64_MAX UINT64_C (18446744073709551615)
#endif
@ -536,8 +536,8 @@
*/
#ifdef stdint_int64_defined
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
# define INTMAX_MAX INT64_MAX
# define INTMAX_MIN INT64_MIN
# define UINTMAX_MAX UINT64_MAX
@ -553,8 +553,8 @@
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
#else
typedef int32_t intmax_t;
typedef uint32_t uintmax_t;
typedef int32_t intmax_t;
typedef uint32_t uintmax_t;
# define INTMAX_MAX INT32_MAX
# define UINTMAX_MAX UINT32_MAX
# define UINTMAX_C(v) UINT32_C(v)
@ -578,12 +578,12 @@
*/
#ifndef stdint_least_defined
typedef int8_t int_least8_t;
typedef uint8_t uint_least8_t;
typedef int16_t int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t int_least32_t;
typedef uint32_t uint_least32_t;
typedef int8_t int_least8_t;
typedef uint8_t uint_least8_t;
typedef int16_t int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t int_least32_t;
typedef uint32_t uint_least32_t;
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
# define UINT_LEAST8_MAX UINT8_MAX
@ -596,8 +596,8 @@
# define INT_LEAST16_MIN INT16_MIN
# define INT_LEAST32_MIN INT32_MIN
# ifdef stdint_int64_defined
typedef int64_t int_least64_t;
typedef uint64_t uint_least64_t;
typedef int64_t int_least64_t;
typedef uint64_t uint_least64_t;
# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
# define UINT_LEAST64_MAX UINT64_MAX
# define INT_LEAST64_MAX INT64_MAX
@ -633,8 +633,8 @@ typedef uint_least32_t uint_fast32_t;
#define INT_FAST16_MIN INT_LEAST16_MIN
#define INT_FAST32_MIN INT_LEAST32_MIN
#ifdef stdint_int64_defined
typedef int_least64_t int_fast64_t;
typedef uint_least64_t uint_fast64_t;
typedef int_least64_t int_fast64_t;
typedef uint_least64_t uint_fast64_t;
# define UINT_FAST64_MAX UINT_LEAST64_MAX
# define INT_FAST64_MAX INT_LEAST64_MAX
# define INT_FAST64_MIN INT_LEAST64_MIN
@ -647,7 +647,7 @@ typedef uint_least32_t uint_fast32_t;
* type limits.
*/
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__GNUC__)
# include <wchar.h>
# ifndef WCHAR_MIN
# define WCHAR_MIN 0
@ -662,28 +662,28 @@ typedef uint_least32_t uint_fast32_t;
* (u)intptr_t types and limits.
*/
#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
#if defined(_MSC_VER) && defined(_UINTPTR_T_DEFINED)
# define STDINT_H_UINTPTR_T_DEFINED
#endif
#ifndef STDINT_H_UINTPTR_T_DEFINED
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
# if defined(__alpha__) || defined(__ia64__) || defined(__x86_64__) || defined(_WIN64)
# define stdint_intptr_bits 64
# elif defined (__WATCOMC__) || defined (__TURBOC__)
# elif defined(__WATCOMC__) || defined(__TURBOC__)
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
# define stdint_intptr_bits 16
# else
# define stdint_intptr_bits 32
# endif
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
# elif defined(__i386__) || defined(_WIN32) || defined(WIN32)
# define stdint_intptr_bits 32
# elif defined (__INTEL_COMPILER)
# elif defined(__INTEL_COMPILER)
/* TODO -- what did Intel do about x86-64? */
# endif
# ifdef stdint_intptr_bits
# define stdint_intptr_glue3_i(a,b,c) a##b##c
# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
# define stdint_intptr_glue3_i(a, b, c) a##b##c
# define stdint_intptr_glue3(a, b, c) stdint_intptr_glue3_i(a,b,c)
# ifndef PRINTF_INTPTR_MODIFIER
# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
# endif
@ -708,12 +708,12 @@ typedef uint_least32_t uint_fast32_t;
# ifndef UINTPTR_C
# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
# endif
typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
typedef stdint_intptr_glue3 (uint, stdint_intptr_bits, _t) uintptr_t;
typedef stdint_intptr_glue3 (int, stdint_intptr_bits, _t) intptr_t;
# else
/* TODO -- This following is likely wrong for some platforms, and does
nothing for the definition of uintptr_t. */
typedef ptrdiff_t intptr_t;
typedef ptrdiff_t intptr_t;
# endif
# define STDINT_H_UINTPTR_T_DEFINED
#endif
@ -728,73 +728,74 @@ typedef uint_least32_t uint_fast32_t;
#endif
#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
#if defined(__TEST_PSTDINT_FOR_CORRECTNESS)
/*
/*
* Please compile with the maximum warning settings to make sure macros are not
* defined more than once.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define glue3_aux(x,y,z) x ## y ## z
#define glue3(x,y,z) glue3_aux(x,y,z)
#define glue3_aux(x, y, z) x ## y ## z
#define glue3(x, y, z) glue3_aux(x,y,z)
#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0);
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0);
#define DECL(us,bits) glue3(DECL,us,) (bits)
#define DECL(us, bits) glue3(DECL,us,) (bits)
#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits)
int main () {
DECL(I,8)
DECL(U,8)
DECL(I,16)
DECL(U,16)
DECL(I,32)
DECL(U,32)
#ifdef INT64_MAX
DECL(I,64)
DECL(U,64)
#endif
intmax_t imax = INTMAX_C(0);
uintmax_t umax = UINTMAX_C(0);
char str0[256], str1[256];
sprintf (str0, "%d %x\n", 0, ~0);
sprintf (str1, "%d %x\n", i8, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1);
sprintf (str1, "%u %x\n", u8, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1);
sprintf (str1, "%d %x\n", i16, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1);
sprintf (str1, "%u %x\n", u16, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1);
sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1);
sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1);
#ifdef INT64_MAX
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1);
#endif
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1);
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1);
TESTUMAX(8);
TESTUMAX(16);
TESTUMAX(32);
int main()
{
DECL(I, 8)
DECL(U, 8)
DECL(I, 16)
DECL(U, 16)
DECL(I, 32)
DECL(U, 32)
#ifdef INT64_MAX
TESTUMAX(64);
DECL(I, 64)
DECL(U, 64)
#endif
intmax_t imax = INTMAX_C(0);
uintmax_t umax = UINTMAX_C(0);
char str0[256], str1[256];
sprintf(str0, "%d %x\n", 0, ~0);
sprintf(str1, "%d %x\n", i8, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with i8 : %s\n", str1);
sprintf(str1, "%u %x\n", u8, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with u8 : %s\n", str1);
sprintf(str1, "%d %x\n", i16, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with i16 : %s\n", str1);
sprintf(str1, "%u %x\n", u16, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with u16 : %s\n", str1);
sprintf(str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with i32 : %s\n", str1);
sprintf(str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with u32 : %s\n", str1);
#ifdef INT64_MAX
sprintf(str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with i64 : %s\n", str1);
#endif
sprintf(str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with imax : %s\n", str1);
sprintf(str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
if (0 != strcmp(str0, str1)) printf("Something wrong with umax : %s\n", str1);
TESTUMAX(8);
TESTUMAX(16);
TESTUMAX(32);
#ifdef INT64_MAX
TESTUMAX(64);
#endif
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,3 @@
#include "ControlFlowGraphUtils.h"
#include "internal_includes/debug.h"
@ -6,22 +5,20 @@
#include "internal_includes/Operand.h"
// Get the next instruction that's not one of CASE, DEFAULT, LOOP, ENDSWITCH
const Instruction *HLSLcc::ControlFlow::Utils::GetNextNonLabelInstruction(const Instruction *psStart, bool *sawEndSwitch /*= 0*/)
{
const Instruction *inst = psStart;
// Skip CASE/DEFAULT/ENDSWITCH/LOOP labels
while (inst->eOpcode == OPCODE_CASE || inst->eOpcode == OPCODE_DEFAULT || inst->eOpcode == OPCODE_ENDSWITCH || inst->eOpcode == OPCODE_LOOP)
{
// We really shouldn't be seeing ENDSWITCH without sawEndSwitch being set (as in, we're expecting it)
ASSERT(inst->eOpcode != OPCODE_ENDSWITCH || sawEndSwitch != NULL);
if (inst->eOpcode == OPCODE_ENDSWITCH && sawEndSwitch != NULL)
*sawEndSwitch = true;
inst++;
}
return inst;
const Instruction *inst = psStart;
// Skip CASE/DEFAULT/ENDSWITCH/LOOP labels
while (inst->eOpcode == OPCODE_CASE || inst->eOpcode == OPCODE_DEFAULT || inst->eOpcode == OPCODE_ENDSWITCH || inst->eOpcode == OPCODE_LOOP)
{
// We really shouldn't be seeing ENDSWITCH without sawEndSwitch being set (as in, we're expecting it)
ASSERT(inst->eOpcode != OPCODE_ENDSWITCH || sawEndSwitch != NULL);
if (inst->eOpcode == OPCODE_ENDSWITCH && sawEndSwitch != NULL)
*sawEndSwitch = true;
inst++;
}
return inst;
}
// For a given flow-control instruction, find the corresponding jump location:
@ -37,85 +34,83 @@ const Instruction *HLSLcc::ControlFlow::Utils::GetNextNonLabelInstruction(const
// Always returns the beginning of the next block, so skip multiple CASE/DEFAULT labels etc.
const Instruction * HLSLcc::ControlFlow::Utils::GetJumpPoint(const Instruction *psStart, bool *sawEndSwitch /*= 0*/, bool *needConnectToParent /* = 0*/)
{
const Instruction *inst = psStart;
int depth = 0;
OPCODE_TYPE op = psStart->eOpcode;
ASSERT(op == OPCODE_IF || op == OPCODE_ELSE || op == OPCODE_BREAK || op == OPCODE_BREAKC
|| op == OPCODE_SWITCH || op == OPCODE_CASE || op == OPCODE_DEFAULT
|| op == OPCODE_ENDLOOP || op == OPCODE_CONTINUE || op == OPCODE_CONTINUEC);
const Instruction *inst = psStart;
int depth = 0;
OPCODE_TYPE op = psStart->eOpcode;
ASSERT(op == OPCODE_IF || op == OPCODE_ELSE || op == OPCODE_BREAK || op == OPCODE_BREAKC
|| op == OPCODE_SWITCH || op == OPCODE_CASE || op == OPCODE_DEFAULT
|| op == OPCODE_ENDLOOP || op == OPCODE_CONTINUE || op == OPCODE_CONTINUEC);
switch (op)
{
default:
ASSERT(0);
break;
case OPCODE_IF:
case OPCODE_ELSE:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_ELSE || inst->eOpcode == OPCODE_ENDIF) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_IF)
depth++;
if (inst->eOpcode == OPCODE_ENDIF)
depth--;
}
case OPCODE_BREAK:
case OPCODE_BREAKC:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_ENDLOOP || inst->eOpcode == OPCODE_ENDSWITCH) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_SWITCH || inst->eOpcode == OPCODE_LOOP)
depth++;
if (inst->eOpcode == OPCODE_ENDSWITCH || inst->eOpcode == OPCODE_ENDLOOP)
depth--;
}
case OPCODE_CONTINUE:
case OPCODE_CONTINUEC:
case OPCODE_ENDLOOP:
while (1)
{
inst--;
if ((inst->eOpcode == OPCODE_LOOP) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_LOOP)
depth--;
if (inst->eOpcode == OPCODE_ENDLOOP)
depth++;
}
case OPCODE_SWITCH:
case OPCODE_CASE:
case OPCODE_DEFAULT:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_CASE || inst->eOpcode == OPCODE_DEFAULT || inst->eOpcode == OPCODE_ENDSWITCH) && (depth == 0))
{
// Note that we'll skip setting sawEndSwitch if inst->eOpcode = OPCODE_ENDSWITCH
// so that BasicBlock::Build can distinguish between there being a direct route
// from SWITCH->ENDSWITCH (CASE followed directly by ENDSWITCH) and not.
switch (op)
{
default:
ASSERT(0);
break;
case OPCODE_IF:
case OPCODE_ELSE:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_ELSE || inst->eOpcode == OPCODE_ENDIF) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_IF)
depth++;
if (inst->eOpcode == OPCODE_ENDIF)
depth--;
}
case OPCODE_BREAK:
case OPCODE_BREAKC:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_ENDLOOP || inst->eOpcode == OPCODE_ENDSWITCH) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_SWITCH || inst->eOpcode == OPCODE_LOOP)
depth++;
if (inst->eOpcode == OPCODE_ENDSWITCH || inst->eOpcode == OPCODE_ENDLOOP)
depth--;
}
case OPCODE_CONTINUE:
case OPCODE_CONTINUEC:
case OPCODE_ENDLOOP:
while (1)
{
inst--;
if ((inst->eOpcode == OPCODE_LOOP) && (depth == 0))
{
return GetNextNonLabelInstruction(inst + 1, sawEndSwitch);
}
if (inst->eOpcode == OPCODE_LOOP)
depth--;
if (inst->eOpcode == OPCODE_ENDLOOP)
depth++;
}
case OPCODE_SWITCH:
case OPCODE_CASE:
case OPCODE_DEFAULT:
while (1)
{
inst++;
if ((inst->eOpcode == OPCODE_CASE || inst->eOpcode == OPCODE_DEFAULT || inst->eOpcode == OPCODE_ENDSWITCH) && (depth == 0))
{
// Note that we'll skip setting sawEndSwitch if inst->eOpcode = OPCODE_ENDSWITCH
// so that BasicBlock::Build can distinguish between there being a direct route
// from SWITCH->ENDSWITCH (CASE followed directly by ENDSWITCH) and not.
if (inst->eOpcode == OPCODE_ENDSWITCH && sawEndSwitch != 0)
*sawEndSwitch = true;
if (inst->eOpcode == OPCODE_ENDSWITCH && sawEndSwitch != 0)
*sawEndSwitch = true;
return GetNextNonLabelInstruction(inst + 1, needConnectToParent);
}
if (inst->eOpcode == OPCODE_SWITCH)
depth++;
if (inst->eOpcode == OPCODE_ENDSWITCH)
depth--;
}
}
return 0;
return GetNextNonLabelInstruction(inst + 1, needConnectToParent);
}
if (inst->eOpcode == OPCODE_SWITCH)
depth++;
if (inst->eOpcode == OPCODE_ENDSWITCH)
depth--;
}
}
return 0;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,2 +1 @@
#include "internal_includes/Declaration.h"
#include "internal_includes/Declaration.h"

Просмотреть файл

@ -1,4 +1,3 @@
#include "internal_includes/HLSLCrossCompilerContext.h"
#include "internal_includes/HLSLccToolkit.h"
#include "internal_includes/Shader.h"
@ -13,287 +12,284 @@
void HLSLCrossCompilerContext::DoDataTypeAnalysis(ShaderPhase *psPhase)
{
size_t ui32DeclCount = psPhase->psDecl.size();
uint32_t i;
size_t ui32DeclCount = psPhase->psDecl.size();
uint32_t i;
psPhase->psTempDeclaration = NULL;
psPhase->ui32OrigTemps = 0;
psPhase->ui32TotalTemps = 0;
psPhase->psTempDeclaration = NULL;
psPhase->ui32OrigTemps = 0;
psPhase->ui32TotalTemps = 0;
// Retrieve the temp decl count
for (i = 0; i < ui32DeclCount; ++i)
{
if (psPhase->psDecl[i].eOpcode == OPCODE_DCL_TEMPS)
{
psPhase->ui32TotalTemps = psPhase->psDecl[i].value.ui32NumTemps;
psPhase->psTempDeclaration = &psPhase->psDecl[i];
break;
}
}
// Retrieve the temp decl count
for (i = 0; i < ui32DeclCount; ++i)
{
if (psPhase->psDecl[i].eOpcode == OPCODE_DCL_TEMPS)
{
psPhase->ui32TotalTemps = psPhase->psDecl[i].value.ui32NumTemps;
psPhase->psTempDeclaration = &psPhase->psDecl[i];
break;
}
}
if (psPhase->ui32TotalTemps == 0)
return;
if (psPhase->ui32TotalTemps == 0)
return;
psPhase->ui32OrigTemps = psPhase->ui32TotalTemps;
psPhase->ui32OrigTemps = psPhase->ui32TotalTemps;
// The split table is a table containing the index of the original register this register was split out from, or 0xffffffff
// Format: lowest 16 bits: original register. bits 16-23: rebase (eg value of 1 means .yzw was changed to .xyz): bits 24-31: component count
psPhase->pui32SplitInfo.clear();
psPhase->pui32SplitInfo.resize(psPhase->ui32TotalTemps * 2, 0xffffffff);
// The split table is a table containing the index of the original register this register was split out from, or 0xffffffff
// Format: lowest 16 bits: original register. bits 16-23: rebase (eg value of 1 means .yzw was changed to .xyz): bits 24-31: component count
psPhase->pui32SplitInfo.clear();
psPhase->pui32SplitInfo.resize(psPhase->ui32TotalTemps * 2, 0xffffffff);
// Build use-define chains and split temps based on those.
{
DefineUseChains duChains;
UseDefineChains udChains;
// Build use-define chains and split temps based on those.
{
DefineUseChains duChains;
UseDefineChains udChains;
BuildUseDefineChains(psPhase->psInst, psPhase->ui32TotalTemps, duChains, udChains, psPhase->GetCFG());
BuildUseDefineChains(psPhase->psInst, psPhase->ui32TotalTemps, duChains, udChains, psPhase->GetCFG());
CalculateStandaloneDefinitions(duChains, psPhase->ui32TotalTemps);
CalculateStandaloneDefinitions(duChains, psPhase->ui32TotalTemps);
// Only do sampler precision downgrade on pixel shaders.
if (psShader->eShaderType == PIXEL_SHADER)
UpdateSamplerPrecisions(psShader->sInfo, duChains, psPhase->ui32TotalTemps);
// Only do sampler precision downgrade on pixel shaders.
if (psShader->eShaderType == PIXEL_SHADER)
UpdateSamplerPrecisions(psShader->sInfo, duChains, psPhase->ui32TotalTemps);
UDSplitTemps(&psPhase->ui32TotalTemps, duChains, udChains, psPhase->pui32SplitInfo);
UDSplitTemps(&psPhase->ui32TotalTemps, duChains, udChains, psPhase->pui32SplitInfo);
WriteBackUsesAndDefines(duChains);
}
HLSLcc::DataTypeAnalysis::SetDataTypes(this, psPhase->psInst, psPhase->ui32TotalTemps, psPhase->peTempTypes);
WriteBackUsesAndDefines(duChains);
}
if (psPhase->psTempDeclaration && (psPhase->ui32OrigTemps != psPhase->ui32TotalTemps))
psPhase->psTempDeclaration->value.ui32NumTemps = psPhase->ui32TotalTemps;
HLSLcc::DataTypeAnalysis::SetDataTypes(this, psPhase->psInst, psPhase->ui32TotalTemps, psPhase->peTempTypes);
if (psPhase->psTempDeclaration && (psPhase->ui32OrigTemps != psPhase->ui32TotalTemps))
psPhase->psTempDeclaration->value.ui32NumTemps = psPhase->ui32TotalTemps;
}
void HLSLCrossCompilerContext::ClearDependencyData()
{
switch (psShader->eShaderType)
{
case PIXEL_SHADER:
{
psDependencies->ClearCrossDependencyData();
break;
}
case HULL_SHADER:
{
psDependencies->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED;
psDependencies->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED;
break;
}
default:
break;
}
switch (psShader->eShaderType)
{
case PIXEL_SHADER:
{
psDependencies->ClearCrossDependencyData();
break;
}
case HULL_SHADER:
{
psDependencies->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED;
psDependencies->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED;
break;
}
default:
break;
}
}
void HLSLCrossCompilerContext::AddIndentation()
{
int i;
bstring glsl = *currentGLSLString;
for (i = 0; i < indent; ++i)
{
bcatcstr(glsl, " ");
}
int i;
bstring glsl = *currentGLSLString;
for (i = 0; i < indent; ++i)
{
bcatcstr(glsl, " ");
}
}
bool HLSLCrossCompilerContext::RequireExtension(const std::string &extName)
{
if (m_EnabledExtensions.find(extName) != m_EnabledExtensions.end())
return true;
if (m_EnabledExtensions.find(extName) != m_EnabledExtensions.end())
return true;
m_EnabledExtensions.insert(extName);
bformata(extensions, "#extension %s : require\n", extName.c_str());
return false;
m_EnabledExtensions.insert(extName);
bformata(extensions, "#extension %s : require\n", extName.c_str());
return false;
}
bool HLSLCrossCompilerContext::EnableExtension(const std::string &extName)
{
if (m_EnabledExtensions.find(extName) != m_EnabledExtensions.end())
return true;
if (m_EnabledExtensions.find(extName) != m_EnabledExtensions.end())
return true;
m_EnabledExtensions.insert(extName);
bformata(extensions, "#ifdef %s\n", extName.c_str());
bformata(extensions, "#extension %s : enable\n", extName.c_str());
bcatcstr(extensions, "#endif\n");
return false;
m_EnabledExtensions.insert(extName);
bformata(extensions, "#ifdef %s\n", extName.c_str());
bformata(extensions, "#extension %s : enable\n", extName.c_str());
bcatcstr(extensions, "#endif\n");
return false;
}
std::string HLSLCrossCompilerContext::GetDeclaredInputName(const Operand* psOperand, int *piRebase, int iIgnoreRedirect, uint32_t *puiIgnoreSwizzle) const
{
std::ostringstream oss;
const ShaderInfo::InOutSignature* psIn = NULL;
int regSpace = psOperand->GetRegisterSpace(this);
std::ostringstream oss;
const ShaderInfo::InOutSignature* psIn = NULL;
int regSpace = psOperand->GetRegisterSpace(this);
if (iIgnoreRedirect == 0)
{
if ((regSpace == 0 && psShader->asPhases[currentPhase].acInputNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe)
||
(regSpace == 1 && psShader->asPhases[currentPhase].acPatchConstantsNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe))
{
oss << "phase" << currentPhase << "_Input" << regSpace << "_" << psOperand->ui32RegisterNumber;
if (piRebase)
*piRebase = 0;
return oss.str();
}
}
if (iIgnoreRedirect == 0)
{
if ((regSpace == 0 && psShader->asPhases[currentPhase].acInputNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe)
||
(regSpace == 1 && psShader->asPhases[currentPhase].acPatchConstantsNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe))
{
oss << "phase" << currentPhase << "_Input" << regSpace << "_" << psOperand->ui32RegisterNumber;
if (piRebase)
*piRebase = 0;
return oss.str();
}
}
if (regSpace == 0)
psShader->sInfo.GetInputSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psIn, true);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psIn, true);
if (regSpace == 0)
psShader->sInfo.GetInputSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psIn, true);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psIn, true);
if (psIn && piRebase)
*piRebase = psIn->iRebase;
if (psIn && piRebase)
*piRebase = psIn->iRebase;
const std::string patchPrefix = psShader->eTargetLanguage == LANG_METAL ? "patch." : "patch";
std::string res = "";
const std::string patchPrefix = psShader->eTargetLanguage == LANG_METAL ? "patch." : "patch";
std::string res = "";
bool skipPrefix = false;
if (psTranslator->TranslateSystemValue(psOperand, psIn, res, puiIgnoreSwizzle, psShader->aIndexedInput[regSpace][psOperand->ui32RegisterNumber] != 0, true, &skipPrefix, &iIgnoreRedirect))
{
if (psShader->eTargetLanguage == LANG_METAL && (iIgnoreRedirect == 0) && !skipPrefix)
return inputPrefix + res;
else
return res;
}
bool skipPrefix = false;
if (psTranslator->TranslateSystemValue(psOperand, psIn, res, puiIgnoreSwizzle, psShader->aIndexedInput[regSpace][psOperand->ui32RegisterNumber] != 0, true, &skipPrefix, &iIgnoreRedirect))
{
if (psShader->eTargetLanguage == LANG_METAL && (iIgnoreRedirect == 0) && !skipPrefix)
return inputPrefix + res;
else
return res;
}
ASSERT(psIn != NULL);
oss << inputPrefix << (regSpace == 1 ? patchPrefix : "") << psIn->semanticName << psIn->ui32SemanticIndex;
return oss.str();
ASSERT(psIn != NULL);
oss << inputPrefix << (regSpace == 1 ? patchPrefix : "") << psIn->semanticName << psIn->ui32SemanticIndex;
return oss.str();
}
std::string HLSLCrossCompilerContext::GetDeclaredOutputName(const Operand* psOperand,
int* piStream,
uint32_t *puiIgnoreSwizzle,
int *piRebase,
int iIgnoreRedirect) const
int* piStream,
uint32_t *puiIgnoreSwizzle,
int *piRebase,
int iIgnoreRedirect) const
{
std::ostringstream oss;
const ShaderInfo::InOutSignature* psOut = NULL;
int regSpace = psOperand->GetRegisterSpace(this);
std::ostringstream oss;
const ShaderInfo::InOutSignature* psOut = NULL;
int regSpace = psOperand->GetRegisterSpace(this);
if (iIgnoreRedirect == 0)
{
if ((regSpace == 0 && psShader->asPhases[currentPhase].acOutputNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe)
|| (regSpace == 1 && psShader->asPhases[currentPhase].acPatchConstantsNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe))
{
oss << "phase" << currentPhase << "_Output" << regSpace << "_" << psOperand->ui32RegisterNumber;
if (piRebase)
*piRebase = 0;
return oss.str();
}
}
if (iIgnoreRedirect == 0)
{
if ((regSpace == 0 && psShader->asPhases[currentPhase].acOutputNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe)
|| (regSpace == 1 && psShader->asPhases[currentPhase].acPatchConstantsNeedsRedirect[psOperand->ui32RegisterNumber] == 0xfe))
{
oss << "phase" << currentPhase << "_Output" << regSpace << "_" << psOperand->ui32RegisterNumber;
if (piRebase)
*piRebase = 0;
return oss.str();
}
}
if (regSpace == 0)
psShader->sInfo.GetOutputSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), psShader->ui32CurrentVertexOutputStream, &psOut, true);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psOut, true);
if (regSpace == 0)
psShader->sInfo.GetOutputSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), psShader->ui32CurrentVertexOutputStream, &psOut, true);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(psOperand->ui32RegisterNumber, psOperand->GetAccessMask(), &psOut, true);
if (psOut && piRebase)
*piRebase = psOut->iRebase;
if (psOut && piRebase)
*piRebase = psOut->iRebase;
if (psOut && (psOut->isIndexed.find(currentPhase) != psOut->isIndexed.end()))
{
// Need to route through temp output variable
oss << "phase" << currentPhase << "_Output" << regSpace << "_" << psOut->indexStart.find(currentPhase)->second;
if (!psOperand->m_SubOperands[0].get())
{
oss << "[" << psOperand->ui32RegisterNumber << "]";
}
if (piRebase)
*piRebase = 0;
return oss.str();
}
if (psOut && (psOut->isIndexed.find(currentPhase) != psOut->isIndexed.end()))
{
// Need to route through temp output variable
oss << "phase" << currentPhase << "_Output" << regSpace << "_" << psOut->indexStart.find(currentPhase)->second;
if (!psOperand->m_SubOperands[0].get())
{
oss << "[" << psOperand->ui32RegisterNumber << "]";
}
if (piRebase)
*piRebase = 0;
return oss.str();
}
const std::string patchPrefix = psShader->eTargetLanguage == LANG_METAL ? "patch." : "patch";
std::string res = "";
const std::string patchPrefix = psShader->eTargetLanguage == LANG_METAL ? "patch." : "patch";
std::string res = "";
if (psTranslator->TranslateSystemValue(psOperand, psOut, res, puiIgnoreSwizzle, psShader->aIndexedOutput[regSpace][psOperand->ui32RegisterNumber], false, NULL, &iIgnoreRedirect))
{
// clip/cull planes will always have interim variable, as HLSL operates on float4 but we need to size output accordingly with actual planes count
// with tessellation factor buffers, a separate buffer from output is used. for some reason TranslateSystemValue return *outSkipPrefix = true
// for ALL system vars and then we simply ignore it here, so opt to modify iIgnoreRedirect for these special cases
if (psTranslator->TranslateSystemValue(psOperand, psOut, res, puiIgnoreSwizzle, psShader->aIndexedOutput[regSpace][psOperand->ui32RegisterNumber], false, NULL, &iIgnoreRedirect))
{
// clip/cull planes will always have interim variable, as HLSL operates on float4 but we need to size output accordingly with actual planes count
// with tessellation factor buffers, a separate buffer from output is used. for some reason TranslateSystemValue return *outSkipPrefix = true
// for ALL system vars and then we simply ignore it here, so opt to modify iIgnoreRedirect for these special cases
if (psShader->eTargetLanguage == LANG_METAL && regSpace == 0 && (iIgnoreRedirect == 0))
return outputPrefix + res;
else if (psShader->eTargetLanguage == LANG_METAL && (iIgnoreRedirect == 0))
return patchPrefix + res;
else
return res;
}
ASSERT(psOut != NULL);
if (psShader->eTargetLanguage == LANG_METAL && regSpace == 0 && (iIgnoreRedirect == 0))
return outputPrefix + res;
else if (psShader->eTargetLanguage == LANG_METAL && (iIgnoreRedirect == 0))
return patchPrefix + res;
else
return res;
}
ASSERT(psOut != NULL);
oss << outputPrefix << (regSpace == 1 ? patchPrefix : "") << psOut->semanticName << psOut->ui32SemanticIndex;
return oss.str();
oss << outputPrefix << (regSpace == 1 ? patchPrefix : "") << psOut->semanticName << psOut->ui32SemanticIndex;
return oss.str();
}
bool HLSLCrossCompilerContext::OutputNeedsDeclaring(const Operand* psOperand, const int count)
{
char compMask = (char)psOperand->ui32CompMask;
int regSpace = psOperand->GetRegisterSpace(this);
uint32_t startIndex = psOperand->ui32RegisterNumber + (psShader->ui32CurrentVertexOutputStream * 1024); // Assume less than 1K input streams
ASSERT(psShader->ui32CurrentVertexOutputStream < 4);
char compMask = (char)psOperand->ui32CompMask;
int regSpace = psOperand->GetRegisterSpace(this);
uint32_t startIndex = psOperand->ui32RegisterNumber + (psShader->ui32CurrentVertexOutputStream * 1024); // Assume less than 1K input streams
ASSERT(psShader->ui32CurrentVertexOutputStream < 4);
// First check for various builtins, mostly depth-output ones.
if (psShader->eShaderType == PIXEL_SHADER)
{
if (psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL ||
psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL)
{
return true;
}
// First check for various builtins, mostly depth-output ones.
if (psShader->eShaderType == PIXEL_SHADER)
{
if (psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL ||
psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL)
{
return true;
}
if (psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH)
{
// GL doesn't need declaration, Metal does.
return psShader->eTargetLanguage == LANG_METAL;
}
}
if (psOperand->eType == OPERAND_TYPE_OUTPUT_DEPTH)
{
// GL doesn't need declaration, Metal does.
return psShader->eTargetLanguage == LANG_METAL;
}
}
// Needs declaring if any of the components hasn't been already declared
if ((compMask & ~psShader->acOutputDeclared[regSpace][startIndex]) != 0)
{
int offset;
const ShaderInfo::InOutSignature* psSignature = NULL;
// Needs declaring if any of the components hasn't been already declared
if ((compMask & ~psShader->acOutputDeclared[regSpace][startIndex]) != 0)
{
int offset;
const ShaderInfo::InOutSignature* psSignature = NULL;
if (psOperand->eSpecialName == NAME_UNDEFINED)
{
// Need to fetch the actual comp mask
if (regSpace == 0)
psShader->sInfo.GetOutputSignatureFromRegister(
psOperand->ui32RegisterNumber,
psOperand->ui32CompMask,
psShader->ui32CurrentVertexOutputStream,
&psSignature);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(
psOperand->ui32RegisterNumber,
psOperand->ui32CompMask,
&psSignature);
if (psOperand->eSpecialName == NAME_UNDEFINED)
{
// Need to fetch the actual comp mask
if (regSpace == 0)
psShader->sInfo.GetOutputSignatureFromRegister(
psOperand->ui32RegisterNumber,
psOperand->ui32CompMask,
psShader->ui32CurrentVertexOutputStream,
&psSignature);
else
psShader->sInfo.GetPatchConstantSignatureFromRegister(
psOperand->ui32RegisterNumber,
psOperand->ui32CompMask,
&psSignature);
compMask = (char)psSignature->ui32Mask;
}
for (offset = 0; offset < count; offset++)
{
psShader->acOutputDeclared[regSpace][startIndex + offset] |= compMask;
}
compMask = (char)psSignature->ui32Mask;
}
for (offset = 0; offset < count; offset++)
{
psShader->acOutputDeclared[regSpace][startIndex + offset] |= compMask;
}
if (psSignature && (psSignature->semanticName == "PSIZE") && (psShader->eTargetLanguage != LANG_METAL))
{
// gl_PointSize, doesn't need declaring. TODO: Metal doesn't have pointsize at all?
return false;
}
if (psSignature && (psSignature->semanticName == "PSIZE") && (psShader->eTargetLanguage != LANG_METAL))
{
// gl_PointSize, doesn't need declaring. TODO: Metal doesn't have pointsize at all?
return false;
}
return true;
}
return true;
}
return false;
return false;
}
bool HLSLCrossCompilerContext::IsVulkan() const
{
return (flags & HLSLCC_FLAG_VULKAN_BINDINGS) != 0;
return (flags & HLSLCC_FLAG_VULKAN_BINDINGS) != 0;
}

Просмотреть файл

@ -1,4 +1,3 @@
#include "hlslcc.h"
#include <memory>
@ -30,192 +29,191 @@
HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromMem(const char* shader,
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result)
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result)
{
uint32_t* tokens;
char* glslcstr = NULL;
int GLSLShaderType = GL_FRAGMENT_SHADER_ARB;
int success = 0;
uint32_t i;
uint32_t* tokens;
char* glslcstr = NULL;
int GLSLShaderType = GL_FRAGMENT_SHADER_ARB;
int success = 0;
uint32_t i;
tokens = (uint32_t*)shader;
tokens = (uint32_t*)shader;
std::auto_ptr<Shader> psShader(DecodeDXBC(tokens, flags));
std::auto_ptr<Shader> psShader(DecodeDXBC(tokens, flags));
if (psShader.get())
{
HLSLCrossCompilerContext sContext(reflectionCallbacks);
if (psShader.get())
{
HLSLCrossCompilerContext sContext(reflectionCallbacks);
// Add shader precisions from the list
psShader->sInfo.AddSamplerPrecisions(samplerPrecisions);
// Add shader precisions from the list
psShader->sInfo.AddSamplerPrecisions(samplerPrecisions);
if (psShader->ui32MajorVersion <= 3)
{
flags &= ~HLSLCC_FLAG_COMBINE_TEXTURE_SAMPLERS;
}
if (psShader->ui32MajorVersion <= 3)
{
flags &= ~HLSLCC_FLAG_COMBINE_TEXTURE_SAMPLERS;
}
sContext.psShader = psShader.get();
sContext.flags = flags;
sContext.psShader = psShader.get();
sContext.flags = flags;
// If dependencies == NULL, we'll create a dummy object for it so that there's always something there.
std::auto_ptr<GLSLCrossDependencyData> depPtr(NULL);
if (dependencies == NULL)
{
depPtr.reset(new GLSLCrossDependencyData());
sContext.psDependencies = depPtr.get();
}
else
sContext.psDependencies = dependencies;
// If dependencies == NULL, we'll create a dummy object for it so that there's always something there.
std::auto_ptr<GLSLCrossDependencyData> depPtr(NULL);
if (dependencies == NULL)
{
depPtr.reset(new GLSLCrossDependencyData());
sContext.psDependencies = depPtr.get();
}
else
sContext.psDependencies = dependencies;
for (i = 0; i < psShader->asPhases.size(); ++i)
{
psShader->asPhases[i].hasPostShaderCode = 0;
}
for (i = 0; i < psShader->asPhases.size(); ++i)
{
psShader->asPhases[i].hasPostShaderCode = 0;
}
if (language == LANG_METAL)
{
// Geometry shader is not supported
if (psShader->eShaderType == GEOMETRY_SHADER)
{
result->sourceCode = "";
return 0;
}
ToMetal translator(&sContext);
if(!translator.Translate())
{
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
if (language == LANG_METAL)
{
// Geometry shader is not supported
if (psShader->eShaderType == GEOMETRY_SHADER)
{
result->sourceCode = "";
return 0;
}
ToMetal translator(&sContext);
if (!translator.Translate())
{
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
return 0;
}
}
else
{
ToGLSL translator(&sContext);
language = translator.SetLanguage(language);
translator.SetExtensions(extensions);
if (!translator.Translate())
{
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
return 0;
}
}
else
{
ToGLSL translator(&sContext);
language = translator.SetLanguage(language);
translator.SetExtensions(extensions);
if (!translator.Translate())
{
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
return 0;
}
}
return 0;
}
}
switch (psShader->eShaderType)
{
case VERTEX_SHADER:
{
GLSLShaderType = GL_VERTEX_SHADER_ARB;
break;
}
case GEOMETRY_SHADER:
{
GLSLShaderType = GL_GEOMETRY_SHADER;
break;
}
case DOMAIN_SHADER:
{
GLSLShaderType = GL_TESS_EVALUATION_SHADER;
break;
}
case HULL_SHADER:
{
GLSLShaderType = GL_TESS_CONTROL_SHADER;
break;
}
case COMPUTE_SHADER:
{
GLSLShaderType = GL_COMPUTE_SHADER;
break;
}
default:
{
break;
}
}
switch (psShader->eShaderType)
{
case VERTEX_SHADER:
{
GLSLShaderType = GL_VERTEX_SHADER_ARB;
break;
}
case GEOMETRY_SHADER:
{
GLSLShaderType = GL_GEOMETRY_SHADER;
break;
}
case DOMAIN_SHADER:
{
GLSLShaderType = GL_TESS_EVALUATION_SHADER;
break;
}
case HULL_SHADER:
{
GLSLShaderType = GL_TESS_CONTROL_SHADER;
break;
}
case COMPUTE_SHADER:
{
GLSLShaderType = GL_COMPUTE_SHADER;
break;
}
default:
{
break;
}
}
glslcstr = bstr2cstr(sContext.glsl, '\0');
result->sourceCode = glslcstr;
bcstrfree(glslcstr);
glslcstr = bstr2cstr(sContext.glsl, '\0');
result->sourceCode = glslcstr;
bcstrfree(glslcstr);
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
bdestroy(sContext.glsl);
for (i = 0; i < psShader->asPhases.size(); ++i)
{
bdestroy(psShader->asPhases[i].postShaderCode);
bdestroy(psShader->asPhases[i].earlyMain);
}
result->reflection = psShader->sInfo;
result->reflection = psShader->sInfo;
result->textureSamplers = psShader->textureSamplers;
result->textureSamplers = psShader->textureSamplers;
success = 1;
}
success = 1;
}
shader = 0;
tokens = 0;
shader = 0;
tokens = 0;
/* Fill in the result struct */
/* Fill in the result struct */
result->shaderType = GLSLShaderType;
result->GLSLLanguage = language;
result->shaderType = GLSLShaderType;
result->GLSLLanguage = language;
return success;
return success;
}
HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename,
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result)
unsigned int flags,
GLLang language,
const GlExtensions *extensions,
GLSLCrossDependencyData* dependencies,
HLSLccSamplerPrecisionInfo& samplerPrecisions,
HLSLccReflection& reflectionCallbacks,
GLSLShader* result)
{
FILE* shaderFile;
int length;
size_t readLength;
std::vector<char> shader;
int success = 0;
FILE* shaderFile;
int length;
size_t readLength;
std::vector<char> shader;
int success = 0;
shaderFile = fopen(filename, "rb");
shaderFile = fopen(filename, "rb");
if (!shaderFile)
{
return 0;
}
if (!shaderFile)
{
return 0;
}
fseek(shaderFile, 0, SEEK_END);
length = ftell(shaderFile);
fseek(shaderFile, 0, SEEK_SET);
fseek(shaderFile, 0, SEEK_END);
length = ftell(shaderFile);
fseek(shaderFile, 0, SEEK_SET);
shader.reserve(length + 1);
shader.reserve(length + 1);
readLength = fread(&shader[0], 1, length, shaderFile);
readLength = fread(&shader[0], 1, length, shaderFile);
fclose(shaderFile);
shaderFile = 0;
fclose(shaderFile);
shaderFile = 0;
shader[readLength] = '\0';
shader[readLength] = '\0';
success = TranslateHLSLFromMem(&shader[0], flags, language, extensions, dependencies, samplerPrecisions, reflectionCallbacks, result);
success = TranslateHLSLFromMem(&shader[0], flags, language, extensions, dependencies, samplerPrecisions, reflectionCallbacks, result);
return success;
return success;
}

Просмотреть файл

@ -1,4 +1,3 @@
#include "internal_includes/HLSLccToolkit.h"
#include "internal_includes/debug.h"
#include "internal_includes/toGLSLOperand.h"
@ -11,460 +10,457 @@
namespace HLSLcc
{
uint32_t GetNumberBitsSet(uint32_t a)
{
// Calculate number of bits in a
// Taken from https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64
// Works only up to 14 bits (we're only using up to 4)
return (a * 0x200040008001ULL & 0x111111111111111ULL) % 0xf;
}
uint32_t GetNumberBitsSet(uint32_t a)
{
// Calculate number of bits in a
// Taken from https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64
// Works only up to 14 bits (we're only using up to 4)
return (a * 0x200040008001ULL & 0x111111111111111ULL) % 0xf;
}
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType)
{
if (eType == SVT_FLOAT16)
{
return TO_FLAG_FORCE_HALF;
}
if (eType == SVT_UINT || eType == SVT_UINT16)
{
return TO_FLAG_UNSIGNED_INTEGER;
}
else if (eType == SVT_INT || eType == SVT_INT16 || eType == SVT_INT12)
{
return TO_FLAG_INTEGER;
}
else if (eType == SVT_BOOL)
{
return TO_FLAG_BOOL;
}
else
{
return TO_FLAG_NONE;
}
}
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType)
{
if (eType == SVT_FLOAT16)
{
return TO_FLAG_FORCE_HALF;
}
if (eType == SVT_UINT || eType == SVT_UINT16)
{
return TO_FLAG_UNSIGNED_INTEGER;
}
else if (eType == SVT_INT || eType == SVT_INT16 || eType == SVT_INT12)
{
return TO_FLAG_INTEGER;
}
else if (eType == SVT_BOOL)
{
return TO_FLAG_BOOL;
}
else
{
return TO_FLAG_NONE;
}
}
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags)
{
if (typeflags & TO_FLAG_FORCE_HALF)
return SVT_FLOAT16;
if (typeflags & (TO_FLAG_INTEGER | TO_AUTO_BITCAST_TO_INT))
return SVT_INT;
if (typeflags & (TO_FLAG_UNSIGNED_INTEGER | TO_AUTO_BITCAST_TO_UINT))
return SVT_UINT;
if (typeflags & TO_FLAG_BOOL)
return SVT_BOOL;
return SVT_FLOAT;
}
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags)
{
if (typeflags & TO_FLAG_FORCE_HALF)
return SVT_FLOAT16;
if (typeflags & (TO_FLAG_INTEGER | TO_AUTO_BITCAST_TO_INT))
return SVT_INT;
if (typeflags & (TO_FLAG_UNSIGNED_INTEGER | TO_AUTO_BITCAST_TO_UINT))
return SVT_UINT;
if (typeflags & TO_FLAG_BOOL)
return SVT_BOOL;
return SVT_FLOAT;
}
const char * GetConstructorForTypeGLSL(const HLSLCrossCompilerContext *context, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision)
{
static const char * const uintTypes[] = { " ", "uint", "uvec2", "uvec3", "uvec4" };
static const char * const uint16Types[] = { " ", "mediump uint", "mediump uvec2", "mediump uvec3", "mediump uvec4" };
static const char * const intTypes[] = { " ", "int", "ivec2", "ivec3", "ivec4" };
static const char * const int16Types[] = { " ", "mediump int", "mediump ivec2", "mediump ivec3", "mediump ivec4" };
static const char * const int12Types[] = { " ", "lowp int", "lowp ivec2", "lowp ivec3", "lowp ivec4" };
static const char * const floatTypes[] = { " ", "float", "vec2", "vec3", "vec4" };
static const char * const float16Types[] = { " ", "mediump float", "mediump vec2", "mediump vec3", "mediump vec4" };
static const char * const float10Types[] = { " ", "lowp float", "lowp vec2", "lowp vec3", "lowp vec4" };
static const char * const boolTypes[] = { " ", "bool", "bvec2", "bvec3", "bvec4" };
const char * GetConstructorForTypeGLSL(const HLSLCrossCompilerContext *context, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision)
{
static const char * const uintTypes[] = { " ", "uint", "uvec2", "uvec3", "uvec4" };
static const char * const uint16Types[] = { " ", "mediump uint", "mediump uvec2", "mediump uvec3", "mediump uvec4" };
static const char * const intTypes[] = { " ", "int", "ivec2", "ivec3", "ivec4" };
static const char * const int16Types[] = { " ", "mediump int", "mediump ivec2", "mediump ivec3", "mediump ivec4" };
static const char * const int12Types[] = { " ", "lowp int", "lowp ivec2", "lowp ivec3", "lowp ivec4" };
static const char * const floatTypes[] = { " ", "float", "vec2", "vec3", "vec4" };
static const char * const float16Types[] = { " ", "mediump float", "mediump vec2", "mediump vec3", "mediump vec4" };
static const char * const float10Types[] = { " ", "lowp float", "lowp vec2", "lowp vec3", "lowp vec4" };
static const char * const boolTypes[] = { " ", "bool", "bvec2", "bvec3", "bvec4" };
ASSERT(components >= 1 && components <= 4);
ASSERT(components >= 1 && components <= 4);
bool emitLowp = EmitLowp(context);
switch (eType)
{
case SVT_UINT:
return HaveUnsignedTypes(context->psShader->eTargetLanguage) ? uintTypes[components] : intTypes[components];
case SVT_UINT16:
return useGLSLPrecision ? uint16Types[components] : uintTypes[components];
case SVT_INT:
return intTypes[components];
case SVT_INT16:
return useGLSLPrecision ? int16Types[components] : intTypes[components];
case SVT_INT12:
return useGLSLPrecision ? (emitLowp ? int12Types[components] : int16Types[components]) : intTypes[components];
case SVT_FLOAT:
return floatTypes[components];
case SVT_FLOAT16:
return useGLSLPrecision ? float16Types[components] : floatTypes[components];
case SVT_FLOAT10:
return useGLSLPrecision ? (emitLowp ? float10Types[components] : float16Types[components]) : floatTypes[components];
case SVT_BOOL:
return boolTypes[components];
default:
ASSERT(0);
return " ";
}
}
switch (eType)
{
case SVT_UINT:
return HaveUnsignedTypes(context->psShader->eTargetLanguage) ? uintTypes[components] : intTypes[components];
case SVT_UINT16:
return useGLSLPrecision ? uint16Types[components] : uintTypes[components];
case SVT_INT:
return intTypes[components];
case SVT_INT16:
return useGLSLPrecision ? int16Types[components] : intTypes[components];
case SVT_INT12:
return useGLSLPrecision ? (emitLowp ? int12Types[components] : int16Types[components]) : intTypes[components];
case SVT_FLOAT:
return floatTypes[components];
case SVT_FLOAT16:
return useGLSLPrecision ? float16Types[components] : floatTypes[components];
case SVT_FLOAT10:
return useGLSLPrecision ? (emitLowp ? float10Types[components] : float16Types[components]) : floatTypes[components];
case SVT_BOOL:
return boolTypes[components];
default:
ASSERT(0);
return " ";
}
}
const char * GetConstructorForTypeMetal(const SHADER_VARIABLE_TYPE eType,
const int components)
{
static const char * const uintTypes[] = { " ", "uint", "uint2", "uint3", "uint4" };
static const char * const ushortTypes[] = { " ", "ushort", "ushort2", "ushort3", "ushort4" };
static const char * const intTypes[] = { " ", "int", "int2", "int3", "int4" };
static const char * const shortTypes[] = { " ", "short", "short2", "short3", "short4" };
static const char * const floatTypes[] = { " ", "float", "float2", "float3", "float4" };
static const char * const halfTypes[] = { " ", "half", "half2", "half3", "half4" };
static const char * const boolTypes[] = { " ", "bool", "bool2", "bool3", "bool4" };
const char * GetConstructorForTypeMetal(const SHADER_VARIABLE_TYPE eType,
const int components)
{
static const char * const uintTypes[] = { " ", "uint", "uint2", "uint3", "uint4" };
static const char * const ushortTypes[] = { " ", "ushort", "ushort2", "ushort3", "ushort4" };
static const char * const intTypes[] = { " ", "int", "int2", "int3", "int4" };
static const char * const shortTypes[] = { " ", "short", "short2", "short3", "short4" };
static const char * const floatTypes[] = { " ", "float", "float2", "float3", "float4" };
static const char * const halfTypes[] = { " ", "half", "half2", "half3", "half4" };
static const char * const boolTypes[] = { " ", "bool", "bool2", "bool3", "bool4" };
ASSERT(components >= 1 && components <= 4);
ASSERT(components >= 1 && components <= 4);
switch (eType)
{
case SVT_UINT:
return uintTypes[components];
case SVT_UINT16:
return ushortTypes[components];
case SVT_INT:
return intTypes[components];
case SVT_INT16:
case SVT_INT12:
return shortTypes[components];
case SVT_FLOAT:
return floatTypes[components];
case SVT_FLOAT16:
case SVT_FLOAT10:
return halfTypes[components];
case SVT_BOOL:
return boolTypes[components];
default:
ASSERT(0);
return " ";
}
}
switch (eType)
{
case SVT_UINT:
return uintTypes[components];
case SVT_UINT16:
return ushortTypes[components];
case SVT_INT:
return intTypes[components];
case SVT_INT16:
case SVT_INT12:
return shortTypes[components];
case SVT_FLOAT:
return floatTypes[components];
case SVT_FLOAT16:
case SVT_FLOAT10:
return halfTypes[components];
case SVT_BOOL:
return boolTypes[components];
default:
ASSERT(0);
return " ";
}
}
const char * GetConstructorForType(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision /* = true*/)
{
if (psContext->psShader->eTargetLanguage == LANG_METAL)
return GetConstructorForTypeMetal(eType, components);
else
return GetConstructorForTypeGLSL(psContext, eType, components, useGLSLPrecision);
}
const char * GetConstructorForType(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision /* = true*/)
{
if (psContext->psShader->eTargetLanguage == LANG_METAL)
return GetConstructorForTypeMetal(eType, components);
else
return GetConstructorForTypeGLSL(psContext, eType, components, useGLSLPrecision);
}
std::string GetMatrixTypeName(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eBaseType, const int columns, const int rows)
{
std::string result;
std::ostringstream oss;
if (psContext->psShader->eTargetLanguage == LANG_METAL)
{
switch (eBaseType)
{
case SVT_FLOAT:
oss << "float" << columns << "x" << rows;
break;
case SVT_FLOAT16:
case SVT_FLOAT10:
oss << "half" << columns << "x" << rows;
break;
default:
ASSERT(0);
break;
}
}
else
{
switch (eBaseType)
{
case SVT_FLOAT:
oss << "mat" << columns << "x" << rows;
break;
case SVT_FLOAT16:
oss << "mediump mat" << columns << "x" << rows;
break;
case SVT_FLOAT10:
oss << "lowp mat" << columns << "x" << rows;
break;
default:
ASSERT(0);
break;
}
std::string GetMatrixTypeName(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eBaseType, const int columns, const int rows)
{
std::string result;
std::ostringstream oss;
if (psContext->psShader->eTargetLanguage == LANG_METAL)
{
switch (eBaseType)
{
case SVT_FLOAT:
oss << "float" << columns << "x" << rows;
break;
case SVT_FLOAT16:
case SVT_FLOAT10:
oss << "half" << columns << "x" << rows;
break;
default:
ASSERT(0);
break;
}
}
else
{
switch (eBaseType)
{
case SVT_FLOAT:
oss << "mat" << columns << "x" << rows;
break;
case SVT_FLOAT16:
oss << "mediump mat" << columns << "x" << rows;
break;
case SVT_FLOAT10:
oss << "lowp mat" << columns << "x" << rows;
break;
default:
ASSERT(0);
break;
}
}
result = oss.str();
return result;
}
}
result = oss.str();
return result;
}
void AddSwizzleUsingElementCount(bstring dest, uint32_t count)
{
if (count == 4)
return;
if (count)
{
bcatcstr(dest, ".");
bcatcstr(dest, "x");
count--;
}
if (count)
{
bcatcstr(dest, "y");
count--;
}
if (count)
{
bcatcstr(dest, "z");
count--;
}
if (count)
{
bcatcstr(dest, "w");
count--;
}
}
void AddSwizzleUsingElementCount(bstring dest, uint32_t count)
{
if (count == 4)
return;
if (count)
{
bcatcstr(dest, ".");
bcatcstr(dest, "x");
count--;
}
if (count)
{
bcatcstr(dest, "y");
count--;
}
if (count)
{
bcatcstr(dest, "z");
count--;
}
if (count)
{
bcatcstr(dest, "w");
count--;
}
}
// Calculate the bits set in mask
int WriteMaskToComponentCount(uint32_t writeMask)
{
// In HLSL bytecode writemask 0 also means everything
if (writeMask == 0)
return 4;
// Calculate the bits set in mask
int WriteMaskToComponentCount(uint32_t writeMask)
{
// In HLSL bytecode writemask 0 also means everything
if (writeMask == 0)
return 4;
return (int)GetNumberBitsSet(writeMask);
}
return (int)GetNumberBitsSet(writeMask);
}
uint32_t BuildComponentMaskFromElementCount(int count)
{
// Translate numComponents into bitmask
// 1 -> 1, 2 -> 3, 3 -> 7 and 4 -> 15
return (1 << count) - 1;
}
uint32_t BuildComponentMaskFromElementCount(int count)
{
// Translate numComponents into bitmask
// 1 -> 1, 2 -> 3, 3 -> 7 and 4 -> 15
return (1 << count) - 1;
}
// Returns true if we can do direct assignment between types (mostly for mediump<->highp floats etc)
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src)
{
if (src == dest)
return true;
// Returns true if we can do direct assignment between types (mostly for mediump<->highp floats etc)
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src)
{
if (src == dest)
return true;
if ((dest == SVT_FLOAT || dest == SVT_FLOAT10 || dest == SVT_FLOAT16) &&
(src == SVT_FLOAT || src == SVT_FLOAT10 || src == SVT_FLOAT16))
return true;
if ((dest == SVT_FLOAT || dest == SVT_FLOAT10 || dest == SVT_FLOAT16) &&
(src == SVT_FLOAT || src == SVT_FLOAT10 || src == SVT_FLOAT16))
return true;
if ((dest == SVT_INT || dest == SVT_INT12 || dest == SVT_INT16) &&
(src == SVT_INT || src == SVT_INT12 || src == SVT_INT16))
return true;
if ((dest == SVT_INT || dest == SVT_INT12 || dest == SVT_INT16) &&
(src == SVT_INT || src == SVT_INT12 || src == SVT_INT16))
return true;
if ((dest == SVT_UINT || dest == SVT_UINT16) &&
(src == SVT_UINT || src == SVT_UINT16))
return true;
if ((dest == SVT_UINT || dest == SVT_UINT16) &&
(src == SVT_UINT || src == SVT_UINT16))
return true;
return false;
}
return false;
}
uint32_t ResourceReturnTypeToFlag(const RESOURCE_RETURN_TYPE eType)
{
if (eType == RETURN_TYPE_SINT)
{
return TO_FLAG_INTEGER;
}
else if (eType == RETURN_TYPE_UINT)
{
return TO_FLAG_UNSIGNED_INTEGER;
}
else
{
return TO_FLAG_NONE;
}
}
uint32_t ResourceReturnTypeToFlag(const RESOURCE_RETURN_TYPE eType)
{
if (eType == RETURN_TYPE_SINT)
{
return TO_FLAG_INTEGER;
}
else if (eType == RETURN_TYPE_UINT)
{
return TO_FLAG_UNSIGNED_INTEGER;
}
else
{
return TO_FLAG_NONE;
}
}
SHADER_VARIABLE_TYPE ResourceReturnTypeToSVTType(const RESOURCE_RETURN_TYPE eType, const REFLECT_RESOURCE_PRECISION ePrec)
{
if (eType == RETURN_TYPE_SINT)
{
switch (ePrec)
{
default:
return SVT_INT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_INT12;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_INT16;
}
}
else if (eType == RETURN_TYPE_UINT)
{
switch (ePrec)
{
default:
return SVT_UINT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_UINT8;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_UINT16;
}
}
else
{
switch (ePrec)
{
default:
return SVT_FLOAT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_FLOAT10;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_FLOAT16;
}
}
}
SHADER_VARIABLE_TYPE ResourceReturnTypeToSVTType(const RESOURCE_RETURN_TYPE eType, const REFLECT_RESOURCE_PRECISION ePrec)
{
if (eType == RETURN_TYPE_SINT)
{
switch (ePrec)
{
default:
return SVT_INT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_INT12;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_INT16;
}
}
else if (eType == RETURN_TYPE_UINT)
{
switch (ePrec)
{
default:
return SVT_UINT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_UINT8;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_UINT16;
}
}
else
{
switch (ePrec)
{
default:
return SVT_FLOAT;
case REFLECT_RESOURCE_PRECISION_LOWP:
return SVT_FLOAT10;
case REFLECT_RESOURCE_PRECISION_MEDIUMP:
return SVT_FLOAT16;
}
}
}
uint32_t ElemCountToAutoExpandFlag(uint32_t elemCount)
{
return TO_AUTO_EXPAND_TO_VEC2 << (elemCount - 2);
}
uint32_t ElemCountToAutoExpandFlag(uint32_t elemCount)
{
return TO_AUTO_EXPAND_TO_VEC2 << (elemCount - 2);
}
// Returns true if the operation is commutative
bool IsOperationCommutative(int eOpCode)
{
switch ((OPCODE_TYPE)eOpCode)
{
case OPCODE_DADD:
case OPCODE_IADD:
case OPCODE_ADD:
case OPCODE_MUL:
case OPCODE_IMUL:
case OPCODE_OR:
case OPCODE_AND:
return true;
default:
return false;
}
}
// Returns true if the operation is commutative
bool IsOperationCommutative(int eOpCode)
{
switch ((OPCODE_TYPE)eOpCode)
{
case OPCODE_DADD:
case OPCODE_IADD:
case OPCODE_ADD:
case OPCODE_MUL:
case OPCODE_IMUL:
case OPCODE_OR:
case OPCODE_AND:
return true;
default:
return false;
};
}
// Returns true if operands are identical, only cares about temp registers currently.
bool AreTempOperandsIdentical(const Operand * psA, const Operand * psB)
{
if (!psA || !psB)
return 0;
// Returns true if operands are identical, only cares about temp registers currently.
bool AreTempOperandsIdentical(const Operand * psA, const Operand * psB)
{
if (!psA || !psB)
return 0;
if (psA->eType != OPERAND_TYPE_TEMP || psB->eType != OPERAND_TYPE_TEMP)
return 0;
if (psA->eType != OPERAND_TYPE_TEMP || psB->eType != OPERAND_TYPE_TEMP)
return 0;
if (psA->eModifier != psB->eModifier)
return 0;
if (psA->eModifier != psB->eModifier)
return 0;
if (psA->iNumComponents != psB->iNumComponents)
return 0;
if (psA->iNumComponents != psB->iNumComponents)
return 0;
if (psA->ui32RegisterNumber != psB->ui32RegisterNumber)
return 0;
if (psA->ui32RegisterNumber != psB->ui32RegisterNumber)
return 0;
if (psA->eSelMode != psB->eSelMode)
return 0;
if (psA->eSelMode != psB->eSelMode)
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_MASK_MODE && psA->ui32CompMask != psB->ui32CompMask)
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_MASK_MODE && psA->ui32CompMask != psB->ui32CompMask)
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE && psA->aui32Swizzle[0] != psB->aui32Swizzle[0])
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE && psA->aui32Swizzle[0] != psB->aui32Swizzle[0])
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE && std::equal(&psA->aui32Swizzle[0], &psA->aui32Swizzle[4], &psB->aui32Swizzle[0]))
return 0;
if (psA->eSelMode == OPERAND_4_COMPONENT_SWIZZLE_MODE && std::equal(&psA->aui32Swizzle[0], &psA->aui32Swizzle[4], &psB->aui32Swizzle[0]))
return 0;
return 1;
}
return 1;
}
bool IsAddOneInstruction(const Instruction *psInst)
{
if (psInst->eOpcode != OPCODE_IADD)
return false;
if (psInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
bool IsAddOneInstruction(const Instruction *psInst)
{
if (psInst->eOpcode != OPCODE_IADD)
return false;
if (psInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
if (psInst->asOperands[1].eType == OPERAND_TYPE_TEMP)
{
if (psInst->asOperands[1].ui32RegisterNumber != psInst->asOperands[0].ui32RegisterNumber)
return false;
if (psInst->asOperands[2].eType != OPERAND_TYPE_IMMEDIATE32)
return false;
if (psInst->asOperands[1].eType == OPERAND_TYPE_TEMP)
{
if (psInst->asOperands[1].ui32RegisterNumber != psInst->asOperands[0].ui32RegisterNumber)
return false;
if (psInst->asOperands[2].eType != OPERAND_TYPE_IMMEDIATE32)
return false;
if (*(int *)&psInst->asOperands[2].afImmediates[0] != 1)
return false;
}
else
{
if (psInst->asOperands[1].eType != OPERAND_TYPE_IMMEDIATE32)
return false;
if (psInst->asOperands[2].eType != OPERAND_TYPE_TEMP)
return false;
if (*(int *)&psInst->asOperands[2].afImmediates[0] != 1)
return false;
}
else
{
if (psInst->asOperands[1].eType != OPERAND_TYPE_IMMEDIATE32)
return false;
if (psInst->asOperands[2].eType != OPERAND_TYPE_TEMP)
return false;
if (psInst->asOperands[2].ui32RegisterNumber != psInst->asOperands[0].ui32RegisterNumber)
return false;
if (psInst->asOperands[2].ui32RegisterNumber != psInst->asOperands[0].ui32RegisterNumber)
return false;
if (*(int *)&psInst->asOperands[1].afImmediates[0] != 1)
return false;
}
return true;
}
if (*(int *)&psInst->asOperands[1].afImmediates[0] != 1)
return false;
}
return true;
}
int GetNumTextureDimensions(int /* RESOURCE_DIMENSION */ eResDim)
{
switch ((RESOURCE_DIMENSION)eResDim)
{
case RESOURCE_DIMENSION_TEXTURE1D:
return 1;
case RESOURCE_DIMENSION_TEXTURE2D:
case RESOURCE_DIMENSION_TEXTURE2DMS:
case RESOURCE_DIMENSION_TEXTURE1DARRAY:
case RESOURCE_DIMENSION_TEXTURECUBE:
return 2;
case RESOURCE_DIMENSION_TEXTURE3D:
case RESOURCE_DIMENSION_TEXTURE2DARRAY:
case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
return 3;
default:
ASSERT(0);
break;
}
return 0;
}
int GetNumTextureDimensions(int /* RESOURCE_DIMENSION */ eResDim)
{
switch ((RESOURCE_DIMENSION)eResDim)
{
case RESOURCE_DIMENSION_TEXTURE1D:
return 1;
case RESOURCE_DIMENSION_TEXTURE2D:
case RESOURCE_DIMENSION_TEXTURE2DMS:
case RESOURCE_DIMENSION_TEXTURE1DARRAY:
case RESOURCE_DIMENSION_TEXTURECUBE:
return 2;
case RESOURCE_DIMENSION_TEXTURE3D:
case RESOURCE_DIMENSION_TEXTURE2DARRAY:
case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
return 3;
default:
ASSERT(0);
break;
}
return 0;
}
// Returns the "more important" type of a and b, currently int < uint < float
SHADER_VARIABLE_TYPE SelectHigherType(SHADER_VARIABLE_TYPE a, SHADER_VARIABLE_TYPE b)
{
// Returns the "more important" type of a and b, currently int < uint < float
SHADER_VARIABLE_TYPE SelectHigherType(SHADER_VARIABLE_TYPE a, SHADER_VARIABLE_TYPE b)
{
#define DO_CHECK(type) if( a == type || b == type ) return type
// Priority ordering
DO_CHECK(SVT_FLOAT16);
DO_CHECK(SVT_FLOAT10);
DO_CHECK(SVT_UINT16);
DO_CHECK(SVT_UINT8);
DO_CHECK(SVT_INT16);
DO_CHECK(SVT_INT12);
DO_CHECK(SVT_FORCED_INT);
DO_CHECK(SVT_FLOAT);
DO_CHECK(SVT_UINT);
DO_CHECK(SVT_INT);
DO_CHECK(SVT_INT_AMBIGUOUS);
// Priority ordering
DO_CHECK(SVT_FLOAT16);
DO_CHECK(SVT_FLOAT10);
DO_CHECK(SVT_UINT16);
DO_CHECK(SVT_UINT8);
DO_CHECK(SVT_INT16);
DO_CHECK(SVT_INT12);
DO_CHECK(SVT_FORCED_INT);
DO_CHECK(SVT_FLOAT);
DO_CHECK(SVT_UINT);
DO_CHECK(SVT_INT);
DO_CHECK(SVT_INT_AMBIGUOUS);
#undef DO_CHECK
// After these just rely on ordering.
return a > b ? a : b;
}
// After these just rely on ordering.
return a > b ? a : b;
}
// Returns true if a direct constructor can convert src->dest
bool CanDoDirectCast(const HLSLCrossCompilerContext *context, SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest)
{
// uint<->int<->bool conversions possible
if ((src == SVT_INT || src == SVT_UINT || src == SVT_BOOL || src == SVT_INT12 || src == SVT_INT16 || src == SVT_UINT16) &&
(dest == SVT_INT || dest == SVT_UINT || dest == SVT_BOOL || dest == SVT_INT12 || dest == SVT_INT16 || dest == SVT_UINT16))
return true;
// Returns true if a direct constructor can convert src->dest
bool CanDoDirectCast(const HLSLCrossCompilerContext *context, SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest)
{
// uint<->int<->bool conversions possible
if ((src == SVT_INT || src == SVT_UINT || src == SVT_BOOL || src == SVT_INT12 || src == SVT_INT16 || src == SVT_UINT16) &&
(dest == SVT_INT || dest == SVT_UINT || dest == SVT_BOOL || dest == SVT_INT12 || dest == SVT_INT16 || dest == SVT_UINT16))
return true;
// float<->double possible
if ((src == SVT_FLOAT || src == SVT_DOUBLE || src == SVT_FLOAT16 || src == SVT_FLOAT10) &&
(dest == SVT_FLOAT || dest == SVT_DOUBLE || dest == SVT_FLOAT16 || dest == SVT_FLOAT10))
return true;
// float<->double possible
if ((src == SVT_FLOAT || src == SVT_DOUBLE || src == SVT_FLOAT16 || src == SVT_FLOAT10) &&
(dest == SVT_FLOAT || dest == SVT_DOUBLE || dest == SVT_FLOAT16 || dest == SVT_FLOAT10))
return true;
if (context->psShader->eTargetLanguage == LANG_METAL)
{
// avoid compiler error: cannot use as_type to cast from 'half' to 'unsigned int', types of different size
if ((src == SVT_FLOAT16 || src == SVT_FLOAT10) && (dest == SVT_UINT))
return true;
}
if (context->psShader->eTargetLanguage == LANG_METAL)
{
// avoid compiler error: cannot use as_type to cast from 'half' to 'unsigned int', types of different size
if ((src == SVT_FLOAT16 || src == SVT_FLOAT10) && (dest == SVT_UINT))
return true;
}
return false;
}
return false;
}
bool IsUnityFlexibleInstancingBuffer(const ConstantBuffer* psCBuf)
{
@ -481,22 +477,21 @@ namespace HLSLcc
#endif
#endif // #ifndef fpcheck
// Helper function to print floats with full precision
void PrintFloat(bstring b, float f)
{
bstring temp;
int ePos;
int pointPos;
// Helper function to print floats with full precision
void PrintFloat(bstring b, float f)
{
bstring temp;
int ePos;
int pointPos;
temp = bformat("%.9g", f);
ePos = bstrchrp(temp, 'e', 0);
pointPos = bstrchrp(temp, '.', 0);
temp = bformat("%.9g", f);
ePos = bstrchrp(temp, 'e', 0);
pointPos = bstrchrp(temp, '.', 0);
bconcat(b, temp);
bdestroy(temp);
if (ePos < 0 && pointPos < 0 && !fpcheck(f))
bcatcstr(b, ".0");
}
};
bconcat(b, temp);
bdestroy(temp);
if (ePos < 0 && pointPos < 0 && !fpcheck(f))
bcatcstr(b, ".0");
}
}

Просмотреть файл

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Instruction">
<DisplayString>{{ id={id} op={eOpcode} o0={asOperands[0]}, o1={asOperands[1]}}}</DisplayString>
<DisplayString>{{ id={id} op={eOpcode} o0={asOperands[0]}, o1={asOperands[1]}}}</DisplayString>
</Type>
<Type Name="Operand">
<DisplayString>{{ type={eType}, reg={ui32RegisterNumber} }}</DisplayString>
</Type>
</AutoVisualizer>
</AutoVisualizer>

Просмотреть файл

@ -1,4 +1,3 @@
#include "internal_includes/Instruction.h"
#include "internal_includes/debug.h"
#include "include/ShaderInfo.h"
@ -6,353 +5,345 @@
// Returns the result swizzle operand for an instruction, or NULL if all src operands have swizzles
static Operand *GetSrcSwizzleOperand(Instruction *psInst)
{
switch (psInst->eOpcode)
{
case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_NOP:
case OPCODE_SWAPC:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
ASSERT(0);
return NULL;
switch (psInst->eOpcode)
{
case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_NOP:
case OPCODE_SWAPC:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
ASSERT(0);
return NULL;
// Normal arithmetics, all srcs have swizzles
case OPCODE_ADD:
case OPCODE_AND:
case OPCODE_DERIV_RTX:
case OPCODE_DERIV_RTX_COARSE:
case OPCODE_DERIV_RTX_FINE:
case OPCODE_DERIV_RTY:
case OPCODE_DERIV_RTY_COARSE:
case OPCODE_DERIV_RTY_FINE:
case OPCODE_DIV:
case OPCODE_EQ:
case OPCODE_EXP:
case OPCODE_FRC:
case OPCODE_FTOI:
case OPCODE_FTOU:
case OPCODE_GE:
case OPCODE_IADD:
case OPCODE_IEQ:
case OPCODE_IGE:
case OPCODE_ILT:
case OPCODE_IMAD:
case OPCODE_IMAX:
case OPCODE_IMIN:
case OPCODE_IMUL:
case OPCODE_INE:
case OPCODE_INEG:
case OPCODE_ITOF:
case OPCODE_LOG:
case OPCODE_LT:
case OPCODE_MAD:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MOV:
case OPCODE_MUL:
case OPCODE_NE:
case OPCODE_NOT:
case OPCODE_OR:
case OPCODE_ROUND_NE:
case OPCODE_ROUND_NI:
case OPCODE_ROUND_PI:
case OPCODE_ROUND_Z:
case OPCODE_RSQ:
case OPCODE_SINCOS:
case OPCODE_SQRT:
case OPCODE_UDIV:
case OPCODE_UGE:
case OPCODE_ULT:
case OPCODE_UMAD:
case OPCODE_UMAX:
case OPCODE_UMIN:
case OPCODE_UMUL:
case OPCODE_UTOF:
case OPCODE_XOR:
// Normal arithmetics, all srcs have swizzles
case OPCODE_ADD:
case OPCODE_AND:
case OPCODE_DERIV_RTX:
case OPCODE_DERIV_RTX_COARSE:
case OPCODE_DERIV_RTX_FINE:
case OPCODE_DERIV_RTY:
case OPCODE_DERIV_RTY_COARSE:
case OPCODE_DERIV_RTY_FINE:
case OPCODE_DIV:
case OPCODE_EQ:
case OPCODE_EXP:
case OPCODE_FRC:
case OPCODE_FTOI:
case OPCODE_FTOU:
case OPCODE_GE:
case OPCODE_IADD:
case OPCODE_IEQ:
case OPCODE_IGE:
case OPCODE_ILT:
case OPCODE_IMAD:
case OPCODE_IMAX:
case OPCODE_IMIN:
case OPCODE_IMUL:
case OPCODE_INE:
case OPCODE_INEG:
case OPCODE_ITOF:
case OPCODE_LOG:
case OPCODE_LT:
case OPCODE_MAD:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MOV:
case OPCODE_MUL:
case OPCODE_NE:
case OPCODE_NOT:
case OPCODE_OR:
case OPCODE_ROUND_NE:
case OPCODE_ROUND_NI:
case OPCODE_ROUND_PI:
case OPCODE_ROUND_Z:
case OPCODE_RSQ:
case OPCODE_SINCOS:
case OPCODE_SQRT:
case OPCODE_UDIV:
case OPCODE_UGE:
case OPCODE_ULT:
case OPCODE_UMAD:
case OPCODE_UMAX:
case OPCODE_UMIN:
case OPCODE_UMUL:
case OPCODE_UTOF:
case OPCODE_XOR:
case OPCODE_BFI:
case OPCODE_BFREV:
case OPCODE_COUNTBITS:
case OPCODE_DADD:
case OPCODE_DDIV:
case OPCODE_DEQ:
case OPCODE_DFMA:
case OPCODE_DGE:
case OPCODE_DLT:
case OPCODE_DMAX:
case OPCODE_DMIN:
case OPCODE_DMUL:
case OPCODE_DMOV:
case OPCODE_DNE:
case OPCODE_DRCP:
case OPCODE_DTOF:
case OPCODE_F16TOF32:
case OPCODE_F32TOF16:
case OPCODE_FIRSTBIT_HI:
case OPCODE_FIRSTBIT_LO:
case OPCODE_FIRSTBIT_SHI:
case OPCODE_FTOD:
case OPCODE_IBFE:
case OPCODE_RCP:
case OPCODE_UADDC:
case OPCODE_UBFE:
case OPCODE_USUBB:
case OPCODE_MOVC:
case OPCODE_DMOVC:
return NULL;
case OPCODE_BFI:
case OPCODE_BFREV:
case OPCODE_COUNTBITS:
case OPCODE_DADD:
case OPCODE_DDIV:
case OPCODE_DEQ:
case OPCODE_DFMA:
case OPCODE_DGE:
case OPCODE_DLT:
case OPCODE_DMAX:
case OPCODE_DMIN:
case OPCODE_DMUL:
case OPCODE_DMOV:
case OPCODE_DNE:
case OPCODE_DRCP:
case OPCODE_DTOF:
case OPCODE_F16TOF32:
case OPCODE_F32TOF16:
case OPCODE_FIRSTBIT_HI:
case OPCODE_FIRSTBIT_LO:
case OPCODE_FIRSTBIT_SHI:
case OPCODE_FTOD:
case OPCODE_IBFE:
case OPCODE_RCP:
case OPCODE_UADDC:
case OPCODE_UBFE:
case OPCODE_USUBB:
case OPCODE_MOVC:
case OPCODE_DMOVC:
return NULL;
// Special cases:
case OPCODE_GATHER4:
case OPCODE_GATHER4_C:
case OPCODE_LD:
case OPCODE_LD_MS:
case OPCODE_LOD:
case OPCODE_LD_UAV_TYPED:
case OPCODE_LD_RAW:
case OPCODE_SAMPLE:
case OPCODE_SAMPLE_B:
case OPCODE_SAMPLE_L:
case OPCODE_SAMPLE_D:
case OPCODE_RESINFO:
return &psInst->asOperands[2];
// Special cases:
case OPCODE_GATHER4:
case OPCODE_GATHER4_C:
case OPCODE_LD:
case OPCODE_LD_MS:
case OPCODE_LOD:
case OPCODE_LD_UAV_TYPED:
case OPCODE_LD_RAW:
case OPCODE_SAMPLE:
case OPCODE_SAMPLE_B:
case OPCODE_SAMPLE_L:
case OPCODE_SAMPLE_D:
case OPCODE_RESINFO:
return &psInst->asOperands[2];
case OPCODE_GATHER4_PO:
case OPCODE_GATHER4_PO_C:
case OPCODE_LD_STRUCTURED:
return &psInst->asOperands[3];
case OPCODE_GATHER4_PO:
case OPCODE_GATHER4_PO_C:
case OPCODE_LD_STRUCTURED:
return &psInst->asOperands[3];
case OPCODE_SAMPLE_INFO:
return &psInst->asOperands[1];
case OPCODE_SAMPLE_INFO:
return &psInst->asOperands[1];
case OPCODE_ISHL:
case OPCODE_ISHR:
case OPCODE_USHR:
// sm4 variant has single component selection on src1 -> only src0 has swizzle
if (psInst->asOperands[2].eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE)
return &psInst->asOperands[1];
else // whereas sm5 variant has swizzle also on src1
return NULL;
default:
ASSERT(0);
return NULL;
}
case OPCODE_ISHL:
case OPCODE_ISHR:
case OPCODE_USHR:
// sm4 variant has single component selection on src1 -> only src0 has swizzle
if (psInst->asOperands[2].eSelMode == OPERAND_4_COMPONENT_SELECT_1_MODE)
return &psInst->asOperands[1];
else // whereas sm5 variant has swizzle also on src1
return NULL;
default:
ASSERT(0);
return NULL;
}
}
// Tweak the source operands of an instruction so that the rebased write mask will still work
static void DoSrcOperandRebase(Operand *psOperand, uint32_t rebase)
{
uint32_t i;
switch (psOperand->eSelMode)
{
default:
case OPERAND_4_COMPONENT_MASK_MODE:
ASSERT(psOperand->ui32CompMask == 0 || psOperand->ui32CompMask == OPERAND_4_COMPONENT_MASK_ALL);
uint32_t i;
switch (psOperand->eSelMode)
{
default:
case OPERAND_4_COMPONENT_MASK_MODE:
ASSERT(psOperand->ui32CompMask == 0 || psOperand->ui32CompMask == OPERAND_4_COMPONENT_MASK_ALL);
// Special case for immediates, they do not have swizzles
if (psOperand->eType == OPERAND_TYPE_IMMEDIATE32)
{
if (psOperand->iNumComponents > 1)
std::copy(&psOperand->afImmediates[rebase], &psOperand->afImmediates[4], &psOperand->afImmediates[0]);
return;
}
if (psOperand->eType == OPERAND_TYPE_IMMEDIATE64)
{
if (psOperand->iNumComponents > 1)
std::copy(&psOperand->adImmediates[rebase], &psOperand->adImmediates[4], &psOperand->adImmediates[0]);
return;
}
// Special case for immediates, they do not have swizzles
if (psOperand->eType == OPERAND_TYPE_IMMEDIATE32)
{
if (psOperand->iNumComponents > 1)
std::copy(&psOperand->afImmediates[rebase], &psOperand->afImmediates[4], &psOperand->afImmediates[0]);
return;
}
if (psOperand->eType == OPERAND_TYPE_IMMEDIATE64)
{
if (psOperand->iNumComponents > 1)
std::copy(&psOperand->adImmediates[rebase], &psOperand->adImmediates[4], &psOperand->adImmediates[0]);
return;
}
// Need to change this to swizzle
psOperand->eSelMode = OPERAND_4_COMPONENT_SWIZZLE_MODE;
psOperand->ui32Swizzle = 0;
for (i = 0; i < 4 - rebase; i++)
psOperand->aui32Swizzle[i] = i + rebase;
for (; i < 4; i++)
psOperand->aui32Swizzle[i] = rebase; // The first actual input.
break;
case OPERAND_4_COMPONENT_SELECT_1_MODE:
// Nothing to do
break;
case OPERAND_4_COMPONENT_SWIZZLE_MODE:
for (i = rebase; i < 4; i++)
psOperand->aui32Swizzle[i - rebase] = psOperand->aui32Swizzle[i];
break;
}
// Need to change this to swizzle
psOperand->eSelMode = OPERAND_4_COMPONENT_SWIZZLE_MODE;
psOperand->ui32Swizzle = 0;
for (i = 0; i < 4 - rebase; i++)
psOperand->aui32Swizzle[i] = i + rebase;
for (; i < 4; i++)
psOperand->aui32Swizzle[i] = rebase; // The first actual input.
break;
case OPERAND_4_COMPONENT_SELECT_1_MODE:
// Nothing to do
break;
case OPERAND_4_COMPONENT_SWIZZLE_MODE:
for (i = rebase; i < 4; i++)
psOperand->aui32Swizzle[i - rebase] = psOperand->aui32Swizzle[i];
break;
}
}
void Instruction::ChangeOperandTempRegister(Operand *psOperand, uint32_t oldReg, uint32_t newReg, uint32_t compMask, uint32_t flags, uint32_t rebase)
{
uint32_t i = 0;
uint32_t accessMask = 0;
int isDestination = 0;
Operand *psSwizzleOperand = NULL;
uint32_t i = 0;
uint32_t accessMask = 0;
int isDestination = 0;
Operand *psSwizzleOperand = NULL;
if (flags & UD_CHANGE_SUBOPERANDS)
{
for (i = 0; i < MAX_SUB_OPERANDS; i++)
{
if (psOperand->m_SubOperands[i].get())
ChangeOperandTempRegister(psOperand->m_SubOperands[i].get(), oldReg, newReg, compMask, UD_CHANGE_ALL, rebase);
}
}
if (flags & UD_CHANGE_SUBOPERANDS)
{
for (i = 0; i < MAX_SUB_OPERANDS; i++)
{
if (psOperand->m_SubOperands[i].get())
ChangeOperandTempRegister(psOperand->m_SubOperands[i].get(), oldReg, newReg, compMask, UD_CHANGE_ALL, rebase);
}
}
if ((flags & UD_CHANGE_MAIN_OPERAND) == 0)
return;
if ((flags & UD_CHANGE_MAIN_OPERAND) == 0)
return;
if (psOperand->eType != OPERAND_TYPE_TEMP)
return;
if (psOperand->eType != OPERAND_TYPE_TEMP)
return;
if (psOperand->ui32RegisterNumber != oldReg)
return;
if (psOperand->ui32RegisterNumber != oldReg)
return;
accessMask = psOperand->GetAccessMask();
// If this operation touches other components than the one(s) we're splitting, skip it
if ((accessMask & (~compMask)) != 0)
{
// Verify that we've not messed up in reachability analysis.
// This would mean that we've encountered an instruction that accesses
// a component in multi-component mode and we're supposed to treat it as single-use only.
// Now that we track operands we can bring this back
ASSERT((accessMask & compMask) == 0);
return;
}
accessMask = psOperand->GetAccessMask();
// If this operation touches other components than the one(s) we're splitting, skip it
if ((accessMask & (~compMask)) != 0)
{
// Verify that we've not messed up in reachability analysis.
// This would mean that we've encountered an instruction that accesses
// a component in multi-component mode and we're supposed to treat it as single-use only.
// Now that we track operands we can bring this back
ASSERT((accessMask & compMask) == 0);
return;
}
#if 0
printf("Updating operand %d with access mask %X\n", (int)psOperand->id, accessMask);
printf("Updating operand %d with access mask %X\n", (int)psOperand->id, accessMask);
#endif
psOperand->ui32RegisterNumber = newReg;
psOperand->ui32RegisterNumber = newReg;
if (rebase == 0)
return;
if (rebase == 0)
return;
// Update component mask. Note that we don't need to do anything to the suboperands. They do not affect destination writemask.
switch (psOperand->eSelMode)
{
case OPERAND_4_COMPONENT_MASK_MODE:
{
uint32_t oldMask = psOperand->ui32CompMask;
if (oldMask == 0)
oldMask = OPERAND_4_COMPONENT_MASK_ALL;
// Update component mask. Note that we don't need to do anything to the suboperands. They do not affect destination writemask.
switch (psOperand->eSelMode)
{
case OPERAND_4_COMPONENT_MASK_MODE:
{
uint32_t oldMask = psOperand->ui32CompMask;
if (oldMask == 0)
oldMask = OPERAND_4_COMPONENT_MASK_ALL;
// Check that we're not losing any information
ASSERT((oldMask >> rebase) << rebase == oldMask);
psOperand->ui32CompMask = (oldMask >> rebase);
break;
}
case OPERAND_4_COMPONENT_SELECT_1_MODE:
ASSERT(psOperand->aui32Swizzle[0] >= rebase);
psOperand->aui32Swizzle[0] -= rebase;
break;
case OPERAND_4_COMPONENT_SWIZZLE_MODE:
{
for (i = 0; i < 4; i++)
{
// Note that this rebase is different from the one done for source operands
ASSERT(psOperand->aui32Swizzle[i] >= rebase);
psOperand->aui32Swizzle[i] -= rebase;
}
break;
}
default:
ASSERT(0);
// Check that we're not losing any information
ASSERT((oldMask >> rebase) << rebase == oldMask);
psOperand->ui32CompMask = (oldMask >> rebase);
break;
}
case OPERAND_4_COMPONENT_SELECT_1_MODE:
ASSERT(psOperand->aui32Swizzle[0] >= rebase);
psOperand->aui32Swizzle[0] -= rebase;
break;
case OPERAND_4_COMPONENT_SWIZZLE_MODE:
{
for (i = 0; i < 4; i++)
{
// Note that this rebase is different from the one done for source operands
ASSERT(psOperand->aui32Swizzle[i] >= rebase);
psOperand->aui32Swizzle[i] -= rebase;
}
break;
}
default:
ASSERT(0);
}
}
// Tweak operand datatypes
std::copy(&psOperand->aeDataType[rebase], &psOperand->aeDataType[4], &psOperand->aeDataType[0]);
// Tweak operand datatypes
std::copy(&psOperand->aeDataType[rebase], &psOperand->aeDataType[4], &psOperand->aeDataType[0]);
// If this operand is a destination, we'll need to tweak sources as well
for (i = 0; i < ui32FirstSrc; i++)
{
if (psOperand == &asOperands[i])
{
isDestination = 1;
break;
}
}
// If this operand is a destination, we'll need to tweak sources as well
for (i = 0; i < ui32FirstSrc; i++)
{
if (psOperand == &asOperands[i])
{
isDestination = 1;
break;
}
}
if (isDestination == 0)
return;
if (isDestination == 0)
return;
// Nasty corner case of 2 destinations, not supported if both targets are written
ASSERT((ui32FirstSrc < 2) || (asOperands[0].eType == OPERAND_TYPE_NULL) || (asOperands[1].eType == OPERAND_TYPE_NULL));
// Nasty corner case of 2 destinations, not supported if both targets are written
ASSERT((ui32FirstSrc < 2) || (asOperands[0].eType == OPERAND_TYPE_NULL) || (asOperands[1].eType == OPERAND_TYPE_NULL));
// If we made it this far, we're rebasing a destination temp (and the only destination), need to tweak sources depending on the instruction
switch (eOpcode)
{
// The opcodes that do not need tweaking:
case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_BUFINFO:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
return;
default:
psSwizzleOperand = GetSrcSwizzleOperand(this); // Null means tweak all source operands
if (psSwizzleOperand)
{
DoSrcOperandRebase(psSwizzleOperand, rebase);
return;
}
else
{
for (i = ui32FirstSrc; i < ui32NumOperands; i++)
{
DoSrcOperandRebase(&asOperands[i], rebase);
}
}
return;
}
// If we made it this far, we're rebasing a destination temp (and the only destination), need to tweak sources depending on the instruction
switch (eOpcode)
{
// The opcodes that do not need tweaking:
case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_BUFINFO:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
return;
default:
psSwizzleOperand = GetSrcSwizzleOperand(this); // Null means tweak all source operands
if (psSwizzleOperand)
{
DoSrcOperandRebase(psSwizzleOperand, rebase);
return;
}
else
{
for (i = ui32FirstSrc; i < ui32NumOperands; i++)
{
DoSrcOperandRebase(&asOperands[i], rebase);
}
}
return;
}
}
// Returns nonzero if psInst is a sample instruction and the sampler has medium or low precision
bool Instruction::IsPartialPrecisionSamplerInstruction(const ShaderInfo &info, OPERAND_MIN_PRECISION *pType) const
{
const Operand *op;
const ResourceBinding *psBinding = NULL;
OPERAND_MIN_PRECISION sType = OPERAND_MIN_PRECISION_DEFAULT;
switch (eOpcode)
{
default:
return false;
case OPCODE_SAMPLE:
case OPCODE_SAMPLE_B:
case OPCODE_SAMPLE_L:
case OPCODE_SAMPLE_D:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
break;
}
const Operand *op;
const ResourceBinding *psBinding = NULL;
OPERAND_MIN_PRECISION sType = OPERAND_MIN_PRECISION_DEFAULT;
switch (eOpcode)
{
default:
return false;
case OPCODE_SAMPLE:
case OPCODE_SAMPLE_B:
case OPCODE_SAMPLE_L:
case OPCODE_SAMPLE_D:
case OPCODE_SAMPLE_C:
case OPCODE_SAMPLE_C_LZ:
break;
}
op = &asOperands[3];
ASSERT(op->eType == OPERAND_TYPE_SAMPLER);
op = &asOperands[3];
ASSERT(op->eType == OPERAND_TYPE_SAMPLER);
info.GetResourceFromBindingPoint(RGROUP_SAMPLER, op->ui32RegisterNumber, &psBinding);
if (!psBinding)
{
/* Try to look from texture group */
info.GetResourceFromBindingPoint(RGROUP_TEXTURE, op->ui32RegisterNumber, &psBinding);
}
info.GetResourceFromBindingPoint(RGROUP_SAMPLER, op->ui32RegisterNumber, &psBinding);
if (!psBinding)
{
/* Try to look from texture group */
info.GetResourceFromBindingPoint(RGROUP_TEXTURE, op->ui32RegisterNumber, &psBinding);
}
sType = Operand::ResourcePrecisionToOperandPrecision(psBinding ? psBinding->ePrecision : REFLECT_RESOURCE_PRECISION_UNKNOWN);
sType = Operand::ResourcePrecisionToOperandPrecision(psBinding ? psBinding->ePrecision : REFLECT_RESOURCE_PRECISION_UNKNOWN);
if (sType == OPERAND_MIN_PRECISION_DEFAULT)
return false;
if (sType == OPERAND_MIN_PRECISION_DEFAULT)
return false;
if (pType)
*pType = sType;
if (pType)
*pType = sType;
return true;
return true;
}

Просмотреть файл

@ -1,4 +1,3 @@
#include "src/internal_includes/HLSLCrossCompilerContext.h"
#include "src/internal_includes/LoopTransform.h"
#include "src/internal_includes/Shader.h"
@ -9,366 +8,363 @@
namespace HLSLcc
{
struct LoopInfo
{
public:
LoopInfo() : m_StartLoop(0), m_EndLoop(0), m_ExitPoints(), m_IsSwitch(false) {}
struct LoopInfo
{
public:
LoopInfo() : m_StartLoop(0), m_EndLoop(0), m_ExitPoints(), m_IsSwitch(false) {}
Instruction * m_StartLoop; // OPCODE_LOOP
Instruction * m_EndLoop; // OPCODE_ENDLOOP that matches the LOOP above.
std::vector<Instruction *> m_ExitPoints; // Any BREAK/RET/BREAKC instructions within the same loop depth
bool m_IsSwitch; // True if this is a switch-case and not a LOOP/ENDLOOP pair. Used as a helper when parsing.
};
Instruction * m_StartLoop; // OPCODE_LOOP
Instruction * m_EndLoop; // OPCODE_ENDLOOP that matches the LOOP above.
std::vector<Instruction *> m_ExitPoints; // Any BREAK/RET/BREAKC instructions within the same loop depth
bool m_IsSwitch; // True if this is a switch-case and not a LOOP/ENDLOOP pair. Used as a helper when parsing.
};
typedef std::list<LoopInfo> Loops;
typedef std::list<LoopInfo> Loops;
// Build a loopinfo array of all the loops in this shader phase
void BuildLoopInfo(ShaderPhase &phase, Loops &res)
{
using namespace std;
res.clear();
// Build a loopinfo array of all the loops in this shader phase
void BuildLoopInfo(ShaderPhase &phase, Loops &res)
{
using namespace std;
res.clear();
// A stack of loopinfo elements (stored in res)
list<LoopInfo *> loopStack;
// A stack of loopinfo elements (stored in res)
list<LoopInfo *> loopStack;
// Storage for dummy LoopInfo elements to be used for switch-cases. We don't want them cluttering the Loops list so store them here.
list<LoopInfo> dummyLIForSwitches;
// Storage for dummy LoopInfo elements to be used for switch-cases. We don't want them cluttering the Loops list so store them here.
list<LoopInfo> dummyLIForSwitches;
for (std::vector<Instruction>::iterator instItr = phase.psInst.begin(); instItr != phase.psInst.end(); instItr++)
{
Instruction *i = &*instItr;
for (std::vector<Instruction>::iterator instItr = phase.psInst.begin(); instItr != phase.psInst.end(); instItr++)
{
Instruction *i = &*instItr;
if (i->eOpcode == OPCODE_LOOP)
{
LoopInfo *currLoopInfo = &*res.insert(res.end(), LoopInfo());
currLoopInfo->m_StartLoop = i;
loopStack.push_front(currLoopInfo);
}
else if(i->eOpcode == OPCODE_ENDLOOP)
{
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
loopStack.pop_front();
li->m_EndLoop = i;
}
else if (i->eOpcode == OPCODE_SWITCH)
{
// Create a dummy entry into the stack
LoopInfo *li = &*dummyLIForSwitches.insert(dummyLIForSwitches.end(), LoopInfo());
li->m_IsSwitch = true;
loopStack.push_front(li);
}
else if (i->eOpcode == OPCODE_ENDSWITCH)
{
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
loopStack.pop_front();
ASSERT(li->m_IsSwitch);
}
else if (i->eOpcode == OPCODE_BREAK || i->eOpcode == OPCODE_BREAKC)
{
// Get the current loopstack head
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
// Ignore breaks from switch-cases
if(!li->m_IsSwitch)
{
li->m_ExitPoints.push_back(i);
}
}
}
if (i->eOpcode == OPCODE_LOOP)
{
LoopInfo *currLoopInfo = &*res.insert(res.end(), LoopInfo());
currLoopInfo->m_StartLoop = i;
loopStack.push_front(currLoopInfo);
}
else if (i->eOpcode == OPCODE_ENDLOOP)
{
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
loopStack.pop_front();
li->m_EndLoop = i;
}
else if (i->eOpcode == OPCODE_SWITCH)
{
// Create a dummy entry into the stack
LoopInfo *li = &*dummyLIForSwitches.insert(dummyLIForSwitches.end(), LoopInfo());
li->m_IsSwitch = true;
loopStack.push_front(li);
}
else if (i->eOpcode == OPCODE_ENDSWITCH)
{
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
loopStack.pop_front();
ASSERT(li->m_IsSwitch);
}
else if (i->eOpcode == OPCODE_BREAK || i->eOpcode == OPCODE_BREAKC)
{
// Get the current loopstack head
ASSERT(!loopStack.empty());
LoopInfo *li = *loopStack.begin();
// Ignore breaks from switch-cases
if (!li->m_IsSwitch)
{
li->m_ExitPoints.push_back(i);
}
}
}
}
}
// Returns true if the given instruction is a non-vectorized int or uint comparison instruction that reads from at least one temp and writes to a temp
static bool IsScalarTempComparisonInstruction(const Instruction *i)
{
switch (i->eOpcode)
{
default:
return false;
case OPCODE_IGE:
case OPCODE_ILT:
case OPCODE_IEQ:
case OPCODE_INE:
case OPCODE_UGE:
case OPCODE_ULT:
break;
}
// Returns true if the given instruction is a non-vectorized int or uint comparison instruction that reads from at least one temp and writes to a temp
static bool IsScalarTempComparisonInstruction(const Instruction *i)
{
switch (i->eOpcode)
{
default:
return false;
case OPCODE_IGE:
case OPCODE_ILT:
case OPCODE_IEQ:
case OPCODE_INE:
case OPCODE_UGE:
case OPCODE_ULT:
break;
}
if (i->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
if (i->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
int tempOp = -1;
if (i->asOperands[1].eType == OPERAND_TYPE_TEMP)
tempOp = 1;
else if (i->asOperands[2].eType == OPERAND_TYPE_TEMP)
tempOp = 2;
int tempOp = -1;
if (i->asOperands[1].eType == OPERAND_TYPE_TEMP)
tempOp = 1;
else if (i->asOperands[2].eType == OPERAND_TYPE_TEMP)
tempOp = 2;
// Also reject comparisons where we compare temp.x vs temp.y
if (i->asOperands[1].eType == OPERAND_TYPE_TEMP && i->asOperands[2].eType == OPERAND_TYPE_TEMP && i->asOperands[1].ui32RegisterNumber == i->asOperands[2].ui32RegisterNumber)
return false;
// Also reject comparisons where we compare temp.x vs temp.y
if (i->asOperands[1].eType == OPERAND_TYPE_TEMP && i->asOperands[2].eType == OPERAND_TYPE_TEMP && i->asOperands[1].ui32RegisterNumber == i->asOperands[2].ui32RegisterNumber)
return false;
if (tempOp == -1)
return false;
if (tempOp == -1)
return false;
if (i->asOperands[0].GetNumSwizzleElements() != 1)
return false;
if (i->asOperands[0].GetNumSwizzleElements() != 1)
return false;
return true;
}
return true;
}
// Returns true iff both instructions perform identical operation. For the purposes of Loop transformation, we only consider operations of type tX = tX <op> imm32
static bool AreInstructionsIdentical(const Instruction *a, const Instruction *b)
{
if (a->eOpcode != b->eOpcode)
return false;
ASSERT(a->ui32NumOperands == b->ui32NumOperands);
uint32_t dstReg = 0;
if (a->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
dstReg = a->asOperands[0].ui32RegisterNumber;
// Returns true iff both instructions perform identical operation. For the purposes of Loop transformation, we only consider operations of type tX = tX <op> imm32
static bool AreInstructionsIdentical(const Instruction *a, const Instruction *b)
{
if (a->eOpcode != b->eOpcode)
return false;
ASSERT(a->ui32NumOperands == b->ui32NumOperands);
uint32_t dstReg = 0;
if (a->asOperands[0].eType != OPERAND_TYPE_TEMP)
return false;
dstReg = a->asOperands[0].ui32RegisterNumber;
for (uint32_t i = 0; i < a->ui32NumOperands; i++)
{
const Operand &aop = a->asOperands[i];
const Operand &bop = b->asOperands[i];
if (aop.eType != bop.eType)
return false;
for (uint32_t i = 0; i < a->ui32NumOperands; i++)
{
const Operand &aop = a->asOperands[i];
const Operand &bop = b->asOperands[i];
if (aop.eType != bop.eType)
return false;
if (aop.GetAccessMask() != bop.GetAccessMask())
return false;
if (aop.GetAccessMask() != bop.GetAccessMask())
return false;
if (aop.GetNumSwizzleElements() != 1)
return false;
if (aop.GetNumSwizzleElements() != 1)
return false;
if (aop.eType == OPERAND_TYPE_TEMP)
{
if (aop.ui32RegisterNumber != bop.ui32RegisterNumber)
return false;
if (aop.ui32RegisterNumber != dstReg)
return false;
}
else if (aop.eType == OPERAND_TYPE_IMMEDIATE32)
{
if (memcmp(aop.afImmediates, bop.afImmediates, 4 * sizeof(float)) != 0)
return false;
}
}
return true;
}
if (aop.eType == OPERAND_TYPE_TEMP)
{
if (aop.ui32RegisterNumber != bop.ui32RegisterNumber)
return false;
if (aop.ui32RegisterNumber != dstReg)
return false;
}
else if (aop.eType == OPERAND_TYPE_IMMEDIATE32)
{
if (memcmp(aop.afImmediates, bop.afImmediates, 4 * sizeof(float)) != 0)
return false;
}
}
return true;
}
// Attempt to transform a single loop into a for-statement
static void AttemptLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase, LoopInfo &li)
{
// In order to transform a loop into a for, the following has to hold:
// - The loop must start with a comparison instruction where one of the src operands is a temp (induction variable), followed by OPCODE_BREAKC.
// - The loop must end with an arithmetic operation (SUB or ADD) where the dest operand is the same temp as one of the sources in the comparison instruction above
// Additionally, if the loop induction variable is initialized before the start of the loop and it has only uses inside the LOOP/ENDLOOP pair, we can declare that inside the for statement.
// Also, the loop induction variable must be standalone (as in, never used as part of a larger vector)
// Attempt to transform a single loop into a for-statement
static void AttemptLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase, LoopInfo &li)
{
// In order to transform a loop into a for, the following has to hold:
// - The loop must start with a comparison instruction where one of the src operands is a temp (induction variable), followed by OPCODE_BREAKC.
// - The loop must end with an arithmetic operation (SUB or ADD) where the dest operand is the same temp as one of the sources in the comparison instruction above
// Additionally, if the loop induction variable is initialized before the start of the loop and it has only uses inside the LOOP/ENDLOOP pair, we can declare that inside the for statement.
// Also, the loop induction variable must be standalone (as in, never used as part of a larger vector)
Instruction *cmpInst = li.m_StartLoop + 1;
Instruction *cmpInst = li.m_StartLoop + 1;
if (!IsScalarTempComparisonInstruction(cmpInst))
return;
if (!IsScalarTempComparisonInstruction(cmpInst))
return;
Instruction *breakInst = li.m_StartLoop + 2;
if (breakInst->eOpcode != OPCODE_BREAKC)
return;
if (breakInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return;
if (breakInst->asOperands[0].ui32RegisterNumber != cmpInst->asOperands[0].ui32RegisterNumber)
return;
Instruction *breakInst = li.m_StartLoop + 2;
if (breakInst->eOpcode != OPCODE_BREAKC)
return;
if (breakInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return;
if (breakInst->asOperands[0].ui32RegisterNumber != cmpInst->asOperands[0].ui32RegisterNumber)
return;
// Check that the comparison result isn't used anywhere else
if (cmpInst->m_Uses.size() != 1)
return;
// Check that the comparison result isn't used anywhere else
if (cmpInst->m_Uses.size() != 1)
return;
ASSERT(cmpInst->m_Uses[0].m_Inst == breakInst);
ASSERT(cmpInst->m_Uses[0].m_Inst == breakInst);
// Ok, at least we have the comparison + breakc combo at top. Try to find the induction variable
uint32_t inductionVarIdx = 0;
// Ok, at least we have the comparison + breakc combo at top. Try to find the induction variable
uint32_t inductionVarIdx = 0;
Instruction *lastInst = li.m_EndLoop - 1;
if (lastInst->eOpcode != OPCODE_IADD)
return;
if (lastInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return;
Instruction *lastInst = li.m_EndLoop - 1;
if (lastInst->eOpcode != OPCODE_IADD)
return;
if (lastInst->asOperands[0].eType != OPERAND_TYPE_TEMP)
return;
if (lastInst->asOperands[0].GetNumSwizzleElements() != 1)
return;
if (lastInst->asOperands[0].GetNumSwizzleElements() != 1)
return;
uint32_t indVar = lastInst->asOperands[0].ui32RegisterNumber;
// Verify that the induction variable actually matches.
if (cmpInst->asOperands[1].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[1].ui32RegisterNumber == indVar)
inductionVarIdx = 1;
else if (cmpInst->asOperands[2].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[2].ui32RegisterNumber == indVar)
inductionVarIdx = 2;
else
return;
uint32_t indVar = lastInst->asOperands[0].ui32RegisterNumber;
// Verify that the induction variable actually matches.
if (cmpInst->asOperands[1].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[1].ui32RegisterNumber == indVar)
inductionVarIdx = 1;
else if (cmpInst->asOperands[2].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[2].ui32RegisterNumber == indVar)
inductionVarIdx = 2;
else
return;
// Verify that we also read from the induction variable in the last instruction
if (!((lastInst->asOperands[1].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[1].ui32RegisterNumber == indVar) ||
(lastInst->asOperands[2].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[2].ui32RegisterNumber == indVar)))
return;
// Verify that we also read from the induction variable in the last instruction
if (!((lastInst->asOperands[1].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[1].ui32RegisterNumber == indVar) ||
(lastInst->asOperands[2].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[2].ui32RegisterNumber == indVar)))
return;
// Nvidia compiler bug workaround: The shader compiler tries to be smart and unrolls constant loops,
// but then fails miserably if the loop variable is used as an index to UAV loads/stores or some other cases ("array access too complex")
// This is also triggered when the driver optimizer sees "simple enough" arithmetics (whatever that is) done on the loop variable before indexing.
// So, disable for-loop transformation altogether whenever we see a UAV load or store inside a loop.
if (psContext->psShader->eTargetLanguage >= LANG_400 && psContext->psShader->eTargetLanguage < LANG_GL_LAST && !psContext->IsVulkan())
{
for (auto itr = li.m_StartLoop; itr != li.m_EndLoop; itr++)
{
switch (itr->eOpcode)
{
case OPCODE_LD_RAW:
case OPCODE_LD_STRUCTURED:
case OPCODE_LD_UAV_TYPED:
case OPCODE_STORE_RAW:
case OPCODE_STORE_STRUCTURED:
case OPCODE_STORE_UAV_TYPED:
return; // Nope, can't do a for, not even a partial one.
default:
break;
}
}
}
// Nvidia compiler bug workaround: The shader compiler tries to be smart and unrolls constant loops,
// but then fails miserably if the loop variable is used as an index to UAV loads/stores or some other cases ("array access too complex")
// This is also triggered when the driver optimizer sees "simple enough" arithmetics (whatever that is) done on the loop variable before indexing.
// So, disable for-loop transformation altogether whenever we see a UAV load or store inside a loop.
if(psContext->psShader->eTargetLanguage >= LANG_400 && psContext->psShader->eTargetLanguage < LANG_GL_LAST && !psContext->IsVulkan())
{
for (auto itr = li.m_StartLoop; itr != li.m_EndLoop; itr++)
{
switch (itr->eOpcode)
{
case OPCODE_LD_RAW:
case OPCODE_LD_STRUCTURED:
case OPCODE_LD_UAV_TYPED:
case OPCODE_STORE_RAW:
case OPCODE_STORE_STRUCTURED:
case OPCODE_STORE_UAV_TYPED:
return; // Nope, can't do a for, not even a partial one.
default:
break;
}
}
}
// One more thing to check: The comparison input may only see 1 definition that originates from inside the loop range: the one in lastInst.
// Anything else means that there's a continue statement, or another break/breakc and that means that lastInst wouldn't get called.
// Of course, if all those instructions are identical, then it's fine.
// Ideally, if there's only one definition that's from outside the loop range, then we can use that as the initializer, as well.
// One more thing to check: The comparison input may only see 1 definition that originates from inside the loop range: the one in lastInst.
// Anything else means that there's a continue statement, or another break/breakc and that means that lastInst wouldn't get called.
// Of course, if all those instructions are identical, then it's fine.
// Ideally, if there's only one definition that's from outside the loop range, then we can use that as the initializer, as well.
Instruction *initializer = NULL;
std::vector<const Operand::Define *> definitionsOutsideRange;
std::vector<const Operand::Define *> definitionsInsideRange;
std::for_each(cmpInst->asOperands[inductionVarIdx].m_Defines.begin(), cmpInst->asOperands[inductionVarIdx].m_Defines.end(), [&](const Operand::Define &def)
{
if (def.m_Inst < li.m_StartLoop || def.m_Inst > li.m_EndLoop)
definitionsOutsideRange.push_back(&def);
else
definitionsInsideRange.push_back(&def);
});
Instruction *initializer = NULL;
std::vector<const Operand::Define *> definitionsOutsideRange;
std::vector<const Operand::Define *> definitionsInsideRange;
std::for_each(cmpInst->asOperands[inductionVarIdx].m_Defines.begin(), cmpInst->asOperands[inductionVarIdx].m_Defines.end(), [&](const Operand::Define &def)
{
if (def.m_Inst < li.m_StartLoop || def.m_Inst > li.m_EndLoop)
definitionsOutsideRange.push_back(&def);
else
definitionsInsideRange.push_back(&def);
});
if (definitionsInsideRange.size() != 1)
{
// All definitions must be identical
for (std::vector<const Operand::Define*>::iterator itr = definitionsInsideRange.begin() + 1; itr != definitionsInsideRange.end(); itr++)
{
if (!AreInstructionsIdentical((*itr)->m_Inst, definitionsInsideRange[0]->m_Inst))
return;
}
}
if (definitionsInsideRange.size() != 1)
{
// All definitions must be identical
for (std::vector<const Operand::Define*>::iterator itr = definitionsInsideRange.begin()+1; itr != definitionsInsideRange.end(); itr++)
{
if (!AreInstructionsIdentical((*itr)->m_Inst, definitionsInsideRange[0]->m_Inst))
return;
}
}
ASSERT(definitionsOutsideRange.size() > 0);
if (definitionsOutsideRange.size() == 1)
initializer = definitionsOutsideRange[0]->m_Inst;
ASSERT(definitionsOutsideRange.size() > 0);
if (definitionsOutsideRange.size() == 1)
initializer = definitionsOutsideRange[0]->m_Inst;
// Initializer must only write to one component
if (initializer && initializer->asOperands[0].GetNumSwizzleElements() != 1)
initializer = 0;
// Initializer data type must be int or uint
if (initializer)
{
SHADER_VARIABLE_TYPE dataType = initializer->asOperands[0].GetDataType(psContext);
if (dataType != SVT_INT && dataType != SVT_UINT)
return;
}
// Initializer must only write to one component
if (initializer && initializer->asOperands[0].GetNumSwizzleElements() != 1)
initializer = 0;
// Initializer data type must be int or uint
if (initializer)
{
SHADER_VARIABLE_TYPE dataType = initializer->asOperands[0].GetDataType(psContext);
if (dataType != SVT_INT && dataType != SVT_UINT)
return;
}
// Check that the initializer is only used within the range so we can move it to for statement
if (initializer)
{
bool hasUsesOutsideRange = false;
std::for_each(initializer->m_Uses.begin(), initializer->m_Uses.end(), [&](const Instruction::Use &u)
{
if (u.m_Inst < li.m_StartLoop || u.m_Inst > li.m_EndLoop)
hasUsesOutsideRange = true;
});
// Has outside uses? we cannot pull that up to the for statement
if (hasUsesOutsideRange)
initializer = 0;
}
// Check that the initializer is only used within the range so we can move it to for statement
if (initializer)
{
bool hasUsesOutsideRange = false;
std::for_each(initializer->m_Uses.begin(), initializer->m_Uses.end(), [&](const Instruction::Use &u)
{
if (u.m_Inst < li.m_StartLoop || u.m_Inst > li.m_EndLoop)
hasUsesOutsideRange = true;
});
// Has outside uses? we cannot pull that up to the for statement
if (hasUsesOutsideRange)
initializer = 0;
}
// Check that the loop adder instruction only has uses inside the loop range, otherwise we cannot move the initializer either
if (initializer)
{
bool cannotDoInitializer = false;
for (auto itr = lastInst->m_Uses.begin(); itr != lastInst->m_Uses.end(); itr++)
{
const Instruction::Use &u = *itr;
if (u.m_Inst < li.m_StartLoop || u.m_Inst > li.m_EndLoop)
{
cannotDoInitializer = true;
break;
}
// Also check that the uses are not vector ops (temp splitting has already pulled everything to .x if this is a standalone var)
if (u.m_Op->GetAccessMask() != 1)
{
cannotDoInitializer = true;
break;
}
}
// Has outside uses? we cannot pull that up to the for statement
if (cannotDoInitializer)
initializer = 0;
}
// Check that the loop adder instruction only has uses inside the loop range, otherwise we cannot move the initializer either
if (initializer)
{
bool cannotDoInitializer = false;
for (auto itr = lastInst->m_Uses.begin(); itr != lastInst->m_Uses.end(); itr++)
{
const Instruction::Use &u = *itr;
if (u.m_Inst < li.m_StartLoop || u.m_Inst > li.m_EndLoop)
{
cannotDoInitializer = true;
break;
}
// Also check that the uses are not vector ops (temp splitting has already pulled everything to .x if this is a standalone var)
if (u.m_Op->GetAccessMask() != 1)
{
cannotDoInitializer = true;
break;
}
}
// Has outside uses? we cannot pull that up to the for statement
if (cannotDoInitializer)
initializer = 0;
}
if (initializer)
{
// We can declare the initializer in the for loop header, allocate a new number for it and change all uses into that.
uint32_t newRegister = phase.m_NextFreeTempRegister++;
li.m_StartLoop->m_InductorRegister = newRegister;
std::for_each(initializer->m_Uses.begin(), initializer->m_Uses.end(), [newRegister](const Instruction::Use &u)
{
u.m_Op->m_ForLoopInductorName = newRegister;
});
// Also tweak the destinations for cmpInst, and lastInst
if (cmpInst->asOperands[1].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[1].ui32RegisterNumber == initializer->asOperands[0].ui32RegisterNumber)
cmpInst->asOperands[1].m_ForLoopInductorName = newRegister;
else
cmpInst->asOperands[2].m_ForLoopInductorName = newRegister;
if (initializer)
{
// We can declare the initializer in the for loop header, allocate a new number for it and change all uses into that.
uint32_t newRegister = phase.m_NextFreeTempRegister++;
li.m_StartLoop->m_InductorRegister = newRegister;
std::for_each(initializer->m_Uses.begin(), initializer->m_Uses.end(), [newRegister](const Instruction::Use &u)
{
u.m_Op->m_ForLoopInductorName = newRegister;
});
// Also tweak the destinations for cmpInst, and lastInst
if (cmpInst->asOperands[1].eType == OPERAND_TYPE_TEMP && cmpInst->asOperands[1].ui32RegisterNumber == initializer->asOperands[0].ui32RegisterNumber)
cmpInst->asOperands[1].m_ForLoopInductorName = newRegister;
else
cmpInst->asOperands[2].m_ForLoopInductorName = newRegister;
if (lastInst->asOperands[1].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[1].ui32RegisterNumber == initializer->asOperands[0].ui32RegisterNumber)
lastInst->asOperands[1].m_ForLoopInductorName = newRegister;
else
lastInst->asOperands[2].m_ForLoopInductorName = newRegister;
if (lastInst->asOperands[1].eType == OPERAND_TYPE_TEMP && lastInst->asOperands[1].ui32RegisterNumber == initializer->asOperands[0].ui32RegisterNumber)
lastInst->asOperands[1].m_ForLoopInductorName = newRegister;
else
lastInst->asOperands[2].m_ForLoopInductorName = newRegister;
lastInst->asOperands[0].m_ForLoopInductorName = newRegister;
initializer->asOperands[0].m_ForLoopInductorName = newRegister;
}
lastInst->asOperands[0].m_ForLoopInductorName = newRegister;
initializer->asOperands[0].m_ForLoopInductorName = newRegister;
}
// This loop can be transformed to for-loop. Do the necessary magicks.
li.m_StartLoop->m_LoopInductors[0] = initializer;
li.m_StartLoop->m_LoopInductors[1] = cmpInst;
li.m_StartLoop->m_LoopInductors[2] = breakInst;
li.m_StartLoop->m_LoopInductors[3] = lastInst;
// This loop can be transformed to for-loop. Do the necessary magicks.
li.m_StartLoop->m_LoopInductors[0] = initializer;
li.m_StartLoop->m_LoopInductors[1] = cmpInst;
li.m_StartLoop->m_LoopInductors[2] = breakInst;
li.m_StartLoop->m_LoopInductors[3] = lastInst;
if (initializer)
initializer->m_SkipTranslation = true;
cmpInst->m_SkipTranslation = true;
breakInst->m_SkipTranslation = true;
lastInst->m_SkipTranslation = true;
if (initializer)
initializer->m_SkipTranslation = true;
cmpInst->m_SkipTranslation = true;
breakInst->m_SkipTranslation = true;
lastInst->m_SkipTranslation = true;
}
}
void DoLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase)
{
Loops loops;
BuildLoopInfo(phase, loops);
void DoLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase)
{
Loops loops;
BuildLoopInfo(phase, loops);
std::for_each(loops.begin(), loops.end(), [&phase, psContext](LoopInfo &li)
{
// Some sanity checks: start and end points must be initialized, we shouldn't have any switches here, and each loop must have at least one exit point
// Also that there's at least 2 instructions in loop body
ASSERT(li.m_StartLoop != 0);
ASSERT(li.m_EndLoop != 0);
ASSERT(li.m_EndLoop > li.m_StartLoop + 2);
ASSERT(!li.m_IsSwitch);
ASSERT(!li.m_ExitPoints.empty());
AttemptLoopTransform(psContext, phase, li);
});
}
};
std::for_each(loops.begin(), loops.end(), [&phase, psContext](LoopInfo &li)
{
// Some sanity checks: start and end points must be initialized, we shouldn't have any switches here, and each loop must have at least one exit point
// Also that there's at least 2 instructions in loop body
ASSERT(li.m_StartLoop != 0);
ASSERT(li.m_EndLoop != 0);
ASSERT(li.m_EndLoop > li.m_StartLoop + 2);
ASSERT(!li.m_IsSwitch);
ASSERT(!li.m_ExitPoints.empty());
AttemptLoopTransform(psContext, phase, li);
});
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,3 @@
#include "ShaderInfo.h"
#include "internal_includes/debug.h"
#include "internal_includes/tokens.h"
@ -8,170 +7,170 @@
SHADER_VARIABLE_TYPE ShaderInfo::GetTextureDataType(uint32_t regNo)
{
const ResourceBinding* psBinding = 0;
int found;
found = GetResourceFromBindingPoint(RGROUP_TEXTURE, regNo, &psBinding);
ASSERT(found != 0);
return psBinding->GetDataType();
const ResourceBinding* psBinding = 0;
int found;
found = GetResourceFromBindingPoint(RGROUP_TEXTURE, regNo, &psBinding);
ASSERT(found != 0);
return psBinding->GetDataType();
}
void ShaderInfo::GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ConstantBuffer** ppsConstBuf) const
{
ASSERT(ui32MajorVersion > 3);
*ppsConstBuf = &psConstantBuffers[aui32ResourceMap[eGroup][ui32BindPoint]];
ASSERT(ui32MajorVersion > 3);
*ppsConstBuf = &psConstantBuffers[aui32ResourceMap[eGroup][ui32BindPoint]];
}
int ShaderInfo::GetResourceFromBindingPoint(const ResourceGroup eGroup, uint32_t const ui32BindPoint, const ResourceBinding** ppsOutBinding) const
{
size_t i;
const size_t ui32NumBindings = psResourceBindings.size();
const ResourceBinding* psBindings = &psResourceBindings[0];
size_t i;
const size_t ui32NumBindings = psResourceBindings.size();
const ResourceBinding* psBindings = &psResourceBindings[0];
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;
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 ShaderInfo::GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderVar** ppsShaderVar) const
{
size_t i;
const size_t ui32NumVars = psThisPointerConstBuffer->asVars.size();
size_t i;
const size_t ui32NumVars = psThisPointerConstBuffer->asVars.size();
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;
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 ShaderInfo::GetInputSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32Mask, const InOutSignature** ppsOut, bool allowNull /* == false */) const
{
size_t i;
const size_t ui32NumVars = psInputSignatures.size();
size_t i;
const size_t ui32NumVars = psInputSignatures.size();
for (i = 0; i < ui32NumVars; ++i)
{
if ((ui32Register == psInputSignatures[i].ui32Register) && (((~psInputSignatures[i].ui32Mask) & ui32Mask) == 0))
{
*ppsOut = &psInputSignatures[i];
return 1;
}
}
ASSERT(allowNull);
return 0;
for (i = 0; i < ui32NumVars; ++i)
{
if ((ui32Register == psInputSignatures[i].ui32Register) && (((~psInputSignatures[i].ui32Mask) & ui32Mask) == 0))
{
*ppsOut = &psInputSignatures[i];
return 1;
}
}
ASSERT(allowNull);
return 0;
}
int ShaderInfo::GetPatchConstantSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32Mask, const InOutSignature** ppsOut, bool allowNull /* == false */) const
{
size_t i;
const size_t ui32NumVars = psPatchConstantSignatures.size();
size_t i;
const size_t ui32NumVars = psPatchConstantSignatures.size();
for (i = 0; i < ui32NumVars; ++i)
{
if ((ui32Register == psPatchConstantSignatures[i].ui32Register) && (((~psPatchConstantSignatures[i].ui32Mask) & ui32Mask) == 0))
{
*ppsOut = &psPatchConstantSignatures[i];
return 1;
}
}
for (i = 0; i < ui32NumVars; ++i)
{
if ((ui32Register == psPatchConstantSignatures[i].ui32Register) && (((~psPatchConstantSignatures[i].ui32Mask) & ui32Mask) == 0))
{
*ppsOut = &psPatchConstantSignatures[i];
return 1;
}
}
// There are situations (especially when using dcl_indexrange) where the compiler happily writes outside the actual masks.
// In those situations just take the last signature that uses that register (it's typically the "highest" one)
for( i = ui32NumVars - 1; i-- > 0; )
{
if (ui32Register == psPatchConstantSignatures[i].ui32Register)
{
*ppsOut = &psPatchConstantSignatures[i];
return 1;
}
}
// There are situations (especially when using dcl_indexrange) where the compiler happily writes outside the actual masks.
// In those situations just take the last signature that uses that register (it's typically the "highest" one)
for (i = ui32NumVars - 1; i-- > 0;)
{
if (ui32Register == psPatchConstantSignatures[i].ui32Register)
{
*ppsOut = &psPatchConstantSignatures[i];
return 1;
}
}
ASSERT(allowNull);
return 0;
ASSERT(allowNull);
return 0;
}
int ShaderInfo::GetOutputSignatureFromRegister(const uint32_t ui32Register,
const uint32_t ui32CompMask,
const uint32_t ui32Stream,
const InOutSignature** ppsOut,
bool allowNull /* = false */) const
const uint32_t ui32CompMask,
const uint32_t ui32Stream,
const InOutSignature** ppsOut,
bool allowNull /* = false */) const
{
size_t i;
const size_t ui32NumVars = psOutputSignatures.size();
ASSERT(ui32CompMask != 0);
size_t i;
const size_t ui32NumVars = psOutputSignatures.size();
ASSERT(ui32CompMask != 0);
for (i = 0; i < ui32NumVars; ++i)
{
if (ui32Register == psOutputSignatures[i].ui32Register &&
(ui32CompMask & psOutputSignatures[i].ui32Mask) &&
ui32Stream == psOutputSignatures[i].ui32Stream)
{
*ppsOut = &psOutputSignatures[i];
return 1;
}
}
ASSERT(allowNull);
return 0;
for (i = 0; i < ui32NumVars; ++i)
{
if (ui32Register == psOutputSignatures[i].ui32Register &&
(ui32CompMask & psOutputSignatures[i].ui32Mask) &&
ui32Stream == psOutputSignatures[i].ui32Stream)
{
*ppsOut = &psOutputSignatures[i];
return 1;
}
}
ASSERT(allowNull);
return 0;
}
int ShaderInfo::GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, const InOutSignature** ppsOut) const
{
size_t i;
const size_t ui32NumVars = psOutputSignatures.size();
size_t i;
const size_t ui32NumVars = psOutputSignatures.size();
for (i = 0; i < ui32NumVars; ++i)
{
if (eSystemValueType == psOutputSignatures[i].eSystemValueType &&
ui32SemanticIndex == psOutputSignatures[i].ui32SemanticIndex)
{
*ppsOut = &psOutputSignatures[i];
return 1;
}
}
ASSERT(0);
return 0;
for (i = 0; i < ui32NumVars; ++i)
{
if (eSystemValueType == psOutputSignatures[i].eSystemValueType &&
ui32SemanticIndex == psOutputSignatures[i].ui32SemanticIndex)
{
*ppsOut = &psOutputSignatures[i];
return 1;
}
}
ASSERT(0);
return 0;
}
uint32_t ShaderInfo::GetCBVarSize(const ShaderVarType* psType, bool matrixAsVectors, bool wholeArraySize)
{
// Default is regular matrices, vectors and scalars
// Default is regular matrices, vectors and scalars
uint32_t size = psType->Columns * psType->Rows * 4;
// Struct size is calculated from the offset and size of its last member.
// Struct size is calculated from the offset and size of its last member.
// Need to take into account that members could be arrays.
if (psType->Class == SVC_STRUCT)
{
if (psType->Class == SVC_STRUCT)
{
size = psType->Members.back().Offset + GetCBVarSize(&psType->Members.back(), matrixAsVectors, true);
}
// Matrices represented as vec4 arrays have special size calculation
else if (matrixAsVectors)
{
if (psType->Class == SVC_MATRIX_ROWS)
{
}
// Matrices represented as vec4 arrays have special size calculation
else if (matrixAsVectors)
{
if (psType->Class == SVC_MATRIX_ROWS)
{
size = psType->Rows * 16;
}
else if (psType->Class == SVC_MATRIX_COLUMNS)
{
size = psType->Columns * 16;
}
}
}
else if (psType->Class == SVC_MATRIX_COLUMNS)
{
size = psType->Columns * 16;
}
}
if (wholeArraySize && psType->Elements > 1)
{
{
uint32_t paddedSize = ((size + 15) / 16) * 16; // Arrays are padded to float4 size
size = (psType->Elements - 1) * paddedSize + size; // Except the last element
}
@ -180,146 +179,146 @@ uint32_t ShaderInfo::GetCBVarSize(const ShaderVarType* psType, bool matrixAsVect
}
static const ShaderVarType* IsOffsetInType(const ShaderVarType* psType,
uint32_t parentOffset,
uint32_t offsetToFind,
bool* isArray,
std::vector<uint32_t>* arrayIndices,
int32_t* pi32Rebase,
uint32_t flags)
uint32_t parentOffset,
uint32_t offsetToFind,
bool* isArray,
std::vector<uint32_t>* arrayIndices,
int32_t* pi32Rebase,
uint32_t flags)
{
uint32_t thisOffset = parentOffset + psType->Offset;
uint32_t thisSize = ShaderInfo::GetCBVarSize(psType, (flags & HLSLCC_FLAG_TRANSLATE_MATRICES) != 0);
uint32_t paddedSize = ((thisSize + 15) / 16) * 16;
uint32_t arraySize = thisSize;
uint32_t thisOffset = parentOffset + psType->Offset;
uint32_t thisSize = ShaderInfo::GetCBVarSize(psType, (flags & HLSLCC_FLAG_TRANSLATE_MATRICES) != 0);
uint32_t paddedSize = ((thisSize + 15) / 16) * 16;
uint32_t arraySize = thisSize;
// Array elements are padded to align on vec4 size, except for the last one
if (psType->Elements)
arraySize = (paddedSize * (psType->Elements - 1)) + thisSize;
// Array elements are padded to align on vec4 size, except for the last one
if (psType->Elements)
arraySize = (paddedSize * (psType->Elements - 1)) + thisSize;
if ((offsetToFind >= thisOffset) &&
offsetToFind < (thisOffset + arraySize))
{
*isArray = false;
if (psType->Class == SVC_STRUCT)
{
if (psType->Elements > 1 && arrayIndices != NULL)
arrayIndices->push_back((offsetToFind - thisOffset) / thisSize);
if ((offsetToFind >= thisOffset) &&
offsetToFind < (thisOffset + arraySize))
{
*isArray = false;
if (psType->Class == SVC_STRUCT)
{
if (psType->Elements > 1 && arrayIndices != NULL)
arrayIndices->push_back((offsetToFind - thisOffset) / thisSize);
// Need to bring offset back to element zero in case of array of structs
uint32_t offsetInStruct = (offsetToFind - thisOffset) % paddedSize;
uint32_t m = 0;
// Need to bring offset back to element zero in case of array of structs
uint32_t offsetInStruct = (offsetToFind - thisOffset) % paddedSize;
uint32_t m = 0;
for (m = 0; m < psType->MemberCount; ++m)
{
const ShaderVarType* psMember = &psType->Members[m];
for (m = 0; m < psType->MemberCount; ++m)
{
const ShaderVarType* psMember = &psType->Members[m];
const ShaderVarType* foundType = IsOffsetInType(psMember, thisOffset, thisOffset + offsetInStruct, isArray, arrayIndices, pi32Rebase, flags);
if (foundType != NULL)
return foundType;
}
}
// Check for array of scalars or vectors (both take up 16 bytes per element).
// Matrices are also treated as arrays of vectors.
else if ((psType->Class == SVC_MATRIX_ROWS || psType->Class == SVC_MATRIX_COLUMNS) ||
((psType->Class == SVC_SCALAR || psType->Class == SVC_VECTOR) && psType->Elements > 1))
{
*isArray = true;
if (arrayIndices != NULL)
arrayIndices->push_back((offsetToFind - thisOffset) / 16);
}
else if (psType->Class == SVC_VECTOR)
{
//Check for vector starting at a non-vec4 offset.
const ShaderVarType* foundType = IsOffsetInType(psMember, thisOffset, thisOffset + offsetInStruct, isArray, arrayIndices, pi32Rebase, flags);
if (foundType != NULL)
return foundType;
}
}
// Check for array of scalars or vectors (both take up 16 bytes per element).
// Matrices are also treated as arrays of vectors.
else if ((psType->Class == SVC_MATRIX_ROWS || psType->Class == SVC_MATRIX_COLUMNS) ||
((psType->Class == SVC_SCALAR || psType->Class == SVC_VECTOR) && psType->Elements > 1))
{
*isArray = true;
if (arrayIndices != NULL)
arrayIndices->push_back((offsetToFind - thisOffset) / 16);
}
else if (psType->Class == SVC_VECTOR)
{
//Check for vector starting at a non-vec4 offset.
// cbuffer $Globals
// {
//
// float angle; // Offset: 0 Size: 4
// float2 angle2; // Offset: 4 Size: 8
//
// }
// cbuffer $Globals
// {
//
// float angle; // Offset: 0 Size: 4
// float2 angle2; // Offset: 4 Size: 8
//
// }
//cb0[0].x = angle
//cb0[0].yzyy = angle2.xyxx
//cb0[0].x = angle
//cb0[0].yzyy = angle2.xyxx
//Rebase angle2 so that .y maps to .x, .z maps to .y
//Rebase angle2 so that .y maps to .x, .z maps to .y
pi32Rebase[0] = thisOffset % 16;
}
pi32Rebase[0] = thisOffset % 16;
}
return psType;
}
return NULL;
return psType;
}
return NULL;
}
int ShaderInfo::GetShaderVarFromOffset(const uint32_t ui32Vec4Offset,
const uint32_t(&pui32Swizzle)[4],
const ConstantBuffer* psCBuf,
const ShaderVarType** ppsShaderVar, // Output the found var
bool* isArray, // Output bool that tells if the found var is an array
std::vector<uint32_t>* arrayIndices, // Output vector of array indices in order from root parent to the found var
int32_t* pi32Rebase, // Output swizzle rebase
uint32_t flags)
const uint32_t(&pui32Swizzle)[4],
const ConstantBuffer* psCBuf,
const ShaderVarType** ppsShaderVar, // Output the found var
bool* isArray, // Output bool that tells if the found var is an array
std::vector<uint32_t>* arrayIndices, // Output vector of array indices in order from root parent to the found var
int32_t* pi32Rebase, // Output swizzle rebase
uint32_t flags)
{
size_t i;
size_t i;
uint32_t ui32ByteOffset = ui32Vec4Offset * 16;
uint32_t ui32ByteOffset = ui32Vec4Offset * 16;
//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.
//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
// }
if (pui32Swizzle[0] == OPERAND_4_COMPONENT_Y)
{
ui32ByteOffset += 4;
}
else if (pui32Swizzle[0] == OPERAND_4_COMPONENT_Z)
{
ui32ByteOffset += 8;
}
else if (pui32Swizzle[0] == OPERAND_4_COMPONENT_W)
{
ui32ByteOffset += 12;
}
// 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
// }
if (pui32Swizzle[0] == OPERAND_4_COMPONENT_Y)
{
ui32ByteOffset += 4;
}
else if (pui32Swizzle[0] == OPERAND_4_COMPONENT_Z)
{
ui32ByteOffset += 8;
}
else if (pui32Swizzle[0] == OPERAND_4_COMPONENT_W)
{
ui32ByteOffset += 12;
}
const size_t ui32NumVars = psCBuf->asVars.size();
const size_t ui32NumVars = psCBuf->asVars.size();
for (i = 0; i < ui32NumVars; ++i)
{
ppsShaderVar[0] = IsOffsetInType(&psCBuf->asVars[i].sType, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, isArray, arrayIndices, pi32Rebase, flags);
if (ppsShaderVar[0] != NULL)
return 1;
}
return 0;
for (i = 0; i < ui32NumVars; ++i)
{
ppsShaderVar[0] = IsOffsetInType(&psCBuf->asVars[i].sType, psCBuf->asVars[i].ui32StartOffset, ui32ByteOffset, isArray, arrayIndices, pi32Rebase, flags);
if (ppsShaderVar[0] != NULL)
return 1;
}
return 0;
}
// Patches the fullName of the var with given array indices. Does not insert the indexing for the var itself if it is an array.
// Searches for brackets and inserts indices one by one.
std::string ShaderInfo::GetShaderVarIndexedFullName(const ShaderVarType* psShaderVar, const std::vector<uint32_t>& indices, const std::string& dynamicIndex, bool revertDynamicIndexCalc, bool matrixAsVectors)
{
std::ostringstream oss;
size_t prevpos = 0;
size_t pos = psShaderVar->fullName.find('[', 0);
uint32_t i = 0;
while (pos != std::string::npos)
{
pos++;
oss << psShaderVar->fullName.substr(prevpos, pos - prevpos);
std::ostringstream oss;
size_t prevpos = 0;
size_t pos = psShaderVar->fullName.find('[', 0);
uint32_t i = 0;
while (pos != std::string::npos)
{
pos++;
oss << psShaderVar->fullName.substr(prevpos, pos - prevpos);
// Add possibly given dynamic index for the root array.
if (i == 0 && !dynamicIndex.empty())
@ -340,71 +339,71 @@ std::string ShaderInfo::GetShaderVarIndexedFullName(const ShaderVarType* psShade
if (!indices.empty() && indices[i] != 0)
oss << " + " << indices[i];
}
else if (i < indices.size())
oss << indices[i];
else if (i < indices.size())
oss << indices[i];
prevpos = pos;
i++;
pos = psShaderVar->fullName.find('[', prevpos);
}
oss << psShaderVar->fullName.substr(prevpos);
prevpos = pos;
i++;
pos = psShaderVar->fullName.find('[', prevpos);
}
oss << psShaderVar->fullName.substr(prevpos);
return oss.str();
return oss.str();
}
ResourceGroup ShaderInfo::ResourceTypeToResourceGroup(ResourceType eType)
{
switch (eType)
{
case RTYPE_CBUFFER:
return RGROUP_CBUFFER;
switch (eType)
{
case RTYPE_CBUFFER:
return RGROUP_CBUFFER;
case RTYPE_SAMPLER:
return RGROUP_SAMPLER;
case RTYPE_SAMPLER:
return RGROUP_SAMPLER;
case RTYPE_TEXTURE:
case RTYPE_BYTEADDRESS:
case RTYPE_STRUCTURED:
return RGROUP_TEXTURE;
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_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;
default:
case RTYPE_TBUFFER:
ASSERT(0); // Need to find out which group this belongs to
return RGROUP_TEXTURE;
default:
break;
}
}
ASSERT(0);
return RGROUP_CBUFFER;
ASSERT(0);
return RGROUP_CBUFFER;
}
void ShaderInfo::AddSamplerPrecisions(HLSLccSamplerPrecisionInfo &info)
{
if (info.empty())
return;
if (info.empty())
return;
for (size_t i = 0; i < psResourceBindings.size(); i++)
{
ResourceBinding *rb = &psResourceBindings[i];
if (rb->eType != RTYPE_SAMPLER && rb->eType != RTYPE_TEXTURE)
continue;
for (size_t i = 0; i < psResourceBindings.size(); i++)
{
ResourceBinding *rb = &psResourceBindings[i];
if (rb->eType != RTYPE_SAMPLER && rb->eType != RTYPE_TEXTURE)
continue;
HLSLccSamplerPrecisionInfo::iterator j = info.find(rb->name); // Try finding exact match
HLSLccSamplerPrecisionInfo::iterator j = info.find(rb->name); // Try finding exact match
// If match not found, check if name has "sampler" prefix
// -> try finding a match without the prefix (DX11 style sampler case)
if (j == info.end() && rb->name.compare(0, 7, "sampler") == 0)
j = info.find(rb->name.substr(7, rb->name.size() - 7));
// If match not found, check if name has "sampler" prefix
// -> try finding a match without the prefix (DX11 style sampler case)
if (j == info.end() && rb->name.compare(0, 7, "sampler") == 0)
j = info.find(rb->name.substr(7, rb->name.size() - 7));
if (j != info.end())
rb->ePrecision = j->second;
}
if (j != info.end())
rb->ePrecision = j->second;
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
@ -21,65 +21,67 @@
static int bsafeShouldExit = 1;
#if 0
char * strcpy (char *dst, const char *src);
char * strcat (char *dst, const char *src);
char * strcpy(char *dst, const char *src);
char * strcat(char *dst, const char *src);
char * strcpy (char *dst, const char *src) {
dst = dst;
src = src;
fprintf (stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * strcpy(char *dst, const char *src)
{
dst = dst;
src = src;
fprintf(stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char * strcat (char *dst, const char *src) {
dst = dst;
src = src;
fprintf (stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * strcat(char *dst, const char *src)
{
dst = dst;
src = src;
fprintf(stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
char * (gets) (char * buf) {
buf = buf;
fprintf (stderr, "bsafe error: gets() is not safe, use bgets.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
#if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
char * (gets)(char * buf) {
buf = buf;
fprintf(stderr, "bsafe error: gets() is not safe, use bgets.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
#endif
char * (strncpy) (char *dst, const char *src, size_t n) {
dst = dst;
src = src;
n = n;
fprintf (stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * (strncpy)(char *dst, const char *src, size_t n) {
dst = dst;
src = src;
n = n;
fprintf(stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char * (strncat) (char *dst, const char *src, size_t n) {
dst = dst;
src = src;
n = n;
fprintf (stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * (strncat)(char *dst, const char *src, size_t n) {
dst = dst;
src = src;
n = n;
fprintf(stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char * (strtok) (char *s1, const char *s2) {
s1 = s1;
s2 = s2;
fprintf (stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * (strtok)(char *s1, const char *s2) {
s1 = s1;
s2 = s2;
fprintf(stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
char * (strdup) (const char *s) {
s = s;
fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n");
if (bsafeShouldExit) exit (-1);
return NULL;
char * (strdup)(const char *s) {
s = s;
fprintf(stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
}
#endif

Просмотреть файл

@ -1,7 +1,7 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
@ -21,20 +21,20 @@
extern "C" {
#endif
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
#if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
/* This is caught in the linker, so its not necessary for gcc. */
extern char * (gets) (char * buf);
extern char * (gets)(char * buf);
#endif
extern char * (strncpy) (char *dst, const char *src, size_t n);
extern char * (strncat) (char *dst, const char *src, size_t n);
extern char * (strtok) (char *s1, const char *s2);
extern char * (strdup) (const char *s);
extern char * (strncpy)(char *dst, const char *src, size_t n);
extern char * (strncat)(char *dst, const char *src, size_t n);
extern char * (strtok)(char *s1, const char *s2);
extern char * (strdup)(const char *s);
#undef strcpy
#undef strcat
#define strcpy(a,b) bsafe_strcpy(a,b)
#define strcat(a,b) bsafe_strcat(a,b)
#define strcpy(a, b) bsafe_strcpy(a,b)
#define strcat(a, b) bsafe_strcat(a,b)
#ifdef __cplusplus
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
@ -9,7 +9,7 @@
* bstraux.h
*
* This file is not a necessary part of the core bstring library itself, but
* is just an auxilliary module which includes miscellaneous or trivial
* is just an auxilliary module which includes miscellaneous or trivial
* functions.
*/
@ -24,86 +24,86 @@ extern "C" {
#endif
/* Safety mechanisms */
#define bstrDeclare(b) bstring (b) = NULL;
#define bstrDeclare(b) bstring (b) = NULL;
#define bstrFree(b) {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }}
/* Backward compatibilty with previous versions of Bstrlib */
#define bAssign(a,b) ((bassign)((a), (b)))
#define bSubs(b,pos,len,a,c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
#define bStrchr(b,c) ((bstrchr)((b), (c)))
#define bStrchrFast(b,c) ((bstrchr)((b), (c)))
#define bCatCstr(b,s) ((bcatcstr)((b), (s)))
#define bCatBlk(b,s,len) ((bcatblk)((b),(s),(len)))
#define bCatStatic(b,s) bCatBlk ((b), ("" s ""), sizeof (s) - 1)
#define bTrunc(b,n) ((btrunc)((b), (n)))
#define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos)))
#define bAssign(a, b) ((bassign)((a), (b)))
#define bSubs(b, pos, len, a, c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
#define bStrchr(b, c) ((bstrchr)((b), (c)))
#define bStrchrFast(b, c) ((bstrchr)((b), (c)))
#define bCatCstr(b, s) ((bcatcstr)((b), (s)))
#define bCatBlk(b, s, len) ((bcatblk)((b),(s),(len)))
#define bCatStatic(b, s) bCatBlk ((b), ("" s ""), sizeof (s) - 1)
#define bTrunc(b, n) ((btrunc)((b), (n)))
#define bReplaceAll(b, find, repl, pos) ((bfindreplace)((b),(find),(repl),(pos)))
#define bUppercase(b) ((btoupper)(b))
#define bLowercase(b) ((btolower)(b))
#define bCaselessCmp(a,b) ((bstricmp)((a), (b)))
#define bCaselessNCmp(a,b,n) ((bstrnicmp)((a), (b), (n)))
#define bCaselessCmp(a, b) ((bstricmp)((a), (b)))
#define bCaselessNCmp(a, b, n) ((bstrnicmp)((a), (b), (n)))
#define bBase64Decode(b) (bBase64DecodeEx ((b), NULL))
#define bUuDecode(b) (bUuDecodeEx ((b), NULL))
/* Unusual functions */
extern struct bStream * bsFromBstr (const_bstring b);
extern bstring bTail (bstring b, int n);
extern bstring bHead (bstring b, int n);
extern int bSetCstrChar (bstring a, int pos, char c);
extern int bSetChar (bstring b, int pos, char c);
extern int bFill (bstring a, char c, int len);
extern int bReplicate (bstring b, int n);
extern int bReverse (bstring b);
extern int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill);
extern bstring bStrfTime (const char * fmt, const struct tm * timeptr);
extern struct bStream * bsFromBstr(const_bstring b);
extern bstring bTail(bstring b, int n);
extern bstring bHead(bstring b, int n);
extern int bSetCstrChar(bstring a, int pos, char c);
extern int bSetChar(bstring b, int pos, char c);
extern int bFill(bstring a, char c, int len);
extern int bReplicate(bstring b, int n);
extern int bReverse(bstring b);
extern int bInsertChrs(bstring b, int pos, int len, unsigned char c, unsigned char fill);
extern bstring bStrfTime(const char * fmt, const struct tm * timeptr);
#define bAscTime(t) (bStrfTime ("%c\n", (t)))
#define bCTime(t) ((t) ? bAscTime (localtime (t)) : NULL)
/* Spacing formatting */
extern int bJustifyLeft (bstring b, int space);
extern int bJustifyRight (bstring b, int width, int space);
extern int bJustifyMargin (bstring b, int width, int space);
extern int bJustifyCenter (bstring b, int width, int space);
extern int bJustifyLeft(bstring b, int space);
extern int bJustifyRight(bstring b, int width, int space);
extern int bJustifyMargin(bstring b, int width, int space);
extern int bJustifyCenter(bstring b, int width, int space);
/* Esoteric standards specific functions */
extern char * bStr2NetStr (const_bstring b);
extern bstring bNetStr2Bstr (const char * buf);
extern bstring bBase64Encode (const_bstring b);
extern bstring bBase64DecodeEx (const_bstring b, int * boolTruncError);
extern struct bStream * bsUuDecode (struct bStream * sInp, int * badlines);
extern bstring bUuDecodeEx (const_bstring src, int * badlines);
extern bstring bUuEncode (const_bstring src);
extern bstring bYEncode (const_bstring src);
extern bstring bYDecode (const_bstring src);
extern char * bStr2NetStr(const_bstring b);
extern bstring bNetStr2Bstr(const char * buf);
extern bstring bBase64Encode(const_bstring b);
extern bstring bBase64DecodeEx(const_bstring b, int * boolTruncError);
extern struct bStream * bsUuDecode(struct bStream * sInp, int * badlines);
extern bstring bUuDecodeEx(const_bstring src, int * badlines);
extern bstring bUuEncode(const_bstring src);
extern bstring bYEncode(const_bstring src);
extern bstring bYDecode(const_bstring src);
/* Writable stream */
typedef int (* bNwrite) (const void * buf, size_t elsize, size_t nelem, void * parm);
struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm);
int bwsWriteBstr (struct bwriteStream * stream, const_bstring b);
int bwsWriteBlk (struct bwriteStream * stream, void * blk, int len);
int bwsWriteFlush (struct bwriteStream * stream);
int bwsIsEOF (const struct bwriteStream * stream);
int bwsBuffLength (struct bwriteStream * stream, int sz);
void * bwsClose (struct bwriteStream * stream);
struct bwriteStream * bwsOpen(bNwrite writeFn, void * parm);
int bwsWriteBstr(struct bwriteStream * stream, const_bstring b);
int bwsWriteBlk(struct bwriteStream * stream, void * blk, int len);
int bwsWriteFlush(struct bwriteStream * stream);
int bwsIsEOF(const struct bwriteStream * stream);
int bwsBuffLength(struct bwriteStream * stream, int sz);
void * bwsClose(struct bwriteStream * stream);
/* Security functions */
#define bSecureDestroy(b) { \
bstring bstr__tmp = (b); \
if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \
(void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \
bdestroy (bstr__tmp); \
} \
#define bSecureDestroy(b) { \
bstring bstr__tmp = (b); \
if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \
(void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \
bdestroy (bstr__tmp); \
} \
}
#define bSecureWriteProtect(t) { \
if ((t).mlen >= 0) { \
if ((t).mlen > (t).slen)) { \
(void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \
} \
(t).mlen = -1; \
} \
#define bSecureWriteProtect(t) { \
if ((t).mlen >= 0) { \
if ((t).mlen > (t).slen)) { \
(void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \
} \
(t).mlen = -1; \
} \
}
extern bstring bSecureInput (int maxlen, int termchar,
bNgetc vgetchar, void * vgcCtx);
extern bstring bSecureInput(int maxlen, int termchar,
bNgetc vgetchar, void * vgcCtx);
#ifdef __cplusplus
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,14 +1,14 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
/*
* bstrlib.h
*
* This file is the header file for the core module for implementing the
* This file is the header file for the core module for implementing the
* bstring functions.
*/
@ -24,8 +24,8 @@ extern "C" {
#include <limits.h>
#include <ctype.h>
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) && !defined (__BORLANDC__)
#if !defined(BSTRLIB_VSNP_OK) && !defined(BSTRLIB_NOVSNP)
# if defined(__TURBOC__) && !defined(__BORLANDC__)
# define BSTRLIB_NOVSNP
# endif
#endif
@ -39,121 +39,122 @@ typedef const struct tagbstring * const_bstring;
/* Copy functions */
#define cstr2bstr bfromcstr
extern bstring bfromcstr (const char * str);
extern bstring bfromcstralloc (int mlen, const char * str);
extern bstring blk2bstr (const void * blk, int len);
extern char * bstr2cstr (const_bstring s, char z);
extern int bcstrfree (char * s);
extern bstring bstrcpy (const_bstring b1);
extern int bassign (bstring a, const_bstring b);
extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
extern int bassigncstr (bstring a, const char * str);
extern int bassignblk (bstring a, const void * s, int len);
extern bstring bfromcstr(const char * str);
extern bstring bfromcstralloc(int mlen, const char * str);
extern bstring blk2bstr(const void * blk, int len);
extern char * bstr2cstr(const_bstring s, char z);
extern int bcstrfree(char * s);
extern bstring bstrcpy(const_bstring b1);
extern int bassign(bstring a, const_bstring b);
extern int bassignmidstr(bstring a, const_bstring b, int left, int len);
extern int bassigncstr(bstring a, const char * str);
extern int bassignblk(bstring a, const void * s, int len);
/* Destroy function */
extern int bdestroy (bstring b);
extern int bdestroy(bstring b);
/* Space allocation hinting functions */
extern int balloc (bstring s, int len);
extern int ballocmin (bstring b, int len);
extern int balloc(bstring s, int len);
extern int ballocmin(bstring b, int len);
/* Substring extraction */
extern bstring bmidstr (const_bstring b, int left, int len);
extern bstring bmidstr(const_bstring b, int left, int len);
/* Various standard manipulations */
extern int bconcat (bstring b0, const_bstring b1);
extern int bconchar (bstring b0, char c);
extern int bcatcstr (bstring b, const char * s);
extern int bcatblk (bstring b, const void * s, int len);
extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
extern int bdelete (bstring s1, int pos, int len);
extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
extern int btrunc (bstring b, int n);
extern int bconcat(bstring b0, const_bstring b1);
extern int bconchar(bstring b0, char c);
extern int bcatcstr(bstring b, const char * s);
extern int bcatblk(bstring b, const void * s, int len);
extern int binsert(bstring s1, int pos, const_bstring s2, unsigned char fill);
extern int binsertch(bstring s1, int pos, int len, unsigned char fill);
extern int breplace(bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
extern int bdelete(bstring s1, int pos, int len);
extern int bsetstr(bstring b0, int pos, const_bstring b1, unsigned char fill);
extern int btrunc(bstring b, int n);
/* Scan/search functions */
extern int bstricmp (const_bstring b0, const_bstring b1);
extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
extern int biseqcaseless (const_bstring b0, const_bstring b1);
extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
extern int biseq (const_bstring b0, const_bstring b1);
extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
extern int biseqcstr (const_bstring b, const char * s);
extern int biseqcstrcaseless (const_bstring b, const char * s);
extern int bstrcmp (const_bstring b0, const_bstring b1);
extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
extern int binstr (const_bstring s1, int pos, const_bstring s2);
extern int binstrr (const_bstring s1, int pos, const_bstring s2);
extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int bstrchrp (const_bstring b, int c, int pos);
extern int bstrrchrp (const_bstring b, int c, int pos);
#define bstrchr(b,c) bstrchrp ((b), (c), 0)
#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
extern int binchr (const_bstring b0, int pos, const_bstring b1);
extern int binchrr (const_bstring b0, int pos, const_bstring b1);
extern int bninchr (const_bstring b0, int pos, const_bstring b1);
extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
extern int bstricmp(const_bstring b0, const_bstring b1);
extern int bstrnicmp(const_bstring b0, const_bstring b1, int n);
extern int biseqcaseless(const_bstring b0, const_bstring b1);
extern int bisstemeqcaselessblk(const_bstring b0, const void * blk, int len);
extern int biseq(const_bstring b0, const_bstring b1);
extern int bisstemeqblk(const_bstring b0, const void * blk, int len);
extern int biseqcstr(const_bstring b, const char * s);
extern int biseqcstrcaseless(const_bstring b, const char * s);
extern int bstrcmp(const_bstring b0, const_bstring b1);
extern int bstrncmp(const_bstring b0, const_bstring b1, int n);
extern int binstr(const_bstring s1, int pos, const_bstring s2);
extern int binstrr(const_bstring s1, int pos, const_bstring s2);
extern int binstrcaseless(const_bstring s1, int pos, const_bstring s2);
extern int binstrrcaseless(const_bstring s1, int pos, const_bstring s2);
extern int bstrchrp(const_bstring b, int c, int pos);
extern int bstrrchrp(const_bstring b, int c, int pos);
#define bstrchr(b, c) bstrchrp ((b), (c), 0)
#define bstrrchr(b, c) bstrrchrp ((b), (c), blength(b)-1)
extern int binchr(const_bstring b0, int pos, const_bstring b1);
extern int binchrr(const_bstring b0, int pos, const_bstring b1);
extern int bninchr(const_bstring b0, int pos, const_bstring b1);
extern int bninchrr(const_bstring b0, int pos, const_bstring b1);
extern int bfindreplace(bstring b, const_bstring find, const_bstring repl, int pos);
extern int bfindreplacecaseless(bstring b, const_bstring find, const_bstring repl, int pos);
/* List of string container functions */
struct bstrList {
struct bstrList
{
int qty, mlen;
bstring * entry;
};
extern struct bstrList * bstrListCreate (void);
extern int bstrListDestroy (struct bstrList * sl);
extern int bstrListAlloc (struct bstrList * sl, int msz);
extern int bstrListAllocMin (struct bstrList * sl, int msz);
extern struct bstrList * bstrListCreate(void);
extern int bstrListDestroy(struct bstrList * sl);
extern int bstrListAlloc(struct bstrList * sl, int msz);
extern int bstrListAllocMin(struct bstrList * sl, int msz);
/* String split and join functions */
extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern struct bstrList * bsplit(const_bstring str, unsigned char splitChar);
extern struct bstrList * bsplits(const_bstring str, const_bstring splitStr);
extern struct bstrList * bsplitstr(const_bstring str, const_bstring splitStr);
extern bstring bjoin(const struct bstrList * bl, const_bstring sep);
extern int bsplitcb(const_bstring str, unsigned char splitChar, int pos,
int (* cb)(void * parm, int ofs, int len), void * parm);
extern int bsplitscb(const_bstring str, const_bstring splitStr, int pos,
int (* cb)(void * parm, int ofs, int len), void * parm);
extern int bsplitstrcb(const_bstring str, const_bstring splitStr, int pos,
int (* cb)(void * parm, int ofs, int len), void * parm);
/* Miscellaneous functions */
extern int bpattern (bstring b, int len);
extern int btoupper (bstring b);
extern int btolower (bstring b);
extern int bltrimws (bstring b);
extern int brtrimws (bstring b);
extern int btrimws (bstring b);
extern int bpattern(bstring b, int len);
extern int btoupper(bstring b);
extern int btolower(bstring b);
extern int bltrimws(bstring b);
extern int brtrimws(bstring b);
extern int btrimws(bstring b);
/* <*>printf format functions */
#if !defined (BSTRLIB_NOVSNP)
extern bstring bformat (const char * fmt, ...);
extern int bformata (bstring b, const char * fmt, ...);
extern int bassignformat (bstring b, const char * fmt, ...);
extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
#if !defined(BSTRLIB_NOVSNP)
extern bstring bformat(const char * fmt, ...);
extern int bformata(bstring b, const char * fmt, ...);
extern int bassignformat(bstring b, const char * fmt, ...);
extern int bvcformata(bstring b, int count, const char * fmt, va_list arglist);
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
@ -162,34 +163,35 @@ typedef int (*bNgetc) (void *parm);
typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
/* Input functions */
extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
extern bstring bread (bNread readPtr, void * parm);
extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int breada (bstring b, bNread readPtr, void * parm);
extern bstring bgets(bNgetc getcPtr, void * parm, char terminator);
extern bstring bread(bNread readPtr, void * parm);
extern int bgetsa(bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int bassigngets(bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int breada(bstring b, bNread readPtr, void * parm);
/* Stream functions */
extern struct bStream * bsopen (bNread readPtr, void * parm);
extern void * bsclose (struct bStream * s);
extern int bsbufflength (struct bStream * s, int sz);
extern int bsreadln (bstring b, struct bStream * s, char terminator);
extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
extern int bsread (bstring b, struct bStream * s, int n);
extern int bsreadlna (bstring b, struct bStream * s, char terminator);
extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
extern int bsreada (bstring b, struct bStream * s, int n);
extern int bsunread (struct bStream * s, const_bstring b);
extern int bspeek (bstring r, const struct bStream * s);
extern int bssplitscb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bseof (const struct bStream * s);
extern struct bStream * bsopen(bNread readPtr, void * parm);
extern void * bsclose(struct bStream * s);
extern int bsbufflength(struct bStream * s, int sz);
extern int bsreadln(bstring b, struct bStream * s, char terminator);
extern int bsreadlns(bstring r, struct bStream * s, const_bstring term);
extern int bsread(bstring b, struct bStream * s, int n);
extern int bsreadlna(bstring b, struct bStream * s, char terminator);
extern int bsreadlnsa(bstring r, struct bStream * s, const_bstring term);
extern int bsreada(bstring b, struct bStream * s, int n);
extern int bsunread(struct bStream * s, const_bstring b);
extern int bspeek(bstring r, const struct bStream * s);
extern int bssplitscb(struct bStream * s, const_bstring splitStr,
int (* cb)(void * parm, int ofs, const_bstring entry), void * parm);
extern int bssplitstrcb(struct bStream * s, const_bstring splitStr,
int (* cb)(void * parm, int ofs, const_bstring entry), void * parm);
extern int bseof(const struct bStream * s);
struct tagbstring {
int mlen;
int slen;
unsigned char * data;
struct tagbstring
{
int mlen;
int slen;
unsigned char * data;
};
/* Accessor macros */
@ -203,7 +205,7 @@ struct tagbstring {
#define bchar(b, p) bchare ((b), (p), '\0')
/* Static constant string initialization macro */
#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
#define bsStaticMlen(q, m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
#if defined(_MSC_VER)
/* There are many versions of MSVC which emit __LINE__ as a non-constant. */
# define bsStatic(q) bsStaticMlen(q,-32)
@ -217,18 +219,18 @@ struct tagbstring {
/* Reference building macros */
#define cstr2tbstr btfromcstr
#define btfromcstr(t,s) { \
#define btfromcstr(t, s) { \
(t).data = (unsigned char *) (s); \
(t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
(t).mlen = -1; \
}
#define blk2tbstr(t,s,l) { \
#define blk2tbstr(t, s, l) { \
(t).data = (unsigned char *) (s); \
(t).slen = l; \
(t).mlen = -1; \
}
#define btfromblk(t,s,l) blk2tbstr(t,s,l)
#define bmid2tbstr(t,b,p,l) { \
#define btfromblk(t, s, l) blk2tbstr(t,s,l)
#define bmid2tbstr(t, b, p, l) { \
const_bstring bstrtmp_s = (b); \
if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
int bstrtmp_left = (p); \
@ -252,7 +254,7 @@ struct tagbstring {
} \
(t).mlen = -__LINE__; \
}
#define btfromblkltrimws(t,s,l) { \
#define btfromblkltrimws(t, s, l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l); \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
@ -264,7 +266,7 @@ struct tagbstring {
(t).slen = bstrtmp_len - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
#define btfromblkrtrimws(t,s,l) { \
#define btfromblkrtrimws(t, s, l) { \
int bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
@ -276,7 +278,7 @@ struct tagbstring {
(t).slen = bstrtmp_len + 1; \
(t).mlen = -__LINE__; \
}
#define btfromblktrimws(t,s,l) { \
#define btfromblktrimws(t, s, l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -14,141 +14,135 @@ class Operand;
namespace HLSLcc
{
using namespace std;
namespace ControlFlow
{
class BasicBlock;
class ControlFlowGraph
{
friend class BasicBlock;
public:
ControlFlowGraph()
: m_BlockMap()
, m_BlockStorage()
{}
namespace ControlFlow
{
class BasicBlock;
typedef std::vector<shared_ptr<BasicBlock> > BasicBlockStorage;
class ControlFlowGraph
{
friend class BasicBlock;
public:
ControlFlowGraph()
: m_BlockMap()
, m_BlockStorage()
{}
const BasicBlock &Build(const Instruction *firstInstruction);
typedef std::vector<shared_ptr<BasicBlock> > BasicBlockStorage;
// Only works for instructions that start the basic block
const BasicBlock *GetBasicBlockForInstruction(const Instruction *instruction) const;
const BasicBlock &Build(const Instruction *firstInstruction);
// non-const version for BasicBlock
BasicBlock *GetBasicBlockForInstruction(const Instruction *instruction);
// Only works for instructions that start the basic block
const BasicBlock *GetBasicBlockForInstruction(const Instruction *instruction) const;
const BasicBlockStorage &AllBlocks() const { return m_BlockStorage; }
private:
// non-const version for BasicBlock
BasicBlock *GetBasicBlockForInstruction(const Instruction *instruction);
// Map for storing the created basic blocks. Map key is the pointer to the first instruction in the block
typedef std::map<const Instruction *, BasicBlock *> BasicBlockMap;
const BasicBlockStorage &AllBlocks() const { return m_BlockStorage; }
private:
BasicBlockMap m_BlockMap;
// Map for storing the created basic blocks. Map key is the pointer to the first instruction in the block
typedef std::map<const Instruction *, BasicBlock *> BasicBlockMap;
// auto_ptr -type storage for multiple BasicBlocks. BlockMap above only has pointers into these
BasicBlockStorage m_BlockStorage;
};
BasicBlockMap m_BlockMap;
// auto_ptr -type storage for multiple BasicBlocks. BlockMap above only has pointers into these
BasicBlockStorage m_BlockStorage;
};
class BasicBlock
{
friend class ControlFlowGraph;
public:
// A set of register indices, one per each vec4 component per register
typedef std::set<uint32_t> RegisterSet;
// The connections (either incoming or outgoing) from this block. The instruction is the same one as the key in ControlFlowGraph to that basic block
typedef std::set<const Instruction *> ConnectionSet;
class BasicBlock
{
friend class ControlFlowGraph;
public:
// A set of register indices, one per each vec4 component per register
typedef std::set<uint32_t> RegisterSet;
// The connections (either incoming or outgoing) from this block. The instruction is the same one as the key in ControlFlowGraph to that basic block
typedef std::set<const Instruction *> ConnectionSet;
struct Definition
{
Definition(const Instruction *i = NULL, const Operand *o = NULL)
: m_Instruction(i)
, m_Operand(o)
{}
struct Definition
{
Definition(const Instruction *i = NULL, const Operand *o = NULL)
: m_Instruction(i)
, m_Operand(o)
{}
Definition(const Definition &a)
: m_Instruction(a.m_Instruction)
, m_Operand(a.m_Operand)
{}
Definition(const Definition &a)
: m_Instruction(a.m_Instruction)
, m_Operand(a.m_Operand)
{}
bool operator==(const Definition &a) const
{
if (a.m_Instruction != m_Instruction)
return false;
return a.m_Operand == m_Operand;
}
bool operator==(const Definition &a) const
{
if (a.m_Instruction != m_Instruction)
return false;
return a.m_Operand == m_Operand;
}
bool operator!=(const Definition &a) const
{
if (a.m_Instruction == m_Instruction)
return false;
return a.m_Operand != m_Operand;
}
bool operator!=(const Definition &a) const
{
if (a.m_Instruction == m_Instruction)
return false;
return a.m_Operand != m_Operand;
}
bool operator<(const Definition &a) const
{
if (m_Instruction != a.m_Instruction)
return m_Instruction < a.m_Instruction;
return m_Operand < a.m_Operand;
}
bool operator<(const Definition &a) const
{
if (m_Instruction != a.m_Instruction)
return m_Instruction < a.m_Instruction;
return m_Operand < a.m_Operand;
}
const Instruction *m_Instruction;
const Operand *m_Operand;
};
const Instruction *m_Instruction;
const Operand *m_Operand;
};
typedef std::set<Definition> ReachableDefinitionsPerVariable; // A set of possibly visible definitions for one component of one vec4 variable
typedef std::map<uint32_t, ReachableDefinitionsPerVariable> ReachableVariables; // A VisibleDefinitionSet for each variable*component.
typedef std::set<Definition> ReachableDefinitionsPerVariable; // A set of possibly visible definitions for one component of one vec4 variable
typedef std::map<uint32_t, ReachableDefinitionsPerVariable> ReachableVariables; // A VisibleDefinitionSet for each variable*component.
const Instruction *First() const { return m_First; }
const Instruction *Last() const { return m_Last; }
const Instruction *First() const { return m_First; }
const Instruction *Last() const { return m_Last; }
const RegisterSet &UEVar() const { return m_UEVar; }
const RegisterSet &VarKill() const { return m_VarKill; }
const RegisterSet &UEVar() const { return m_UEVar; }
const RegisterSet &VarKill() const { return m_VarKill; }
const ConnectionSet &Preceding() const { return m_Preceding; }
const ConnectionSet &Succeeding() const { return m_Succeeding; }
const ConnectionSet &Preceding() const { return m_Preceding; }
const ConnectionSet &Succeeding() const { return m_Succeeding; }
const ReachableVariables &DEDef() const { return m_DEDef; }
const ReachableVariables &Reachable() const { return m_Reachable; }
const ReachableVariables &DEDef() const { return m_DEDef; }
const ReachableVariables &Reachable() const { return m_Reachable; }
// Helper function: Do union of 2 ReachableVariables, store result in a.
static void RVarUnion(ReachableVariables &a, const ReachableVariables &b);
// Helper function: Do union of 2 ReachableVariables, store result in a.
static void RVarUnion(ReachableVariables &a, const ReachableVariables &b);
private:
private:
// Generate a basic block. Private constructor, can only be constructed from ControlFlowGraph::Build()
BasicBlock(const Instruction *psFirst, ControlFlowGraph &graph, const Instruction *psPrecedingBlockHead);
// Generate a basic block. Private constructor, can only be constructed from ControlFlowGraph::Build()
BasicBlock(const Instruction *psFirst, ControlFlowGraph &graph, const Instruction *psPrecedingBlockHead);
// Walk through the instructions and build UEVar and VarKill sets, create succeeding nodes if they don't exist already.
void Build();
// Walk through the instructions and build UEVar and VarKill sets, create succeeding nodes if they don't exist already.
void Build();
bool RebuildReachable(); // Rebuild m_Reachable from preceding blocks and this one. Returns true if current value changed.
bool RebuildReachable(); // Rebuild m_Reachable from preceding blocks and this one. Returns true if current value changed.
BasicBlock * AddChildBasicBlock(const Instruction *psFirst);
BasicBlock * AddChildBasicBlock(const Instruction *psFirst);
private:
ControlFlowGraph &m_Graph; // The graph object containing this block
private:
ControlFlowGraph &m_Graph; // The graph object containing this block
const Instruction *m_First; // The first instruction in the basic block
const Instruction *m_Last; // The last instruction in the basic block. Either OPCODE_RET or a branch/jump/loop instruction
const Instruction *m_First; // The first instruction in the basic block
const Instruction *m_Last; // The last instruction in the basic block. Either OPCODE_RET or a branch/jump/loop instruction
RegisterSet m_UEVar; // Upwards-exposed variables (temps that need definition from upstream and are used in this basic block)
RegisterSet m_VarKill; // Set of variables that are defined in this block.
RegisterSet m_UEVar; // Upwards-exposed variables (temps that need definition from upstream and are used in this basic block)
RegisterSet m_VarKill; // Set of variables that are defined in this block.
ConnectionSet m_Preceding; // Set of blocks that immediately precede this block in the CFG
ConnectionSet m_Succeeding; // Set of blocks that follow this block in the CFG
ReachableVariables m_DEDef; // Downward-exposed definitions from this basic block. Always only one item per set.
ReachableVariables m_Reachable; // The set of variable definitions that are visible at the end of this block.
};
};
};
ConnectionSet m_Preceding; // Set of blocks that immediately precede this block in the CFG
ConnectionSet m_Succeeding; // Set of blocks that follow this block in the CFG
ReachableVariables m_DEDef; // Downward-exposed definitions from this basic block. Always only one item per set.
ReachableVariables m_Reachable; // The set of variable definitions that are visible at the end of this block.
};
}
}

Просмотреть файл

@ -4,28 +4,27 @@ struct Instruction;
namespace HLSLcc
{
namespace ControlFlow
{
class Utils
{
public:
// For a given flow-control instruction, find the corresponding jump location:
// If the input is OPCODE_IF, then find the next same-level ELSE or ENDIF +1
// For ELSE, find same level ENDIF + 1
// For BREAK/BREAKC, find next ENDLOOP or ENDSWITCH + 1
// For SWITCH, find next same-level CASE/DEFAULT (skip multiple consecutive case/default labels) or ENDSWITCH + 1
// For ENDLOOP, find previous same-level LOOP + 1
// For CASE/DEFAULT, find next same-level CASE/DEFAULT or ENDSWITCH + 1, skip multiple consecutive case/default labels
// For CONTINUE/C the previous LOOP + 1
// Note that LOOP/ENDSWITCH itself is nothing but a label but it still starts a new basic block.
// Note that CASE labels fall through.
// Always returns the beginning of the next block, so skip multiple CASE/DEFAULT labels etc.
// If sawEndSwitch != null, will bet set to true if the label skipping saw past ENDSWITCH
// If needConnectToParent != null, will be set to true if sawEndSwitch == true and there are one or more case labels directly before it.
static const Instruction * GetJumpPoint(const Instruction *psStart, bool *sawEndSwitch = 0, bool *needConnectToParent = 0);
namespace ControlFlow
{
class Utils
{
public:
// For a given flow-control instruction, find the corresponding jump location:
// If the input is OPCODE_IF, then find the next same-level ELSE or ENDIF +1
// For ELSE, find same level ENDIF + 1
// For BREAK/BREAKC, find next ENDLOOP or ENDSWITCH + 1
// For SWITCH, find next same-level CASE/DEFAULT (skip multiple consecutive case/default labels) or ENDSWITCH + 1
// For ENDLOOP, find previous same-level LOOP + 1
// For CASE/DEFAULT, find next same-level CASE/DEFAULT or ENDSWITCH + 1, skip multiple consecutive case/default labels
// For CONTINUE/C the previous LOOP + 1
// Note that LOOP/ENDSWITCH itself is nothing but a label but it still starts a new basic block.
// Note that CASE labels fall through.
// Always returns the beginning of the next block, so skip multiple CASE/DEFAULT labels etc.
// If sawEndSwitch != null, will bet set to true if the label skipping saw past ENDSWITCH
// If needConnectToParent != null, will be set to true if sawEndSwitch == true and there are one or more case labels directly before it.
static const Instruction * GetJumpPoint(const Instruction *psStart, bool *sawEndSwitch = 0, bool *needConnectToParent = 0);
static const Instruction *GetNextNonLabelInstruction(const Instruction *psStart, bool *sawEndSwitch = 0);
};
}
}
static const Instruction *GetNextNonLabelInstruction(const Instruction *psStart, bool *sawEndSwitch = 0);
};
}
}

Просмотреть файл

@ -8,8 +8,8 @@ struct Instruction;
namespace HLSLcc
{
namespace DataTypeAnalysis
{
void SetDataTypes(HLSLCrossCompilerContext* psContext, std::vector<Instruction> &instructions, uint32_t ui32TempCount, std::vector<SHADER_VARIABLE_TYPE> &results);
};
};
namespace DataTypeAnalysis
{
void SetDataTypes(HLSLCrossCompilerContext* psContext, std::vector<Instruction> &instructions, uint32_t ui32TempCount, std::vector<SHADER_VARIABLE_TYPE> &results);
}
}

Просмотреть файл

@ -1,4 +1,3 @@
#pragma once
#include <vector>
@ -6,11 +5,12 @@
#include "internal_includes/tokens.h"
#include "internal_includes/Operand.h"
typedef struct ICBVec4_TAG {
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
typedef struct ICBVec4_TAG
{
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} ICBVec4;
#define ACCESS_FLAG_READ 0x1
@ -18,85 +18,86 @@ typedef struct ICBVec4_TAG {
struct Declaration
{
Declaration()
:
eOpcode(OPCODE_INVALID),
ui32NumOperands(0),
ui32BufferStride(0)
{}
Declaration()
:
eOpcode(OPCODE_INVALID),
ui32NumOperands(0),
ui32BufferStride(0)
{}
OPCODE_TYPE eOpcode;
OPCODE_TYPE eOpcode;
uint32_t ui32NumOperands;
uint32_t ui32NumOperands;
Operand asOperands[2];
Operand asOperands[2];
std::vector<ICBVec4> asImmediateConstBuffer;
//The declaration can set one of these
//values depending on the opcode.
union {
uint32_t ui32GlobalFlags;
uint32_t ui32NumTemps;
RESOURCE_DIMENSION eResourceDimension;
INTERPOLATION_MODE eInterpolation;
PRIMITIVE_TOPOLOGY eOutputPrimitiveTopology;
PRIMITIVE eInputPrimitive;
uint32_t ui32MaxOutputVertexCount;
TESSELLATOR_DOMAIN eTessDomain;
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t aui32WorkGroupSize[3];
uint32_t ui32HullPhaseInstanceCount;
float fMaxTessFactor;
uint32_t ui32IndexRange;
uint32_t ui32GSInstanceCount;
SB_SAMPLER_MODE eSamplerMode; // For sampler declarations, the sampler mode.
std::vector<ICBVec4> asImmediateConstBuffer;
//The declaration can set one of these
//values depending on the opcode.
union
{
uint32_t ui32GlobalFlags;
uint32_t ui32NumTemps;
RESOURCE_DIMENSION eResourceDimension;
INTERPOLATION_MODE eInterpolation;
PRIMITIVE_TOPOLOGY eOutputPrimitiveTopology;
PRIMITIVE eInputPrimitive;
uint32_t ui32MaxOutputVertexCount;
TESSELLATOR_DOMAIN eTessDomain;
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t aui32WorkGroupSize[3];
uint32_t ui32HullPhaseInstanceCount;
float fMaxTessFactor;
uint32_t ui32IndexRange;
uint32_t ui32GSInstanceCount;
SB_SAMPLER_MODE eSamplerMode; // For sampler declarations, the sampler mode.
struct Interface_TAG
{
uint32_t ui32InterfaceID;
uint32_t ui32NumFuncTables;
uint32_t ui32ArraySize;
} iface;
} value;
struct Interface_TAG
{
uint32_t ui32InterfaceID;
uint32_t ui32NumFuncTables;
uint32_t ui32ArraySize;
} iface;
} value;
uint32_t ui32BufferStride;
uint32_t ui32BufferStride;
struct UAV_TAG
{
UAV_TAG() :
ui32GloballyCoherentAccess(0),
bCounter(0),
Type(RETURN_TYPE_UNORM),
ui32NumComponents(0),
ui32AccessFlags(0)
{
}
uint32_t ui32GloballyCoherentAccess;
uint8_t bCounter;
RESOURCE_RETURN_TYPE Type;
uint32_t ui32NumComponents;
uint32_t ui32AccessFlags;
} sUAV;
struct UAV_TAG
{
UAV_TAG() :
ui32GloballyCoherentAccess(0),
bCounter(0),
Type(RETURN_TYPE_UNORM),
ui32NumComponents(0),
ui32AccessFlags(0)
{
}
struct TGSM_TAG
{
uint32_t ui32Stride;
uint32_t ui32Count;
} sTGSM;
uint32_t ui32GloballyCoherentAccess;
uint8_t bCounter;
RESOURCE_RETURN_TYPE Type;
uint32_t ui32NumComponents;
uint32_t ui32AccessFlags;
} sUAV;
struct IndexableTemp_TAG
{
uint32_t ui32RegIndex;
uint32_t ui32RegCount;
uint32_t ui32RegComponentSize;
} sIdxTemp;
struct TGSM_TAG
{
uint32_t ui32Stride;
uint32_t ui32Count;
} sTGSM;
uint32_t ui32TableLength;
struct IndexableTemp_TAG
{
uint32_t ui32RegIndex;
uint32_t ui32RegCount;
uint32_t ui32RegComponentSize;
} sIdxTemp;
uint32_t ui32IsShadowTex;
uint32_t ui32TableLength;
// Set indexed by sampler register number.
std::set<uint32_t> samplersUsed;
uint32_t ui32IsShadowTex;
// Set indexed by sampler register number.
std::set<uint32_t> samplersUsed;
};

Просмотреть файл

@ -15,48 +15,48 @@ class HLSLccReflection;
class HLSLCrossCompilerContext
{
public:
HLSLCrossCompilerContext(HLSLccReflection &refl) : m_Reflection(refl) {}
HLSLCrossCompilerContext(HLSLccReflection &refl) : m_Reflection(refl) {}
bstring glsl;
bstring extensions;
bstring beforeMain;
bstring glsl;
bstring extensions;
bstring beforeMain;
bstring* currentGLSLString;//either glsl or earlyMain of current phase
bstring* currentGLSLString;//either glsl or earlyMain of current phase
uint32_t currentPhase;
uint32_t currentPhase;
int indent;
unsigned int flags;
int indent;
unsigned int flags;
// Helper functions for checking flags
// Returns true if VULKAN_BINDINGS flag is set
bool IsVulkan() const;
// Helper functions for checking flags
// Returns true if VULKAN_BINDINGS flag is set
bool IsVulkan() const;
Shader* psShader;
GLSLCrossDependencyData* psDependencies;
const char *inputPrefix; // Prefix for shader inputs
const char *outputPrefix; // Prefix for shader outputs
Shader* psShader;
GLSLCrossDependencyData* psDependencies;
const char *inputPrefix; // Prefix for shader inputs
const char *outputPrefix; // Prefix for shader outputs
void DoDataTypeAnalysis(ShaderPhase *psPhase);
void DoDataTypeAnalysis(ShaderPhase *psPhase);
void ClearDependencyData();
void ClearDependencyData();
void AddIndentation();
void AddIndentation();
// Currently active translator
Translator *psTranslator;
// Currently active translator
Translator *psTranslator;
HLSLccReflection &m_Reflection; // Callbacks for bindings and diagnostic info
HLSLccReflection &m_Reflection; // Callbacks for bindings and diagnostic info
// Retrieve the name for which the input or output is declared as. Takes into account possible redirections.
std::string GetDeclaredInputName(const Operand* psOperand, int *piRebase, int iIgnoreRedirect, uint32_t *puiIgnoreSwizzle) const;
std::string GetDeclaredOutputName(const Operand* psOperand, int* stream, uint32_t *puiIgnoreSwizzle, int *piRebase, int iIgnoreRedirect) const;
// Retrieve the name for which the input or output is declared as. Takes into account possible redirections.
std::string GetDeclaredInputName(const Operand* psOperand, int *piRebase, int iIgnoreRedirect, uint32_t *puiIgnoreSwizzle) const;
std::string GetDeclaredOutputName(const Operand* psOperand, int* stream, uint32_t *puiIgnoreSwizzle, int *piRebase, int iIgnoreRedirect) const;
bool OutputNeedsDeclaring(const Operand* psOperand, const int count);
bool OutputNeedsDeclaring(const Operand* psOperand, const int count);
bool RequireExtension(const std::string &extName);
bool EnableExtension(const std::string &extName);
bool RequireExtension(const std::string &extName);
bool EnableExtension(const std::string &extName);
private:
std::set<std::string> m_EnabledExtensions;
std::set<std::string> m_EnabledExtensions;
};

Просмотреть файл

@ -13,117 +13,115 @@ struct ConstantBuffer;
namespace HLSLcc
{
uint32_t GetNumberBitsSet(uint32_t a);
uint32_t GetNumberBitsSet(uint32_t a);
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType);
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType);
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags);
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags);
const char * GetConstructorForType(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision = true);
const char * GetConstructorForType(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision = true);
const char * GetConstructorForTypeGLSL(const HLSLCrossCompilerContext *context, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision);
const char * GetConstructorForTypeGLSL(const HLSLCrossCompilerContext *context, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision);
const char * GetConstructorForTypeMetal(const SHADER_VARIABLE_TYPE eType, const int components);
const char * GetConstructorForTypeMetal(const SHADER_VARIABLE_TYPE eType, const int components);
std::string GetMatrixTypeName(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eBaseType, const int columns, const int rows);
std::string GetMatrixTypeName(const HLSLCrossCompilerContext *psContext, const SHADER_VARIABLE_TYPE eBaseType, const int columns, const int rows);
void AddSwizzleUsingElementCount(bstring dest, uint32_t count);
void AddSwizzleUsingElementCount(bstring dest, uint32_t count);
int WriteMaskToComponentCount(uint32_t writeMask);
int WriteMaskToComponentCount(uint32_t writeMask);
uint32_t BuildComponentMaskFromElementCount(int count);
uint32_t BuildComponentMaskFromElementCount(int count);
// Returns true if we can do direct assignment between types (mostly for mediump<->highp floats etc)
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src);
// Returns true if we can do direct assignment between types (mostly for mediump<->highp floats etc)
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src);
// Convert resource return type to SVT_ flags
uint32_t ResourceReturnTypeToFlag(const RESOURCE_RETURN_TYPE eType);
// Convert resource return type to SVT_ flags
uint32_t ResourceReturnTypeToFlag(const RESOURCE_RETURN_TYPE eType);
SHADER_VARIABLE_TYPE ResourceReturnTypeToSVTType(const RESOURCE_RETURN_TYPE eType, const REFLECT_RESOURCE_PRECISION ePrec);
SHADER_VARIABLE_TYPE ResourceReturnTypeToSVTType(const RESOURCE_RETURN_TYPE eType, const REFLECT_RESOURCE_PRECISION ePrec);
uint32_t ElemCountToAutoExpandFlag(uint32_t elemCount);
uint32_t ElemCountToAutoExpandFlag(uint32_t elemCount);
bool IsOperationCommutative(int /* OPCODE_TYPE */ eOpCode);
bool IsOperationCommutative(int /* OPCODE_TYPE */ eOpCode);
bool AreTempOperandsIdentical(const Operand * psA, const Operand * psB);
bool AreTempOperandsIdentical(const Operand * psA, const Operand * psB);
int GetNumTextureDimensions(int /* RESOURCE_DIMENSION */ eResDim);
int GetNumTextureDimensions(int /* RESOURCE_DIMENSION */ eResDim);
SHADER_VARIABLE_TYPE SelectHigherType(SHADER_VARIABLE_TYPE a, SHADER_VARIABLE_TYPE b);
SHADER_VARIABLE_TYPE SelectHigherType(SHADER_VARIABLE_TYPE a, SHADER_VARIABLE_TYPE b);
// Returns true if the instruction adds 1 to the destination temp register
bool IsAddOneInstruction(const Instruction *psInst);
// Returns true if the instruction adds 1 to the destination temp register
bool IsAddOneInstruction(const Instruction *psInst);
bool CanDoDirectCast(const HLSLCrossCompilerContext *context, SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest);
bool CanDoDirectCast(const HLSLCrossCompilerContext *context, SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest);
bool IsUnityFlexibleInstancingBuffer(const ConstantBuffer* psCBuf);
// Helper function to print floats with full precision
void PrintFloat(bstring b, float f);
// Helper function to print floats with full precision
void PrintFloat(bstring b, float f);
// Flags for ForeachOperand
// Process suboperands
// Flags for ForeachOperand
// Process suboperands
#define FEO_FLAG_SUBOPERAND 1
// Process src operands
// Process src operands
#define FEO_FLAG_SRC_OPERAND 2
// Process destination operands
// Process destination operands
#define FEO_FLAG_DEST_OPERAND 4
// Convenience: Process all operands, both src and dest, and all suboperands
// Convenience: Process all operands, both src and dest, and all suboperands
#define FEO_FLAG_ALL (FEO_FLAG_SUBOPERAND | FEO_FLAG_SRC_OPERAND | FEO_FLAG_DEST_OPERAND)
// For_each for all operands within a range of instructions. Flags above.
template<typename ItrType, typename F> void ForEachOperand(ItrType _begin, ItrType _end, int flags, F callback)
{
ItrType inst = _begin;
while (inst != _end)
{
uint32_t i, k;
// For_each for all operands within a range of instructions. Flags above.
template<typename ItrType, typename F> void ForEachOperand(ItrType _begin, ItrType _end, int flags, F callback)
{
ItrType inst = _begin;
while (inst != _end)
{
uint32_t i, k;
if ((flags & FEO_FLAG_DEST_OPERAND) || (flags & FEO_FLAG_SUBOPERAND))
{
for (i = 0; i < inst->ui32FirstSrc; i++)
{
if (flags & FEO_FLAG_SUBOPERAND)
{
for (k = 0; k < MAX_SUB_OPERANDS; k++)
{
if (inst->asOperands[i].m_SubOperands[k].get())
{
callback(inst, inst->asOperands[i].m_SubOperands[k].get(), FEO_FLAG_SUBOPERAND);
}
}
}
if (flags & FEO_FLAG_DEST_OPERAND)
{
callback(inst, &inst->asOperands[i], FEO_FLAG_DEST_OPERAND);
}
}
}
if ((flags & FEO_FLAG_DEST_OPERAND) || (flags & FEO_FLAG_SUBOPERAND))
{
for (i = 0; i < inst->ui32FirstSrc; i++)
{
if (flags & FEO_FLAG_SUBOPERAND)
{
for (k = 0; k < MAX_SUB_OPERANDS; k++)
{
if (inst->asOperands[i].m_SubOperands[k].get())
{
callback(inst, inst->asOperands[i].m_SubOperands[k].get(), FEO_FLAG_SUBOPERAND);
}
}
}
if (flags & FEO_FLAG_DEST_OPERAND)
{
callback(inst, &inst->asOperands[i], FEO_FLAG_DEST_OPERAND);
}
}
}
if ((flags & FEO_FLAG_SRC_OPERAND) || (flags & FEO_FLAG_SUBOPERAND))
{
for (i = inst->ui32FirstSrc; i < inst->ui32NumOperands; i++)
{
if (flags & FEO_FLAG_SUBOPERAND)
{
for (k = 0; k < MAX_SUB_OPERANDS; k++)
{
if (inst->asOperands[i].m_SubOperands[k].get())
{
callback(inst, inst->asOperands[i].m_SubOperands[k].get(), FEO_FLAG_SUBOPERAND);
}
}
}
if (flags & FEO_FLAG_SRC_OPERAND)
{
callback(inst, &inst->asOperands[i], FEO_FLAG_SRC_OPERAND);
}
}
}
if ((flags & FEO_FLAG_SRC_OPERAND) || (flags & FEO_FLAG_SUBOPERAND))
{
for (i = inst->ui32FirstSrc; i < inst->ui32NumOperands; i++)
{
if (flags & FEO_FLAG_SUBOPERAND)
{
for (k = 0; k < MAX_SUB_OPERANDS; k++)
{
if (inst->asOperands[i].m_SubOperands[k].get())
{
callback(inst, inst->asOperands[i].m_SubOperands[k].get(), FEO_FLAG_SUBOPERAND);
}
}
}
if (flags & FEO_FLAG_SRC_OPERAND)
{
callback(inst, &inst->asOperands[i], FEO_FLAG_SRC_OPERAND);
}
}
}
inst++;
}
}
};
inst++;
}
}
}

Просмотреть файл

@ -21,134 +21,134 @@
struct Instruction
{
Instruction()
: eOpcode(OPCODE_NOP)
, eBooleanTestType(INSTRUCTION_TEST_ZERO)
, ui32NumOperands(0)
, ui32FirstSrc(0)
, m_Uses()
, m_SkipTranslation(false)
, m_InductorRegister(0)
, bSaturate(0)
, m_IsStaticBranch(false)
, m_StaticBranchCondition(NULL)
{
m_LoopInductors[0] = m_LoopInductors[1] = m_LoopInductors[2] = m_LoopInductors[3] = 0;
}
Instruction()
: eOpcode(OPCODE_NOP)
, eBooleanTestType(INSTRUCTION_TEST_ZERO)
, ui32NumOperands(0)
, ui32FirstSrc(0)
, m_Uses()
, m_SkipTranslation(false)
, m_InductorRegister(0)
, bSaturate(0)
, m_IsStaticBranch(false)
, m_StaticBranchCondition(NULL)
{
m_LoopInductors[0] = m_LoopInductors[1] = m_LoopInductors[2] = m_LoopInductors[3] = 0;
}
// For creating unit tests only. Create an instruction with temps (unless reg is 0xffffffff in which case use OPERAND_TYPE_INPUT/OUTPUT)
Instruction(uint64_t _id, OPCODE_TYPE opcode, uint32_t reg1 = 0, uint32_t reg1Mask = 0, uint32_t reg2 = 0, uint32_t reg2Mask = 0, uint32_t reg3 = 0, uint32_t reg3Mask = 0, uint32_t reg4 = 0, uint32_t reg4Mask = 0)
{
id = _id;
eOpcode = opcode;
eBooleanTestType = INSTRUCTION_TEST_ZERO;
// For creating unit tests only. Create an instruction with temps (unless reg is 0xffffffff in which case use OPERAND_TYPE_INPUT/OUTPUT)
Instruction(uint64_t _id, OPCODE_TYPE opcode, uint32_t reg1 = 0, uint32_t reg1Mask = 0, uint32_t reg2 = 0, uint32_t reg2Mask = 0, uint32_t reg3 = 0, uint32_t reg3Mask = 0, uint32_t reg4 = 0, uint32_t reg4Mask = 0)
{
id = _id;
eOpcode = opcode;
eBooleanTestType = INSTRUCTION_TEST_ZERO;
ui32FirstSrc = 0;
ui32NumOperands = 0;
m_LoopInductors[0] = m_LoopInductors[1] = m_LoopInductors[2] = m_LoopInductors[3] = 0;
m_SkipTranslation = false;
m_InductorRegister = 0;
ui32NumOperands = 0;
m_LoopInductors[0] = m_LoopInductors[1] = m_LoopInductors[2] = m_LoopInductors[3] = 0;
m_SkipTranslation = false;
m_InductorRegister = 0;
if (reg1Mask == 0)
return;
if (reg1Mask == 0)
return;
ui32NumOperands++;
asOperands[0].eType = reg1 == 0xffffffff ? OPERAND_TYPE_OUTPUT : OPERAND_TYPE_TEMP;
asOperands[0].ui32RegisterNumber = reg1 == 0xffffffff ? 0 : reg1;
asOperands[0].ui32CompMask = reg1Mask;
asOperands[0].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
ui32NumOperands++;
asOperands[0].eType = reg1 == 0xffffffff ? OPERAND_TYPE_OUTPUT : OPERAND_TYPE_TEMP;
asOperands[0].ui32RegisterNumber = reg1 == 0xffffffff ? 0 : reg1;
asOperands[0].ui32CompMask = reg1Mask;
asOperands[0].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
if (reg2Mask == 0)
return;
if (reg2Mask == 0)
return;
ui32FirstSrc = 1;
ui32NumOperands++;
ui32FirstSrc = 1;
ui32NumOperands++;
asOperands[1].eType = reg2 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[1].ui32RegisterNumber = reg2 == 0xffffffff ? 0 : reg2;
asOperands[1].ui32CompMask = reg2Mask;
asOperands[1].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
asOperands[1].eType = reg2 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[1].ui32RegisterNumber = reg2 == 0xffffffff ? 0 : reg2;
asOperands[1].ui32CompMask = reg2Mask;
asOperands[1].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
if (reg3Mask == 0)
return;
ui32NumOperands++;
if (reg3Mask == 0)
return;
ui32NumOperands++;
asOperands[2].eType = reg3 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[2].ui32RegisterNumber = reg3 == 0xffffffff ? 0 : reg3;
asOperands[2].ui32CompMask = reg3Mask;
asOperands[2].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
asOperands[2].eType = reg3 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[2].ui32RegisterNumber = reg3 == 0xffffffff ? 0 : reg3;
asOperands[2].ui32CompMask = reg3Mask;
asOperands[2].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
if (reg4Mask == 0)
return;
ui32NumOperands++;
if (reg4Mask == 0)
return;
ui32NumOperands++;
asOperands[3].eType = reg4 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[3].ui32RegisterNumber = reg4 == 0xffffffff ? 0 : reg4;
asOperands[3].ui32CompMask = reg4Mask;
asOperands[3].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
}
asOperands[3].eType = reg4 == 0xffffffff ? OPERAND_TYPE_INPUT : OPERAND_TYPE_TEMP;
asOperands[3].ui32RegisterNumber = reg4 == 0xffffffff ? 0 : reg4;
asOperands[3].ui32CompMask = reg4Mask;
asOperands[3].eSelMode = OPERAND_4_COMPONENT_MASK_MODE;
}
// Returns true if this instruction is a conditional branch
bool IsConditionalBranchInstruction() const
{
switch (eOpcode)
{
case OPCODE_IF:
case OPCODE_BREAKC:
case OPCODE_CONTINUEC:
case OPCODE_RETC:
return true;
default:
return false;
}
}
// Returns true if this instruction is a conditional branch
bool IsConditionalBranchInstruction() const
{
switch (eOpcode)
{
case OPCODE_IF:
case OPCODE_BREAKC:
case OPCODE_CONTINUEC:
case OPCODE_RETC:
return true;
default:
return false;
}
}
bool IsPartialPrecisionSamplerInstruction(const ShaderInfo &info, OPERAND_MIN_PRECISION *pType) const;
bool IsPartialPrecisionSamplerInstruction(const ShaderInfo &info, OPERAND_MIN_PRECISION *pType) const;
// Flags for ChangeOperandTempRegister
// Flags for ChangeOperandTempRegister
#define UD_CHANGE_SUBOPERANDS 1
#define UD_CHANGE_MAIN_OPERAND 2
#define UD_CHANGE_ALL 3
void ChangeOperandTempRegister(Operand *psOperand, uint32_t oldReg, uint32_t newReg, uint32_t compMask, uint32_t flags, uint32_t rebase);
void ChangeOperandTempRegister(Operand *psOperand, uint32_t oldReg, uint32_t newReg, uint32_t compMask, uint32_t flags, uint32_t rebase);
OPCODE_TYPE eOpcode;
INSTRUCTION_TEST_BOOLEAN eBooleanTestType;
uint32_t ui32SyncFlags;
uint32_t ui32NumOperands;
uint32_t ui32FirstSrc;
Operand asOperands[6];
uint32_t bSaturate;
uint32_t ui32FuncIndexWithinInterface;
RESINFO_RETURN_TYPE eResInfoReturnType;
OPCODE_TYPE eOpcode;
INSTRUCTION_TEST_BOOLEAN eBooleanTestType;
uint32_t ui32SyncFlags;
uint32_t ui32NumOperands;
uint32_t ui32FirstSrc;
Operand asOperands[6];
uint32_t bSaturate;
uint32_t ui32FuncIndexWithinInterface;
RESINFO_RETURN_TYPE eResInfoReturnType;
int bAddressOffset;
int8_t iUAddrOffset;
int8_t iVAddrOffset;
int8_t iWAddrOffset;
RESOURCE_RETURN_TYPE xType, yType, zType, wType;
RESOURCE_DIMENSION eResDim;
int8_t iCausedSplit; // Nonzero if has caused a temp split. Later used by sampler datatype tweaking
int bAddressOffset;
int8_t iUAddrOffset;
int8_t iVAddrOffset;
int8_t iWAddrOffset;
RESOURCE_RETURN_TYPE xType, yType, zType, wType;
RESOURCE_DIMENSION eResDim;
int8_t iCausedSplit; // Nonzero if has caused a temp split. Later used by sampler datatype tweaking
bool m_IsStaticBranch; // If true, this instruction is a static branch
const Instruction *m_StaticBranchCondition; // If this is a static branch, this instruction points to the condition instruction. Can also be NULL if the operand itself is the condition
std::string m_StaticBranchName; // The name of the static branch variable, with the condition encoded in it.
bool m_IsStaticBranch; // If true, this instruction is a static branch
const Instruction *m_StaticBranchCondition; // If this is a static branch, this instruction points to the condition instruction. Can also be NULL if the operand itself is the condition
std::string m_StaticBranchName; // The name of the static branch variable, with the condition encoded in it.
struct Use
{
Use() : m_Inst(0), m_Op(0) {}
Use(const Use &a) : m_Inst(a.m_Inst), m_Op(a.m_Op) {}
Use(Instruction *inst, Operand *op) : m_Inst(inst), m_Op(op) {}
struct Use
{
Use() : m_Inst(0), m_Op(0) {}
Use(const Use &a) : m_Inst(a.m_Inst), m_Op(a.m_Op) {}
Use(Instruction *inst, Operand *op) : m_Inst(inst), m_Op(op) {}
Instruction *m_Inst; // The instruction that references the result of this instruction
Operand *m_Op; // The operand within the instruction above. Note: can also be suboperand.
};
Instruction *m_Inst; // The instruction that references the result of this instruction
Operand *m_Op; // The operand within the instruction above. Note: can also be suboperand.
};
std::vector<Use> m_Uses; // Array of use sites for the result(s) of this instruction, if any of the results is a temp reg.
std::vector<Use> m_Uses; // Array of use sites for the result(s) of this instruction, if any of the results is a temp reg.
Instruction *m_LoopInductors[4]; // If OPCODE_LOOP and is suitable for transforming into for-loop, contains pointers to for initializer, end condition, breakc, and increment.
bool m_SkipTranslation; // If true, don't emit this instruction (currently used by the for loop translation)
uint32_t m_InductorRegister; // If non-zero, the inductor variable can be declared in the for statement, and this register number has been allocated for it
Instruction *m_LoopInductors[4]; // If OPCODE_LOOP and is suitable for transforming into for-loop, contains pointers to for initializer, end condition, breakc, and increment.
bool m_SkipTranslation; // If true, don't emit this instruction (currently used by the for loop translation)
uint32_t m_InductorRegister; // If non-zero, the inductor variable can be declared in the for statement, and this register number has been allocated for it
uint64_t id;
uint64_t id;
};

Просмотреть файл

@ -1,9 +1,8 @@
#pragma once
class ShaderPhase;
class HLSLCrossCompilerContext;
namespace HLSLcc
{
void DoLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase);
};
void DoLoopTransform(HLSLCrossCompilerContext *psContext, ShaderPhase &phase);
}

Просмотреть файл

@ -4,7 +4,7 @@
#include <vector>
#include <memory>
enum{ MAX_SUB_OPERANDS = 3 };
enum { MAX_SUB_OPERANDS = 3 };
class Operand;
class HLSLCrossCompilerContext;
struct Instruction;
@ -17,130 +17,129 @@ struct Instruction;
class Operand
{
public:
typedef std::shared_ptr<Operand> SubOperandPtr;
typedef std::shared_ptr<Operand> SubOperandPtr;
Operand()
:
iExtended(),
eType(),
eModifier(),
eMinPrecision(),
iIndexDims(),
iWriteMask(),
iGSInput(),
iPSInOut(),
iWriteMaskEnabled(),
iArrayElements(),
iNumComponents(),
eSelMode(),
ui32CompMask(),
ui32Swizzle(),
aui32Swizzle(),
aui32ArraySizes(),
ui32RegisterNumber(),
afImmediates(),
adImmediates(),
eSpecialName(),
specialName(),
eIndexRep(),
m_SubOperands(),
aeDataType(),
m_Rebase(0),
m_Size(0),
m_Defines(),
m_ForLoopInductorName(0)
Operand()
:
iExtended(),
eType(),
eModifier(),
eMinPrecision(),
iIndexDims(),
iWriteMask(),
iGSInput(),
iPSInOut(),
iWriteMaskEnabled(),
iArrayElements(),
iNumComponents(),
eSelMode(),
ui32CompMask(),
ui32Swizzle(),
aui32Swizzle(),
aui32ArraySizes(),
ui32RegisterNumber(),
afImmediates(),
adImmediates(),
eSpecialName(),
specialName(),
eIndexRep(),
m_SubOperands(),
aeDataType(),
m_Rebase(0),
m_Size(0),
m_Defines(),
m_ForLoopInductorName(0)
#ifdef _DEBUG
, id(0)
, id(0)
#endif
{}
{}
// Retrieve the mask of all the components this operand accesses (either reads from or writes to).
// Note that destination writemask does affect the effective access mask.
uint32_t GetAccessMask() const;
// Returns the index of the highest accessed component, based on component mask
int GetMaxComponent() const;
// Retrieve the mask of all the components this operand accesses (either reads from or writes to).
// Note that destination writemask does affect the effective access mask.
uint32_t GetAccessMask() const;
bool IsSwizzleReplicated() const;
// Returns the index of the highest accessed component, based on component mask
int GetMaxComponent() const;
// Get the number of elements returned by operand, taking additional component mask into account
//e.g.
//.z = 1
//.x = 1
//.yw = 2
uint32_t GetNumSwizzleElements(uint32_t ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL) const;
bool IsSwizzleReplicated() const;
// When this operand is used as an input declaration, how many components does it have?
int GetNumInputElements(const HLSLCrossCompilerContext *psContext) const;
// Get the number of elements returned by operand, taking additional component mask into account
//e.g.
//.z = 1
//.x = 1
//.yw = 2
uint32_t GetNumSwizzleElements(uint32_t ui32CompMask = OPERAND_4_COMPONENT_MASK_ALL) const;
// Retrieve the operand data type.
SHADER_VARIABLE_TYPE GetDataType(HLSLCrossCompilerContext* psContext, SHADER_VARIABLE_TYPE ePreferredTypeForImmediates = SVT_INT) const;
// When this operand is used as an input declaration, how many components does it have?
int GetNumInputElements(const HLSLCrossCompilerContext *psContext) const;
// Returns 0 if the register used by the operand is per-vertex, or 1 if per-patch
int GetRegisterSpace(const HLSLCrossCompilerContext *psContext) const;
// Same as above but with explicit shader type and phase
int GetRegisterSpace(SHADER_TYPE eShaderType, SHADER_PHASE_TYPE eShaderPhaseType) const;
// Retrieve the operand data type.
SHADER_VARIABLE_TYPE GetDataType(HLSLCrossCompilerContext* psContext, SHADER_VARIABLE_TYPE ePreferredTypeForImmediates = SVT_INT) const;
// Returns 0 if the register used by the operand is per-vertex, or 1 if per-patch
int GetRegisterSpace(const HLSLCrossCompilerContext *psContext) const;
// Same as above but with explicit shader type and phase
int GetRegisterSpace(SHADER_TYPE eShaderType, SHADER_PHASE_TYPE eShaderPhaseType) const;
// Find the operand that contains the dynamic index for this operand (array in constant buffer).
// When isAoS is true, we'll try to find the original index var to avoid additional calculations.
// needsIndexCalcRevert output will tell if we need to divide the value to get the correct index.
Operand* GetDynamicIndexOperand(HLSLCrossCompilerContext *psContext, const ShaderVarType* psVar, bool isAoS, bool *needsIndexCalcRevert) const;
// Maps REFLECT_RESOURCE_PRECISION into OPERAND_MIN_PRECISION as much as possible
static OPERAND_MIN_PRECISION ResourcePrecisionToOperandPrecision(REFLECT_RESOURCE_PRECISION ePrec);
// Maps REFLECT_RESOURCE_PRECISION into OPERAND_MIN_PRECISION as much as possible
static OPERAND_MIN_PRECISION ResourcePrecisionToOperandPrecision(REFLECT_RESOURCE_PRECISION ePrec);
int iExtended;
OPERAND_TYPE eType;
OPERAND_MODIFIER eModifier;
OPERAND_MIN_PRECISION eMinPrecision;
int iIndexDims;
int iWriteMask;
int iGSInput;
int iPSInOut;
int iWriteMaskEnabled;
int iArrayElements;
int iNumComponents;
int iExtended;
OPERAND_TYPE eType;
OPERAND_MODIFIER eModifier;
OPERAND_MIN_PRECISION eMinPrecision;
int iIndexDims;
int iWriteMask;
int iGSInput;
int iPSInOut;
int iWriteMaskEnabled;
int iArrayElements;
int iNumComponents;
OPERAND_4_COMPONENT_SELECTION_MODE eSelMode;
uint32_t ui32CompMask;
uint32_t ui32Swizzle;
uint32_t aui32Swizzle[4];
OPERAND_4_COMPONENT_SELECTION_MODE eSelMode;
uint32_t ui32CompMask;
uint32_t ui32Swizzle;
uint32_t aui32Swizzle[4];
uint32_t aui32ArraySizes[3];
uint32_t ui32RegisterNumber;
//If eType is OPERAND_TYPE_IMMEDIATE32
float afImmediates[4];
//If eType is OPERAND_TYPE_IMMEDIATE64
double adImmediates[4];
uint32_t aui32ArraySizes[3];
uint32_t ui32RegisterNumber;
//If eType is OPERAND_TYPE_IMMEDIATE32
float afImmediates[4];
//If eType is OPERAND_TYPE_IMMEDIATE64
double adImmediates[4];
SPECIAL_NAME eSpecialName;
std::string specialName;
SPECIAL_NAME eSpecialName;
std::string specialName;
OPERAND_INDEX_REPRESENTATION eIndexRep[3];
OPERAND_INDEX_REPRESENTATION eIndexRep[3];
SubOperandPtr m_SubOperands[MAX_SUB_OPERANDS];
SubOperandPtr m_SubOperands[MAX_SUB_OPERANDS];
//One type for each component.
SHADER_VARIABLE_TYPE aeDataType[4];
//One type for each component.
SHADER_VARIABLE_TYPE aeDataType[4];
uint32_t m_Rebase; // Rebase value, for constant array accesses.
uint32_t m_Size; // Component count, only for constant array access.
uint32_t m_Rebase; // Rebase value, for constant array accesses.
uint32_t m_Size; // Component count, only for constant array access.
struct Define
{
Define() : m_Inst(0), m_Op(0) {}
Define(const Define &a) : m_Inst(a.m_Inst), m_Op(a.m_Op) {}
Define(Instruction *inst, Operand *op) : m_Inst(inst), m_Op(op) {}
struct Define
{
Define() : m_Inst(0), m_Op(0) {}
Define(const Define &a) : m_Inst(a.m_Inst), m_Op(a.m_Op) {}
Define(Instruction *inst, Operand *op) : m_Inst(inst), m_Op(op) {}
Instruction *m_Inst; // Instruction that writes to the temp
Operand *m_Op; // The (destination) operand within that instruction.
};
Instruction *m_Inst; // Instruction that writes to the temp
Operand *m_Op; // The (destination) operand within that instruction.
};
std::vector<Define> m_Defines; // Array of instructions whose results this operand can use. (only if eType == OPERAND_TYPE_TEMP)
uint32_t m_ForLoopInductorName; // If non-zero, this (eType==OPERAND_TYPE_TEMP) is an inductor variable used in for loop, and it has a special number as given here (overrides ui32RegisterNumber)
std::vector<Define> m_Defines; // Array of instructions whose results this operand can use. (only if eType == OPERAND_TYPE_TEMP)
uint32_t m_ForLoopInductorName; // If non-zero, this (eType==OPERAND_TYPE_TEMP) is an inductor variable used in for loop, and it has a special number as given here (overrides ui32RegisterNumber)
#ifdef _DEBUG
uint64_t id;
uint64_t id;
#endif
};

Просмотреть файл

@ -1,4 +1,3 @@
#pragma once
#include <vector>
@ -16,251 +15,252 @@
struct ConstantArrayChunk
{
ConstantArrayChunk() : m_Size(0), m_AccessMask(0) {}
ConstantArrayChunk(uint32_t sz, uint32_t mask, Operand *firstUse)
: m_Size(sz), m_AccessMask(mask)
{
m_UseSites.push_back(firstUse);
}
ConstantArrayChunk() : m_Size(0), m_AccessMask(0) {}
ConstantArrayChunk(uint32_t sz, uint32_t mask, Operand *firstUse)
: m_Size(sz), m_AccessMask(mask)
{
m_UseSites.push_back(firstUse);
}
uint32_t m_Size;
uint32_t m_AccessMask;
uint32_t m_Rebase;
uint32_t m_ComponentCount;
uint32_t m_Size;
uint32_t m_AccessMask;
uint32_t m_Rebase;
uint32_t m_ComponentCount;
std::vector<Operand *> m_UseSites;
std::vector<Operand *> m_UseSites;
};
typedef std::multimap<uint32_t, ConstantArrayChunk> ChunkMap;
struct ConstantArrayInfo
{
ConstantArrayInfo() : m_OrigDeclaration(0), m_Chunks() {}
ConstantArrayInfo() : m_OrigDeclaration(0), m_Chunks() {}
Declaration *m_OrigDeclaration; // Pointer to the original declaration of the const array
ChunkMap m_Chunks; // map of <starting offset, chunk info>, same start offset might have multiple entries for different access masks
Declaration *m_OrigDeclaration; // Pointer to the original declaration of the const array
ChunkMap m_Chunks; // map of <starting offset, chunk info>, same start offset might have multiple entries for different access masks
};
class ShaderPhase
{
public:
ShaderPhase()
:
ePhase(MAIN_PHASE),
ui32InstanceCount(0),
postShaderCode(),
hasPostShaderCode(0),
earlyMain(),
ui32OrigTemps(0),
ui32TotalTemps(0),
psTempDeclaration(NULL),
pui32SplitInfo(),
peTempTypes(),
acInputNeedsRedirect(),
acOutputNeedsRedirect(),
acPatchConstantsNeedsRedirect(),
m_CFG(),
m_CFGInitialized(false),
m_NextFreeTempRegister(1),
m_NextTexCoordTemp(0)
{}
ShaderPhase()
:
ePhase(MAIN_PHASE),
ui32InstanceCount(0),
postShaderCode(),
hasPostShaderCode(0),
earlyMain(),
ui32OrigTemps(0),
ui32TotalTemps(0),
psTempDeclaration(NULL),
pui32SplitInfo(),
peTempTypes(),
acInputNeedsRedirect(),
acOutputNeedsRedirect(),
acPatchConstantsNeedsRedirect(),
m_CFG(),
m_CFGInitialized(false),
m_NextFreeTempRegister(1),
m_NextTexCoordTemp(0)
{}
void ResolveUAVProperties();
void ResolveUAVProperties();
void UnvectorizeImmMoves(); // Transform MOV tX.xyz, (0, 1, 2) into MOV tX.x, 0; MOV tX.y, 1; MOV tX.z, 2 to make datatype analysis easier
void UnvectorizeImmMoves(); // Transform MOV tX.xyz, (0, 1, 2) into MOV tX.x, 0; MOV tX.y, 1; MOV tX.z, 2 to make datatype analysis easier
void PruneConstArrays(); // Walk through everything that accesses a const array to see if we could make it smaller
void PruneConstArrays(); // Walk through everything that accesses a const array to see if we could make it smaller
void ExpandSWAPCs(); // Expand all SWAPC opcodes into a bunch of MOVCs. Must be done first!
void ExpandSWAPCs(); // Expand all SWAPC opcodes into a bunch of MOVCs. Must be done first!
ConstantArrayInfo m_ConstantArrayInfo;
ConstantArrayInfo m_ConstantArrayInfo;
std::vector<Declaration> psDecl;
std::vector<Instruction> psInst;
std::vector<Declaration> psDecl;
std::vector<Instruction> psInst;
SHADER_PHASE_TYPE ePhase;
uint32_t ui32InstanceCount; // In case of hull shaders, how many instances this phase needs to have. Defaults to 1.
bstring postShaderCode;//End of main or before emit()
int hasPostShaderCode;
SHADER_PHASE_TYPE ePhase;
uint32_t ui32InstanceCount; // In case of hull shaders, how many instances this phase needs to have. Defaults to 1.
bstring postShaderCode;//End of main or before emit()
int hasPostShaderCode;
bstring earlyMain;//Code to be inserted at the start of phase
bstring earlyMain;//Code to be inserted at the start of phase
uint32_t ui32OrigTemps; // The number of temporaries this phase originally declared
uint32_t ui32TotalTemps; // The number of temporaries this phase has now
Declaration *psTempDeclaration; // Shortcut to the OPCODE_DCL_TEMPS opcode
uint32_t ui32OrigTemps; // The number of temporaries this phase originally declared
uint32_t ui32TotalTemps; // The number of temporaries this phase has now
Declaration *psTempDeclaration; // Shortcut to the OPCODE_DCL_TEMPS opcode
// The split table is a table containing the index of the original register this register was split out from, or 0xffffffff
// Format: lowest 16 bits: original register. bits 16-23: rebase (eg value of 1 means .yzw was changed to .xyz): bits 24-31: component count
std::vector<uint32_t> pui32SplitInfo;
std::vector<SHADER_VARIABLE_TYPE> peTempTypes;
// The split table is a table containing the index of the original register this register was split out from, or 0xffffffff
// Format: lowest 16 bits: original register. bits 16-23: rebase (eg value of 1 means .yzw was changed to .xyz): bits 24-31: component count
std::vector<uint32_t> pui32SplitInfo;
std::vector<SHADER_VARIABLE_TYPE> peTempTypes;
// These are needed in cases we have 2 vec2 texcoords combined into one vec4 and they are accessed together.
std::vector<unsigned char> acInputNeedsRedirect; // If 0xff, requires re-routing all reads via a combined vec4. If 0xfe, the same but the vec4 has already been declared.
std::vector<unsigned char> acOutputNeedsRedirect; // Same for outputs
std::vector<unsigned char> acPatchConstantsNeedsRedirect; // Same for patch constants
// These are needed in cases we have 2 vec2 texcoords combined into one vec4 and they are accessed together.
std::vector<unsigned char> acInputNeedsRedirect; // If 0xff, requires re-routing all reads via a combined vec4. If 0xfe, the same but the vec4 has already been declared.
std::vector<unsigned char> acOutputNeedsRedirect; // Same for outputs
std::vector<unsigned char> acPatchConstantsNeedsRedirect; // Same for patch constants
// Get the Control Flow Graph for this phase, build it if necessary.
HLSLcc::ControlFlow::ControlFlowGraph &GetCFG();
// Get the Control Flow Graph for this phase, build it if necessary.
HLSLcc::ControlFlow::ControlFlowGraph &GetCFG();
uint32_t m_NextFreeTempRegister; // A counter for creating new temporaries for for-loops.
uint32_t m_NextTexCoordTemp; // A counter for creating tex coord temps for driver issue workarounds
uint32_t m_NextFreeTempRegister; // A counter for creating new temporaries for for-loops.
uint32_t m_NextTexCoordTemp; // A counter for creating tex coord temps for driver issue workarounds
// Instructions that are static branches (branches based on constant buffer values only)
std::vector<Instruction *> m_StaticBranchInstructions;
// Instructions that are static branches (branches based on constant buffer values only)
std::vector<Instruction *> m_StaticBranchInstructions;
private:
bool m_CFGInitialized;
HLSLcc::ControlFlow::ControlFlowGraph m_CFG;
bool m_CFGInitialized;
HLSLcc::ControlFlow::ControlFlowGraph m_CFG;
};
class Shader
{
public:
Shader()
:
ui32MajorVersion(0),
ui32MinorVersion(0),
eShaderType(INVALID_SHADER),
eTargetLanguage(LANG_DEFAULT),
extensions(0),
fp64(0),
ui32ShaderLength(0),
aui32FuncTableToFuncPointer(),
aui32FuncBodyToFuncTable(),
funcTable(),
funcPointer(),
ui32NextClassFuncName(),
pui32FirstToken(NULL),
asPhases(),
sInfo(),
abScalarInput(),
abScalarOutput(),
aIndexedInput(),
aIndexedOutput(),
aIndexedInputParents(),
aeResourceDims(),
acInputDeclared(),
acOutputDeclared(),
aiOpcodeUsed(NUM_OPCODES, 0),
ui32CurrentVertexOutputStream(0),
textureSamplers(),
aui32StructuredBufferBindingPoints(MAX_RESOURCE_BINDINGS, 0),
ui32CurrentStructuredBufferIndex(),
m_DummySamplerDeclared(false)
{
}
Shader()
:
ui32MajorVersion(0),
ui32MinorVersion(0),
eShaderType(INVALID_SHADER),
eTargetLanguage(LANG_DEFAULT),
extensions(0),
fp64(0),
ui32ShaderLength(0),
aui32FuncTableToFuncPointer(),
aui32FuncBodyToFuncTable(),
funcTable(),
funcPointer(),
ui32NextClassFuncName(),
pui32FirstToken(NULL),
asPhases(),
sInfo(),
abScalarInput(),
abScalarOutput(),
aIndexedInput(),
aIndexedOutput(),
aIndexedInputParents(),
aeResourceDims(),
acInputDeclared(),
acOutputDeclared(),
aiOpcodeUsed(NUM_OPCODES, 0),
ui32CurrentVertexOutputStream(0),
textureSamplers(),
aui32StructuredBufferBindingPoints(MAX_RESOURCE_BINDINGS, 0),
ui32CurrentStructuredBufferIndex(),
m_DummySamplerDeclared(false)
{
}
// Retrieve the number of components the temp register has.
uint32_t GetTempComponentCount(SHADER_VARIABLE_TYPE eType, uint32_t ui32Reg) const;
// Retrieve the number of components the temp register has.
uint32_t GetTempComponentCount(SHADER_VARIABLE_TYPE eType, uint32_t ui32Reg) const;
//Hull shaders have multiple phases.
//Each phase has its own temps.
//Convert from per-phase temps to global temps.
void ConsolidateHullTempVars();
//Hull shaders have multiple phases.
//Each phase has its own temps.
//Convert from per-phase temps to global temps.
void ConsolidateHullTempVars();
// Go through all declarations and remove UAV occupied binding points from the aui32StructuredBufferBindingPoints list
void ResolveStructuredBufferBindingSlots(ShaderPhase *psPhase);
// Go through all declarations and remove UAV occupied binding points from the aui32StructuredBufferBindingPoints list
void ResolveStructuredBufferBindingSlots(ShaderPhase *psPhase);
// HLSL has separate register spaces for UAV and structured buffers. GLSL has shared register space for all buffers.
// The aim here is to preserve the UAV buffer bindings as they are and use remaining binding points for structured buffers.
// In this step make aui32StructuredBufferBindingPoints contain increasingly ordered uints starting from zero.
void PrepareStructuredBufferBindingSlots();
// HLSL has separate register spaces for UAV and structured buffers. GLSL has shared register space for all buffers.
// The aim here is to preserve the UAV buffer bindings as they are and use remaining binding points for structured buffers.
// In this step make aui32StructuredBufferBindingPoints contain increasingly ordered uints starting from zero.
void PrepareStructuredBufferBindingSlots();
// Detect temp registers per data type that are actually used.
void PruneTempRegisters();
// Detect temp registers per data type that are actually used.
void PruneTempRegisters();
// Check if inputs and outputs are accessed across semantic boundaries
// as in, 2x texcoord vec2's are packed together as vec4 but still accessed together.
void AnalyzeIOOverlap();
// Check if inputs and outputs are accessed across semantic boundaries
// as in, 2x texcoord vec2's are packed together as vec4 but still accessed together.
void AnalyzeIOOverlap();
// Change all references to vertex position to always be highp, having them be mediump causes problems on Metal and Vivante GPUs.
void ForcePositionToHighp();
void FindUnusedGlobals(uint32_t flags); // Finds the DCL_CONSTANT_BUFFER with name "$Globals" and searches through all usages for each member of it and mark if they're actually ever used.
// Change all references to vertex position to always be highp, having them be mediump causes problems on Metal and Vivante GPUs.
void ForcePositionToHighp();
void ExpandSWAPCs();
void FindUnusedGlobals(uint32_t flags); // Finds the DCL_CONSTANT_BUFFER with name "$Globals" and searches through all usages for each member of it and mark if they're actually ever used.
uint32_t ui32MajorVersion;
uint32_t ui32MinorVersion;
SHADER_TYPE eShaderType;
void ExpandSWAPCs();
GLLang eTargetLanguage;
const struct GlExtensions *extensions;
uint32_t ui32MajorVersion;
uint32_t ui32MinorVersion;
SHADER_TYPE eShaderType;
int fp64;
GLLang eTargetLanguage;
const struct GlExtensions *extensions;
//DWORDs in program code, including version and length tokens.
uint32_t ui32ShaderLength;
int fp64;
//DWORDs in program code, including version and length tokens.
uint32_t ui32ShaderLength;
//Instruction* functions;//non-main subroutines
HLSLcc::growing_vector<uint32_t> aui32FuncTableToFuncPointer; // dynamic alloc?
HLSLcc::growing_vector<uint32_t> aui32FuncBodyToFuncTable;
//Instruction* functions;//non-main subroutines
HLSLcc::growing_vector<uint32_t> aui32FuncTableToFuncPointer; // dynamic alloc?
HLSLcc::growing_vector<uint32_t> aui32FuncBodyToFuncTable;
struct FuncTableEntry{
HLSLcc::growing_vector<uint32_t> aui32FuncBodies;
};
HLSLcc::growing_vector<FuncTableEntry> funcTable;
struct FuncTableEntry
{
HLSLcc::growing_vector<uint32_t> aui32FuncBodies;
};
HLSLcc::growing_vector<FuncTableEntry> funcTable;
struct FuncPointerEntry {
HLSLcc::growing_vector<uint32_t> aui32FuncTables;
uint32_t ui32NumBodiesPerTable;
};
struct FuncPointerEntry
{
HLSLcc::growing_vector<uint32_t> aui32FuncTables;
uint32_t ui32NumBodiesPerTable;
};
HLSLcc::growing_vector<FuncPointerEntry> funcPointer;
HLSLcc::growing_vector<FuncPointerEntry> funcPointer;
HLSLcc::growing_vector<uint32_t> ui32NextClassFuncName;
HLSLcc::growing_vector<uint32_t> ui32NextClassFuncName;
const uint32_t* pui32FirstToken;//Reference for calculating current position in token stream.
const uint32_t* pui32FirstToken;//Reference for calculating current position in token stream.
std::vector<ShaderPhase> asPhases;
ShaderInfo sInfo;
std::vector<ShaderPhase> asPhases;
// There are 2 input/output register spaces in DX bytecode: one for per-patch data and one for per-vertex.
// Which one is used depends on the context:
// per-vertex space is used in vertex/pixel/geom shaders always
// hull shader control point phase uses per-vertex by default, other phases are per-patch by default (can access per-vertex with OPERAND_TYPE_I/O_CONTROL_POINT)
// domain shader is per-patch by default, can access per-vertex with OPERAND_TYPE_I/O_CONTROL_POINT
ShaderInfo sInfo;
// Below, the [2] is accessed with 0 == per-vertex, 1 == per-patch
// Note that these ints are component masks
HLSLcc::growing_vector<int> abScalarInput[2];
HLSLcc::growing_vector<int> abScalarOutput[2];
// There are 2 input/output register spaces in DX bytecode: one for per-patch data and one for per-vertex.
// Which one is used depends on the context:
// per-vertex space is used in vertex/pixel/geom shaders always
// hull shader control point phase uses per-vertex by default, other phases are per-patch by default (can access per-vertex with OPERAND_TYPE_I/O_CONTROL_POINT)
// domain shader is per-patch by default, can access per-vertex with OPERAND_TYPE_I/O_CONTROL_POINT
HLSLcc::growing_vector<int> aIndexedInput[2];
HLSLcc::growing_vector<bool> aIndexedOutput[2];
// Below, the [2] is accessed with 0 == per-vertex, 1 == per-patch
// Note that these ints are component masks
HLSLcc::growing_vector<int> abScalarInput[2];
HLSLcc::growing_vector<int> abScalarOutput[2];
HLSLcc::growing_vector<int> aIndexedInputParents[2];
HLSLcc::growing_vector<int> aIndexedInput[2];
HLSLcc::growing_vector<bool> aIndexedOutput[2];
HLSLcc::growing_vector<RESOURCE_DIMENSION> aeResourceDims;
HLSLcc::growing_vector<int> aIndexedInputParents[2];
HLSLcc::growing_vector<char> acInputDeclared[2];
HLSLcc::growing_vector<char> acOutputDeclared[2];
HLSLcc::growing_vector<RESOURCE_DIMENSION> aeResourceDims;
std::vector<int> aiOpcodeUsed; // Initialized to NUM_OPCODES elements above.
HLSLcc::growing_vector<char> acInputDeclared[2];
HLSLcc::growing_vector<char> acOutputDeclared[2];
uint32_t ui32CurrentVertexOutputStream;
std::vector<int> aiOpcodeUsed; // Initialized to NUM_OPCODES elements above.
TextureSamplerPairs textureSamplers;
uint32_t ui32CurrentVertexOutputStream;
std::vector<uint32_t> aui32StructuredBufferBindingPoints;
uint32_t ui32CurrentStructuredBufferIndex;
TextureSamplerPairs textureSamplers;
std::vector<char> psIntTempSizes; // Array for whether this temp register needs declaration as int temp
std::vector<char> psInt16TempSizes; // min16ints
std::vector<char> psInt12TempSizes; // min12ints
std::vector<char> psUIntTempSizes; // Same for uints
std::vector<char> psUInt16TempSizes; // ... and for uint16's
std::vector<char> psFloatTempSizes; // ...and for floats
std::vector<char> psFloat16TempSizes; // ...and for min16floats
std::vector<char> psFloat10TempSizes; // ...and for min10floats
std::vector<char> psDoubleTempSizes; // ...and for doubles
std::vector<char> psBoolTempSizes; // ... and for bools
std::vector<uint32_t> aui32StructuredBufferBindingPoints;
uint32_t ui32CurrentStructuredBufferIndex;
bool m_DummySamplerDeclared; // If true, the shader doesn't declare any samplers but uses texelFetch and we have added a dummy sampler for Vulkan for that.
std::vector<char> psIntTempSizes; // Array for whether this temp register needs declaration as int temp
std::vector<char> psInt16TempSizes; // min16ints
std::vector<char> psInt12TempSizes; // min12ints
std::vector<char> psUIntTempSizes; // Same for uints
std::vector<char> psUInt16TempSizes; // ... and for uint16's
std::vector<char> psFloatTempSizes; // ...and for floats
std::vector<char> psFloat16TempSizes; // ...and for min16floats
std::vector<char> psFloat10TempSizes; // ...and for min10floats
std::vector<char> psDoubleTempSizes; // ...and for doubles
std::vector<char> psBoolTempSizes; // ... and for bools
bool m_DummySamplerDeclared; // If true, the shader doesn't declare any samplers but uses texelFetch and we have added a dummy sampler for Vulkan for that.
private:
void DoIOOverlapOperand(ShaderPhase *psPhase, Operand *psOperand);
void DoIOOverlapOperand(ShaderPhase *psPhase, Operand *psOperand);
};

Просмотреть файл

@ -1,4 +1,3 @@
#pragma once
#include "HLSLCrossCompilerContext.h"
#include "Shader.h"
@ -8,28 +7,26 @@ struct Declaration;
class Translator
{
protected:
HLSLCrossCompilerContext *psContext;
HLSLCrossCompilerContext *psContext;
public:
explicit Translator(HLSLCrossCompilerContext *ctx) : psContext(ctx) {}
virtual ~Translator() {}
explicit Translator(HLSLCrossCompilerContext *ctx) : psContext(ctx) {}
virtual ~Translator() {}
virtual bool Translate() = 0;
virtual bool Translate() = 0;
virtual void TranslateDeclaration(const Declaration *psDecl) = 0;
virtual void TranslateDeclaration(const Declaration *psDecl) = 0;
// Translate system value type to name, return true if succeeded and no further translation is necessary
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL) = 0;
// Translate system value type to name, return true if succeeded and no further translation is necessary
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL) = 0;
// In GLSL, the input and output names cannot clash.
// Also, the output name of previous stage must match the input name of the next stage.
// So, do gymnastics depending on which shader we're running on and which other shaders exist in this program.
//
virtual void SetIOPrefixes() = 0;
// In GLSL, the input and output names cannot clash.
// Also, the output name of previous stage must match the input name of the next stage.
// So, do gymnastics depending on which shader we're running on and which other shaders exist in this program.
//
virtual void SetIOPrefixes() = 0;
void SetExtensions(const struct GlExtensions *ext)
{
psContext->psShader->extensions = ext;
}
};
void SetExtensions(const struct GlExtensions *ext)
{
psContext->psShader->extensions = ext;
}
};

Просмотреть файл

@ -20,102 +20,100 @@ class Operand;
class ShaderInfo;
namespace HLSLcc
{
namespace ControlFlow
{
class ControlFlowGraph;
};
};
namespace ControlFlow
{
class ControlFlowGraph;
}
}
// Def-Use chain per temp component
struct DefineUseChainEntry
{
DefineUseChainEntry()
: psInst(0)
, psOp(0)
, usages()
, writeMask(0)
, index(0)
, isStandalone(0)
{
memset(psSiblings, 0, 4 * sizeof(DefineUseChainEntry *));
}
DefineUseChainEntry()
: psInst(0)
, psOp(0)
, usages()
, writeMask(0)
, index(0)
, isStandalone(0)
{
memset(psSiblings, 0, 4 * sizeof(DefineUseChainEntry *));
}
Instruction *psInst; // The declaration (write to this temp component)
Operand *psOp; // The operand within this instruction for the write target
UsageSet usages; // List of usages that are dependent on this write
uint32_t writeMask; // Access mask; which all components were written to in the same op
uint32_t index; // For which component was this definition created for?
uint32_t isStandalone; // A shortcut for analysis: if nonzero, all siblings of all usages for both this and all this siblings
struct DefineUseChainEntry *psSiblings[4]; // In case of vectorized op, contains pointer to this define's corresponding entries for the other components.
Instruction *psInst; // The declaration (write to this temp component)
Operand *psOp; // The operand within this instruction for the write target
UsageSet usages; // List of usages that are dependent on this write
uint32_t writeMask; // Access mask; which all components were written to in the same op
uint32_t index; // For which component was this definition created for?
uint32_t isStandalone; // A shortcut for analysis: if nonzero, all siblings of all usages for both this and all this siblings
struct DefineUseChainEntry *psSiblings[4]; // In case of vectorized op, contains pointer to this define's corresponding entries for the other components.
#if _DEBUG
bool operator==(const DefineUseChainEntry &a) const
{
if (psInst != a.psInst)
return false;
if (psOp != a.psOp)
return false;
if (writeMask != a.writeMask)
return false;
if (index != a.index)
return false;
if (isStandalone != a.isStandalone)
return false;
bool operator==(const DefineUseChainEntry &a) const
{
if (psInst != a.psInst)
return false;
if (psOp != a.psOp)
return false;
if (writeMask != a.writeMask)
return false;
if (index != a.index)
return false;
if (isStandalone != a.isStandalone)
return false;
// Just check that each one has the same amount of usages
if (usages.size() != a.usages.size())
return false;
// Just check that each one has the same amount of usages
if (usages.size() != a.usages.size())
return false;
return true;
}
return true;
}
#endif
};
typedef std::list<DefineUseChainEntry> DefineUseChain;
struct UseDefineChainEntry
{
UseDefineChainEntry()
: psInst(0)
, psOp(0)
, defines()
, accessMask(0)
, index(0)
{
memset(psSiblings, 0, 4 * sizeof(UseDefineChainEntry *));
}
UseDefineChainEntry()
: psInst(0)
, psOp(0)
, defines()
, accessMask(0)
, index(0)
{
memset(psSiblings, 0, 4 * sizeof(UseDefineChainEntry *));
}
Instruction *psInst; // The use (read from this temp component)
Operand *psOp; // The operand within this instruction for the read
DefineSet defines; // List of writes that are visible to this read
uint32_t accessMask; // Which all components were read together with this one
uint32_t index; // For which component was this usage created for?
struct UseDefineChainEntry *psSiblings[4]; // In case of vectorized op, contains pointer to this usage's corresponding entries for the other components.
Instruction *psInst; // The use (read from this temp component)
Operand *psOp; // The operand within this instruction for the read
DefineSet defines; // List of writes that are visible to this read
uint32_t accessMask; // Which all components were read together with this one
uint32_t index; // For which component was this usage created for?
struct UseDefineChainEntry *psSiblings[4]; // In case of vectorized op, contains pointer to this usage's corresponding entries for the other components.
#if _DEBUG
bool operator==(const UseDefineChainEntry &a) const
{
if (psInst != a.psInst)
return false;
if (psOp != a.psOp)
return false;
if (accessMask != a.accessMask)
return false;
if (index != a.index)
return false;
bool operator==(const UseDefineChainEntry &a) const
{
if (psInst != a.psInst)
return false;
if (psOp != a.psOp)
return false;
if (accessMask != a.accessMask)
return false;
if (index != a.index)
return false;
// Just check that each one has the same amount of usages
if (defines.size() != a.defines.size())
return false;
// Just check that each one has the same amount of usages
if (defines.size() != a.defines.size())
return false;
return true;
}
return true;
}
#endif
};
typedef std::list<UseDefineChainEntry> UseDefineChain;
@ -138,4 +136,3 @@ void CalculateStandaloneDefinitions(DefineUseChains &psDUChains, uint32_t ui32Nu
// Write the uses and defines back to Instruction and Operand member lists.
void WriteBackUsesAndDefines(DefineUseChains &psDUChains);

Просмотреть файл

@ -6,14 +6,15 @@
#define ASSERT(expr) CustomAssert(expr)
static void CustomAssert(int expression)
{
if(!expression)
if (!expression)
{
assert(0);
}
}
#else
#define UNUSED(EXPR_) \
do { if (false) (void)(EXPR_); } while(0)
do { if (false) (void)(EXPR_); } while(0)
#define ASSERT(expr) UNUSED(expr)
#endif

Просмотреть файл

@ -7,55 +7,55 @@
static int InOutSupported(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
if (eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
}
static int WriteToFragData(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 1;
}
return 0;
if (eLang == LANG_ES_100 || eLang == LANG_120)
{
return 1;
}
return 0;
}
static int ShaderBitEncodingSupported(const GLLang eLang)
{
if( eLang != LANG_ES_300 &&
eLang != LANG_ES_310 &&
eLang < LANG_330)
{
return 0;
}
return 1;
if (eLang != LANG_ES_300 &&
eLang != LANG_ES_310 &&
eLang < LANG_330)
{
return 0;
}
return 1;
}
static int HaveOverloadedTextureFuncs(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
if (eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
}
//Only enable for ES. Vulkan and Switch.
//Not present in 120, ignored in other desktop languages. Specifically enabled on Vulkan.
static int HavePrecisionQualifiers(const HLSLCrossCompilerContext *psContext)
{
if ((psContext->flags & HLSLCC_FLAG_VULKAN_BINDINGS) != 0 || (psContext->flags & HLSLCC_FLAG_NVN_TARGET) != 0)
return 1;
if ((psContext->flags & HLSLCC_FLAG_VULKAN_BINDINGS) != 0 || (psContext->flags & HLSLCC_FLAG_NVN_TARGET) != 0)
return 1;
const GLLang eLang = psContext->psShader->eTargetLanguage;
if(eLang >= LANG_ES_100 && eLang <= LANG_ES_310)
{
return 1;
}
return 0;
const GLLang eLang = psContext->psShader->eTargetLanguage;
if (eLang >= LANG_ES_100 && eLang <= LANG_ES_310)
{
return 1;
}
return 0;
}
static int EmitLowp(const HLSLCrossCompilerContext *psContext)
@ -66,25 +66,25 @@ static int EmitLowp(const HLSLCrossCompilerContext *psContext)
static int HaveCubemapArray(const GLLang eLang)
{
if (eLang >= LANG_400 && eLang <= LANG_GL_LAST)
return 1;
return 0;
if (eLang >= LANG_400 && eLang <= LANG_GL_LAST)
return 1;
return 0;
}
static bool IsESLanguage(const GLLang eLang)
{
return (eLang >= LANG_ES_FIRST && eLang <= LANG_ES_LAST);
return (eLang >= LANG_ES_FIRST && eLang <= LANG_ES_LAST);
}
static bool IsDesktopGLLanguage(const GLLang eLang)
{
return (eLang >= LANG_GL_FIRST && eLang <= LANG_GL_LAST);
return (eLang >= LANG_GL_FIRST && eLang <= LANG_GL_LAST);
}
//Only on vertex inputs and pixel outputs.
static int HaveLimitedInOutLocationQualifier(const GLLang eLang, const struct GlExtensions *extensions)
{
if(eLang >= LANG_330 || eLang == LANG_ES_300 || eLang == LANG_ES_310 || (extensions && ((struct GlExtensions*)extensions)->ARB_explicit_attrib_location))
if (eLang >= LANG_330 || eLang == LANG_ES_300 || eLang == LANG_ES_310 || (extensions && ((struct GlExtensions*)extensions)->ARB_explicit_attrib_location))
{
return 1;
}
@ -93,7 +93,7 @@ static int HaveLimitedInOutLocationQualifier(const GLLang eLang, const struct Gl
static int HaveInOutLocationQualifier(const GLLang eLang)
{
if(eLang >= LANG_410 || eLang == LANG_ES_310)
if (eLang >= LANG_410 || eLang == LANG_ES_310)
{
return 1;
}
@ -102,13 +102,13 @@ static int HaveInOutLocationQualifier(const GLLang eLang)
//layout(binding = X) uniform {uniformA; uniformB;}
//layout(location = X) uniform uniform_name;
static int HaveUniformBindingsAndLocations(const GLLang eLang,const struct GlExtensions *extensions, unsigned int flags)
static int HaveUniformBindingsAndLocations(const GLLang eLang, const struct GlExtensions *extensions, unsigned int flags)
{
if (flags & HLSLCC_FLAG_DISABLE_EXPLICIT_LOCATIONS)
return 0;
if (flags & HLSLCC_FLAG_DISABLE_EXPLICIT_LOCATIONS)
return 0;
if (eLang >= LANG_430 || eLang == LANG_ES_310 ||
(extensions && ((struct GlExtensions*)extensions)->ARB_explicit_uniform_location && ((struct GlExtensions*)extensions)->ARB_shading_language_420pack))
if (eLang >= LANG_430 || eLang == LANG_ES_310 ||
(extensions && ((struct GlExtensions*)extensions)->ARB_explicit_uniform_location && ((struct GlExtensions*)extensions)->ARB_shading_language_420pack))
{
return 1;
}
@ -117,7 +117,7 @@ static int HaveUniformBindingsAndLocations(const GLLang eLang,const struct GlExt
static int DualSourceBlendSupported(const GLLang eLang)
{
if(eLang >= LANG_330)
if (eLang >= LANG_330)
{
return 1;
}
@ -126,7 +126,7 @@ static int DualSourceBlendSupported(const GLLang eLang)
static int SubroutinesSupported(const GLLang eLang)
{
if(eLang >= LANG_400)
if (eLang >= LANG_400)
{
return 1;
}
@ -138,7 +138,7 @@ static int SubroutinesSupported(const GLLang eLang)
//HLSL bytecode only tells us the interpolation in pixel shader.
static int PixelInterpDependency(const GLLang eLang)
{
if(eLang < LANG_430)
if (eLang < LANG_430)
{
return 1;
}
@ -147,166 +147,165 @@ static int PixelInterpDependency(const GLLang eLang)
static int HaveUnsignedTypes(const GLLang eLang)
{
switch(eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
switch (eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
}
static int HaveBitEncodingOps(const GLLang eLang)
{
switch(eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
switch (eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
}
static int HaveNativeBitwiseOps(const GLLang eLang)
{
switch(eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
switch (eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
}
static int HaveDynamicIndexing(HLSLCrossCompilerContext *psContext, const Operand* psOperand = NULL)
{
// WebGL only allows dynamic indexing with constant expressions, loop indices or a combination.
// The only exception is for uniform access in vertex shaders, which can be indexed using any expression.
// WebGL only allows dynamic indexing with constant expressions, loop indices or a combination.
// The only exception is for uniform access in vertex shaders, which can be indexed using any expression.
switch(psContext->psShader->eTargetLanguage)
{
case LANG_ES_100:
case LANG_120:
if (psOperand != NULL)
{
if (psOperand->m_ForLoopInductorName)
return 1;
switch (psContext->psShader->eTargetLanguage)
{
case LANG_ES_100:
case LANG_120:
if (psOperand != NULL)
{
if (psOperand->m_ForLoopInductorName)
return 1;
if (psContext->psShader->eShaderType == VERTEX_SHADER && psOperand->eType == OPERAND_TYPE_CONSTANT_BUFFER)
return 1;
}
if (psContext->psShader->eShaderType == VERTEX_SHADER && psOperand->eType == OPERAND_TYPE_CONSTANT_BUFFER)
return 1;
}
return 0;
default:
break;
}
return 1;
return 0;
default:
break;
}
return 1;
}
static int HaveGather(const GLLang eLang)
{
if(eLang >= LANG_400 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_400 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveGatherNonConstOffset(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveQueryLod(const GLLang eLang)
{
if(eLang >= LANG_400)
{
return 1;
}
return 0;
if (eLang >= LANG_400)
{
return 1;
}
return 0;
}
static int HaveQueryLevels(const GLLang eLang)
{
if(eLang >= LANG_430)
{
return 1;
}
return 0;
if (eLang >= LANG_430)
{
return 1;
}
return 0;
}
static int HaveFragmentCoordConventions(const GLLang eLang)
{
if(eLang >= LANG_150)
{
return 1;
}
return 0;
if (eLang >= LANG_150)
{
return 1;
}
return 0;
}
static int HaveGeometryShaderARB(const GLLang eLang)
{
if(eLang >= LANG_150)
{
return 1;
}
return 0;
if (eLang >= LANG_150)
{
return 1;
}
return 0;
}
static int HaveAtomicCounter(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveAtomicMem(const GLLang eLang)
{
if (eLang >= LANG_430 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_430 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveImageAtomics(const GLLang eLang)
{
if (eLang >= LANG_420)
{
return 1;
}
return 0;
if (eLang >= LANG_420)
{
return 1;
}
return 0;
}
static int HaveCompute(const GLLang eLang)
{
if(eLang >= LANG_430 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_430 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveImageLoadStore(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
if (eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
#endif

Просмотреть файл

@ -13,9 +13,9 @@ typedef struct
uint32_t* pui32Interfaces;
uint32_t* pui32Inputs11;
uint32_t* pui32Outputs11;
uint32_t* pui32OutputsWithStreams;
uint32_t* pui32PatchConstants;
uint32_t* pui32PatchConstants11;
uint32_t* pui32OutputsWithStreams;
uint32_t* pui32PatchConstants;
uint32_t* pui32PatchConstants11;
} ReflectionChunks;
void LoadShaderInfo(const uint32_t ui32MajorVersion,
@ -24,4 +24,3 @@ void LoadShaderInfo(const uint32_t ui32MajorVersion,
ShaderInfo* psInfo, uint32_t decodeFlags);
#endif

Просмотреть файл

@ -8,121 +8,121 @@ class HLSLCrossCompilerContext;
class ToGLSL : public Translator
{
protected:
GLLang language;
GLLang language;
bool m_NeedUnityInstancingArraySizeDecl;
public:
explicit ToGLSL(HLSLCrossCompilerContext *ctx) : Translator(ctx), language(LANG_DEFAULT), m_NeedUnityInstancingArraySizeDecl(false), m_NumDeclaredWhileTrueLoops(0) {}
// Sets the target language according to given input. if LANG_DEFAULT, does autodetect and returns the selected language
GLLang SetLanguage(GLLang suggestedLanguage);
explicit ToGLSL(HLSLCrossCompilerContext *ctx) : Translator(ctx), language(LANG_DEFAULT), m_NeedUnityInstancingArraySizeDecl(false), m_NumDeclaredWhileTrueLoops(0) {}
// Sets the target language according to given input. if LANG_DEFAULT, does autodetect and returns the selected language
GLLang SetLanguage(GLLang suggestedLanguage);
virtual bool Translate();
virtual void TranslateDeclaration(const Declaration* psDecl);
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL);
virtual void SetIOPrefixes();
virtual bool Translate();
virtual void TranslateDeclaration(const Declaration* psDecl);
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL);
virtual void SetIOPrefixes();
private:
// Vulkan-only: detect which branches only depend on uniforms and immediate values and can be turned into specialization constants.
void IdentifyStaticBranches(ShaderPhase *psPhase);
// May return false when we detect too complex stuff (matrices, arrays etc)
bool BuildStaticBranchNameForInstruction(Instruction &inst);
// Vulkan-only: detect which branches only depend on uniforms and immediate values and can be turned into specialization constants.
void IdentifyStaticBranches(ShaderPhase *psPhase);
// May return false when we detect too complex stuff (matrices, arrays etc)
bool BuildStaticBranchNameForInstruction(Instruction &inst);
void DeclareSpecializationConstants(ShaderPhase &phase);
void DeclareSpecializationConstants(ShaderPhase &phase);
void TranslateOperand(bstring glsl, const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
void TranslateOperand(const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
void TranslateInstruction(Instruction* psInst, bool isEmbedded = false);
void TranslateOperand(bstring glsl, const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
void TranslateOperand(const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
void TranslateInstruction(Instruction* psInst, bool isEmbedded = false);
void TranslateVariableNameWithMask(bstring glsl, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
void TranslateVariableNameWithMask(const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
void TranslateVariableNameWithMask(bstring glsl, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
void TranslateVariableNameWithMask(const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
void TranslateOperandIndex(const Operand* psOperand, int index);
void TranslateOperandIndexMAD(const Operand* psOperand, int index, uint32_t multiply, uint32_t add);
void TranslateOperandIndex(const Operand* psOperand, int index);
void TranslateOperandIndexMAD(const Operand* psOperand, int index, uint32_t multiply, uint32_t add);
void AddOpAssignToDestWithMask(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, const char *szAssignmentOp, int *pNeedsParenthesis, uint32_t ui32CompMask);
void AddAssignToDest(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, int* pNeedsParenthesis);
void AddAssignPrologue(int numParenthesis, bool isEmbedded = false);
void AddOpAssignToDestWithMask(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, const char *szAssignmentOp, int *pNeedsParenthesis, uint32_t ui32CompMask);
void AddAssignToDest(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, int* pNeedsParenthesis);
void AddAssignPrologue(int numParenthesis, bool isEmbedded = false);
void AddBuiltinOutput(const Declaration* psDecl, int arrayElements, const char* builtinName);
void AddBuiltinInput(const Declaration* psDecl, const char* builtinName);
void HandleOutputRedirect(const Declaration *psDecl, const char *Precision);
void HandleInputRedirect(const Declaration *psDecl, const char *Precision);
void AddBuiltinOutput(const Declaration* psDecl, int arrayElements, const char* builtinName);
void AddBuiltinInput(const Declaration* psDecl, const char* builtinName);
void HandleOutputRedirect(const Declaration *psDecl, const char *Precision);
void HandleInputRedirect(const Declaration *psDecl, const char *Precision);
void AddUserOutput(const Declaration* psDecl);
void DeclareStructConstants(const uint32_t ui32BindingPoint, const ConstantBuffer* psCBuf, const Operand* psOperand, bstring glsl);
void AddUserOutput(const Declaration* psDecl);
void DeclareStructConstants(const uint32_t ui32BindingPoint, const ConstantBuffer* psCBuf, const Operand* psOperand, bstring glsl);
void DeclareConstBufferShaderVariable(const char* varName, const struct ShaderVarType* psType, const struct ConstantBuffer* psCBuf, int unsizedArray, bool addUniformPrefix = false);
void PreDeclareStructType(const std::string &name, const struct ShaderVarType* psType);
void DeclareUBOConstants(const uint32_t ui32BindingPoint, const ConstantBuffer* psCBuf, bstring glsl);
typedef enum
{
CMP_EQ,
CMP_LT,
CMP_GE,
CMP_NE,
} ComparisonType;
void AddComparison(Instruction* psInst, ComparisonType eType,
uint32_t typeFlag);
typedef enum
{
CMP_EQ,
CMP_LT,
CMP_GE,
CMP_NE,
} ComparisonType;
void AddMOVBinaryOp(const Operand *pDest, Operand *pSrc, bool isEmbedded = false);
void AddMOVCBinaryOp(const Operand *pDest, const Operand *src0, Operand *src1, Operand *src2);
void CallBinaryOp(const char* name, Instruction* psInst,
int dest, int src0, int src1, SHADER_VARIABLE_TYPE eDataType, bool isEmbedded = false);
void CallTernaryOp(const char* op1, const char* op2, Instruction* psInst,
int dest, int src0, int src1, int src2, uint32_t dataType);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask);
void CallHelper2(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2Int(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2UInt(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper1(const char* name, Instruction* psInst,
int dest, int src0, int paramsShouldFollowWriteMask);
void CallHelper1Int(
const char* name,
Instruction* psInst,
const int dest,
const int src0,
int paramsShouldFollowWriteMask);
void TranslateTexelFetch(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexCoord(
const RESOURCE_DIMENSION eResDim,
Operand* psTexCoordOperand);
void GetResInfoData(Instruction* psInst, int index, int destElem);
void TranslateTextureSample(Instruction* psInst,
uint32_t ui32Flags);
void TranslateDynamicComponentSelection(const ShaderVarType* psVarType,
const Operand* psByteAddr, uint32_t offset, uint32_t mask);
void TranslateShaderStorageStore(Instruction* psInst);
void TranslateShaderStorageLoad(Instruction* psInst);
void TranslateAtomicMemOp(Instruction* psInst);
void TranslateConditional(
Instruction* psInst,
bstring glsl);
void AddComparison(Instruction* psInst, ComparisonType eType,
uint32_t typeFlag);
// Add an extra function to the m_FunctionDefinitions list, unless it's already there.
bool DeclareExtraFunction(const std::string &name, bstring body);
void UseExtraFunctionDependency(const std::string &name);
void AddMOVBinaryOp(const Operand *pDest, Operand *pSrc, bool isEmbedded = false);
void AddMOVCBinaryOp(const Operand *pDest, const Operand *src0, Operand *src1, Operand *src2);
void CallBinaryOp(const char* name, Instruction* psInst,
int dest, int src0, int src1, SHADER_VARIABLE_TYPE eDataType, bool isEmbedded = false);
void CallTernaryOp(const char* op1, const char* op2, Instruction* psInst,
int dest, int src0, int src1, int src2, uint32_t dataType);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask);
void CallHelper2(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2Int(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2UInt(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper1(const char* name, Instruction* psInst,
int dest, int src0, int paramsShouldFollowWriteMask);
void CallHelper1Int(
const char* name,
Instruction* psInst,
const int dest,
const int src0,
int paramsShouldFollowWriteMask);
void TranslateTexelFetch(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexCoord(
const RESOURCE_DIMENSION eResDim,
Operand* psTexCoordOperand);
void GetResInfoData(Instruction* psInst, int index, int destElem);
void TranslateTextureSample(Instruction* psInst,
uint32_t ui32Flags);
void TranslateDynamicComponentSelection(const ShaderVarType* psVarType,
const Operand* psByteAddr, uint32_t offset, uint32_t mask);
void TranslateShaderStorageStore(Instruction* psInst);
void TranslateShaderStorageLoad(Instruction* psInst);
void TranslateAtomicMemOp(Instruction* psInst);
void TranslateConditional(
Instruction* psInst,
bstring glsl);
void DeclareDynamicIndexWrapper(const struct ShaderVarType* psType);
void DeclareDynamicIndexWrapper(const char* psName, SHADER_VARIABLE_CLASS eClass, SHADER_VARIABLE_TYPE eType, uint32_t ui32Rows, uint32_t ui32Columns, uint32_t ui32Elements);
// Add an extra function to the m_FunctionDefinitions list, unless it's already there.
bool DeclareExtraFunction(const std::string &name, bstring body);
void UseExtraFunctionDependency(const std::string &name);
bool RenderTargetDeclared(uint32_t input);
void DeclareDynamicIndexWrapper(const struct ShaderVarType* psType);
void DeclareDynamicIndexWrapper(const char* psName, SHADER_VARIABLE_CLASS eClass, SHADER_VARIABLE_TYPE eType, uint32_t ui32Rows, uint32_t ui32Columns, uint32_t ui32Elements);
std::string GetVulkanDummySamplerName();
bool RenderTargetDeclared(uint32_t input);
// A <function name, body text> map of extra helper functions we'll need.
FunctionDefinitions m_FunctionDefinitions;
std::string GetVulkanDummySamplerName();
std::set<uint32_t> m_DeclaredRenderTarget;
int m_NumDeclaredWhileTrueLoops;
// A <function name, body text> map of extra helper functions we'll need.
FunctionDefinitions m_FunctionDefinitions;
std::set<uint32_t> m_DeclaredRenderTarget;
int m_NumDeclaredWhileTrueLoops;
};

Просмотреть файл

@ -1,4 +1,3 @@
#pragma once
#include "internal_includes/Translator.h"
#include <map>
@ -6,174 +5,172 @@
struct SamplerDesc
{
std::string name;
uint32_t reg, slot;
std::string name;
uint32_t reg, slot;
};
struct TextureSamplerDesc
{
std::string name;
int textureBind, samplerBind;
HLSLCC_TEX_DIMENSION dim;
bool isMultisampled;
bool isDepthSampler;
bool uav;
std::string name;
int textureBind, samplerBind;
HLSLCC_TEX_DIMENSION dim;
bool isMultisampled;
bool isDepthSampler;
bool uav;
};
class ToMetal : public Translator
{
protected:
GLLang language;
GLLang language;
public:
explicit ToMetal(HLSLCrossCompilerContext *ctx)
explicit ToMetal(HLSLCrossCompilerContext *ctx)
: Translator(ctx)
, m_ShadowSamplerDeclared(false)
, m_NeedFBOutputRemapDecl(false)
, m_NeedFBInputRemapDecl(false)
{}
virtual bool Translate();
virtual void TranslateDeclaration(const Declaration *psDecl);
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL);
std::string TranslateOperand(const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
virtual bool Translate();
virtual void TranslateDeclaration(const Declaration *psDecl);
virtual bool TranslateSystemValue(const Operand *psOperand, const ShaderInfo::InOutSignature *sig, std::string &result, uint32_t *pui32IgnoreSwizzle, bool isIndexed, bool isInput, bool *outSkipPrefix = NULL, int *iIgnoreRedirect = NULL);
std::string TranslateOperand(const Operand *psOp, uint32_t flags, uint32_t ui32ComponentMask = OPERAND_4_COMPONENT_MASK_ALL);
virtual void SetIOPrefixes();
virtual void SetIOPrefixes();
private:
void TranslateInstruction(Instruction* psInst);
void TranslateInstruction(Instruction* psInst);
void DeclareBuiltinInput(const Declaration *psDecl);
void DeclareBuiltinOutput(const Declaration *psDecl);
void DeclareClipPlanes(const Declaration* decl, unsigned declCount);
void GenerateTexturesReflection(HLSLccReflection* refl);
void DeclareBuiltinInput(const Declaration *psDecl);
void DeclareBuiltinOutput(const Declaration *psDecl);
void DeclareClipPlanes(const Declaration* decl, unsigned declCount);
void GenerateTexturesReflection(HLSLccReflection* refl);
// Retrieve the name of the output struct for this shader
std::string GetOutputStructName() const;
std::string GetInputStructName() const;
std::string GetCBName(const std::string& cbName) const;
// Retrieve the name of the output struct for this shader
std::string GetOutputStructName() const;
std::string GetInputStructName() const;
std::string GetCBName(const std::string& cbName) const;
void DeclareHullShaderPassthrough();
void HandleInputRedirect(const Declaration *psDecl, const std::string &typeName);
void HandleOutputRedirect(const Declaration *psDecl, const std::string &typeName);
void DeclareHullShaderPassthrough();
void HandleInputRedirect(const Declaration *psDecl, const std::string &typeName);
void HandleOutputRedirect(const Declaration *psDecl, const std::string &typeName);
void DeclareConstantBuffer(const ConstantBuffer *psCBuf, uint32_t ui32BindingPoint);
void DeclareStructType(const std::string &name, const std::vector<ShaderVar> &contents, bool withinCB = false, uint32_t cumulativeOffset = 0, bool stripUnused = false);
void DeclareStructType(const std::string &name, const std::vector<ShaderVarType> &contents, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareStructVariable(const std::string &parentName, const ShaderVar &var, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareStructVariable(const std::string &parentName, const ShaderVarType &var, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareBufferVariable(const Declaration *psDecl, bool isRaw, bool isUAV);
void DeclareConstantBuffer(const ConstantBuffer *psCBuf, uint32_t ui32BindingPoint);
void DeclareStructType(const std::string &name, const std::vector<ShaderVar> &contents, bool withinCB = false, uint32_t cumulativeOffset = 0, bool stripUnused = false);
void DeclareStructType(const std::string &name, const std::vector<ShaderVarType> &contents, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareStructVariable(const std::string &parentName, const ShaderVar &var, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareStructVariable(const std::string &parentName, const ShaderVarType &var, bool withinCB = false, uint32_t cumulativeOffset = 0);
void DeclareBufferVariable(const Declaration *psDecl, bool isRaw, bool isUAV);
void DeclareResource(const Declaration *psDecl);
void TranslateResourceTexture(const Declaration* psDecl, uint32_t samplerCanDoShadowCmp, HLSLCC_TEX_DIMENSION texDim);
void DeclareResource(const Declaration *psDecl);
void TranslateResourceTexture(const Declaration* psDecl, uint32_t samplerCanDoShadowCmp, HLSLCC_TEX_DIMENSION texDim);
void DeclareOutput(const Declaration *decl);
void DeclareOutput(const Declaration *decl);
void PrintStructDeclarations(StructDefinitions &defs, const char *name = "");
void PrintStructDeclarations(StructDefinitions &defs, const char *name = "");
std::string ResourceName(ResourceGroup group, const uint32_t ui32RegisterNumber);
std::string ResourceName(ResourceGroup group, const uint32_t ui32RegisterNumber);
// ToMetalOperand.cpp
std::string TranslateOperandSwizzle(const Operand* psOperand, uint32_t ui32ComponentMask, int iRebase, bool includeDot = true);
std::string TranslateOperandIndex(const Operand* psOperand, int index);
std::string TranslateVariableName(const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
// ToMetalOperand.cpp
std::string TranslateOperandSwizzle(const Operand* psOperand, uint32_t ui32ComponentMask, int iRebase, bool includeDot = true);
std::string TranslateOperandIndex(const Operand* psOperand, int index);
std::string TranslateVariableName(const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle, uint32_t ui32CompMask, int *piRebase);
// ToMetalInstruction.cpp
// ToMetalInstruction.cpp
void AddOpAssignToDestWithMask(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, const char *szAssignmentOp, int *pNeedsParenthesis, uint32_t ui32CompMask);
void AddAssignToDest(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, int* pNeedsParenthesis);
void AddAssignPrologue(int numParenthesis);
void AddOpAssignToDestWithMask(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, const char *szAssignmentOp, int *pNeedsParenthesis, uint32_t ui32CompMask);
void AddAssignToDest(const Operand* psDest,
SHADER_VARIABLE_TYPE eSrcType, uint32_t ui32SrcElementCount, int* pNeedsParenthesis);
void AddAssignPrologue(int numParenthesis);
typedef enum
{
CMP_EQ,
CMP_LT,
CMP_GE,
CMP_NE,
} ComparisonType;
typedef enum
{
CMP_EQ,
CMP_LT,
CMP_GE,
CMP_NE,
} ComparisonType;
void AddComparison(Instruction* psInst, ComparisonType eType,
uint32_t typeFlag);
void AddComparison(Instruction* psInst, ComparisonType eType,
uint32_t typeFlag);
bool CanForceToHalfOperand(const Operand *psOperand);
bool CanForceToHalfOperand(const Operand *psOperand);
void AddMOVBinaryOp(const Operand *pDest, Operand *pSrc);
void AddMOVCBinaryOp(const Operand *pDest, const Operand *src0, Operand *src1, Operand *src2);
void CallBinaryOp(const char* name, Instruction* psInst,
int dest, int src0, int src1, SHADER_VARIABLE_TYPE eDataType);
void CallTernaryOp(const char* op1, const char* op2, Instruction* psInst,
int dest, int src0, int src1, int src2, uint32_t dataType);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask, uint32_t ui32Flags);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask);
void CallHelper2(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2Int(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2UInt(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper1(const char* name, Instruction* psInst,
int dest, int src0, int paramsShouldFollowWriteMask);
void CallHelper1Int(
const char* name,
Instruction* psInst,
const int dest,
const int src0,
int paramsShouldFollowWriteMask);
void TranslateTexelFetch(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexelFetchOffset(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexCoord(
const RESOURCE_DIMENSION eResDim,
Operand* psTexCoordOperand);
void GetResInfoData(Instruction* psInst, int index, int destElem);
void TranslateTextureSample(Instruction* psInst,
uint32_t ui32Flags);
void TranslateDynamicComponentSelection(const ShaderVarType* psVarType,
const Operand* psByteAddr, uint32_t offset, uint32_t mask);
void TranslateShaderStorageStore(Instruction* psInst);
void TranslateShaderStorageLoad(Instruction* psInst);
void TranslateAtomicMemOp(Instruction* psInst);
void TranslateConditional(
Instruction* psInst,
bstring glsl);
void AddMOVBinaryOp(const Operand *pDest, Operand *pSrc);
void AddMOVCBinaryOp(const Operand *pDest, const Operand *src0, Operand *src1, Operand *src2);
void CallBinaryOp(const char* name, Instruction* psInst,
int dest, int src0, int src1, SHADER_VARIABLE_TYPE eDataType);
void CallTernaryOp(const char* op1, const char* op2, Instruction* psInst,
int dest, int src0, int src1, int src2, uint32_t dataType);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask, uint32_t ui32Flags);
void CallHelper3(const char* name, Instruction* psInst,
int dest, int src0, int src1, int src2, int paramsShouldFollowWriteMask);
void CallHelper2(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2Int(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper2UInt(const char* name, Instruction* psInst,
int dest, int src0, int src1, int paramsShouldFollowWriteMask);
void CallHelper1(const char* name, Instruction* psInst,
int dest, int src0, int paramsShouldFollowWriteMask);
void CallHelper1Int(
const char* name,
Instruction* psInst,
const int dest,
const int src0,
int paramsShouldFollowWriteMask);
void TranslateTexelFetch(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexelFetchOffset(
Instruction* psInst,
const ResourceBinding* psBinding,
bstring glsl);
void TranslateTexCoord(
const RESOURCE_DIMENSION eResDim,
Operand* psTexCoordOperand);
void GetResInfoData(Instruction* psInst, int index, int destElem);
void TranslateTextureSample(Instruction* psInst,
uint32_t ui32Flags);
void TranslateDynamicComponentSelection(const ShaderVarType* psVarType,
const Operand* psByteAddr, uint32_t offset, uint32_t mask);
void TranslateShaderStorageStore(Instruction* psInst);
void TranslateShaderStorageLoad(Instruction* psInst);
void TranslateAtomicMemOp(Instruction* psInst);
void TranslateConditional(
Instruction* psInst,
bstring glsl);
// The map is keyed by struct name. The special name "" (empty string) is reserved for entry point function parameters
StructDefinitions m_StructDefinitions;
// The map is keyed by struct name. The special name "" (empty string) is reserved for entry point function parameters
StructDefinitions m_StructDefinitions;
// A <function name, body text> map of extra helper functions we'll need.
FunctionDefinitions m_FunctionDefinitions;
// A <function name, body text> map of extra helper functions we'll need.
FunctionDefinitions m_FunctionDefinitions;
BindingSlotAllocator m_TextureSlots, m_SamplerSlots;
BindingSlotAllocator m_BufferSlots;
BindingSlotAllocator m_TextureSlots, m_SamplerSlots;
BindingSlotAllocator m_BufferSlots;
std::vector<SamplerDesc> m_Samplers;
std::vector<TextureSamplerDesc> m_Textures;
std::vector<SamplerDesc> m_Samplers;
std::vector<TextureSamplerDesc> m_Textures;
std::string m_ExtraGlobalDefinitions;
std::string m_ExtraGlobalDefinitions;
// Flags for whether we need to add the declaration for the FB IO remaps
bool m_NeedFBInputRemapDecl;
bool m_NeedFBOutputRemapDecl;
bool m_ShadowSamplerDeclared;
void EnsureShadowSamplerDeclared();
bool m_ShadowSamplerDeclared;
// Add an extra function to the m_FunctionDefinitions list, unless it's already there.
void DeclareExtraFunction(const std::string &name, const std::string &body);
void EnsureShadowSamplerDeclared();
// Move all lowp -> mediump
void ClampPartialPrecisions();
// Reseve UAV slots in advance to match the original HLSL bindings -> correct bindings in SetRandomWriteTarget()
void ReserveUAVBindingSlots(ShaderPhase *phase);
// Add an extra function to the m_FunctionDefinitions list, unless it's already there.
void DeclareExtraFunction(const std::string &name, const std::string &body);
// Move all lowp -> mediump
void ClampPartialPrecisions();
// Reseve UAV slots in advance to match the original HLSL bindings -> correct bindings in SetRandomWriteTarget()
void ReserveUAVBindingSlots(ShaderPhase *phase);
};

Просмотреть файл

@ -1,3 +1,3 @@
#pragma once
#include "internal_includes/Declaration.h"
#include "internal_includes/Declaration.h"

Просмотреть файл

@ -5,17 +5,17 @@
enum SHADER_PHASE_TYPE
{
SHADER_PHASE_INVALID = -1,
MAIN_PHASE = 0,
HS_GLOBAL_DECL_PHASE = 1,
HS_CTRL_POINT_PHASE = 2,
HS_FORK_PHASE = 3,
HS_JOIN_PHASE = 4
SHADER_PHASE_INVALID = -1,
MAIN_PHASE = 0,
HS_GLOBAL_DECL_PHASE = 1,
HS_CTRL_POINT_PHASE = 2,
HS_FORK_PHASE = 3,
HS_JOIN_PHASE = 4
};
static SHADER_TYPE DecodeShaderType(uint32_t ui32Token)
{
return (SHADER_TYPE)((ui32Token & 0xffff0000) >> 16);
return (SHADER_TYPE)((ui32Token & 0xffff0000) >> 16);
}
static uint32_t DecodeProgramMajorVersion(uint32_t ui32Token)
@ -51,25 +51,24 @@ static EXTENDED_OPCODE_TYPE DecodeExtendedOpcodeType(uint32_t ui32Token)
return (EXTENDED_OPCODE_TYPE)(ui32Token & 0x0000003f);
}
static RESOURCE_RETURN_TYPE DecodeResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token)
{
return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4))&0xF);
return (RESOURCE_RETURN_TYPE)((ui32Token >> (ui32Coord * 4)) & 0xF);
}
static RESOURCE_RETURN_TYPE DecodeExtendedResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token)
{
return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4 + 6))&0xF);
return (RESOURCE_RETURN_TYPE)((ui32Token >> (ui32Coord * 4 + 6)) & 0xF);
}
enum OPCODE_TYPE
{
//For DX9
OPCODE_POW = -6,
OPCODE_DP2ADD = -5,
OPCODE_LRP = -4,
OPCODE_ENDREP = -3,
OPCODE_REP = -2,
OPCODE_POW = -6,
OPCODE_DP2ADD = -5,
OPCODE_LRP = -4,
OPCODE_ENDREP = -3,
OPCODE_REP = -2,
OPCODE_SPECIAL_DCL_IMMCONST = -1,
OPCODE_ADD,
@ -183,7 +182,7 @@ enum OPCODE_TYPE
// -----------------------------------------------
OPCODE_RESERVED_10,
// ---------- DX 10.1 op codes---------------------
OPCODE_LOD,
@ -234,7 +233,7 @@ enum OPCODE_TYPE
OPCODE_DCL_FUNCTION_BODY,
OPCODE_DCL_FUNCTION_TABLE,
OPCODE_DCL_INTERFACE,
OPCODE_DCL_INPUT_CONTROL_POINT_COUNT,
OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT,
OPCODE_DCL_TESS_DOMAIN,
@ -278,9 +277,9 @@ enum OPCODE_TYPE
OPCODE_IMM_ATOMIC_IMAX,
OPCODE_IMM_ATOMIC_IMIN,
OPCODE_IMM_ATOMIC_UMAX,
OPCODE_IMM_ATOMIC_UMIN,
OPCODE_IMM_ATOMIC_UMIN,
OPCODE_SYNC,
OPCODE_DADD,
OPCODE_DMAX,
OPCODE_DMIN,
@ -297,7 +296,7 @@ enum OPCODE_TYPE
OPCODE_EVAL_SNAPPED,
OPCODE_EVAL_SAMPLE_INDEX,
OPCODE_EVAL_CENTROID,
OPCODE_DCL_GS_INSTANCE_COUNT,
OPCODE_ABORT,
@ -343,14 +342,14 @@ typedef enum
static OPERAND_INDEX_DIMENSION DecodeOperandIndexDimension(uint32_t ui32Token)
{
return (OPERAND_INDEX_DIMENSION)((ui32Token & 0x00300000) >> 20);
return (OPERAND_INDEX_DIMENSION)((ui32Token & 0x00300000) >> 20);
}
typedef enum OPERAND_TYPE
{
OPERAND_TYPE_SPECIAL_LOOPCOUNTER = -10,
OPERAND_TYPE_SPECIAL_IMMCONSTINT = -9,
OPERAND_TYPE_SPECIAL_TEXCOORD = -8,
OPERAND_TYPE_SPECIAL_IMMCONSTINT = -9,
OPERAND_TYPE_SPECIAL_TEXCOORD = -8,
OPERAND_TYPE_SPECIAL_POSITION = -7,
OPERAND_TYPE_SPECIAL_FOG = -6,
OPERAND_TYPE_SPECIAL_POINTSIZE = -5,
@ -363,25 +362,25 @@ typedef enum OPERAND_TYPE
OPERAND_TYPE_OUTPUT = 2, // General Output Register File
OPERAND_TYPE_INDEXABLE_TEMP = 3, // Temporary Register File (indexable)
OPERAND_TYPE_IMMEDIATE32 = 4, // 32bit/component immediate value(s)
// If for example, operand token bits
// [01:00]==OPERAND_4_COMPONENT,
// this means that the operand type:
// OPERAND_TYPE_IMMEDIATE32
// results in 4 additional 32bit
// DWORDS present for the operand.
// If for example, operand token bits
// [01:00]==OPERAND_4_COMPONENT,
// this means that the operand type:
// OPERAND_TYPE_IMMEDIATE32
// results in 4 additional 32bit
// DWORDS present for the operand.
OPERAND_TYPE_IMMEDIATE64 = 5, // 64bit/comp.imm.val(s)HI:LO
OPERAND_TYPE_SAMPLER = 6, // Reference to sampler state
OPERAND_TYPE_RESOURCE = 7, // Reference to memory resource (e.g. texture)
OPERAND_TYPE_CONSTANT_BUFFER= 8, // Reference to constant buffer
OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER= 9, // Reference to immediate constant buffer
OPERAND_TYPE_CONSTANT_BUFFER = 8, // Reference to constant buffer
OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER = 9, // Reference to immediate constant buffer
OPERAND_TYPE_LABEL = 10, // Label
OPERAND_TYPE_INPUT_PRIMITIVEID = 11, // Input primitive ID
OPERAND_TYPE_OUTPUT_DEPTH = 12, // Output Depth
OPERAND_TYPE_NULL = 13, // Null register, used to discard results of operations
// Below Are operands new in DX 10.1
// Below Are operands new in DX 10.1
OPERAND_TYPE_RASTERIZER = 14, // DX10.1 Rasterizer register, used to denote the depth/stencil and render target resources
OPERAND_TYPE_OUTPUT_COVERAGE_MASK = 15, // DX10.1 PS output MSAA coverage mask (scalar)
// Below Are operands new in DX 11
// Below Are operands new in DX 11
OPERAND_TYPE_STREAM = 16, // Reference to GS stream output resource
OPERAND_TYPE_FUNCTION_BODY = 17, // Reference to a function definition
OPERAND_TYPE_FUNCTION_TABLE = 18, // Reference to a set of functions used by a class
@ -411,30 +410,30 @@ typedef enum OPERAND_TYPE
static OPERAND_TYPE DecodeOperandType(uint32_t ui32Token)
{
return (OPERAND_TYPE)((ui32Token & 0x000ff000) >> 12);
return (OPERAND_TYPE)((ui32Token & 0x000ff000) >> 12);
}
static SPECIAL_NAME DecodeOperandSpecialName(uint32_t ui32Token)
{
return (SPECIAL_NAME)(ui32Token & 0x0000ffff);
return (SPECIAL_NAME)(ui32Token & 0x0000ffff);
}
typedef enum OPERAND_INDEX_REPRESENTATION
{
OPERAND_INDEX_IMMEDIATE32 = 0, // Extra DWORD
OPERAND_INDEX_IMMEDIATE64 = 1, // 2 Extra DWORDs
// (HI32:LO32)
// (HI32:LO32)
OPERAND_INDEX_RELATIVE = 2, // Extra operand
OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE = 3, // Extra DWORD followed by
// extra operand
// extra operand
OPERAND_INDEX_IMMEDIATE64_PLUS_RELATIVE = 4, // 2 Extra DWORDS
// (HI32:LO32) followed
// by extra operand
// (HI32:LO32) followed
// by extra operand
} OPERAND_INDEX_REPRESENTATION;
static OPERAND_INDEX_REPRESENTATION DecodeOperandIndexRepresentation(uint32_t ui32Dimension, uint32_t ui32Token)
{
return (OPERAND_INDEX_REPRESENTATION)((ui32Token & (0x3<<(22+3*((ui32Dimension)&3)))) >> (22+3*((ui32Dimension)&3)));
return (OPERAND_INDEX_REPRESENTATION)((ui32Token & (0x3 << (22 + 3 * ((ui32Dimension) & 3)))) >> (22 + 3 * ((ui32Dimension) & 3)));
}
typedef enum OPERAND_NUM_COMPONENTS
@ -447,7 +446,7 @@ typedef enum OPERAND_NUM_COMPONENTS
static OPERAND_NUM_COMPONENTS DecodeOperandNumComponents(uint32_t ui32Token)
{
return (OPERAND_NUM_COMPONENTS)(ui32Token & 0x00000003);
return (OPERAND_NUM_COMPONENTS)(ui32Token & 0x00000003);
}
typedef enum OPERAND_4_COMPONENT_SELECTION_MODE
@ -459,7 +458,7 @@ typedef enum OPERAND_4_COMPONENT_SELECTION_MODE
static OPERAND_4_COMPONENT_SELECTION_MODE DecodeOperand4CompSelMode(uint32_t ui32Token)
{
return (OPERAND_4_COMPONENT_SELECTION_MODE)((ui32Token & 0x0000000c) >> 2);
return (OPERAND_4_COMPONENT_SELECTION_MODE)((ui32Token & 0x0000000c) >> 2);
}
#define OPERAND_4_COMPONENT_MASK_X 0x00000001
@ -474,17 +473,17 @@ static OPERAND_4_COMPONENT_SELECTION_MODE DecodeOperand4CompSelMode(uint32_t ui3
static uint32_t DecodeOperand4CompMask(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x000000f0) >> 4);
return (uint32_t)((ui32Token & 0x000000f0) >> 4);
}
static uint32_t DecodeOperand4CompSwizzle(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x00000ff0) >> 4);
return (uint32_t)((ui32Token & 0x00000ff0) >> 4);
}
static uint32_t DecodeOperand4CompSel1(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x00000030) >> 4);
return (uint32_t)((ui32Token & 0x00000030) >> 4);
}
#define OPERAND_4_COMPONENT_X 0
@ -492,7 +491,7 @@ static uint32_t DecodeOperand4CompSel1(uint32_t ui32Token)
#define OPERAND_4_COMPONENT_Z 2
#define OPERAND_4_COMPONENT_W 3
static const uint32_t NO_SWIZZLE = (( (OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_Y<<2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_W << 6))/*<<4*/);
static const uint32_t NO_SWIZZLE = (((OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_Y << 2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_W << 6)) /*<<4*/);
static const uint32_t XXXX_SWIZZLE = (((OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_X << 2) | (OPERAND_4_COMPONENT_X << 4) | (OPERAND_4_COMPONENT_X << 6)));
static const uint32_t YYYY_SWIZZLE = (((OPERAND_4_COMPONENT_Y) | (OPERAND_4_COMPONENT_Y << 2) | (OPERAND_4_COMPONENT_Y << 4) | (OPERAND_4_COMPONENT_Y << 6)));
@ -501,7 +500,7 @@ static const uint32_t WWWW_SWIZZLE = (((OPERAND_4_COMPONENT_W) | (OPERAND_4_COMP
static uint32_t DecodeOperand4CompSwizzleSource(uint32_t ui32Token, uint32_t comp)
{
return (uint32_t)(((ui32Token)>>(4+2*((comp)&3)))&3);
return (uint32_t)(((ui32Token) >> (4 + 2 * ((comp) & 3))) & 3);
}
typedef enum RESOURCE_DIMENSION
@ -523,12 +522,12 @@ typedef enum RESOURCE_DIMENSION
static RESOURCE_DIMENSION DecodeResourceDimension(uint32_t ui32Token)
{
return (RESOURCE_DIMENSION)((ui32Token & 0x0000f800) >> 11);
return (RESOURCE_DIMENSION)((ui32Token & 0x0000f800) >> 11);
}
static RESOURCE_DIMENSION DecodeExtendedResourceDimension(uint32_t ui32Token)
{
return (RESOURCE_DIMENSION)((ui32Token & 0x000007C0) >> 6);
return (RESOURCE_DIMENSION)((ui32Token & 0x000007C0) >> 6);
}
typedef enum INSTRUCTION_TEST_BOOLEAN
@ -539,7 +538,7 @@ typedef enum INSTRUCTION_TEST_BOOLEAN
static INSTRUCTION_TEST_BOOLEAN DecodeInstrTestBool(uint32_t ui32Token)
{
return (INSTRUCTION_TEST_BOOLEAN)((ui32Token & 0x00040000) >> 18);
return (INSTRUCTION_TEST_BOOLEAN)((ui32Token & 0x00040000) >> 18);
}
static uint32_t DecodeIsOperandExtended(uint32_t ui32Token)
@ -555,7 +554,7 @@ typedef enum EXTENDED_OPERAND_TYPE
static EXTENDED_OPERAND_TYPE DecodeExtendedOperandType(uint32_t ui32Token)
{
return (EXTENDED_OPERAND_TYPE)(ui32Token & 0x0000003f);
return (EXTENDED_OPERAND_TYPE)(ui32Token & 0x0000003f);
}
typedef enum OPERAND_MODIFIER
@ -568,29 +567,28 @@ typedef enum OPERAND_MODIFIER
static OPERAND_MODIFIER DecodeExtendedOperandModifier(uint32_t ui32Token)
{
return (OPERAND_MODIFIER)((ui32Token & 0x00003fc0) >> 6);
return (OPERAND_MODIFIER)((ui32Token & 0x00003fc0) >> 6);
}
static const uint32_t GLOBAL_FLAG_REFACTORING_ALLOWED = (1<<11);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = (1<<12);
static const uint32_t GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL = (1<<13);
static const uint32_t GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS = (1<<14);
static const uint32_t GLOBAL_FLAG_SKIP_OPTIMIZATION = (1<<15);
static const uint32_t GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION = (1<<16);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS = (1<<17);
static const uint32_t GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS = (1<<18);
static const uint32_t GLOBAL_FLAG_REFACTORING_ALLOWED = (1 << 11);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = (1 << 12);
static const uint32_t GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL = (1 << 13);
static const uint32_t GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS = (1 << 14);
static const uint32_t GLOBAL_FLAG_SKIP_OPTIMIZATION = (1 << 15);
static const uint32_t GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION = (1 << 16);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS = (1 << 17);
static const uint32_t GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS = (1 << 18);
static uint32_t DecodeGlobalFlags(uint32_t ui32Token)
{
return (uint32_t)(ui32Token & 0x00fff800);
return (uint32_t)(ui32Token & 0x00fff800);
}
static INTERPOLATION_MODE DecodeInterpolationMode(uint32_t ui32Token)
{
return (INTERPOLATION_MODE)((ui32Token & 0x00007800) >> 11);
return (INTERPOLATION_MODE)((ui32Token & 0x00007800) >> 11);
}
typedef enum PRIMITIVE_TOPOLOGY
{
PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
@ -609,7 +607,7 @@ typedef enum PRIMITIVE_TOPOLOGY
static PRIMITIVE_TOPOLOGY DecodeGSOutputPrimitiveTopology(uint32_t ui32Token)
{
return (PRIMITIVE_TOPOLOGY)((ui32Token & 0x0001f800) >> 11);
return (PRIMITIVE_TOPOLOGY)((ui32Token & 0x0001f800) >> 11);
}
typedef enum PRIMITIVE
@ -657,22 +655,22 @@ typedef enum PRIMITIVE
static PRIMITIVE DecodeGSInputPrimitive(uint32_t ui32Token)
{
return (PRIMITIVE)((ui32Token & 0x0001f800) >> 11);
return (PRIMITIVE)((ui32Token & 0x0001f800) >> 11);
}
static TESSELLATOR_PARTITIONING DecodeTessPartitioning(uint32_t ui32Token)
{
return (TESSELLATOR_PARTITIONING)((ui32Token & 0x00003800) >> 11);
return (TESSELLATOR_PARTITIONING)((ui32Token & 0x00003800) >> 11);
}
static TESSELLATOR_DOMAIN DecodeTessDomain(uint32_t ui32Token)
{
return (TESSELLATOR_DOMAIN)((ui32Token & 0x00001800) >> 11);
return (TESSELLATOR_DOMAIN)((ui32Token & 0x00001800) >> 11);
}
static TESSELLATOR_OUTPUT_PRIMITIVE DecodeTessOutPrim(uint32_t ui32Token)
{
return (TESSELLATOR_OUTPUT_PRIMITIVE)((ui32Token & 0x00003800) >> 11);
return (TESSELLATOR_OUTPUT_PRIMITIVE)((ui32Token & 0x00003800) >> 11);
}
static const uint32_t SYNC_THREADS_IN_GROUP = 0x00000800;
@ -682,19 +680,19 @@ static const uint32_t SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GLOBAL = 0x00004000;
static uint32_t DecodeSyncFlags(uint32_t ui32Token)
{
return ui32Token & 0x00007800;
return ui32Token & 0x00007800;
}
// The number of types that implement this interface
static uint32_t DecodeInterfaceTableLength(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x0000ffff) >> 0);
return (uint32_t)((ui32Token & 0x0000ffff) >> 0);
}
// The number of interfaces that are defined in this array.
static uint32_t DecodeInterfaceArrayLength(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0xffff0000) >> 16);
return (uint32_t)((ui32Token & 0xffff0000) >> 16);
}
typedef enum CUSTOMDATA_CLASS
@ -708,7 +706,7 @@ typedef enum CUSTOMDATA_CLASS
static CUSTOMDATA_CLASS DecodeCustomDataClass(uint32_t ui32Token)
{
return (CUSTOMDATA_CLASS)((ui32Token & 0xfffff800) >> 11);
return (CUSTOMDATA_CLASS)((ui32Token & 0xfffff800) >> 11);
}
static uint32_t DecodeInstructionSaturate(uint32_t ui32Token)
@ -718,8 +716,8 @@ static uint32_t DecodeInstructionSaturate(uint32_t ui32Token)
typedef enum OPERAND_MIN_PRECISION
{
OPERAND_MIN_PRECISION_DEFAULT = 0, // Default precision
// for the shader model
OPERAND_MIN_PRECISION_DEFAULT = 0, // Default precision
// for the shader model
OPERAND_MIN_PRECISION_FLOAT_16 = 1, // Min 16 bit/component float
OPERAND_MIN_PRECISION_FLOAT_2_8 = 2, // Min 10(2.8)bit/comp. float
OPERAND_MIN_PRECISION_SINT_16 = 4, // Min 16 bit/comp. signed integer
@ -733,7 +731,7 @@ static uint32_t DecodeOperandMinPrecision(uint32_t ui32Token)
static uint32_t DecodeOutputControlPointCount(uint32_t ui32Token)
{
return ((ui32Token & 0x0001f800) >> 11);
return ((ui32Token & 0x0001f800) >> 11);
}
typedef enum IMMEDIATE_ADDRESS_OFFSET_COORD
@ -749,7 +747,7 @@ typedef enum IMMEDIATE_ADDRESS_OFFSET_COORD
static uint32_t DecodeImmediateAddressOffset(IMMEDIATE_ADDRESS_OFFSET_COORD eCoord, uint32_t ui32Token)
{
return ((((ui32Token)&IMMEDIATE_ADDRESS_OFFSET_MASK(eCoord))>>(IMMEDIATE_ADDRESS_OFFSET_SHIFT(eCoord))));
return ((((ui32Token) & IMMEDIATE_ADDRESS_OFFSET_MASK(eCoord)) >> (IMMEDIATE_ADDRESS_OFFSET_SHIFT(eCoord))));
}
// UAV access scope flags
@ -759,7 +757,6 @@ static uint32_t DecodeAccessCoherencyFlags(uint32_t ui32Token)
return ui32Token & 0x00010000;
}
typedef enum RESINFO_RETURN_TYPE
{
RESINFO_INSTRUCTION_RETURN_FLOAT = 0,
@ -774,15 +771,14 @@ static RESINFO_RETURN_TYPE DecodeResInfoReturnType(uint32_t ui32Token)
typedef enum SB_SAMPLER_MODE
{
D3D10_SB_SAMPLER_MODE_DEFAULT = 0,
D3D10_SB_SAMPLER_MODE_COMPARISON = 1,
D3D10_SB_SAMPLER_MODE_MONO = 2,
D3D10_SB_SAMPLER_MODE_DEFAULT = 0,
D3D10_SB_SAMPLER_MODE_COMPARISON = 1,
D3D10_SB_SAMPLER_MODE_MONO = 2,
} SB_SAMPLER_MODE;
static SB_SAMPLER_MODE DecodeSamplerMode(uint32_t ui32Token)
{
return (SB_SAMPLER_MODE)((ui32Token & 0x00001800) >> 11);
return (SB_SAMPLER_MODE)((ui32Token & 0x00001800) >> 11);
}
#endif

Просмотреть файл

@ -1,4 +1,3 @@
#include "internal_includes/reflect.h"
#include "internal_includes/debug.h"
#include "internal_includes/decode.h"
@ -18,11 +17,11 @@ static void FormatVariableName(std::string & Name)
/* Leave $ThisPointer, $Element and $Globals as-is.
Otherwise remove $ character ($ is not a valid character for GLSL variable names). */
if(Name[0] == '$')
if (Name[0] == '$')
{
if(strcmp(Name.c_str(), "$Element") !=0 &&
strcmp(Name.c_str(), "$Globals") != 0 &&
strcmp(Name.c_str(), "$ThisPointer") != 0)
if (strcmp(Name.c_str(), "$Element") != 0 &&
strcmp(Name.c_str(), "$Globals") != 0 &&
strcmp(Name.c_str(), "$ThisPointer") != 0)
{
Name[0] = '_';
}
@ -31,25 +30,25 @@ static void FormatVariableName(std::string & Name)
static std::string ReadStringFromTokenStream(const uint32_t* tokens)
{
char* charTokens = (char*) tokens;
return std::string(charTokens);
char* charTokens = (char*)tokens;
return std::string(charTokens);
}
static int MaskToRebaseOffset(const uint32_t mask)
{
int res = 0;
uint32_t m = mask;
while ((m & 1) == 0)
{
res++;
m = m >> 1;
}
return res;
int res = 0;
uint32_t m = mask;
while ((m & 1) == 0)
{
res++;
m = m >> 1;
}
return res;
}
static void ReadInputSignatures(const uint32_t* pui32Tokens,
ShaderInfo* psShaderInfo,
const int extended)
ShaderInfo* psShaderInfo,
const int extended)
{
uint32_t i;
@ -57,44 +56,44 @@ static void ReadInputSignatures(const uint32_t* pui32Tokens,
const uint32_t ui32ElementCount = *pui32Tokens++;
/* const uint32_t ui32Key = * */ pui32Tokens++;
psShaderInfo->psInputSignatures.clear();
psShaderInfo->psInputSignatures.resize(ui32ElementCount);
psShaderInfo->psInputSignatures.clear();
psShaderInfo->psInputSignatures.resize(ui32ElementCount);
for(i=0; i<ui32ElementCount; ++i)
for (i = 0; i < ui32ElementCount; ++i)
{
uint32_t ui32ComponentMasks;
ShaderInfo::InOutSignature* psCurrentSignature = &psShaderInfo->psInputSignatures[i];
uint32_t ui32SemanticNameOffset;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
if(extended)
psCurrentSignature->ui32Stream = *pui32Tokens++;
if (extended)
psCurrentSignature->ui32Stream = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
psCurrentSignature->ui32SemanticIndex = *pui32Tokens++;
psCurrentSignature->eSystemValueType = (SPECIAL_NAME) *pui32Tokens++;
psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *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;
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
if(extended)
psCurrentSignature->eMinPrec = (MIN_PRECISION) *pui32Tokens++;
if (extended)
psCurrentSignature->eMinPrec = (MIN_PRECISION)*pui32Tokens++;
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken+ui32SemanticNameOffset));
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken + ui32SemanticNameOffset));
}
}
static void ReadOutputSignatures(const uint32_t* pui32Tokens,
ShaderInfo* psShaderInfo,
const int minPrec,
const int streams)
ShaderInfo* psShaderInfo,
const int minPrec,
const int streams)
{
uint32_t i;
@ -102,50 +101,50 @@ static void ReadOutputSignatures(const uint32_t* pui32Tokens,
const uint32_t ui32ElementCount = *pui32Tokens++;
/*const uint32_t ui32Key = * */ pui32Tokens++;
psShaderInfo->psOutputSignatures.clear();
psShaderInfo->psOutputSignatures.resize(ui32ElementCount);
psShaderInfo->psOutputSignatures.clear();
psShaderInfo->psOutputSignatures.resize(ui32ElementCount);
for(i=0; i<ui32ElementCount; ++i)
for (i = 0; i < ui32ElementCount; ++i)
{
uint32_t ui32ComponentMasks;
ShaderInfo::InOutSignature* psCurrentSignature = &psShaderInfo->psOutputSignatures[i];
uint32_t ui32SemanticNameOffset;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
if(streams)
psCurrentSignature->ui32Stream = *pui32Tokens++;
if (streams)
psCurrentSignature->ui32Stream = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
psCurrentSignature->ui32SemanticIndex = *pui32Tokens++;
psCurrentSignature->eSystemValueType = (SPECIAL_NAME)*pui32Tokens++;
psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *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;
}
// 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;
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
if(minPrec)
psCurrentSignature->eMinPrec = (MIN_PRECISION)*pui32Tokens++;
if (minPrec)
psCurrentSignature->eMinPrec = (MIN_PRECISION)*pui32Tokens++;
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken + ui32SemanticNameOffset));
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken + ui32SemanticNameOffset));
}
}
static void ReadPatchConstantSignatures(const uint32_t* pui32Tokens,
ShaderInfo* psShaderInfo,
const int minPrec,
const int streams)
ShaderInfo* psShaderInfo,
const int minPrec,
const int streams)
{
uint32_t i;
@ -153,43 +152,43 @@ static void ReadPatchConstantSignatures(const uint32_t* pui32Tokens,
const uint32_t ui32ElementCount = *pui32Tokens++;
/*const uint32_t ui32Key = * */ pui32Tokens++;
psShaderInfo->psPatchConstantSignatures.clear();
psShaderInfo->psPatchConstantSignatures.resize(ui32ElementCount);
psShaderInfo->psPatchConstantSignatures.clear();
psShaderInfo->psPatchConstantSignatures.resize(ui32ElementCount);
for(i=0; i<ui32ElementCount; ++i)
for (i = 0; i < ui32ElementCount; ++i)
{
uint32_t ui32ComponentMasks;
ShaderInfo::InOutSignature* psCurrentSignature = &psShaderInfo->psPatchConstantSignatures[i];
ShaderInfo::InOutSignature* psCurrentSignature = &psShaderInfo->psPatchConstantSignatures[i];
uint32_t ui32SemanticNameOffset;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
psCurrentSignature->ui32Stream = 0;
psCurrentSignature->eMinPrec = MIN_PRECISION_DEFAULT;
if(streams)
psCurrentSignature->ui32Stream = *pui32Tokens++;
if (streams)
psCurrentSignature->ui32Stream = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
ui32SemanticNameOffset = *pui32Tokens++;
psCurrentSignature->ui32SemanticIndex = *pui32Tokens++;
psCurrentSignature->eSystemValueType = (SPECIAL_NAME)*pui32Tokens++;
psCurrentSignature->eComponentType = (INOUT_COMPONENT_TYPE) *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;
}
// 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;
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
psCurrentSignature->iRebase = MaskToRebaseOffset(psCurrentSignature->ui32Mask);
if(minPrec)
psCurrentSignature->eMinPrec = (MIN_PRECISION)*pui32Tokens++;
if (minPrec)
psCurrentSignature->eMinPrec = (MIN_PRECISION)*pui32Tokens++;
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken + ui32SemanticNameOffset));
psCurrentSignature->semanticName = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstSignatureToken + ui32SemanticNameOffset));
}
}
@ -197,50 +196,50 @@ static const uint32_t* ReadResourceBinding(const uint32_t* pui32FirstResourceTok
{
uint32_t ui32NameOffset = *pui32Tokens++;
psBinding->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstResourceToken+ui32NameOffset));
psBinding->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstResourceToken + ui32NameOffset));
FormatVariableName(psBinding->name);
psBinding->eType = (ResourceType)*pui32Tokens++;
psBinding->eType = (ResourceType) * pui32Tokens++;
psBinding->ui32ReturnType = (RESOURCE_RETURN_TYPE)*pui32Tokens++;
psBinding->eDimension = (REFLECT_RESOURCE_DIMENSION)*pui32Tokens++;
psBinding->ui32NumSamples = *pui32Tokens++;
psBinding->ui32BindPoint = *pui32Tokens++;
psBinding->ui32BindCount = *pui32Tokens++;
psBinding->ui32Flags = *pui32Tokens++;
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_UNKNOWN;
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_UNKNOWN;
if (decodeFlags & HLSLCC_FLAG_SAMPLER_PRECISION_ENCODED_IN_NAME)
{
if (psBinding->name.rfind("_highp") == psBinding->name.length() - 6)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_HIGHP;
psBinding->name.resize(psBinding->name.length() - 6);
}
else if (psBinding->name.rfind("_mediump") == psBinding->name.length() - 8)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_MEDIUMP;
psBinding->name.resize(psBinding->name.length() - 8);
}
else if (psBinding->name.rfind("_lowp") == psBinding->name.length() - 5)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_LOWP;
psBinding->name.resize(psBinding->name.length() - 5);
}
}
if (decodeFlags & HLSLCC_FLAG_SAMPLER_PRECISION_ENCODED_IN_NAME)
{
if (psBinding->name.rfind("_highp") == psBinding->name.length() - 6)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_HIGHP;
psBinding->name.resize(psBinding->name.length() - 6);
}
else if (psBinding->name.rfind("_mediump") == psBinding->name.length() - 8)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_MEDIUMP;
psBinding->name.resize(psBinding->name.length() - 8);
}
else if (psBinding->name.rfind("_lowp") == psBinding->name.length() - 5)
{
psBinding->ePrecision = REFLECT_RESOURCE_PRECISION_LOWP;
psBinding->name.resize(psBinding->name.length() - 5);
}
}
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 uint32_t* pui32FirstConstBufToken,
const uint32_t* pui32tokens, ShaderVarType* varType)
{
const uint16_t* pui16Tokens = (const uint16_t*) pui32tokens;
const uint16_t* pui16Tokens = (const uint16_t*)pui32tokens;
uint16_t ui32MemberCount;
uint32_t ui32MemberOffset;
const uint32_t* pui32MemberTokens;
uint32_t i;
const uint32_t* pui32MemberTokens;
uint32_t i;
varType->Class = (SHADER_VARIABLE_CLASS)pui16Tokens[0];
varType->Type = (SHADER_VARIABLE_TYPE)pui16Tokens[1];
@ -249,41 +248,41 @@ static void ReadShaderVariableType(const uint32_t ui32MajorVersion,
varType->Elements = pui16Tokens[4];
varType->MemberCount = ui32MemberCount = pui16Tokens[5];
varType->Members.clear();
varType->Members.clear();
if(varType->ParentCount)
{
// Add empty brackets for array parents. Indices are filled in later in the printing codes.
if (varType->Parent->Elements > 1)
varType->fullName = varType->Parent->fullName + "[]." + varType->name;
else
varType->fullName = varType->Parent->fullName + "." + varType->name;
}
if (varType->ParentCount)
{
// Add empty brackets for array parents. Indices are filled in later in the printing codes.
if (varType->Parent->Elements > 1)
varType->fullName = varType->Parent->fullName + "[]." + varType->name;
else
varType->fullName = varType->Parent->fullName + "." + varType->name;
}
if(ui32MemberCount)
{
varType->Members.resize(ui32MemberCount);
if (ui32MemberCount)
{
varType->Members.resize(ui32MemberCount);
ui32MemberOffset = pui32tokens[3];
pui32MemberTokens = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberOffset);
ui32MemberOffset = pui32tokens[3];
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;
pui32MemberTokens = (const uint32_t*)((const char*)pui32FirstConstBufToken + ui32MemberOffset);
varType->Members[i].Offset = *pui32MemberTokens++;
for (i = 0; i < ui32MemberCount; ++i)
{
uint32_t ui32NameOffset = *pui32MemberTokens++;
uint32_t ui32MemberTypeOffset = *pui32MemberTokens++;
varType->Members[i].name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
varType->Members[i].Parent = varType;
varType->Members[i].ParentCount = varType->ParentCount + 1;
ReadShaderVariableType(ui32MajorVersion, pui32FirstConstBufToken,
(const uint32_t*)((const char*)pui32FirstConstBufToken+ui32MemberTypeOffset), &varType->Members[i]);
}
}
varType->Members[i].Offset = *pui32MemberTokens++;
varType->Members[i].name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
ReadShaderVariableType(ui32MajorVersion, pui32FirstConstBufToken,
(const uint32_t*)((const char*)pui32FirstConstBufToken + ui32MemberTypeOffset), &varType->Members[i]);
}
}
}
static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo,
@ -293,15 +292,15 @@ static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo,
uint32_t ui32NameOffset = *pui32Tokens++;
uint32_t ui32VarCount = *pui32Tokens++;
uint32_t ui32VarOffset = *pui32Tokens++;
const uint32_t* pui32VarToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32VarOffset);
const uint32_t* pui32VarToken = (const uint32_t*)((const char*)pui32FirstConstBufToken + ui32VarOffset);
psBuffer->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
psBuffer->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
FormatVariableName(psBuffer->name);
psBuffer->asVars.clear();
psBuffer->asVars.resize(ui32VarCount);
psBuffer->asVars.clear();
psBuffer->asVars.resize(ui32VarCount);
for(i=0; i<ui32VarCount; ++i)
for (i = 0; i < ui32VarCount; ++i)
{
//D3D11_SHADER_VARIABLE_DESC
ShaderVar * const psVar = &psBuffer->asVars[i];
@ -311,66 +310,66 @@ static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo,
ui32NameOffset = *pui32VarToken++;
psVar->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
psVar->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstConstBufToken + ui32NameOffset));
FormatVariableName(psVar->name);
psVar->ui32StartOffset = *pui32VarToken++;
psVar->ui32Size = *pui32VarToken++;
//skip ui32Flags
pui32VarToken++;
ui32TypeOffset = *pui32VarToken++;
psVar->sType.name = psVar->name;
psVar->sType.fullName = psVar->name;
psVar->sType.Parent = 0;
psVar->sType.ParentCount = 0;
psVar->sType.Offset = 0;
psVar->sType.m_IsUsed = false;
psVar->sType.name = psVar->name;
psVar->sType.fullName = psVar->name;
psVar->sType.Parent = 0;
psVar->sType.ParentCount = 0;
psVar->sType.Offset = 0;
psVar->sType.m_IsUsed = false;
ReadShaderVariableType(psShaderInfo->ui32MajorVersion, pui32FirstConstBufToken,
(const uint32_t*)((const char*)pui32FirstConstBufToken+ui32TypeOffset), &psVar->sType);
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)
if (psShaderInfo->ui32MajorVersion >= 5)
{
uint32_t i = 0;
const uint32_t ui32NumDefaultValues = psVar->ui32Size / 4;
const uint32_t* pui32DefaultValToken = (const uint32_t*)((const char*)pui32FirstConstBufToken+ui32DefaultValueOffset);
/*uint32_t StartTexture = * */ pui32VarToken++;
/*uint32_t TextureSize = * */pui32VarToken++;
/*uint32_t StartSampler = * */ pui32VarToken++;
/*uint32_t SamplerSize = * */pui32VarToken++;
}
//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 = 0;
psVar->haveDefaultValue = 1;
if (ui32DefaultValueOffset)
{
uint32_t i = 0;
const uint32_t ui32NumDefaultValues = psVar->ui32Size / 4;
const uint32_t* pui32DefaultValToken = (const uint32_t*)((const char*)pui32FirstConstBufToken + ui32DefaultValueOffset);
psVar->pui32DefaultValues.clear();
psVar->pui32DefaultValues.resize(psVar->ui32Size / 4);
//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);
for(i=0; i<ui32NumDefaultValues;++i)
{
psVar->pui32DefaultValues[i] = pui32DefaultValToken[i];
}
psVar->haveDefaultValue = 1;
psVar->pui32DefaultValues.clear();
psVar->pui32DefaultValues.resize(psVar->ui32Size / 4);
for (i = 0; i < ui32NumDefaultValues; ++i)
{
psVar->pui32DefaultValues[i] = pui32DefaultValToken[i];
}
}
}
{
psBuffer->ui32TotalSizeInBytes = *pui32Tokens++;
//skip ui32Flags
pui32Tokens++;
//skip ui32BufferType
@ -381,8 +380,8 @@ static const uint32_t* ReadConstantBuffer(ShaderInfo* psShaderInfo,
}
static void ReadResources(const uint32_t* pui32Tokens,//in
ShaderInfo* psShaderInfo, //out
uint32_t decodeFlags)
ShaderInfo* psShaderInfo, //out
uint32_t decodeFlags)
{
ResourceBinding* psResBindings;
ConstantBuffer* psConstantBuffers;
@ -391,7 +390,7 @@ static void ReadResources(const uint32_t* pui32Tokens,//in
const uint32_t* pui32FirstToken = pui32Tokens;
uint32_t i;
const uint32_t ui32NumConstantBuffers = *pui32Tokens++;
const uint32_t ui32NumConstantBuffers = *pui32Tokens++;
const uint32_t ui32ConstantBufferOffset = *pui32Tokens++;
uint32_t ui32NumResourceBindings = *pui32Tokens++;
@ -402,63 +401,63 @@ static void ReadResources(const uint32_t* pui32Tokens,//in
//Resources
pui32ResourceBindings = (const uint32_t*)((const char*)pui32FirstToken + ui32ResourceBindingOffset);
psShaderInfo->psResourceBindings.clear();
psShaderInfo->psResourceBindings.resize(ui32NumResourceBindings);
psResBindings = ui32NumResourceBindings == 0 ? NULL : &psShaderInfo->psResourceBindings[0];
psShaderInfo->psResourceBindings.clear();
psShaderInfo->psResourceBindings.resize(ui32NumResourceBindings);
psResBindings = ui32NumResourceBindings == 0 ? NULL : &psShaderInfo->psResourceBindings[0];
for(i=0; i < ui32NumResourceBindings; ++i)
for (i = 0; i < ui32NumResourceBindings; ++i)
{
pui32ResourceBindings = ReadResourceBinding(pui32FirstToken, pui32ResourceBindings, psResBindings+i, decodeFlags);
ASSERT(psResBindings[i].ui32BindPoint < MAX_RESOURCE_BINDINGS);
}
pui32ResourceBindings = ReadResourceBinding(pui32FirstToken, pui32ResourceBindings, psResBindings + i, decodeFlags);
ASSERT(psResBindings[i].ui32BindPoint < MAX_RESOURCE_BINDINGS);
}
//Constant buffers
pui32ConstantBuffers = (const uint32_t*)((const char*)pui32FirstToken + ui32ConstantBufferOffset);
psShaderInfo->psConstantBuffers.clear();
psShaderInfo->psConstantBuffers.resize(ui32NumConstantBuffers);
psConstantBuffers = ui32NumConstantBuffers == 0 ? NULL : &psShaderInfo->psConstantBuffers[0];
psShaderInfo->psConstantBuffers.clear();
psShaderInfo->psConstantBuffers.resize(ui32NumConstantBuffers);
psConstantBuffers = ui32NumConstantBuffers == 0 ? NULL : &psShaderInfo->psConstantBuffers[0];
for(i=0; i < ui32NumConstantBuffers; ++i)
for (i = 0; i < ui32NumConstantBuffers; ++i)
{
pui32ConstantBuffers = ReadConstantBuffer(psShaderInfo, pui32FirstToken, pui32ConstantBuffers, psConstantBuffers+i);
pui32ConstantBuffers = ReadConstantBuffer(psShaderInfo, pui32FirstToken, pui32ConstantBuffers, psConstantBuffers + i);
}
//Map resource bindings to constant buffers
if(psShaderInfo->psConstantBuffers.size())
{
for(i=0; i < ui32NumResourceBindings; ++i)
{
ResourceGroup eRGroup;
uint32_t cbufIndex = 0;
//Map resource bindings to constant buffers
if (psShaderInfo->psConstantBuffers.size())
{
for (i = 0; i < ui32NumResourceBindings; ++i)
{
ResourceGroup eRGroup;
uint32_t cbufIndex = 0;
eRGroup = ShaderInfo::ResourceTypeToResourceGroup(psResBindings[i].eType);
eRGroup = ShaderInfo::ResourceTypeToResourceGroup(psResBindings[i].eType);
//Find the constant buffer whose name matches the resource at the given resource binding point
for(cbufIndex=0; cbufIndex < psShaderInfo->psConstantBuffers.size(); cbufIndex++)
{
if(psConstantBuffers[cbufIndex].name == psResBindings[i].name)
{
psShaderInfo->aui32ResourceMap[eRGroup][psResBindings[i].ui32BindPoint] = cbufIndex;
}
}
}
}
//Find the constant buffer whose name matches the resource at the given resource binding point
for (cbufIndex = 0; cbufIndex < psShaderInfo->psConstantBuffers.size(); cbufIndex++)
{
if (psConstantBuffers[cbufIndex].name == psResBindings[i].name)
{
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;
pui16Tokens += 2;
psClassType->ui16ID = *pui16Tokens++;
psClassType->ui16ConstBufStride = *pui16Tokens++;
psClassType->ui16Texture = *pui16Tokens++;
psClassType->ui16Sampler = *pui16Tokens++;
psClassType->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32NameOffset));
psClassType->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32NameOffset));
return pui16Tokens;
}
@ -474,14 +473,13 @@ static const uint16_t* ReadClassInstance(const uint32_t* pui32FirstInterfaceToke
psClassInstance->ui16Texture = *pui16Tokens++;
psClassInstance->ui16Sampler = *pui16Tokens++;
psClassInstance->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32NameOffset));
psClassInstance->name = ReadStringFromTokenStream((const uint32_t*)((const char*)pui32FirstInterfaceToken + ui32NameOffset));
return pui16Tokens;
}
static void ReadInterfaces(const uint32_t* pui32Tokens,
ShaderInfo* psShaderInfo)
ShaderInfo* psShaderInfo)
{
uint32_t i;
uint32_t ui32StartSlot;
@ -503,64 +501,63 @@ static void ReadInterfaces(const uint32_t* pui32Tokens,
ClassType* psClassTypes;
ClassInstance* psClassInstances;
psShaderInfo->psClassTypes.clear();
psShaderInfo->psClassTypes.resize(ui32ClassTypeCount);
psClassTypes = &psShaderInfo->psClassTypes[0];
psShaderInfo->psClassTypes.clear();
psShaderInfo->psClassTypes.resize(ui32ClassTypeCount);
psClassTypes = &psShaderInfo->psClassTypes[0];
for(i=0; i<ui32ClassTypeCount; ++i)
for (i = 0; i < ui32ClassTypeCount; ++i)
{
pui16ClassTypes = ReadClassType(pui32FirstInterfaceToken, pui16ClassTypes, psClassTypes+i);
pui16ClassTypes = ReadClassType(pui32FirstInterfaceToken, pui16ClassTypes, psClassTypes + i);
psClassTypes[i].ui16ID = (uint16_t)i;
}
psShaderInfo->psClassInstances.clear();
psShaderInfo->psClassInstances.resize(ui32ClassInstanceCount);
psClassInstances = &psShaderInfo->psClassInstances[0];
psShaderInfo->psClassInstances.clear();
psShaderInfo->psClassInstances.resize(ui32ClassInstanceCount);
psClassInstances = &psShaderInfo->psClassInstances[0];
for(i=0; i<ui32ClassInstanceCount; ++i)
for (i = 0; i < ui32ClassInstanceCount; ++i)
{
pui16ClassInstances = ReadClassInstance(pui32FirstInterfaceToken, pui16ClassInstances, psClassInstances+i);
pui16ClassInstances = ReadClassInstance(pui32FirstInterfaceToken, pui16ClassInstances, psClassInstances + i);
}
//Slots map function table to $ThisPointer cbuffer variable index
ui32StartSlot = 0;
for(i=0; i<ui32InterfaceSlotRecordCount;++i)
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);
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)
for (k = 0; k < ui32Count; ++k)
{
psShaderInfo->aui32TableIDToTypeID[*pui32TableID++] = *pui16TypeID++;
}
ui32StartSlot += ui32SlotSpan;
}
}
void LoadShaderInfo(const uint32_t ui32MajorVersion,
const uint32_t ui32MinorVersion,
const ReflectionChunks* psChunks,
ShaderInfo* psInfo,
uint32_t decodeFlags)
uint32_t decodeFlags)
{
const uint32_t* pui32Inputs = psChunks->pui32Inputs;
const uint32_t* pui32Inputs11 = psChunks->pui32Inputs11;
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;
const uint32_t* pui32PatchConstants = psChunks->pui32PatchConstants;
const uint32_t* pui32PatchConstants11 = psChunks->pui32PatchConstants11;
const uint32_t* pui32Outputs11 = psChunks->pui32Outputs11;
const uint32_t* pui32OutputsWithStreams = psChunks->pui32OutputsWithStreams;
const uint32_t* pui32PatchConstants = psChunks->pui32PatchConstants;
const uint32_t* pui32PatchConstants11 = psChunks->pui32PatchConstants11;
psInfo->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED;
psInfo->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED;
@ -573,34 +570,33 @@ void LoadShaderInfo(const uint32_t ui32MajorVersion,
psInfo->ui32MinorVersion = ui32MinorVersion;
if(pui32Inputs)
if (pui32Inputs)
ReadInputSignatures(pui32Inputs, psInfo, 0);
if(pui32Inputs11)
if (pui32Inputs11)
ReadInputSignatures(pui32Inputs11, psInfo, 1);
if(pui32Resources)
if (pui32Resources)
ReadResources(pui32Resources, psInfo, decodeFlags);
if(pui32Interfaces)
if (pui32Interfaces)
ReadInterfaces(pui32Interfaces, psInfo);
if(pui32Outputs)
if (pui32Outputs)
ReadOutputSignatures(pui32Outputs, psInfo, 0, 0);
if(pui32Outputs11)
if (pui32Outputs11)
ReadOutputSignatures(pui32Outputs11, psInfo, 1, 1);
if(pui32OutputsWithStreams)
ReadOutputSignatures(pui32OutputsWithStreams, psInfo, 0, 1);
if(pui32PatchConstants)
ReadPatchConstantSignatures(pui32PatchConstants, psInfo, 0, 0);
if (pui32PatchConstants11)
ReadPatchConstantSignatures(pui32PatchConstants11, psInfo, 1, 1);
if (pui32OutputsWithStreams)
ReadOutputSignatures(pui32OutputsWithStreams, psInfo, 0, 1);
if (pui32PatchConstants)
ReadPatchConstantSignatures(pui32PatchConstants, psInfo, 0, 0);
if (pui32PatchConstants11)
ReadPatchConstantSignatures(pui32PatchConstants11, psInfo, 1, 1);
{
uint32_t i;
for(i=0; i<psInfo->psConstantBuffers.size();++i)
for (i = 0; i < psInfo->psConstantBuffers.size(); ++i)
{
if (psInfo->psConstantBuffers[i].name == "$ThisPointer")
if (psInfo->psConstantBuffers[i].name == "$ThisPointer")
{
psInfo->psThisPointerConstBuffer = &psInfo->psConstantBuffers[i];
}
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу