mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-04 10:25:29 +00:00
Add missing "fwidth" intrinsic in HLSL transpiler
Signed-off-by: Kai Blaschke <kai.blaschke@kb-dev.net>
This commit is contained in:
147
vendor/hlslparser/src/HLSLParser.cpp
vendored
147
vendor/hlslparser/src/HLSLParser.cpp
vendored
@ -36,7 +36,7 @@ enum CompareFunctionsResult
|
|||||||
Function2Better
|
Function2Better
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** This structure stores a HLSLFunction-like declaration for an intrinsic function */
|
/** This structure stores a HLSLFunction-like declaration for an intrinsic function */
|
||||||
struct Intrinsic
|
struct Intrinsic
|
||||||
{
|
{
|
||||||
@ -103,7 +103,7 @@ struct Intrinsic
|
|||||||
HLSLFunction function;
|
HLSLFunction function;
|
||||||
HLSLArgument argument[4];
|
HLSLArgument argument[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
Intrinsic SamplerIntrinsic(const char* name, HLSLBaseType returnType, HLSLBaseType arg1, HLSLBaseType samplerType, HLSLBaseType arg2)
|
Intrinsic SamplerIntrinsic(const char* name, HLSLBaseType returnType, HLSLBaseType arg1, HLSLBaseType samplerType, HLSLBaseType arg2)
|
||||||
{
|
{
|
||||||
Intrinsic i(name, returnType, arg1, arg2);
|
Intrinsic i(name, returnType, arg1, arg2);
|
||||||
@ -113,7 +113,7 @@ Intrinsic SamplerIntrinsic(const char* name, HLSLBaseType returnType, HLSLBaseTy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const int _numberTypeRank[NumericType_Count][NumericType_Count] =
|
static const int _numberTypeRank[NumericType_Count][NumericType_Count] =
|
||||||
{
|
{
|
||||||
//F B I U
|
//F B I U
|
||||||
{ 0, 4, 4, 4 }, // NumericType_Float
|
{ 0, 4, 4, 4 }, // NumericType_Float
|
||||||
@ -261,7 +261,7 @@ static const EffectState samplerStates[] = {
|
|||||||
{"MipMapLodBias", 8, floatValues},
|
{"MipMapLodBias", 8, floatValues},
|
||||||
{"MaxMipLevel", 9, integerValues},
|
{"MaxMipLevel", 9, integerValues},
|
||||||
{"MaxAnisotropy", 10, integerValues},
|
{"MaxAnisotropy", 10, integerValues},
|
||||||
{"sRGBTexture", 11, booleanValues},
|
{"sRGBTexture", 11, booleanValues},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const EffectState effectStates[] = {
|
static const EffectState effectStates[] = {
|
||||||
@ -415,7 +415,7 @@ static const EffectState pipelineStates[] = {
|
|||||||
#define SAMPLER_INTRINSIC_FUNCTION(name, sampler, arg1) \
|
#define SAMPLER_INTRINSIC_FUNCTION(name, sampler, arg1) \
|
||||||
Intrinsic( name, HLSLBaseType_Float4, sampler, arg1)
|
Intrinsic( name, HLSLBaseType_Float4, sampler, arg1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Intrinsic _intrinsic[] =
|
const Intrinsic _intrinsic[] =
|
||||||
{
|
{
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "abs" ),
|
INTRINSIC_FLOAT1_FUNCTION( "abs" ),
|
||||||
@ -478,6 +478,11 @@ const Intrinsic _intrinsic[] =
|
|||||||
Intrinsic( "length", HLSLBaseType_Float, HLSLBaseType_Float3 ),
|
Intrinsic( "length", HLSLBaseType_Float, HLSLBaseType_Float3 ),
|
||||||
Intrinsic( "length", HLSLBaseType_Float, HLSLBaseType_Float4 ),
|
Intrinsic( "length", HLSLBaseType_Float, HLSLBaseType_Float4 ),
|
||||||
|
|
||||||
|
Intrinsic( "fwidth", HLSLBaseType_Float, HLSLBaseType_Float ),
|
||||||
|
Intrinsic( "fwidth", HLSLBaseType_Float, HLSLBaseType_Float2 ),
|
||||||
|
Intrinsic( "fwidth", HLSLBaseType_Float, HLSLBaseType_Float3 ),
|
||||||
|
Intrinsic( "fwidth", HLSLBaseType_Float, HLSLBaseType_Float4 ),
|
||||||
|
|
||||||
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float , HLSLBaseType_Float ),
|
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float , HLSLBaseType_Float ),
|
||||||
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float2, HLSLBaseType_Float2 ),
|
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float2, HLSLBaseType_Float2 ),
|
||||||
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float3, HLSLBaseType_Float3 ),
|
Intrinsic( "distance", HLSLBaseType_Float, HLSLBaseType_Float3, HLSLBaseType_Float3 ),
|
||||||
@ -617,10 +622,10 @@ const Intrinsic _intrinsic[] =
|
|||||||
INTRINSIC_FLOAT1_FUNCTION( "log" ),
|
INTRINSIC_FLOAT1_FUNCTION( "log" ),
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "log2" ),
|
INTRINSIC_FLOAT1_FUNCTION( "log2" ),
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "log10" ),
|
INTRINSIC_FLOAT1_FUNCTION( "log10" ),
|
||||||
|
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "ddx" ),
|
INTRINSIC_FLOAT1_FUNCTION( "ddx" ),
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "ddy" ),
|
INTRINSIC_FLOAT1_FUNCTION( "ddy" ),
|
||||||
|
|
||||||
INTRINSIC_FLOAT1_FUNCTION( "sign" ),
|
INTRINSIC_FLOAT1_FUNCTION( "sign" ),
|
||||||
INTRINSIC_FLOAT2_FUNCTION( "step" ),
|
INTRINSIC_FLOAT2_FUNCTION( "step" ),
|
||||||
INTRINSIC_FLOAT2_FUNCTION( "reflect" ),
|
INTRINSIC_FLOAT2_FUNCTION( "reflect" ),
|
||||||
@ -657,15 +662,15 @@ const Intrinsic _intrinsic[] =
|
|||||||
Intrinsic("asuint", HLSLBaseType_Uint, HLSLBaseType_Float),
|
Intrinsic("asuint", HLSLBaseType_Uint, HLSLBaseType_Float),
|
||||||
|
|
||||||
SAMPLER_INTRINSIC_FUNCTION("tex2D", HLSLBaseType_Sampler2D, HLSLBaseType_Float2),
|
SAMPLER_INTRINSIC_FUNCTION("tex2D", HLSLBaseType_Sampler2D, HLSLBaseType_Float2),
|
||||||
|
|
||||||
Intrinsic("tex2Dproj", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
Intrinsic("tex2Dproj", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
||||||
|
|
||||||
SAMPLER_INTRINSIC_FUNCTION("tex2Dlod", HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
SAMPLER_INTRINSIC_FUNCTION("tex2Dlod", HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
||||||
|
|
||||||
Intrinsic("tex2Dlod", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float4, HLSLBaseType_Int2), // With offset.
|
Intrinsic("tex2Dlod", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float4, HLSLBaseType_Int2), // With offset.
|
||||||
|
|
||||||
SAMPLER_INTRINSIC_FUNCTION("tex2Dbias", HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
SAMPLER_INTRINSIC_FUNCTION("tex2Dbias", HLSLBaseType_Sampler2D, HLSLBaseType_Float4),
|
||||||
|
|
||||||
Intrinsic("tex2Dgrad", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Float2, HLSLBaseType_Float2),
|
Intrinsic("tex2Dgrad", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Float2, HLSLBaseType_Float2),
|
||||||
Intrinsic("tex2Dgather", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Int),
|
Intrinsic("tex2Dgather", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Int),
|
||||||
Intrinsic("tex2Dgather", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Int2, HLSLBaseType_Int), // With offset.
|
Intrinsic("tex2Dgather", HLSLBaseType_Float4, HLSLBaseType_Sampler2D, HLSLBaseType_Float2, HLSLBaseType_Int2, HLSLBaseType_Int), // With offset.
|
||||||
@ -718,7 +723,7 @@ const int _binaryOpPriority[] =
|
|||||||
// IC: I'm not sure this table is right, but any errors should be caught by the backend compiler.
|
// IC: I'm not sure this table is right, but any errors should be caught by the backend compiler.
|
||||||
// Also, this is operator dependent. The type resulting from (float4 * float4x4) is not the same as (float4 + float4x4).
|
// Also, this is operator dependent. The type resulting from (float4 * float4x4) is not the same as (float4 + float4x4).
|
||||||
// We should probably distinguish between component-wise operator and only allow same dimensions
|
// We should probably distinguish between component-wise operator and only allow same dimensions
|
||||||
HLSLBaseType _binaryOpTypeLookup[HLSLBaseType_NumericCount][HLSLBaseType_NumericCount] =
|
HLSLBaseType _binaryOpTypeLookup[HLSLBaseType_NumericCount][HLSLBaseType_NumericCount] =
|
||||||
{
|
{
|
||||||
{ // float
|
{ // float
|
||||||
HLSLBaseType_Float, HLSLBaseType_Float2, HLSLBaseType_Float3, HLSLBaseType_Float4,
|
HLSLBaseType_Float, HLSLBaseType_Float2, HLSLBaseType_Float3, HLSLBaseType_Float4,
|
||||||
@ -1001,7 +1006,7 @@ static const char* GetBinaryOpName(HLSLBinaryOp binaryOp)
|
|||||||
* 4.) Conversion + scalar dimension promotion
|
* 4.) Conversion + scalar dimension promotion
|
||||||
* 5.) Truncation (vector -> scalar or lower component vector, matrix -> scalar or lower component matrix)
|
* 5.) Truncation (vector -> scalar or lower component vector, matrix -> scalar or lower component matrix)
|
||||||
* 6.) Conversion + truncation
|
* 6.) Conversion + truncation
|
||||||
*/
|
*/
|
||||||
static int GetTypeCastRank(HLSLTree * tree, const HLSLType& srcType, const HLSLType& dstType)
|
static int GetTypeCastRank(HLSLTree * tree, const HLSLType& srcType, const HLSLType& dstType)
|
||||||
{
|
{
|
||||||
/*if (srcType.array != dstType.array || srcType.arraySize != dstType.arraySize)
|
/*if (srcType.array != dstType.array || srcType.arraySize != dstType.arraySize)
|
||||||
@ -1039,7 +1044,7 @@ static int GetTypeCastRank(HLSLTree * tree, const HLSLType& srcType, const HLSLT
|
|||||||
{
|
{
|
||||||
return srcType.samplerType == dstType.samplerType ? 0 : -1;
|
return srcType.samplerType == dstType.samplerType ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,7 +1086,7 @@ static int GetTypeCastRank(HLSLTree * tree, const HLSLType& srcType, const HLSLT
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetFunctionCallCastRanks(HLSLTree* tree, const HLSLFunctionCall* call, const HLSLFunction* function, int* rankBuffer)
|
static bool GetFunctionCallCastRanks(HLSLTree* tree, const HLSLFunctionCall* call, const HLSLFunction* function, int* rankBuffer)
|
||||||
@ -1095,7 +1100,7 @@ static bool GetFunctionCallCastRanks(HLSLTree* tree, const HLSLFunctionCall* cal
|
|||||||
|
|
||||||
const HLSLExpression* expression = call->argument;
|
const HLSLExpression* expression = call->argument;
|
||||||
const HLSLArgument* argument = function->argument;
|
const HLSLArgument* argument = function->argument;
|
||||||
|
|
||||||
for (int i = 0; i < call->numArguments; ++i)
|
for (int i = 0; i < call->numArguments; ++i)
|
||||||
{
|
{
|
||||||
int rank = GetTypeCastRank(tree, expression->expressionType, argument->type);
|
int rank = GetTypeCastRank(tree, expression->expressionType, argument->type);
|
||||||
@ -1105,7 +1110,7 @@ static bool GetFunctionCallCastRanks(HLSLTree* tree, const HLSLFunctionCall* cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
rankBuffer[i] = rank;
|
rankBuffer[i] = rank;
|
||||||
|
|
||||||
argument = argument->nextArgument;
|
argument = argument->nextArgument;
|
||||||
expression = expression->nextExpression;
|
expression = expression->nextExpression;
|
||||||
}
|
}
|
||||||
@ -1129,7 +1134,7 @@ struct CompareRanks
|
|||||||
};
|
};
|
||||||
|
|
||||||
static CompareFunctionsResult CompareFunctions(HLSLTree* tree, const HLSLFunctionCall* call, const HLSLFunction* function1, const HLSLFunction* function2)
|
static CompareFunctionsResult CompareFunctions(HLSLTree* tree, const HLSLFunctionCall* call, const HLSLFunction* function1, const HLSLFunction* function2)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined _WIN32 && !defined alloca
|
#if defined _WIN32 && !defined alloca
|
||||||
int* function1Ranks = static_cast<int*>(_alloca(sizeof(int) * call->numArguments));
|
int* function1Ranks = static_cast<int*>(_alloca(sizeof(int) * call->numArguments));
|
||||||
@ -1161,7 +1166,7 @@ static CompareFunctionsResult CompareFunctions(HLSLTree* tree, const HLSLFunctio
|
|||||||
|
|
||||||
std::sort(function1Ranks, function1Ranks + call->numArguments, CompareRanks());
|
std::sort(function1Ranks, function1Ranks + call->numArguments, CompareRanks());
|
||||||
std::sort(function2Ranks, function2Ranks + call->numArguments, CompareRanks());
|
std::sort(function2Ranks, function2Ranks + call->numArguments, CompareRanks());
|
||||||
|
|
||||||
for (int i = 0; i < call->numArguments; ++i)
|
for (int i = 0; i < call->numArguments; ++i)
|
||||||
{
|
{
|
||||||
if (function1Ranks[i] < function2Ranks[i])
|
if (function1Ranks[i] < function2Ranks[i])
|
||||||
@ -1242,7 +1247,7 @@ static bool GetBinaryOpResultType(HLSLBinaryOp binaryOp, const HLSLType& type1,
|
|||||||
result.array = false;
|
result.array = false;
|
||||||
result.arraySize = NULL;
|
result.arraySize = NULL;
|
||||||
result.flags = (type1.flags & type2.flags) & HLSLTypeFlag_Const; // Propagate constness.
|
result.flags = (type1.flags & type2.flags) & HLSLTypeFlag_Const; // Propagate constness.
|
||||||
|
|
||||||
return result.baseType != HLSLBaseType_Unknown;
|
return result.baseType != HLSLBaseType_Unknown;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1358,7 +1363,7 @@ bool HLSLParser::ParseTopLevel(HLSLStatement*& statement)
|
|||||||
|
|
||||||
int line = GetLineNumber();
|
int line = GetLineNumber();
|
||||||
const char* fileName = GetFileName();
|
const char* fileName = GetFileName();
|
||||||
|
|
||||||
HLSLType type;
|
HLSLType type;
|
||||||
//HLSLBaseType type;
|
//HLSLBaseType type;
|
||||||
//const char* typeName = NULL;
|
//const char* typeName = NULL;
|
||||||
@ -1390,7 +1395,7 @@ bool HLSLParser::ParseTopLevel(HLSLStatement*& statement)
|
|||||||
structure->name = structName;
|
structure->name = structName;
|
||||||
|
|
||||||
m_userTypes.PushBack(structure);
|
m_userTypes.PushBack(structure);
|
||||||
|
|
||||||
HLSLStructField* lastField = NULL;
|
HLSLStructField* lastField = NULL;
|
||||||
|
|
||||||
// Add the struct to our list of user defined types.
|
// Add the struct to our list of user defined types.
|
||||||
@ -1544,7 +1549,7 @@ bool HLSLParser::ParseTopLevel(HLSLStatement*& statement)
|
|||||||
|
|
||||||
// Note, no semi-colon at the end of a function declaration.
|
// Note, no semi-colon at the end of a function declaration.
|
||||||
statement = function;
|
statement = function;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1693,7 +1698,7 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
}
|
}
|
||||||
|
|
||||||
HLSLAttribute * attributes = NULL;
|
HLSLAttribute * attributes = NULL;
|
||||||
ParseAttributeBlock(attributes); // @@ Leak if not assigned to node?
|
ParseAttributeBlock(attributes); // @@ Leak if not assigned to node?
|
||||||
|
|
||||||
#if 0 // @@ Work in progress.
|
#if 0 // @@ Work in progress.
|
||||||
// Static statements: @if only for now.
|
// Static statements: @if only for now.
|
||||||
@ -1704,9 +1709,9 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
//HLSLIfStatement* ifStatement = m_tree->AddNode<HLSLIfStatement>(fileName, line);
|
//HLSLIfStatement* ifStatement = m_tree->AddNode<HLSLIfStatement>(fileName, line);
|
||||||
//ifStatement->isStatic = true;
|
//ifStatement->isStatic = true;
|
||||||
//ifStatement->attributes = attributes;
|
//ifStatement->attributes = attributes;
|
||||||
|
|
||||||
HLSLExpression * condition = NULL;
|
HLSLExpression * condition = NULL;
|
||||||
|
|
||||||
m_allowUndeclaredIdentifiers = true; // Not really correct... better to push to stack?
|
m_allowUndeclaredIdentifiers = true; // Not really correct... better to push to stack?
|
||||||
if (!Expect('(') || !ParseExpression(condition) || !Expect(')'))
|
if (!Expect('(') || !ParseExpression(condition) || !Expect(')'))
|
||||||
{
|
{
|
||||||
@ -1714,25 +1719,25 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_allowUndeclaredIdentifiers = false;
|
m_allowUndeclaredIdentifiers = false;
|
||||||
|
|
||||||
if ((condition->expressionType.flags & HLSLTypeFlag_Const) == 0)
|
if ((condition->expressionType.flags & HLSLTypeFlag_Const) == 0)
|
||||||
{
|
{
|
||||||
m_tokenizer.Error("Syntax error: @if condition is not constant");
|
m_tokenizer.Error("Syntax error: @if condition is not constant");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int conditionValue;
|
int conditionValue;
|
||||||
if (!m_tree->GetExpressionValue(condition, conditionValue))
|
if (!m_tree->GetExpressionValue(condition, conditionValue))
|
||||||
{
|
{
|
||||||
m_tokenizer.Error("Syntax error: Cannot evaluate @if condition");
|
m_tokenizer.Error("Syntax error: Cannot evaluate @if condition");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conditionValue) m_disableSemanticValidation = true;
|
if (!conditionValue) m_disableSemanticValidation = true;
|
||||||
|
|
||||||
HLSLStatement * ifStatements = NULL;
|
HLSLStatement * ifStatements = NULL;
|
||||||
HLSLStatement * elseStatements = NULL;
|
HLSLStatement * elseStatements = NULL;
|
||||||
|
|
||||||
if (!ParseStatementOrBlock(ifStatements, returnType, /*scoped=*/false))
|
if (!ParseStatementOrBlock(ifStatements, returnType, /*scoped=*/false))
|
||||||
{
|
{
|
||||||
m_disableSemanticValidation = false;
|
m_disableSemanticValidation = false;
|
||||||
@ -1741,7 +1746,7 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
if (Accept(HLSLToken_Else))
|
if (Accept(HLSLToken_Else))
|
||||||
{
|
{
|
||||||
if (conditionValue) m_disableSemanticValidation = true;
|
if (conditionValue) m_disableSemanticValidation = true;
|
||||||
|
|
||||||
if (!ParseStatementOrBlock(elseStatements, returnType, /*scoped=*/false))
|
if (!ParseStatementOrBlock(elseStatements, returnType, /*scoped=*/false))
|
||||||
{
|
{
|
||||||
m_disableSemanticValidation = false;
|
m_disableSemanticValidation = false;
|
||||||
@ -1749,12 +1754,12 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_disableSemanticValidation = false;
|
m_disableSemanticValidation = false;
|
||||||
|
|
||||||
if (conditionValue) statement = ifStatements;
|
if (conditionValue) statement = ifStatements;
|
||||||
else statement = elseStatements;
|
else statement = elseStatements;
|
||||||
|
|
||||||
// @@ Free the pruned statements?
|
// @@ Free the pruned statements?
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1762,7 +1767,7 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If statement.
|
// If statement.
|
||||||
if (Accept(HLSLToken_If))
|
if (Accept(HLSLToken_If))
|
||||||
{
|
{
|
||||||
@ -1783,7 +1788,7 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For statement.
|
// For statement.
|
||||||
if (Accept(HLSLToken_For))
|
if (Accept(HLSLToken_For))
|
||||||
{
|
{
|
||||||
@ -2184,15 +2189,15 @@ bool HLSLParser::AcceptAssign(HLSLBinaryOp& binaryOp)
|
|||||||
else if (Accept(HLSLToken_MinusEqual))
|
else if (Accept(HLSLToken_MinusEqual))
|
||||||
{
|
{
|
||||||
binaryOp = HLSLBinaryOp_SubAssign;
|
binaryOp = HLSLBinaryOp_SubAssign;
|
||||||
}
|
}
|
||||||
else if (Accept(HLSLToken_TimesEqual))
|
else if (Accept(HLSLToken_TimesEqual))
|
||||||
{
|
{
|
||||||
binaryOp = HLSLBinaryOp_MulAssign;
|
binaryOp = HLSLBinaryOp_MulAssign;
|
||||||
}
|
}
|
||||||
else if (Accept(HLSLToken_DivideEqual))
|
else if (Accept(HLSLToken_DivideEqual))
|
||||||
{
|
{
|
||||||
binaryOp = HLSLBinaryOp_DivAssign;
|
binaryOp = HLSLBinaryOp_DivAssign;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -2242,10 +2247,10 @@ bool HLSLParser::ParseBinaryExpression(int priority, HLSLExpression*& expression
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate constness.
|
// Propagate constness.
|
||||||
binaryExpression->expressionType.flags = (expression->expressionType.flags | expression2->expressionType.flags) & HLSLTypeFlag_Const;
|
binaryExpression->expressionType.flags = (expression->expressionType.flags | expression2->expressionType.flags) & HLSLTypeFlag_Const;
|
||||||
|
|
||||||
expression = binaryExpression;
|
expression = binaryExpression;
|
||||||
}
|
}
|
||||||
else if (_conditionalOpPriority > priority && Accept('?'))
|
else if (_conditionalOpPriority > priority && Accept('?'))
|
||||||
@ -2253,7 +2258,7 @@ bool HLSLParser::ParseBinaryExpression(int priority, HLSLExpression*& expression
|
|||||||
|
|
||||||
HLSLConditionalExpression* conditionalExpression = m_tree->AddNode<HLSLConditionalExpression>(fileName, line);
|
HLSLConditionalExpression* conditionalExpression = m_tree->AddNode<HLSLConditionalExpression>(fileName, line);
|
||||||
conditionalExpression->condition = expression;
|
conditionalExpression->condition = expression;
|
||||||
|
|
||||||
HLSLExpression* expression1 = NULL;
|
HLSLExpression* expression1 = NULL;
|
||||||
HLSLExpression* expression2 = NULL;
|
HLSLExpression* expression2 = NULL;
|
||||||
if (!ParseBinaryExpression(_conditionalOpPriority, expression1) || !Expect(':') || !ParseBinaryExpression(_conditionalOpPriority, expression2))
|
if (!ParseBinaryExpression(_conditionalOpPriority, expression1) || !Expect(':') || !ParseBinaryExpression(_conditionalOpPriority, expression2))
|
||||||
@ -2311,7 +2316,7 @@ bool HLSLParser::ParsePartialConstructor(HLSLExpression*& expression, HLSLBaseTy
|
|||||||
if (!ParseExpressionList(')', false, constructorExpression->argument, numArguments))
|
if (!ParseExpressionList(')', false, constructorExpression->argument, numArguments))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
constructorExpression->expressionType = constructorExpression->type;
|
constructorExpression->expressionType = constructorExpression->type;
|
||||||
constructorExpression->expressionType.flags = HLSLTypeFlag_Const;
|
constructorExpression->expressionType.flags = HLSLTypeFlag_Const;
|
||||||
expression = constructorExpression;
|
expression = constructorExpression;
|
||||||
@ -2336,7 +2341,7 @@ bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, char& need
|
|||||||
}
|
}
|
||||||
if (unaryOp == HLSLUnaryOp_BitNot)
|
if (unaryOp == HLSLUnaryOp_BitNot)
|
||||||
{
|
{
|
||||||
if (unaryExpression->expression->expressionType.baseType < HLSLBaseType_FirstInteger ||
|
if (unaryExpression->expression->expressionType.baseType < HLSLBaseType_FirstInteger ||
|
||||||
unaryExpression->expression->expressionType.baseType > HLSLBaseType_LastInteger)
|
unaryExpression->expression->expressionType.baseType > HLSLBaseType_LastInteger)
|
||||||
{
|
{
|
||||||
const char * typeName = GetTypeName(unaryExpression->expression->expressionType);
|
const char * typeName = GetTypeName(unaryExpression->expression->expressionType);
|
||||||
@ -2359,7 +2364,7 @@ bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, char& need
|
|||||||
}
|
}
|
||||||
|
|
||||||
unaryExpression->expressionType = HLSLType(HLSLBaseType_Bool);
|
unaryExpression->expressionType = HLSLType(HLSLBaseType_Bool);
|
||||||
|
|
||||||
// Propagate constness.
|
// Propagate constness.
|
||||||
unaryExpression->expressionType.flags = unaryExpression->expression->expressionType.flags & HLSLTypeFlag_Const;
|
unaryExpression->expressionType.flags = unaryExpression->expression->expressionType.flags & HLSLTypeFlag_Const;
|
||||||
}
|
}
|
||||||
@ -2395,7 +2400,7 @@ bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, char& need
|
|||||||
expression = unaryExpression;
|
expression = unaryExpression;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expressions inside parenthesis or casts.
|
// Expressions inside parenthesis or casts.
|
||||||
char expressionEndChar = 0;
|
char expressionEndChar = 0;
|
||||||
if (Accept('('))
|
if (Accept('('))
|
||||||
@ -2426,7 +2431,7 @@ bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, char& need
|
|||||||
castingExpression->expressionType = type;
|
castingExpression->expressionType = type;
|
||||||
return Expect(')') && ParseExpression(castingExpression->expression);
|
return Expect(')') && ParseExpression(castingExpression->expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
int numArguments = 0;
|
int numArguments = 0;
|
||||||
if (!ParseExpressionList(expressionEndChar, false, expression, numArguments))
|
if (!ParseExpressionList(expressionEndChar, false, expression, numArguments))
|
||||||
{
|
{
|
||||||
@ -2447,7 +2452,7 @@ bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, char& need
|
|||||||
// Terminal values.
|
// Terminal values.
|
||||||
float fValue = 0.0f;
|
float fValue = 0.0f;
|
||||||
int iValue = 0;
|
int iValue = 0;
|
||||||
|
|
||||||
if (AcceptFloat(fValue))
|
if (AcceptFloat(fValue))
|
||||||
{
|
{
|
||||||
HLSLLiteralExpression* literalExpression = m_tree->AddNode<HLSLLiteralExpression>(fileName, line);
|
HLSLLiteralExpression* literalExpression = m_tree->AddNode<HLSLLiteralExpression>(fileName, line);
|
||||||
@ -2728,7 +2733,7 @@ bool HLSLParser::ParseArgumentList(HLSLArgument*& firstArgument, int& numArgumen
|
|||||||
{
|
{
|
||||||
const char* fileName = GetFileName();
|
const char* fileName = GetFileName();
|
||||||
int line = GetLineNumber();
|
int line = GetLineNumber();
|
||||||
|
|
||||||
HLSLArgument* lastArgument = NULL;
|
HLSLArgument* lastArgument = NULL;
|
||||||
numArguments = 0;
|
numArguments = 0;
|
||||||
|
|
||||||
@ -3000,7 +3005,7 @@ const EffectState* GetEffectState(const char* name, bool isSamplerState, bool is
|
|||||||
{
|
{
|
||||||
const EffectState* validStates = effectStates;
|
const EffectState* validStates = effectStates;
|
||||||
int count = sizeof(effectStates)/sizeof(effectStates[0]);
|
int count = sizeof(effectStates)/sizeof(effectStates[0]);
|
||||||
|
|
||||||
if (isPipeline)
|
if (isPipeline)
|
||||||
{
|
{
|
||||||
validStates = pipelineStates;
|
validStates = pipelineStates;
|
||||||
@ -3016,7 +3021,7 @@ const EffectState* GetEffectState(const char* name, bool isSamplerState, bool is
|
|||||||
// Case insensitive comparison.
|
// Case insensitive comparison.
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (String_EqualNoCase(name, validStates[i].name))
|
if (String_EqualNoCase(name, validStates[i].name))
|
||||||
{
|
{
|
||||||
return &validStates[i];
|
return &validStates[i];
|
||||||
}
|
}
|
||||||
@ -3028,12 +3033,12 @@ const EffectState* GetEffectState(const char* name, bool isSamplerState, bool is
|
|||||||
static const EffectStateValue* GetStateValue(const char* name, const EffectState* state)
|
static const EffectStateValue* GetStateValue(const char* name, const EffectState* state)
|
||||||
{
|
{
|
||||||
// Case insensitive comparison.
|
// Case insensitive comparison.
|
||||||
for (int i = 0; ; i++)
|
for (int i = 0; ; i++)
|
||||||
{
|
{
|
||||||
const EffectStateValue & value = state->values[i];
|
const EffectStateValue & value = state->values[i];
|
||||||
if (value.name == NULL) break;
|
if (value.name == NULL) break;
|
||||||
|
|
||||||
if (String_EqualNoCase(name, value.name))
|
if (String_EqualNoCase(name, value.name))
|
||||||
{
|
{
|
||||||
return &value;
|
return &value;
|
||||||
}
|
}
|
||||||
@ -3099,7 +3104,7 @@ bool HLSLParser::ParseStateValue(const EffectState * state, HLSLStateAssignment*
|
|||||||
const bool expectsFloat = state->values == floatValues;
|
const bool expectsFloat = state->values == floatValues;
|
||||||
const bool expectsBoolean = state->values == booleanValues;
|
const bool expectsBoolean = state->values == booleanValues;
|
||||||
|
|
||||||
if (!expectsExpression && !expectsInteger && !expectsFloat && !expectsBoolean)
|
if (!expectsExpression && !expectsInteger && !expectsFloat && !expectsBoolean)
|
||||||
{
|
{
|
||||||
if (m_tokenizer.GetToken() != HLSLToken_Identifier)
|
if (m_tokenizer.GetToken() != HLSLToken_Identifier)
|
||||||
{
|
{
|
||||||
@ -3176,7 +3181,7 @@ bool HLSLParser::ParseStateValue(const EffectState * state, HLSLStateAssignment*
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Expect one of the allowed values.
|
// Expect one of the allowed values.
|
||||||
const EffectStateValue * stateValue = GetStateValue(m_tokenizer.GetIdentifier(), state);
|
const EffectStateValue * stateValue = GetStateValue(m_tokenizer.GetIdentifier(), state);
|
||||||
@ -3233,7 +3238,7 @@ bool HLSLParser::ParseAttributeList(HLSLAttribute*& firstAttribute)
|
|||||||
{
|
{
|
||||||
const char* fileName = GetFileName();
|
const char* fileName = GetFileName();
|
||||||
int line = GetLineNumber();
|
int line = GetLineNumber();
|
||||||
|
|
||||||
HLSLAttribute * lastAttribute = firstAttribute;
|
HLSLAttribute * lastAttribute = firstAttribute;
|
||||||
do {
|
do {
|
||||||
const char * identifier = NULL;
|
const char * identifier = NULL;
|
||||||
@ -3242,12 +3247,12 @@ bool HLSLParser::ParseAttributeList(HLSLAttribute*& firstAttribute)
|
|||||||
}
|
}
|
||||||
|
|
||||||
HLSLAttribute * attribute = m_tree->AddNode<HLSLAttribute>(fileName, line);
|
HLSLAttribute * attribute = m_tree->AddNode<HLSLAttribute>(fileName, line);
|
||||||
|
|
||||||
if (strcmp(identifier, "unroll") == 0) attribute->attributeType = HLSLAttributeType_Unroll;
|
if (strcmp(identifier, "unroll") == 0) attribute->attributeType = HLSLAttributeType_Unroll;
|
||||||
else if (strcmp(identifier, "flatten") == 0) attribute->attributeType = HLSLAttributeType_Flatten;
|
else if (strcmp(identifier, "flatten") == 0) attribute->attributeType = HLSLAttributeType_Flatten;
|
||||||
else if (strcmp(identifier, "branch") == 0) attribute->attributeType = HLSLAttributeType_Branch;
|
else if (strcmp(identifier, "branch") == 0) attribute->attributeType = HLSLAttributeType_Branch;
|
||||||
else if (strcmp(identifier, "nofastmath") == 0) attribute->attributeType = HLSLAttributeType_NoFastMath;
|
else if (strcmp(identifier, "nofastmath") == 0) attribute->attributeType = HLSLAttributeType_NoFastMath;
|
||||||
|
|
||||||
// @@ parse arguments, () not required if attribute constructor has no arguments.
|
// @@ parse arguments, () not required if attribute constructor has no arguments.
|
||||||
|
|
||||||
if (firstAttribute == NULL)
|
if (firstAttribute == NULL)
|
||||||
@ -3259,7 +3264,7 @@ bool HLSLParser::ParseAttributeList(HLSLAttribute*& firstAttribute)
|
|||||||
lastAttribute->nextAttribute = attribute;
|
lastAttribute->nextAttribute = attribute;
|
||||||
}
|
}
|
||||||
lastAttribute = attribute;
|
lastAttribute = attribute;
|
||||||
|
|
||||||
} while(Accept(','));
|
} while(Accept(','));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -3339,7 +3344,7 @@ bool HLSLParser::ParseStage(HLSLStatement*& statement)
|
|||||||
|
|
||||||
|
|
||||||
bool HLSLParser::Parse(const char* fileName, const char* buffer, size_t length)
|
bool HLSLParser::Parse(const char* fileName, const char* buffer, size_t length)
|
||||||
{
|
{
|
||||||
HLSLRoot* root = m_tree->GetRoot();
|
HLSLRoot* root = m_tree->GetRoot();
|
||||||
HLSLStatement* lastStatement = NULL;
|
HLSLStatement* lastStatement = NULL;
|
||||||
|
|
||||||
@ -3352,7 +3357,7 @@ bool HLSLParser::Parse(const char* fileName, const char* buffer, size_t length)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (statement != NULL)
|
if (statement != NULL)
|
||||||
{
|
{
|
||||||
if (lastStatement == NULL)
|
if (lastStatement == NULL)
|
||||||
{
|
{
|
||||||
root->statement = statement;
|
root->statement = statement;
|
||||||
@ -3556,7 +3561,7 @@ bool HLSLParser::ApplyPreprocessor(const char* fileName, const char* buffer, siz
|
|||||||
m_tokenizer.Next();
|
m_tokenizer.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueProcessed == "main")
|
if (valueProcessed == "main")
|
||||||
{
|
{
|
||||||
valueProcessed = "sampler_fw_main";
|
valueProcessed = "sampler_fw_main";
|
||||||
}
|
}
|
||||||
@ -3854,12 +3859,12 @@ bool HLSLParser::AcceptTypeModifier(int& flags)
|
|||||||
bool HLSLParser::AcceptInterpolationModifier(int& flags)
|
bool HLSLParser::AcceptInterpolationModifier(int& flags)
|
||||||
{
|
{
|
||||||
if (Accept("linear"))
|
if (Accept("linear"))
|
||||||
{
|
{
|
||||||
flags |= HLSLTypeFlag_Linear;
|
flags |= HLSLTypeFlag_Linear;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (Accept("centroid"))
|
else if (Accept("centroid"))
|
||||||
{
|
{
|
||||||
flags |= HLSLTypeFlag_Centroid;
|
flags |= HLSLTypeFlag_Centroid;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3908,7 +3913,7 @@ bool HLSLParser::AcceptType(bool allowVoid, HLSLType& type/*, bool acceptFlags*/
|
|||||||
case HLSLToken_Double1x1:
|
case HLSLToken_Double1x1:
|
||||||
type.baseType = HLSLBaseType_Float;
|
type.baseType = HLSLBaseType_Float;
|
||||||
break;
|
break;
|
||||||
case HLSLToken_Float2:
|
case HLSLToken_Float2:
|
||||||
case HLSLToken_Float2x1:
|
case HLSLToken_Float2x1:
|
||||||
case HLSLToken_Half2:
|
case HLSLToken_Half2:
|
||||||
case HLSLToken_Half2x1:
|
case HLSLToken_Half2x1:
|
||||||
@ -4041,7 +4046,7 @@ bool HLSLParser::AcceptType(bool allowVoid, HLSLType& type/*, bool acceptFlags*/
|
|||||||
if (type.baseType != HLSLBaseType_Void)
|
if (type.baseType != HLSLBaseType_Void)
|
||||||
{
|
{
|
||||||
m_tokenizer.Next();
|
m_tokenizer.Next();
|
||||||
|
|
||||||
if (IsSamplerType(type.baseType))
|
if (IsSamplerType(type.baseType))
|
||||||
{
|
{
|
||||||
// Parse optional sampler type.
|
// Parse optional sampler type.
|
||||||
@ -4058,7 +4063,7 @@ bool HLSLParser::AcceptType(bool allowVoid, HLSLType& type/*, bool acceptFlags*/
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_tokenizer.Next();
|
m_tokenizer.Next();
|
||||||
|
|
||||||
if (!Expect('>'))
|
if (!Expect('>'))
|
||||||
{
|
{
|
||||||
m_tokenizer.Error("Syntax error: '>' expected for sampler type");
|
m_tokenizer.Error("Syntax error: '>' expected for sampler type");
|
||||||
@ -4303,7 +4308,7 @@ const HLSLFunction* HLSLParser::MatchFunctionCall(const HLSLFunctionCall* functi
|
|||||||
if (function->name == name)
|
if (function->name == name)
|
||||||
{
|
{
|
||||||
nameMatches = true;
|
nameMatches = true;
|
||||||
|
|
||||||
CompareFunctionsResult result = CompareFunctions( m_tree, functionCall, function, matchedFunction );
|
CompareFunctionsResult result = CompareFunctions( m_tree, functionCall, function, matchedFunction );
|
||||||
if (result == Function1Better)
|
if (result == Function1Better)
|
||||||
{
|
{
|
||||||
@ -4454,7 +4459,7 @@ bool HLSLParser::GetMemberType(const HLSLType& objectType, HLSLMemberAccess * me
|
|||||||
static const HLSLBaseType intType[] = { HLSLBaseType_Int, HLSLBaseType_Int2, HLSLBaseType_Int3, HLSLBaseType_Int4 };
|
static const HLSLBaseType intType[] = { HLSLBaseType_Int, HLSLBaseType_Int2, HLSLBaseType_Int3, HLSLBaseType_Int4 };
|
||||||
static const HLSLBaseType uintType[] = { HLSLBaseType_Uint, HLSLBaseType_Uint2, HLSLBaseType_Uint3, HLSLBaseType_Uint4 };
|
static const HLSLBaseType uintType[] = { HLSLBaseType_Uint, HLSLBaseType_Uint2, HLSLBaseType_Uint3, HLSLBaseType_Uint4 };
|
||||||
static const HLSLBaseType boolType[] = { HLSLBaseType_Bool, HLSLBaseType_Bool2, HLSLBaseType_Bool3, HLSLBaseType_Bool4 };
|
static const HLSLBaseType boolType[] = { HLSLBaseType_Bool, HLSLBaseType_Bool2, HLSLBaseType_Bool3, HLSLBaseType_Bool4 };
|
||||||
|
|
||||||
switch (baseTypeDescriptions[objectType.baseType].numericType)
|
switch (baseTypeDescriptions[objectType.baseType].numericType)
|
||||||
{
|
{
|
||||||
case NumericType_Float:
|
case NumericType_Float:
|
||||||
@ -4474,7 +4479,7 @@ bool HLSLParser::GetMemberType(const HLSLType& objectType, HLSLMemberAccess * me
|
|||||||
}
|
}
|
||||||
|
|
||||||
memberAccess->swizzle = true;
|
memberAccess->swizzle = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user