зеркало из https://github.com/stride3d/xkslang.git
HLSL: allow implicit array sizing.
In HLSL array sizes need not be provided explicitly in all circumstances. For example, this is valid (note no number between the [ ]): // no explicit array size uniform float g_array[] = { 1, 2, 3, 4, 5 }; This PR does not attempt to validate most invalid cases. A new test is added to verify the resulting linker objects.
This commit is contained in:
Родитель
16a99a3804
Коммит
265c0618b1
|
@ -0,0 +1,264 @@
|
|||
hlsl.array.implicit-size.frag
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:26 Function Definition: main(struct-PS_OUTPUT-vf41; (global void)
|
||||
0:26 Function Parameters:
|
||||
0:26 'ps_output' (out structure{temp 4-component vector of float color})
|
||||
0:? Sequence
|
||||
0:28 Sequence
|
||||
0:28 move second child to first child (temp 3-element array of float)
|
||||
0:28 'l_array' (temp 3-element array of float)
|
||||
0:28 Constant:
|
||||
0:28 1.000000
|
||||
0:28 2.000000
|
||||
0:28 3.000000
|
||||
0:30 move second child to first child (temp 4-component vector of float)
|
||||
0:30 color: direct index for structure (temp 4-component vector of float)
|
||||
0:30 'ps_output' (out structure{temp 4-component vector of float color})
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 Construct vec4 (temp 4-component vector of float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 Constant:
|
||||
0:30 4 (const int)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'l_array' (temp 3-element array of float)
|
||||
0:30 Constant:
|
||||
0:30 1 (const int)
|
||||
0:30 f: direct index for structure (temp float)
|
||||
0:30 direct index (temp structure{temp int i, temp float f})
|
||||
0:30 'g_mystruct' (uniform 2-element array of structure{temp int i, temp float f})
|
||||
0:30 1 (const int)
|
||||
0:30 2.000000
|
||||
0:30 3 (const int)
|
||||
0:30 4.000000
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 Constant:
|
||||
0:30 1 (const int)
|
||||
0:30 indirect index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 'idx' (temp void)
|
||||
0:? Linker Objects
|
||||
0:? 'g_array' (uniform 5-element array of float)
|
||||
0:? 1.000000
|
||||
0:? 2.000000
|
||||
0:? 3.000000
|
||||
0:? 4.000000
|
||||
0:? 5.000000
|
||||
0:? 'g_array_unused' (uniform 7-element array of float)
|
||||
0:? 1.000000
|
||||
0:? 2.000000
|
||||
0:? 3.000000
|
||||
0:? 4.000000
|
||||
0:? 5.000000
|
||||
0:? 6.000000
|
||||
0:? 7.000000
|
||||
0:? 'g_mystruct' (uniform 2-element array of structure{temp int i, temp float f})
|
||||
0:? 1 (const int)
|
||||
0:? 2.000000
|
||||
0:? 3 (const int)
|
||||
0:? 4.000000
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:26 Function Definition: main(struct-PS_OUTPUT-vf41; (global void)
|
||||
0:26 Function Parameters:
|
||||
0:26 'ps_output' (out structure{temp 4-component vector of float color})
|
||||
0:? Sequence
|
||||
0:28 Sequence
|
||||
0:28 move second child to first child (temp 3-element array of float)
|
||||
0:28 'l_array' (temp 3-element array of float)
|
||||
0:28 Constant:
|
||||
0:28 1.000000
|
||||
0:28 2.000000
|
||||
0:28 3.000000
|
||||
0:30 move second child to first child (temp 4-component vector of float)
|
||||
0:30 color: direct index for structure (temp 4-component vector of float)
|
||||
0:30 'ps_output' (out structure{temp 4-component vector of float color})
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 Construct vec4 (temp 4-component vector of float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 add (temp float)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 Constant:
|
||||
0:30 4 (const int)
|
||||
0:30 direct index (temp float)
|
||||
0:30 'l_array' (temp 3-element array of float)
|
||||
0:30 Constant:
|
||||
0:30 1 (const int)
|
||||
0:30 f: direct index for structure (temp float)
|
||||
0:30 direct index (temp structure{temp int i, temp float f})
|
||||
0:30 'g_mystruct' (uniform 2-element array of structure{temp int i, temp float f})
|
||||
0:30 1 (const int)
|
||||
0:30 2.000000
|
||||
0:30 3 (const int)
|
||||
0:30 4.000000
|
||||
0:30 Constant:
|
||||
0:30 0 (const int)
|
||||
0:30 Constant:
|
||||
0:30 1 (const int)
|
||||
0:30 indirect index (temp float)
|
||||
0:30 'g_array' (uniform 5-element array of float)
|
||||
0:30 1.000000
|
||||
0:30 2.000000
|
||||
0:30 3.000000
|
||||
0:30 4.000000
|
||||
0:30 5.000000
|
||||
0:30 'idx' (temp void)
|
||||
0:? Linker Objects
|
||||
0:? 'g_array' (uniform 5-element array of float)
|
||||
0:? 1.000000
|
||||
0:? 2.000000
|
||||
0:? 3.000000
|
||||
0:? 4.000000
|
||||
0:? 5.000000
|
||||
0:? 'g_array_unused' (uniform 7-element array of float)
|
||||
0:? 1.000000
|
||||
0:? 2.000000
|
||||
0:? 3.000000
|
||||
0:? 4.000000
|
||||
0:? 5.000000
|
||||
0:? 6.000000
|
||||
0:? 7.000000
|
||||
0:? 'g_mystruct' (uniform 2-element array of structure{temp int i, temp float f})
|
||||
0:? 1 (const int)
|
||||
0:? 2.000000
|
||||
0:? 3 (const int)
|
||||
0:? 4.000000
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 62
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "PixelShaderFunction"
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Name 4 "PixelShaderFunction"
|
||||
Name 8 "PS_OUTPUT"
|
||||
MemberName 8(PS_OUTPUT) 0 "color"
|
||||
Name 12 "main(struct-PS_OUTPUT-vf41;"
|
||||
Name 11 "ps_output"
|
||||
Name 18 "l_array"
|
||||
Name 28 "g_array"
|
||||
Name 41 "mystruct"
|
||||
MemberName 41(mystruct) 0 "i"
|
||||
MemberName 41(mystruct) 1 "f"
|
||||
Name 45 "g_mystruct"
|
||||
Name 50 "idx"
|
||||
Name 61 "g_array_unused"
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7: TypeVector 6(float) 4
|
||||
8(PS_OUTPUT): TypeStruct 7(fvec4)
|
||||
9: TypePointer Function 8(PS_OUTPUT)
|
||||
10: TypeFunction 2 9(ptr)
|
||||
14: TypeInt 32 0
|
||||
15: 14(int) Constant 3
|
||||
16: TypeArray 6(float) 15
|
||||
17: TypePointer Function 16
|
||||
19: 6(float) Constant 1065353216
|
||||
20: 6(float) Constant 1073741824
|
||||
21: 6(float) Constant 1077936128
|
||||
22: 16 ConstantComposite 19 20 21
|
||||
23: TypeInt 32 1
|
||||
24: 23(int) Constant 0
|
||||
25: 14(int) Constant 5
|
||||
26: TypeArray 6(float) 25
|
||||
27: TypePointer UniformConstant 26
|
||||
28(g_array): 27(ptr) Variable UniformConstant
|
||||
29: TypePointer UniformConstant 6(float)
|
||||
32: 23(int) Constant 4
|
||||
36: 23(int) Constant 1
|
||||
37: TypePointer Function 6(float)
|
||||
41(mystruct): TypeStruct 23(int) 6(float)
|
||||
42: 14(int) Constant 2
|
||||
43: TypeArray 41(mystruct) 42
|
||||
44: TypePointer UniformConstant 43
|
||||
45(g_mystruct): 44(ptr) Variable UniformConstant
|
||||
49: TypePointer Function 2
|
||||
56: TypePointer Function 7(fvec4)
|
||||
58: 14(int) Constant 7
|
||||
59: TypeArray 6(float) 58
|
||||
60: TypePointer UniformConstant 59
|
||||
61(g_array_unused): 60(ptr) Variable UniformConstant
|
||||
4(PixelShaderFunction): 2 Function None 3
|
||||
5: Label
|
||||
FunctionEnd
|
||||
12(main(struct-PS_OUTPUT-vf41;): 2 Function None 10
|
||||
11(ps_output): 9(ptr) FunctionParameter
|
||||
13: Label
|
||||
18(l_array): 17(ptr) Variable Function
|
||||
50(idx): 49(ptr) Variable Function
|
||||
Store 18(l_array) 22
|
||||
30: 29(ptr) AccessChain 28(g_array) 24
|
||||
31: 6(float) Load 30
|
||||
33: 29(ptr) AccessChain 28(g_array) 32
|
||||
34: 6(float) Load 33
|
||||
35: 6(float) FAdd 31 34
|
||||
38: 37(ptr) AccessChain 18(l_array) 36
|
||||
39: 6(float) Load 38
|
||||
40: 6(float) FAdd 35 39
|
||||
46: 29(ptr) AccessChain 45(g_mystruct) 24 36
|
||||
47: 6(float) Load 46
|
||||
48: 6(float) FAdd 40 47
|
||||
51: 2 Load 50(idx)
|
||||
52: 29(ptr) AccessChain 28(g_array) 51
|
||||
53: 6(float) Load 52
|
||||
54: 6(float) FAdd 48 53
|
||||
55: 7(fvec4) CompositeConstruct 54 54 54 54
|
||||
57: 56(ptr) AccessChain 11(ps_output) 24
|
||||
Store 57 55
|
||||
Return
|
||||
FunctionEnd
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
// implicit sized array
|
||||
uniform float g_array [ ] = { 1, 2, 3, 4, 5 };
|
||||
|
||||
// Unused implicit sized array
|
||||
uniform float g_array_unused [ ] = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
// Test implicit size arrayed structs
|
||||
uniform struct mystruct {
|
||||
int i;
|
||||
float f;
|
||||
} g_mystruct[] = {
|
||||
{ 1, 2.0 },
|
||||
{ 3, 4.0 },
|
||||
};
|
||||
|
||||
struct PS_OUTPUT { float4 color : SV_Target0; };
|
||||
|
||||
// INVALID: implicit size requires an initializer expression.
|
||||
// uniform float bad[];
|
||||
|
||||
// INVALID: function parameters cannot be implicitly sized
|
||||
// void BadFunction(int a[]) { }
|
||||
|
||||
void main(out PS_OUTPUT ps_output)
|
||||
{
|
||||
// implicit sized local array
|
||||
float l_array[] = { 1, 2, 3 };
|
||||
|
||||
ps_output.color = g_array[0] + g_array[4] + l_array[1] + g_mystruct[0].f + g_array[idx];
|
||||
}
|
|
@ -81,6 +81,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
ToSpirv, HlslCompileTest,
|
||||
::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
|
||||
{"hlsl.array.frag", "PixelShaderFunction"},
|
||||
{"hlsl.array.implicit-size.frag", "PixelShaderFunction"},
|
||||
{"hlsl.assoc.frag", "PixelShaderFunction"},
|
||||
{"hlsl.attribute.frag", "PixelShaderFunction"},
|
||||
{"hlsl.buffer.frag", "PixelShaderFunction"},
|
||||
|
|
|
@ -1515,8 +1515,14 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
|
|||
// array_specifier
|
||||
TArraySizes* arraySizes = nullptr;
|
||||
acceptArraySpecifier(arraySizes);
|
||||
if (arraySizes)
|
||||
if (arraySizes) {
|
||||
if (arraySizes->isImplicit()) {
|
||||
parseContext.error(token.loc, "function parameter array cannot be implicitly sized", "", "");
|
||||
return false;
|
||||
}
|
||||
|
||||
type->newArraySizes(*arraySizes);
|
||||
}
|
||||
|
||||
// post_decls
|
||||
acceptPostDecls(type->getQualifier());
|
||||
|
@ -2601,6 +2607,7 @@ bool HlslGrammar::acceptDefaultLabel(TIntermNode*& statement)
|
|||
|
||||
// array_specifier
|
||||
// : LEFT_BRACKET integer_expression RGHT_BRACKET post_decls // optional
|
||||
// : LEFT_BRACKET RGHT_BRACKET post_decls // optional
|
||||
//
|
||||
void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes)
|
||||
{
|
||||
|
@ -2610,21 +2617,25 @@ void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes)
|
|||
return;
|
||||
|
||||
TSourceLoc loc = token.loc;
|
||||
TIntermTyped* sizeExpr;
|
||||
if (! acceptAssignmentExpression(sizeExpr)) {
|
||||
expected("array-sizing expression");
|
||||
return;
|
||||
}
|
||||
TIntermTyped* sizeExpr = nullptr;
|
||||
|
||||
// Array sizing expression is optional. If ommitted, array is implicitly sized.
|
||||
const bool hasArraySize = acceptAssignmentExpression(sizeExpr);
|
||||
|
||||
if (! acceptTokenClass(EHTokRightBracket)) {
|
||||
expected("]");
|
||||
return;
|
||||
}
|
||||
|
||||
arraySizes = new TArraySizes;
|
||||
|
||||
if (hasArraySize) {
|
||||
TArraySize arraySize;
|
||||
parseContext.arraySizeCheck(loc, sizeExpr, arraySize);
|
||||
arraySizes = new TArraySizes;
|
||||
arraySizes->addInnerSize(arraySize);
|
||||
} else {
|
||||
arraySizes->addInnerSize(); // implicitly sized
|
||||
}
|
||||
}
|
||||
|
||||
// post_decls
|
||||
|
|
Загрузка…
Ссылка в новой задаче