Skip to content

Commit

Permalink
HLSL: support binary literals
Browse files Browse the repository at this point in the history
  • Loading branch information
Dawid-Lorenz-Mobica authored and kd-11 committed Dec 11, 2023
1 parent 1804b08 commit a94c5ff
Show file tree
Hide file tree
Showing 10 changed files with 745 additions and 252 deletions.
369 changes: 267 additions & 102 deletions Test/baseResults/hlsl.conditional.frag.out

Large diffs are not rendered by default.

370 changes: 225 additions & 145 deletions Test/baseResults/hlsl.numericsuffixes.frag.out

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions Test/baseResults/hlsl.numericsuffixes.negative.frag.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
hlsl.numericsuffixes.negative.frag
ERROR: 0:7: '' : bad digit in binary literal
ERROR: 0:8: '' : binary literal too big
ERROR: 0:9: '' : bad digit in hexadecimal literal
ERROR: 0:10: '' : hexadecimal literal too big
ERROR: 4 compilation errors. No code generated.


Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:5 Function Definition: @main( ( temp structure{ temp 4-component vector of float color})
0:5 Function Parameters:
0:? Sequence
0:7 Sequence
0:7 move second child to first child ( temp uint)
0:7 'r01' ( temp uint)
0:7 Constant:
0:7 0 (const uint)
0:8 Sequence
0:8 move second child to first child ( temp uint)
0:8 'r02' ( temp uint)
0:8 Constant:
0:8 4294967295 (const uint)
0:10 Sequence
0:9 move second child to first child ( temp uint)
0:9 'r03' ( temp uint)
0:9 Constant:
0:9 0 (const uint)
0:10 move second child to first child ( temp uint)
0:10 'r04' ( temp uint)
0:10 Constant:
0:10 4294967295 (const uint)
0:13 move second child to first child ( temp 4-component vector of float)
0:13 color: direct index for structure ( temp 4-component vector of float)
0:13 'ps_output' ( temp structure{ temp 4-component vector of float color})
0:13 Constant:
0:13 0 (const int)
0:13 Construct vec4 ( temp 4-component vector of float)
0:13 Convert uint to float ( temp float)
0:13 'r01' ( temp uint)
0:14 Branch: Return with expression
0:14 'ps_output' ( temp structure{ temp 4-component vector of float color})
0:5 Function Definition: main( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:5 Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput.color' (layout( location=0) out 4-component vector of float)
0:5 color: direct index for structure ( temp 4-component vector of float)
0:5 Function Call: @main( ( temp structure{ temp 4-component vector of float color})
0:5 Constant:
0:5 0 (const int)
0:? Linker Objects
0:? '@entryPointOutput.color' (layout( location=0) out 4-component vector of float)


Linked fragment stage:


Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:5 Function Definition: @main( ( temp structure{ temp 4-component vector of float color})
0:5 Function Parameters:
0:? Sequence
0:7 Sequence
0:7 move second child to first child ( temp uint)
0:7 'r01' ( temp uint)
0:7 Constant:
0:7 0 (const uint)
0:8 Sequence
0:8 move second child to first child ( temp uint)
0:8 'r02' ( temp uint)
0:8 Constant:
0:8 4294967295 (const uint)
0:10 Sequence
0:9 move second child to first child ( temp uint)
0:9 'r03' ( temp uint)
0:9 Constant:
0:9 0 (const uint)
0:10 move second child to first child ( temp uint)
0:10 'r04' ( temp uint)
0:10 Constant:
0:10 4294967295 (const uint)
0:13 move second child to first child ( temp 4-component vector of float)
0:13 color: direct index for structure ( temp 4-component vector of float)
0:13 'ps_output' ( temp structure{ temp 4-component vector of float color})
0:13 Constant:
0:13 0 (const int)
0:13 Construct vec4 ( temp 4-component vector of float)
0:13 Convert uint to float ( temp float)
0:13 'r01' ( temp uint)
0:14 Branch: Return with expression
0:14 'ps_output' ( temp structure{ temp 4-component vector of float color})
0:5 Function Definition: main( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:5 Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput.color' (layout( location=0) out 4-component vector of float)
0:5 color: direct index for structure ( temp 4-component vector of float)
0:5 Function Call: @main( ( temp structure{ temp 4-component vector of float color})
0:5 Constant:
0:5 0 (const int)
0:? Linker Objects
0:? '@entryPointOutput.color' (layout( location=0) out 4-component vector of float)

SPIR-V is not generated for failed compile or link
9 changes: 6 additions & 3 deletions Test/baseResults/tokenLength.vert.out
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ ERROR: 0:62: 'preprocessor evaluation' : undefined macro in expression not allow
ERROR: 0:67: '' : numeric literal too long
ERROR: 0:70: '' : name too long
ERROR: 0:70: 'preprocessor evaluation' : undefined macro in expression not allowed in es profile A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ERROR: 26 compilation errors. No code generated.
ERROR: 0:74: '' : syntax error, unexpected IDENTIFIER, expecting COMMA or SEMICOLON
ERROR: 27 compilation errors. No code generated.


Shader version: 300
Expand Down Expand Up @@ -56,7 +57,7 @@ ERROR: node is still EOpNull!
0:14 move second child to first child ( temp highp int)
0:14 'HE' ( global highp int)
0:14 Constant:
0:14 -1 (const int)
0:14 180150000 (const int)
0:17 Sequence
0:17 move second child to first child ( temp highp float)
0:17 'F' ( global highp float)
Expand Down Expand Up @@ -119,6 +120,7 @@ ERROR: node is still EOpNull!
0:? 'superO' ( global highp int)
0:? 'superI' ( global highp int)
0:? 'superF' ( global highp float)
0:? 'BE' ( global highp int)
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)

Expand Down Expand Up @@ -152,7 +154,7 @@ ERROR: node is still EOpNull!
0:14 move second child to first child ( temp highp int)
0:14 'HE' ( global highp int)
0:14 Constant:
0:14 -1 (const int)
0:14 180150000 (const int)
0:17 Sequence
0:17 move second child to first child ( temp highp float)
0:17 'F' ( global highp float)
Expand Down Expand Up @@ -215,6 +217,7 @@ ERROR: node is still EOpNull!
0:? 'superO' ( global highp int)
0:? 'superI' ( global highp int)
0:? 'superF' ( global highp float)
0:? 'BE' ( global highp int)
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)

4 changes: 4 additions & 0 deletions Test/hlsl.conditional.frag
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ float4 PixelShaderFunction(float4 input) : COLOR0
e = a = b ? c = d : 10, b = a ? d = c : 11;
float4 f;
f = ret.x < input.y ? c * input : d * input;
uint g = d > 0.0 ? 0b010101u : 0u;
uint h = g > 0.0 ? 0B111111u : 0u;
uint i = h > 0.0 ? 0b0101u : 0B01;
uint j = i > 0.0 ? 0xabcd : 0xbcda;
return e * ret + f + vectorCond() + scalarCond() +
float4(fbSelect(bool2(true, false), float2(1.0, 2.0), float2(3.0, 4.0)), 10.0, 10.0);
}
11 changes: 10 additions & 1 deletion Test/hlsl.numericsuffixes.frag
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@

struct PS_OUTPUT { float4 color : SV_Target0; };

#define BIN_UINT 0b00001u
#define BIN_INT 0b00011

PS_OUTPUT main()
{
// Test numeric suffixes
float r00 = 1.0f; // float
uint r01 = 1u; // lower uint
uint r02 = 2U; // upper uint
uint r03 = 0xabcu; // lower hex uint
uint r04 = 0xABCU; // upper hex uint (upper 0X is not accepted)
uint r04 = 0XABCU; // upper hex uint
int r05 = 5l; // lower long int
int r06 = 6L; // upper long int
int r07 = 071; // octal
Expand All @@ -17,6 +20,12 @@ PS_OUTPUT main()
float r10 = 1.H; // half
float r11 = 1.1h; // half
float r12 = 1.1H; // half
uint r13 = 0b00001u;// lower binary uint
uint r14 = 0B00010U;// upper binary uint
int r15 = 0b00011; // lower binary int
int r16 = 0B00100; // upper binary int
uint r17 = BIN_UINT;// lower binart define uint
int r18 = BIN_INT; // lower binart define int

PS_OUTPUT ps_output;
ps_output.color = r07; // gets 71 octal = 57 decimal
Expand Down
15 changes: 15 additions & 0 deletions Test/hlsl.numericsuffixes.negative.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

struct PS_OUTPUT { float4 color : SV_Target0; };

PS_OUTPUT main()
{
// Test numeric suffixes
uint r01 = 0bERROR321u; // Bad digit
uint r02 = 0b11111111111111111111111111111111111111111111111111111111111111111u; // To big
uint r03 = 0xTESTu // Bad digit
uint r04 = 0xFFFFFFFFFFFFFFFFFFu; // To big

PS_OUTPUT ps_output;
ps_output.color = r01;
return ps_output;
}
2 changes: 2 additions & 0 deletions Test/tokenLength.vert
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ float superF = 1.012345678901234567890123456789012345678901234567890123456789012
#if A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
#error in super long macro #if
#endif

int BE = 0b01u; // ERROR (not supported by GLSL)
107 changes: 106 additions & 1 deletion glslang/MachineIndependent/preprocessor/PpScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2017 ARM Limited.
// Copyright (C) 2015-2018 Google, Inc.
// Copyright (c) 2023, Mobica Limited
//
// All rights reserved.
//
Expand Down Expand Up @@ -549,7 +550,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)

ival = 0;
do {
if (len < MaxTokenLength && ival <= 0x0fffffffffffffffull) {
if (len < MaxTokenLength && ival <= 0x7fffffffffffffffull) {
ppToken->name[len++] = (char)ch;
if (ch >= '0' && ch <= '9') {
ii = ch - '0';
Expand Down Expand Up @@ -639,6 +640,110 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->ival = (int)ival;
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
}
} else if ((ch == 'b' || ch == 'B') && pp->parseContext.intermediate.getSource() == EShSourceHlsl) {
// must be binary
bool isUnsigned = false;
bool isInt64 = false;
bool isInt16 = false;
ppToken->name[len++] = (char)ch;
ch = getch();

// Check value
if ((ch == '0' || ch == '1'))
{
ival = 0;
do {
if (len < MaxTokenLength && ival <= 0x7fffffffffffffffull) {
ppToken->name[len++] = (char)ch;
if (ch == '0' || ch == '1') {
ii = ch - '0';
} else {
pp->parseContext.ppError(ppToken->loc, "bad digit in binary literal", "", "");
}
ival = (ival << 1) | ii;
}
else
{
if (! AlreadyComplained) {
if(len < MaxTokenLength)
pp->parseContext.ppError(ppToken->loc, "binary literal too big", "", "");
else
pp->parseContext.ppError(ppToken->loc, "binary literal too long", "", "");
AlreadyComplained = 1;
}
ival = 0xffffffffffffffffull;
}
ch = getch();
} while (ch == '0' || ch == '1');
}
else
{
pp->parseContext.ppError(ppToken->loc, "bad digit in binary literal", "", "");
}

// check type
if (ch == 'u' || ch == 'U') {
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isUnsigned = true;

#ifndef GLSLANG_WEB
int nextCh = getch();
if (nextCh == 'l' || nextCh == 'L') {
if (len < MaxTokenLength)
ppToken->name[len++] = (char)nextCh;
isInt64 = true;
} else
ungetch();

nextCh = getch();
if ((nextCh == 's' || nextCh == 'S') &&
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
if (len < MaxTokenLength)
ppToken->name[len++] = (char)nextCh;
isInt16 = true;
} else
ungetch();
} else if (ch == 'l' || ch == 'L') {
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt64 = true;
} else if ((ch == 's' || ch == 'S') &&
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt16 = true;
#endif
} else {
ungetch();
}
ppToken->name[len] = '\0';

// Assign value
if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
if (pp->ifdepth == 0) {
pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile,
"64-bit binary literal");
pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0,
Num_Int64_Extensions, Int64_Extensions, "64-bit binary literal");
}
ppToken->i64val = ival;
return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
} else if (isInt16) {
if (pp->ifdepth == 0) {
if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile,
"16-bit binary literal");
pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0,
Num_Int16_Extensions, Int16_Extensions, "16-bit binary literal");
}
}
ppToken->ival = (int)ival;
return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16;
} else {
ppToken->ival = (int)ival;
return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
}
} else {
// could be octal integer or floating point, speculative pursue octal until it must be floating point

Expand Down
1 change: 1 addition & 0 deletions gtests/Hlsl.FromFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ INSTANTIATE_TEST_SUITE_P(
{"hlsl.matrixindex.frag", "main"},
{"hlsl.nonstaticMemberFunction.frag", "main"},
{"hlsl.numericsuffixes.frag", "main"},
{"hlsl.numericsuffixes.negative.frag", "main"},
{"hlsl.numthreads.comp", "main_aux2"},
{"hlsl.overload.frag", "PixelShaderFunction"},
{"hlsl.opaque-type-bug.frag", "main"},
Expand Down

0 comments on commit a94c5ff

Please sign in to comment.