reformat upstream code to latest coding convention ( 281bc7d8cfdb )
This commit is contained in:
Родитель
467d0a193a
Коммит
cb9809a23c
|
@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
618
include/hlslcc.h
618
include/hlslcc.h
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
306
src/HLSLcc.cpp
306
src/HLSLcc.cpp
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
991
src/Operand.cpp
991
src/Operand.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1629
src/Shader.cpp
1629
src/Shader.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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) { \
|
||||
|
|
1291
src/decode.cpp
1291
src/decode.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
486
src/reflect.cpp
486
src/reflect.cpp
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1658
src/toGLSL.cpp
1658
src/toGLSL.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1382
src/toMetal.cpp
1382
src/toMetal.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче