Skip to content

Commit 6157c58

Browse files
Fixing HLSLTranslator:
- miising keywords - rsqrt function - modulo support - preprocessor if/else/endif support - several small fixes
1 parent 4d16f3f commit 6157c58

File tree

7 files changed

+130
-11
lines changed

7 files changed

+130
-11
lines changed

src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const char* GLSLGenerator::s_reservedWord[] =
3636
"fract",
3737
"dFdx",
3838
"dFdy",
39+
"filter",
40+
"main",
3941
};
4042

4143
static const char* GetTypeName(const HLSLType& type)
@@ -230,6 +232,7 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
230232
}
231233

232234
// Output the special function used to access rows in a matrix.
235+
m_writer.WriteLine(0, "vec2 %s(mat2 m, int i) { return vec2( m[0][i], m[1][i] ); }", m_matrixRowFunction);
233236
m_writer.WriteLine(0, "vec3 %s(mat3 m, int i) { return vec3( m[0][i], m[1][i], m[2][i] ); }", m_matrixRowFunction);
234237
m_writer.WriteLine(0, "vec4 %s(mat4 m, int i) { return vec4( m[0][i], m[1][i], m[2][i], m[3][i] ); }", m_matrixRowFunction);
235238

@@ -611,6 +614,7 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
611614
case HLSLBinaryOp_Sub: op = " - "; dstType1 = dstType2 = &binaryExpression->expressionType; break;
612615
case HLSLBinaryOp_Mul: op = " * "; dstType1 = dstType2 = &binaryExpression->expressionType; break;
613616
case HLSLBinaryOp_Div: op = " / "; dstType1 = dstType2 = &binaryExpression->expressionType; break;
617+
case HLSLBinaryOp_Mod: op = " % "; dstType1 = dstType2 = &kIntType; break;
614618
case HLSLBinaryOp_Less: op = " < "; dstType1 = dstType2 = commonScalarType(binaryExpression->expression1->expressionType, binaryExpression->expression2->expressionType); break;
615619
case HLSLBinaryOp_Greater: op = " > "; dstType1 = dstType2 = commonScalarType(binaryExpression->expression1->expressionType, binaryExpression->expression2->expressionType); break;
616620
case HLSLBinaryOp_LessEqual: op = " <= "; dstType1 = dstType2 = commonScalarType(binaryExpression->expression1->expressionType, binaryExpression->expression2->expressionType); break;
@@ -824,6 +828,19 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
824828
m_writer.Write(", 0.0, 1.0)");
825829
handled = true;
826830
}
831+
else if (String_Equal(functionName, "rsqrt"))
832+
{
833+
HLSLExpression* argument[1];
834+
if (GetFunctionArguments(functionCall, argument, 1) != 1)
835+
{
836+
Error("saturate expects 1 argument");
837+
return;
838+
}
839+
m_writer.Write("inversesqrt(");
840+
OutputExpression(argument[0]);
841+
m_writer.Write(")");
842+
handled = true;
843+
}
827844

