Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLSL: Possibility to represent variable in binary form #3259

Merged
merged 1 commit into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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