828845
if (!handled)
829846
{
@@ -1115,7 +1132,14 @@ void GLSLGenerator::OutputStatements(int indent, HLSLStatement* statement, const
11151132
HLSLForStatement* forStatement = static_cast<HLSLForStatement*>(statement);
11161133
m_writer.BeginLine(indent, forStatement->fileName, forStatement->line);
11171134
m_writer.Write("for (");
1118-
OutputDeclaration(forStatement->initialization);
1135+
if (forStatement->initialization != NULL)
1136+
{
1137+
OutputDeclaration(forStatement->initialization);
1138+
}
1139+
else
1140+
{
1141+
OutputExpression(forStatement->initializationWithoutType);
1142+
}
11191143
m_writer.Write("; ");
11201144
OutputExpression(forStatement->condition, &kBoolType);
11211145
m_writer.Write("; ");
@@ -1136,6 +1160,13 @@ void GLSLGenerator::OutputStatements(int indent, HLSLStatement* statement, const
11361160
OutputStatements(indent + 1, whileStatement->statement, returnType);
11371161
m_writer.WriteLine(indent, "}");
11381162
}
1163+
else if (statement->nodeType == HLSLNodeType_BlockStatement)
1164+
{
1165+
HLSLBlockStatement* blockStatement = static_cast<HLSLBlockStatement*>(statement);
1166+
m_writer.WriteLine(indent, "{");
1167+
OutputStatements(indent + 1, blockStatement->statement, returnType);
1168+
m_writer.WriteLine(indent, "}");
1169+
}
11391170
else
11401171
{
11411172
// Unhanded statement type.

src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class GLSLGenerator
119119

120120
private:
121121

122-
static const int s_numReservedWords = 7;
122+
static const int s_numReservedWords = 9;
123123
static const char* s_reservedWord[s_numReservedWords];
124124

125125
CodeWriter m_writer;
@@ -161,4 +161,4 @@ class GLSLGenerator
161161

162162
}
163163

164-
#endif
164+
#endif

src/libprojectM/Renderer/hlslparser/src/HLSLParser.cpp

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <algorithm>
1717
#include <ctype.h>
1818
#include <string.h>
19+
#include <stack>
20+
#include <iostream>
1921

2022
namespace M4
2123
{
@@ -930,6 +932,7 @@ static const char* GetBinaryOpName(HLSLBinaryOp binaryOp)
930932
case HLSLBinaryOp_Sub: return "-";
931933
case HLSLBinaryOp_Mul: return "*";
932934
case HLSLBinaryOp_Div: return "/";
935+
case HLSLBinaryOp_Mod: return "%";
933936
case HLSLBinaryOp_Less: return "<";
934937
case HLSLBinaryOp_Greater: return ">";
935938
case HLSLBinaryOp_LessEqual: return "<=";
@@ -1118,6 +1121,25 @@ static CompareFunctionsResult CompareFunctions(HLSLTree* tree, const HLSLFunctio
11181121
}
11191122
}
11201123

1124+
// // Dump matched function argument types
1125+
// std::string arg1;
1126+
// std::string arg2;
1127+
// const HLSLArgument* argument1 = function1->argument;
1128+
// const HLSLArgument* argument2 = function2->argument;
1129+
// for (int i = 0; i < call->numArguments; ++i)
1130+
// {
1131+
// arg1 += GetTypeName(argument1->type);
1132+
// arg1 += " ";
1133+
// arg2 += GetTypeName(argument2->type);
1134+
// arg2 += " ";
1135+
1136+
// argument1 = argument1->nextArgument;
1137+
// argument2 = argument2->nextArgument;
1138+
// }
1139+
1140+
// std::cout << "(" << arg1 << ") vs (" << arg2 << ")" << std::endl;
1141+
1142+
11211143
return FunctionsEqual;
11221144

11231145
}
@@ -1726,7 +1748,7 @@ bool HLSLParser::ParseStatement(HLSLStatement*& statement, const HLSLType& retur
17261748
return false;
17271749
}
17281750
BeginScope();
1729-
if (!ParseDeclaration(forStatement->initialization))
1751+
if (!ParseDeclaration(forStatement->initialization) && !ParseExpression(forStatement->initializationWithoutType))
17301752
{
17311753
return false;
17321754
}
@@ -2047,6 +2069,7 @@ bool HLSLParser::AcceptBinaryOperator(int priority, HLSLBinaryOp& binaryOp)
20472069
case '-': binaryOp = HLSLBinaryOp_Sub; break;
20482070
case '*': binaryOp = HLSLBinaryOp_Mul; break;
20492071
case '/': binaryOp = HLSLBinaryOp_Div; break;
2072+
case '%': binaryOp = HLSLBinaryOp_Mod; break;
20502073
case '<': binaryOp = HLSLBinaryOp_Less; break;
20512074
case '>': binaryOp = HLSLBinaryOp_Greater; break;
20522075
case HLSLToken_LessEqual: binaryOp = HLSLBinaryOp_LessEqual; break;
@@ -2196,7 +2219,7 @@ bool HLSLParser::ParseBinaryExpression(int priority, HLSLExpression*& expression
21962219
{
21972220
const char* srcTypeName = GetTypeName(expression2->expressionType);
21982221
const char* dstTypeName = GetTypeName(expression1->expressionType);
2199-
m_tokenizer.Error("':' no possible conversion from from '%s' to '%s'", srcTypeName, dstTypeName);
2222+
m_tokenizer.Error("':' no possible conversion from '%s' to '%s'", srcTypeName, dstTypeName);
22002223
return false;
22012224
}
22022225

@@ -3468,14 +3491,47 @@ bool HLSLParser::ApplyPreprocessor(const char* fileName, const char* buffer, siz
34683491
index++;
34693492
}
34703493

3471-
// Fouth pass, search and replace define uses
3494+
// Fouth pass, search and replace preprocessor directives
3495+
std::stack<bool> isCodeActive;
3496+
isCodeActive.push(true);
34723497
m_tokenizer = HLSLTokenizer(fileName, buffer, length);
34733498
sourcePreprocessed.clear();
34743499
while (m_tokenizer.GetToken() != HLSLToken_EndOfStream)
34753500
{
34763501
bool addOriginalSource = true;
34773502

3478-
if (m_tokenizer.GetToken() == HLSLToken_PreprocessorDefine)
3503+
if (m_tokenizer.GetToken() == HLSLToken_PreprocessorIf)
3504+
{
3505+
while (m_tokenizer.GetToken() != HLSLToken_IntLiteral && m_tokenizer.GetToken() != HLSLToken_EndOfLine)
3506+
{
3507+
m_tokenizer.Next(false);
3508+
}
3509+
3510+
if (m_tokenizer.GetToken() == HLSLToken_IntLiteral)
3511+
{
3512+
isCodeActive.push(m_tokenizer.GetInt() != 0);
3513+
}
3514+
else
3515+
{
3516+
m_tokenizer.Error("#if evaluation failed: not an integer");
3517+
return false;
3518+
}
3519+
addOriginalSource = false;
3520+
}
3521+
else if (m_tokenizer.GetToken() == HLSLToken_PreprocessorElse)
3522+
{
3523+
// Invert stack state
3524+
bool state = isCodeActive.top();
3525+
isCodeActive.pop();
3526+
isCodeActive.push(!state);
3527+
addOriginalSource = false;
3528+
}
3529+
else if (m_tokenizer.GetToken() == HLSLToken_PreprocessorEndif)
3530+
{
3531+
isCodeActive.pop();
3532+
addOriginalSource = false;
3533+
}
3534+
else if (m_tokenizer.GetToken() == HLSLToken_PreprocessorDefine)
34793535
{
34803536
// Skip macros definition
34813537
while(m_tokenizer.GetToken() != HLSLToken_EndOfLine)
@@ -3485,10 +3541,14 @@ bool HLSLParser::ApplyPreprocessor(const char* fileName, const char* buffer, siz
34853541

34863542
addOriginalSource = false;
34873543
}
3488-
else if (m_tokenizer.GetToken() == HLSLToken_Identifier)
3544+
else if (m_tokenizer.GetToken() == HLSLToken_Identifier && isCodeActive.top())
34893545
{
34903546
ProcessMacroFromIdentifier(sourcePreprocessed, addOriginalSource);
34913547
}
3548+
else if (!isCodeActive.top())
3549+
{
3550+
addOriginalSource = false;
3551+
}
34923552

34933553
if (addOriginalSource)
34943554
{
@@ -3500,7 +3560,7 @@ bool HLSLParser::ApplyPreprocessor(const char* fileName, const char* buffer, siz
35003560
}
35013561

35023562

3503-
return true;
3563+
return isCodeActive.size() == 1;
35043564
}
35053565

35063566

@@ -3849,6 +3909,7 @@ bool HLSLParser::AcceptType(bool allowVoid, HLSLType& type/*, bool acceptFlags*/
38493909

38503910
if (!Expect('>'))
38513911
{
3912+
m_tokenizer.Error("Syntax error: '>' expected for sampler type");
38523913
return false;
38533914
}
38543915
}

src/libprojectM/Renderer/hlslparser/src/HLSLTokenizer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ static const char* _reservedWords[] =
7474
"static",
7575
"inline",
7676
"#define",
77+
"#if",
78+
"#else",
79+
"#endif",
7780
"uniform",
7881
"in",
7982
"out",
@@ -93,7 +96,7 @@ static bool GetIsSymbol(char c)
9396
case '[': case ']':
9497
case '{': case '}':
9598
case '-': case '+':
96-
case '*': case '/':
99+
case '*': case '/': case '%':
97100
case '?':
98101
case '!':
99102
case ',':

src/libprojectM/Renderer/hlslparser/src/HLSLTokenizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ enum HLSLToken
6969
HLSLToken_Static,
7070
HLSLToken_Inline,
7171
HLSLToken_PreprocessorDefine,
72+
HLSLToken_PreprocessorIf,
73+
HLSLToken_PreprocessorElse,
74+
HLSLToken_PreprocessorEndif,
7275

7376
// Input modifiers.
7477
HLSLToken_Uniform,

src/libprojectM/Renderer/hlslparser/src/HLSLTree.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ bool HLSLTree::GetExpressionValue(HLSLExpression * expression, int & value)
383383
case HLSLBinaryOp_Div:
384384
value = value1 / value2;
385385
return true;
386+
case HLSLBinaryOp_Mod:
387+
value = value1 % value2;
388+
return true;
386389
case HLSLBinaryOp_Less:
387390
value = value1 < value2;
388391
return true;
@@ -615,6 +618,9 @@ int HLSLTree::GetExpressionValue(HLSLExpression * expression, float values[4])
615618
case HLSLBinaryOp_Div:
616619
for (int i = 0; i < dim; i++) values[i] = values1[i] / values2[i];
617620
return dim;
621+
case HLSLBinaryOp_Mod:
622+
for (int i = 0; i < dim; i++) values[i] = int(values1[i]) % int(values2[i]);
623+
return dim;
618624
default:
619625
return 0;
620626
}
@@ -772,6 +778,9 @@ void HLSLTreeVisitor::VisitStatement(HLSLStatement * node)
772778
else if (node->nodeType == HLSLNodeType_ForStatement) {
773779
VisitForStatement((HLSLForStatement *)node);
774780
}
781+
else if (node->nodeType == HLSLNodeType_WhileStatement) {
782+
VisitWhileStatement((HLSLWhileStatement *)node);
783+
}
775784
else if (node->nodeType == HLSLNodeType_BlockStatement) {
776785
VisitBlockStatement((HLSLBlockStatement *)node);
777786
}
@@ -926,6 +935,14 @@ void HLSLTreeVisitor::VisitForStatement(HLSLForStatement * node)
926935
VisitStatements(node->statement);
927936
}
928937

938+
void HLSLTreeVisitor::VisitWhileStatement(HLSLWhileStatement * node)
939+
{
940+
if (node->condition) {
941+
VisitExpression(node->condition);
942+
}
943+
VisitStatements(node->statement);
944+
}
945+
929946
void HLSLTreeVisitor::VisitBlockStatement(HLSLBlockStatement * node)
930947
{
931948
VisitStatements(node->statement);

src/libprojectM/Renderer/hlslparser/src/HLSLTree.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ enum HLSLBinaryOp
185185
HLSLBinaryOp_Sub,
186186
HLSLBinaryOp_Mul,
187187
HLSLBinaryOp_Div,
188+
HLSLBinaryOp_Mod,
188189
HLSLBinaryOp_Less,
189190
HLSLBinaryOp_Greater,
190191
HLSLBinaryOp_LessEqual,
@@ -216,7 +217,8 @@ inline bool IsArithmeticOp( HLSLBinaryOp op )
216217
return op == HLSLBinaryOp_Add ||
217218
op == HLSLBinaryOp_Sub ||
218219
op == HLSLBinaryOp_Mul ||
219-
op == HLSLBinaryOp_Div;
220+
op == HLSLBinaryOp_Div ||
221+
op == HLSLBinaryOp_Mod;
220222
}
221223

222224
inline bool IsLogicOp( HLSLBinaryOp op )
@@ -597,6 +599,7 @@ struct HLSLForStatement : public HLSLStatement
597599
statement = NULL;
598600
}
599601
HLSLDeclaration* initialization;
602+
HLSLExpression* initializationWithoutType;
600603
HLSLExpression* condition;
601604
HLSLExpression* increment;
602605
HLSLStatement* statement;
@@ -962,6 +965,7 @@ class HLSLTreeVisitor
962965
virtual void VisitContinueStatement(HLSLContinueStatement * node);
963966
virtual void VisitIfStatement(HLSLIfStatement * node);
964967
virtual void VisitForStatement(HLSLForStatement * node);
968+
virtual void VisitWhileStatement(HLSLWhileStatement * node);
965969
virtual void VisitBlockStatement(HLSLBlockStatement * node);
966970
virtual void VisitUnaryExpression(HLSLUnaryExpression * node);
967971
virtual void VisitBinaryExpression(HLSLBinaryExpression * node);

0 commit comments

Comments
 (0)