mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match, such as for example clamp(int, bool, float). In this case the int and bool will be promoted to a float, and the clamp(float, float, float) form used. These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2). Output conversions are handled either via the existing addOutputArgumentConversion function, which this PR generalizes to handle either aggregates or unaries, or by intrinsic decomposition. If there are methods or intrinsics to be decomposed, then decomposition is responsible for any output conversions, which turns out to happen automatically in all current cases. This can be revisited once inout conversions are in place. Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.* Some intrinsics with only uint versions were expanded to signed ints natively, where the underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous conversion nodes. A new function promoteAggregate is added, and used by findFunction. This is essentially a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary. The actual selection proceeds in three steps, as described in the comments in hlslParseContext::findFunction: 1. Attempt an exact match. If found, use it. 2. If not, obtain the operator from step 1, and promote arguments. 3. Re-select the intrinsic overload from the results of step 2.
This commit is contained in:
parent
1c573fbcfb
commit
ef33ec0925
File diff suppressed because it is too large
Load Diff
184
Test/baseResults/hlsl.intrinsics.promote.down.frag.out
Normal file
184
Test/baseResults/hlsl.intrinsics.promote.down.frag.out
Normal file
@ -0,0 +1,184 @@
|
||||
hlsl.intrinsics.promote.down.frag
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:15 Function Definition: main( (temp structure{temp 4-component vector of float color})
|
||||
0:15 Function Parameters:
|
||||
0:? Sequence
|
||||
0:16 Sequence
|
||||
0:16 move second child to first child (temp uint)
|
||||
0:16 'r00' (temp uint)
|
||||
0:16 bitCount (temp uint)
|
||||
0:16 Convert float to uint (temp uint)
|
||||
0:16 f: direct index for structure (layout(offset=8 ) uniform float)
|
||||
0:16 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
0:16 Constant:
|
||||
0:16 2 (const uint)
|
||||
0:17 Sequence
|
||||
0:17 move second child to first child (temp 2-component vector of uint)
|
||||
0:17 'r01' (temp 2-component vector of uint)
|
||||
0:17 bitFieldReverse (temp 2-component vector of uint)
|
||||
0:17 Convert float to uint (temp 2-component vector of uint)
|
||||
0:17 f2: direct index for structure (layout(offset=32 ) uniform 2-component vector of float)
|
||||
0:17 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
0:17 Constant:
|
||||
0:17 6 (const uint)
|
||||
0:20 move second child to first child (temp 4-component vector of float)
|
||||
0:20 color: direct index for structure (temp 4-component vector of float)
|
||||
0:20 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:20 Constant:
|
||||
0:20 0 (const int)
|
||||
0:? Constant:
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:21 Sequence
|
||||
0:21 Sequence
|
||||
0:21 move second child to first child (temp 4-component vector of float)
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:21 color: direct index for structure (temp 4-component vector of float)
|
||||
0:21 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Branch: Return
|
||||
0:? Linker Objects
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:15 Function Definition: main( (temp structure{temp 4-component vector of float color})
|
||||
0:15 Function Parameters:
|
||||
0:? Sequence
|
||||
0:16 Sequence
|
||||
0:16 move second child to first child (temp uint)
|
||||
0:16 'r00' (temp uint)
|
||||
0:16 bitCount (temp uint)
|
||||
0:16 Convert float to uint (temp uint)
|
||||
0:16 f: direct index for structure (layout(offset=8 ) uniform float)
|
||||
0:16 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
0:16 Constant:
|
||||
0:16 2 (const uint)
|
||||
0:17 Sequence
|
||||
0:17 move second child to first child (temp 2-component vector of uint)
|
||||
0:17 'r01' (temp 2-component vector of uint)
|
||||
0:17 bitFieldReverse (temp 2-component vector of uint)
|
||||
0:17 Convert float to uint (temp 2-component vector of uint)
|
||||
0:17 f2: direct index for structure (layout(offset=32 ) uniform 2-component vector of float)
|
||||
0:17 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
0:17 Constant:
|
||||
0:17 6 (const uint)
|
||||
0:20 move second child to first child (temp 4-component vector of float)
|
||||
0:20 color: direct index for structure (temp 4-component vector of float)
|
||||
0:20 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:20 Constant:
|
||||
0:20 0 (const int)
|
||||
0:? Constant:
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:? 0.000000
|
||||
0:21 Sequence
|
||||
0:21 Sequence
|
||||
0:21 move second child to first child (temp 4-component vector of float)
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:21 color: direct index for structure (temp 4-component vector of float)
|
||||
0:21 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:21 Constant:
|
||||
0:21 0 (const int)
|
||||
0:21 Branch: Return
|
||||
0:? Linker Objects
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2})
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 45
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 41
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Name 4 "main"
|
||||
Name 8 "r00"
|
||||
Name 14 "$Global"
|
||||
MemberName 14($Global) 0 "i"
|
||||
MemberName 14($Global) 1 "u"
|
||||
MemberName 14($Global) 2 "f"
|
||||
MemberName 14($Global) 3 "b"
|
||||
MemberName 14($Global) 4 "i2"
|
||||
MemberName 14($Global) 5 "u2"
|
||||
MemberName 14($Global) 6 "f2"
|
||||
MemberName 14($Global) 7 "b2"
|
||||
Name 16 ""
|
||||
Name 24 "r01"
|
||||
Name 32 "PS_OUTPUT"
|
||||
MemberName 32(PS_OUTPUT) 0 "color"
|
||||
Name 34 "ps_output"
|
||||
Name 41 "color"
|
||||
MemberDecorate 14($Global) 0 Offset 0
|
||||
MemberDecorate 14($Global) 1 Offset 4
|
||||
MemberDecorate 14($Global) 2 Offset 8
|
||||
MemberDecorate 14($Global) 3 Offset 12
|
||||
MemberDecorate 14($Global) 4 Offset 16
|
||||
MemberDecorate 14($Global) 5 Offset 24
|
||||
MemberDecorate 14($Global) 6 Offset 32
|
||||
MemberDecorate 14($Global) 7 Offset 40
|
||||
Decorate 14($Global) Block
|
||||
Decorate 16 DescriptorSet 0
|
||||
Decorate 41(color) Location 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeInt 32 0
|
||||
7: TypePointer Function 6(int)
|
||||
9: TypeInt 32 1
|
||||
10: TypeFloat 32
|
||||
11: TypeVector 9(int) 2
|
||||
12: TypeVector 6(int) 2
|
||||
13: TypeVector 10(float) 2
|
||||
14($Global): TypeStruct 9(int) 6(int) 10(float) 6(int) 11(ivec2) 12(ivec2) 13(fvec2) 12(ivec2)
|
||||
15: TypePointer Uniform 14($Global)
|
||||
16: 15(ptr) Variable Uniform
|
||||
17: 9(int) Constant 2
|
||||
18: TypePointer Uniform 10(float)
|
||||
23: TypePointer Function 12(ivec2)
|
||||
25: 9(int) Constant 6
|
||||
26: TypePointer Uniform 13(fvec2)
|
||||
31: TypeVector 10(float) 4
|
||||
32(PS_OUTPUT): TypeStruct 31(fvec4)
|
||||
33: TypePointer Function 32(PS_OUTPUT)
|
||||
35: 9(int) Constant 0
|
||||
36: 10(float) Constant 0
|
||||
37: 31(fvec4) ConstantComposite 36 36 36 36
|
||||
38: TypePointer Function 31(fvec4)
|
||||
40: TypePointer Output 31(fvec4)
|
||||
41(color): 40(ptr) Variable Output
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
8(r00): 7(ptr) Variable Function
|
||||
24(r01): 23(ptr) Variable Function
|
||||
34(ps_output): 33(ptr) Variable Function
|
||||
19: 18(ptr) AccessChain 16 17
|
||||
20: 10(float) Load 19
|
||||
21: 6(int) ConvertFToU 20
|
||||
22: 6(int) BitCount 21
|
||||
Store 8(r00) 22
|
||||
27: 26(ptr) AccessChain 16 25
|
||||
28: 13(fvec2) Load 27
|
||||
29: 12(ivec2) ConvertFToU 28
|
||||
30: 12(ivec2) BitReverse 29
|
||||
Store 24(r01) 30
|
||||
39: 38(ptr) AccessChain 34(ps_output) 35
|
||||
Store 39 37
|
||||
42: 38(ptr) AccessChain 34(ps_output) 35
|
||||
43: 31(fvec4) Load 42
|
||||
Store 41(color) 43
|
||||
Return
|
||||
FunctionEnd
|
1313
Test/baseResults/hlsl.intrinsics.promote.frag.out
Normal file
1313
Test/baseResults/hlsl.intrinsics.promote.frag.out
Normal file
File diff suppressed because it is too large
Load Diff
337
Test/baseResults/hlsl.intrinsics.promote.outputs.frag.out
Normal file
337
Test/baseResults/hlsl.intrinsics.promote.outputs.frag.out
Normal file
@ -0,0 +1,337 @@
|
||||
hlsl.intrinsics.promote.outputs.frag
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:20 Function Definition: main( (temp structure{temp 4-component vector of float color})
|
||||
0:20 Function Parameters:
|
||||
0:? Sequence
|
||||
0:37 clamp (temp float)
|
||||
0:37 fpos: direct index for structure (layout(offset=52 ) uniform float)
|
||||
0:37 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2, layout(offset=48 ) uniform uint upos, layout(offset=52 ) uniform float fpos})
|
||||
0:37 Constant:
|
||||
0:37 9 (const uint)
|
||||
0:37 Constant:
|
||||
0:37 0.000000
|
||||
0:37 Constant:
|
||||
0:37 1.000000
|
||||
0:40 Sequence
|
||||
0:40 move second child to first child (temp uint)
|
||||
0:40 'sizeQueryTemp' (temp uint)
|
||||
0:40 textureSize (temp uint)
|
||||
0:40 'g_tTex1df4' (uniform texture1D)
|
||||
0:40 move second child to first child (temp int)
|
||||
0:40 'WidthI' (temp int)
|
||||
0:40 Convert uint to int (temp int)
|
||||
0:40 'sizeQueryTemp' (temp uint)
|
||||
0:41 Sequence
|
||||
0:41 move second child to first child (temp uint)
|
||||
0:41 'sizeQueryTemp' (temp uint)
|
||||
0:41 textureSize (temp uint)
|
||||
0:41 'g_tTex1df4' (uniform texture1D)
|
||||
0:41 Constant:
|
||||
0:41 6 (const uint)
|
||||
0:41 move second child to first child (temp int)
|
||||
0:41 'WidthI' (temp int)
|
||||
0:41 Convert uint to int (temp int)
|
||||
0:41 'sizeQueryTemp' (temp uint)
|
||||
0:41 move second child to first child (temp uint)
|
||||
0:41 'NumberOfLevelsU' (temp uint)
|
||||
0:41 textureQueryLevels (temp uint)
|
||||
0:41 'g_tTex1df4' (uniform texture1D)
|
||||
0:42 Sequence
|
||||
0:42 move second child to first child (temp uint)
|
||||
0:42 'sizeQueryTemp' (temp uint)
|
||||
0:42 textureSize (temp uint)
|
||||
0:42 'g_tTex1df4' (uniform texture1D)
|
||||
0:42 Constant:
|
||||
0:42 6 (const uint)
|
||||
0:42 move second child to first child (temp uint)
|
||||
0:42 'WidthU' (temp uint)
|
||||
0:42 'sizeQueryTemp' (temp uint)
|
||||
0:42 move second child to first child (temp int)
|
||||
0:42 'NumberOfLevelsI' (temp int)
|
||||
0:42 Convert uint to int (temp int)
|
||||
0:42 textureQueryLevels (temp uint)
|
||||
0:42 'g_tTex1df4' (uniform texture1D)
|
||||
0:43 Sequence
|
||||
0:43 move second child to first child (temp uint)
|
||||
0:43 'sizeQueryTemp' (temp uint)
|
||||
0:43 textureSize (temp uint)
|
||||
0:43 'g_tTex1df4' (uniform texture1D)
|
||||
0:43 Constant:
|
||||
0:43 6 (const uint)
|
||||
0:43 move second child to first child (temp int)
|
||||
0:43 'WidthI' (temp int)
|
||||
0:43 Convert uint to int (temp int)
|
||||
0:43 'sizeQueryTemp' (temp uint)
|
||||
0:43 move second child to first child (temp int)
|
||||
0:43 'NumberOfLevelsI' (temp int)
|
||||
0:43 Convert uint to int (temp int)
|
||||
0:43 textureQueryLevels (temp uint)
|
||||
0:43 'g_tTex1df4' (uniform texture1D)
|
||||
0:47 move second child to first child (temp 4-component vector of float)
|
||||
0:47 color: direct index for structure (temp 4-component vector of float)
|
||||
0:47 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:47 Constant:
|
||||
0:47 0 (const int)
|
||||
0:47 Constant:
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:48 Sequence
|
||||
0:48 Sequence
|
||||
0:48 move second child to first child (temp 4-component vector of float)
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:48 color: direct index for structure (temp 4-component vector of float)
|
||||
0:48 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:48 Constant:
|
||||
0:48 0 (const int)
|
||||
0:48 Branch: Return
|
||||
0:? Linker Objects
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:? 'g_tTexbfs' (layout(r32f ) uniform samplerBuffer)
|
||||
0:? 'g_tTex1df4' (uniform texture1D)
|
||||
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2, layout(offset=48 ) uniform uint upos, layout(offset=52 ) uniform float fpos})
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 450
|
||||
gl_FragCoord origin is upper left
|
||||
0:? Sequence
|
||||
0:20 Function Definition: main( (temp structure{temp 4-component vector of float color})
|
||||
0:20 Function Parameters:
|
||||
0:? Sequence
|
||||
0:37 clamp (temp float)
|
||||
0:37 fpos: direct index for structure (layout(offset=52 ) uniform float)
|
||||
0:37 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2, layout(offset=48 ) uniform uint upos, layout(offset=52 ) uniform float fpos})
|
||||
0:37 Constant:
|
||||
0:37 9 (const uint)
|
||||
0:37 Constant:
|
||||
0:37 0.000000
|
||||
0:37 Constant:
|
||||
0:37 1.000000
|
||||
0:40 Sequence
|
||||
0:40 move second child to first child (temp uint)
|
||||
0:40 'sizeQueryTemp' (temp uint)
|
||||
0:40 textureSize (temp uint)
|
||||
0:40 'g_tTex1df4' (uniform texture1D)
|
||||
0:40 move second child to first child (temp int)
|
||||
0:40 'WidthI' (temp int)
|
||||
0:40 Convert uint to int (temp int)
|
||||
0:40 'sizeQueryTemp' (temp uint)
|
||||
0:41 Sequence
|
||||
0:41 move second child to first child (temp uint)
|
||||
0:41 'sizeQueryTemp' (temp uint)
|
||||
0:41 textureSize (temp uint)
|
||||
0:41 'g_tTex1df4' (uniform texture1D)
|
||||
0:41 Constant:
|
||||
0:41 6 (const uint)
|
||||
0:41 move second child to first child (temp int)
|
||||
0:41 'WidthI' (temp int)
|
||||
0:41 Convert uint to int (temp int)
|
||||
0:41 'sizeQueryTemp' (temp uint)
|
||||
0:41 move second child to first child (temp uint)
|
||||
0:41 'NumberOfLevelsU' (temp uint)
|
||||
0:41 textureQueryLevels (temp uint)
|
||||
0:41 'g_tTex1df4' (uniform texture1D)
|
||||
0:42 Sequence
|
||||
0:42 move second child to first child (temp uint)
|
||||
0:42 'sizeQueryTemp' (temp uint)
|
||||
0:42 textureSize (temp uint)
|
||||
0:42 'g_tTex1df4' (uniform texture1D)
|
||||
0:42 Constant:
|
||||
0:42 6 (const uint)
|
||||
0:42 move second child to first child (temp uint)
|
||||
0:42 'WidthU' (temp uint)
|
||||
0:42 'sizeQueryTemp' (temp uint)
|
||||
0:42 move second child to first child (temp int)
|
||||
0:42 'NumberOfLevelsI' (temp int)
|
||||
0:42 Convert uint to int (temp int)
|
||||
0:42 textureQueryLevels (temp uint)
|
||||
0:42 'g_tTex1df4' (uniform texture1D)
|
||||
0:43 Sequence
|
||||
0:43 move second child to first child (temp uint)
|
||||
0:43 'sizeQueryTemp' (temp uint)
|
||||
0:43 textureSize (temp uint)
|
||||
0:43 'g_tTex1df4' (uniform texture1D)
|
||||
0:43 Constant:
|
||||
0:43 6 (const uint)
|
||||
0:43 move second child to first child (temp int)
|
||||
0:43 'WidthI' (temp int)
|
||||
0:43 Convert uint to int (temp int)
|
||||
0:43 'sizeQueryTemp' (temp uint)
|
||||
0:43 move second child to first child (temp int)
|
||||
0:43 'NumberOfLevelsI' (temp int)
|
||||
0:43 Convert uint to int (temp int)
|
||||
0:43 textureQueryLevels (temp uint)
|
||||
0:43 'g_tTex1df4' (uniform texture1D)
|
||||
0:47 move second child to first child (temp 4-component vector of float)
|
||||
0:47 color: direct index for structure (temp 4-component vector of float)
|
||||
0:47 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:47 Constant:
|
||||
0:47 0 (const int)
|
||||
0:47 Constant:
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:47 0.000000
|
||||
0:48 Sequence
|
||||
0:48 Sequence
|
||||
0:48 move second child to first child (temp 4-component vector of float)
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:48 color: direct index for structure (temp 4-component vector of float)
|
||||
0:48 'ps_output' (temp structure{temp 4-component vector of float color})
|
||||
0:48 Constant:
|
||||
0:48 0 (const int)
|
||||
0:48 Branch: Return
|
||||
0:? Linker Objects
|
||||
0:? 'color' (layout(location=0 ) out 4-component vector of float)
|
||||
0:? 'g_tTexbfs' (layout(r32f ) uniform samplerBuffer)
|
||||
0:? 'g_tTex1df4' (uniform texture1D)
|
||||
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int i, layout(offset=4 ) uniform uint u, layout(offset=8 ) uniform float f, layout(offset=12 ) uniform bool b, layout(offset=16 ) uniform 2-component vector of int i2, layout(offset=24 ) uniform 2-component vector of uint u2, layout(offset=32 ) uniform 2-component vector of float f2, layout(offset=40 ) uniform 2-component vector of bool b2, layout(offset=48 ) uniform uint upos, layout(offset=52 ) uniform float fpos})
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 76
|
||||
|
||||
Capability Shader
|
||||
Capability Sampled1D
|
||||
Capability SampledBuffer
|
||||
Capability ImageQuery
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 68
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Name 4 "main"
|
||||
Name 12 "$Global"
|
||||
MemberName 12($Global) 0 "i"
|
||||
MemberName 12($Global) 1 "u"
|
||||
MemberName 12($Global) 2 "f"
|
||||
MemberName 12($Global) 3 "b"
|
||||
MemberName 12($Global) 4 "i2"
|
||||
MemberName 12($Global) 5 "u2"
|
||||
MemberName 12($Global) 6 "f2"
|
||||
MemberName 12($Global) 7 "b2"
|
||||
MemberName 12($Global) 8 "upos"
|
||||
MemberName 12($Global) 9 "fpos"
|
||||
Name 14 ""
|
||||
Name 23 "sizeQueryTemp"
|
||||
Name 26 "g_tTex1df4"
|
||||
Name 30 "WidthI"
|
||||
Name 33 "sizeQueryTemp"
|
||||
Name 39 "NumberOfLevelsU"
|
||||
Name 42 "sizeQueryTemp"
|
||||
Name 45 "WidthU"
|
||||
Name 47 "NumberOfLevelsI"
|
||||
Name 51 "sizeQueryTemp"
|
||||
Name 60 "PS_OUTPUT"
|
||||
MemberName 60(PS_OUTPUT) 0 "color"
|
||||
Name 62 "ps_output"
|
||||
Name 68 "color"
|
||||
Name 75 "g_tTexbfs"
|
||||
MemberDecorate 12($Global) 0 Offset 0
|
||||
MemberDecorate 12($Global) 1 Offset 4
|
||||
MemberDecorate 12($Global) 2 Offset 8
|
||||
MemberDecorate 12($Global) 3 Offset 12
|
||||
MemberDecorate 12($Global) 4 Offset 16
|
||||
MemberDecorate 12($Global) 5 Offset 24
|
||||
MemberDecorate 12($Global) 6 Offset 32
|
||||
MemberDecorate 12($Global) 7 Offset 40
|
||||
MemberDecorate 12($Global) 8 Offset 48
|
||||
MemberDecorate 12($Global) 9 Offset 52
|
||||
Decorate 12($Global) Block
|
||||
Decorate 14 DescriptorSet 0
|
||||
Decorate 26(g_tTex1df4) DescriptorSet 0
|
||||
Decorate 68(color) Location 0
|
||||
Decorate 75(g_tTexbfs) DescriptorSet 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeInt 32 1
|
||||
7: TypeInt 32 0
|
||||
8: TypeFloat 32
|
||||
9: TypeVector 6(int) 2
|
||||
10: TypeVector 7(int) 2
|
||||
11: TypeVector 8(float) 2
|
||||
12($Global): TypeStruct 6(int) 7(int) 8(float) 7(int) 9(ivec2) 10(ivec2) 11(fvec2) 10(ivec2) 7(int) 8(float)
|
||||
13: TypePointer Uniform 12($Global)
|
||||
14: 13(ptr) Variable Uniform
|
||||
15: 6(int) Constant 9
|
||||
16: TypePointer Uniform 8(float)
|
||||
19: 8(float) Constant 0
|
||||
20: 8(float) Constant 1065353216
|
||||
22: TypePointer Function 7(int)
|
||||
24: TypeImage 8(float) 1D sampled format:Unknown
|
||||
25: TypePointer UniformConstant 24
|
||||
26(g_tTex1df4): 25(ptr) Variable UniformConstant
|
||||
29: TypePointer Function 6(int)
|
||||
35: 7(int) Constant 6
|
||||
59: TypeVector 8(float) 4
|
||||
60(PS_OUTPUT): TypeStruct 59(fvec4)
|
||||
61: TypePointer Function 60(PS_OUTPUT)
|
||||
63: 6(int) Constant 0
|
||||
64: 59(fvec4) ConstantComposite 19 19 19 19
|
||||
65: TypePointer Function 59(fvec4)
|
||||
67: TypePointer Output 59(fvec4)
|
||||
68(color): 67(ptr) Variable Output
|
||||
72: TypeImage 8(float) Buffer sampled format:R32f
|
||||
73: TypeSampledImage 72
|
||||
74: TypePointer UniformConstant 73
|
||||
75(g_tTexbfs): 74(ptr) Variable UniformConstant
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
23(sizeQueryTemp): 22(ptr) Variable Function
|
||||
30(WidthI): 29(ptr) Variable Function
|
||||
33(sizeQueryTemp): 22(ptr) Variable Function
|
||||
39(NumberOfLevelsU): 22(ptr) Variable Function
|
||||
42(sizeQueryTemp): 22(ptr) Variable Function
|
||||
45(WidthU): 22(ptr) Variable Function
|
||||
47(NumberOfLevelsI): 29(ptr) Variable Function
|
||||
51(sizeQueryTemp): 22(ptr) Variable Function
|
||||
62(ps_output): 61(ptr) Variable Function
|
||||
17: 16(ptr) AccessChain 14 15
|
||||
18: 8(float) Load 17
|
||||
21: 8(float) ExtInst 1(GLSL.std.450) 43(FClamp) 18 19 20
|
||||
27: 24 Load 26(g_tTex1df4)
|
||||
28: 6(int) ImageQuerySize 27
|
||||
Store 23(sizeQueryTemp) 28
|
||||
31: 7(int) Load 23(sizeQueryTemp)
|
||||
32: 6(int) Bitcast 31
|
||||
Store 30(WidthI) 32
|
||||
34: 24 Load 26(g_tTex1df4)
|
||||
36: 6(int) ImageQuerySizeLod 34 35
|
||||
Store 33(sizeQueryTemp) 36
|
||||
37: 7(int) Load 33(sizeQueryTemp)
|
||||
38: 6(int) Bitcast 37
|
||||
Store 30(WidthI) 38
|
||||
40: 24 Load 26(g_tTex1df4)
|
||||
41: 6(int) ImageQueryLevels 40
|
||||
Store 39(NumberOfLevelsU) 41
|
||||
43: 24 Load 26(g_tTex1df4)
|
||||
44: 6(int) ImageQuerySizeLod 43 35
|
||||
Store 42(sizeQueryTemp) 44
|
||||
46: 7(int) Load 42(sizeQueryTemp)
|
||||
Store 45(WidthU) 46
|
||||
48: 24 Load 26(g_tTex1df4)
|
||||
49: 6(int) ImageQueryLevels 48
|
||||
50: 6(int) Bitcast 49
|
||||
Store 47(NumberOfLevelsI) 50
|
||||
52: 24 Load 26(g_tTex1df4)
|
||||
53: 6(int) ImageQuerySizeLod 52 35
|
||||
Store 51(sizeQueryTemp) 53
|
||||
54: 7(int) Load 51(sizeQueryTemp)
|
||||
55: 6(int) Bitcast 54
|
||||
Store 30(WidthI) 55
|
||||
56: 24 Load 26(g_tTex1df4)
|
||||
57: 6(int) ImageQueryLevels 56
|
||||
58: 6(int) Bitcast 57
|
||||
Store 47(NumberOfLevelsI) 58
|
||||
66: 65(ptr) AccessChain 62(ps_output) 63
|
||||
Store 66 64
|
||||
69: 65(ptr) AccessChain 62(ps_output) 63
|
||||
70: 59(fvec4) Load 69
|
||||
Store 68(color) 70
|
||||
Return
|
||||
FunctionEnd
|
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@ Linked fragment stage:
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 30
|
||||
// Id's are bound by 31
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
@ -16,14 +16,14 @@ Linked fragment stage:
|
||||
Name 9 "Color"
|
||||
Name 12 "g_tScene[0]"
|
||||
Name 16 "g_tSamp"
|
||||
Name 24 "g_tScene[1]"
|
||||
Name 25 "g_tScene[1]"
|
||||
Decorate 9(Color) Location 0
|
||||
Decorate 12(g_tScene[0]) DescriptorSet 0
|
||||
Decorate 12(g_tScene[0]) Binding 10
|
||||
Decorate 16(g_tSamp) DescriptorSet 0
|
||||
Decorate 16(g_tSamp) Binding 5
|
||||
Decorate 24(g_tScene[1]) DescriptorSet 0
|
||||
Decorate 24(g_tScene[1]) Binding 11
|
||||
Decorate 25(g_tScene[1]) DescriptorSet 0
|
||||
Decorate 25(g_tScene[1]) Binding 11
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
@ -39,19 +39,20 @@ Linked fragment stage:
|
||||
18: TypeSampledImage 10
|
||||
20: TypeVector 6(float) 2
|
||||
21: 6(float) Constant 1050253722
|
||||
22: 20(fvec2) ConstantComposite 21 21
|
||||
24(g_tScene[1]): 11(ptr) Variable UniformConstant
|
||||
22: 6(float) Constant 1053609165
|
||||
23: 20(fvec2) ConstantComposite 21 22
|
||||
25(g_tScene[1]): 11(ptr) Variable UniformConstant
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
13: 10 Load 12(g_tScene[0])
|
||||
17: 14 Load 16(g_tSamp)
|
||||
19: 18 SampledImage 13 17
|
||||
23: 7(fvec4) ImageSampleImplicitLod 19 22
|
||||
25: 10 Load 24(g_tScene[1])
|
||||
26: 14 Load 16(g_tSamp)
|
||||
27: 18 SampledImage 25 26
|
||||
28: 7(fvec4) ImageSampleImplicitLod 27 22
|
||||
29: 7(fvec4) FAdd 23 28
|
||||
Store 9(Color) 29
|
||||
24: 7(fvec4) ImageSampleImplicitLod 19 23
|
||||
26: 10 Load 25(g_tScene[1])
|
||||
27: 14 Load 16(g_tSamp)
|
||||
28: 18 SampledImage 26 27
|
||||
29: 7(fvec4) ImageSampleImplicitLod 28 23
|
||||
30: 7(fvec4) FAdd 24 29
|
||||
Store 9(Color) 30
|
||||
Return
|
||||
FunctionEnd
|
||||
|
@ -33,7 +33,7 @@ float PixelShaderFunctionS(float inF0, float inF1, float inF2, uint inU0, uint i
|
||||
clip(inF0);
|
||||
float r014 = cos(inF0);
|
||||
float r015 = cosh(inF0);
|
||||
uint r016 = countbits(7);
|
||||
int r016 = countbits(7);
|
||||
float r017 = ddx(inF0);
|
||||
float r018 = ddx_coarse(inF0);
|
||||
float r019 = ddx_fine(inF0);
|
||||
@ -111,7 +111,7 @@ float2 PixelShaderFunction2(float2 inF0, float2 inF1, float2 inF2, uint2 inU0, u
|
||||
clip(inF0);
|
||||
float2 r013 = cos(inF0);
|
||||
float2 r015 = cosh(inF0);
|
||||
uint2 r016 = countbits(int2(7,3));
|
||||
int2 r016 = countbits(int2(7,3));
|
||||
float2 r017 = ddx(inF0);
|
||||
float2 r018 = ddx_coarse(inF0);
|
||||
float2 r019 = ddx_fine(inF0);
|
||||
|
22
Test/hlsl.intrinsics.promote.down.frag
Normal file
22
Test/hlsl.intrinsics.promote.down.frag
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
struct PS_OUTPUT { float4 color : SV_Target0; };
|
||||
|
||||
int i;
|
||||
uint u;
|
||||
float f;
|
||||
bool b;
|
||||
|
||||
int2 i2;
|
||||
uint2 u2;
|
||||
float2 f2;
|
||||
bool2 b2;
|
||||
|
||||
PS_OUTPUT main()
|
||||
{
|
||||
uint r00 = countbits(f);
|
||||
uint2 r01 = reversebits(f2);
|
||||
|
||||
PS_OUTPUT ps_output;
|
||||
ps_output.color = float4(0,0,0,0);
|
||||
return ps_output;
|
||||
};
|
79
Test/hlsl.intrinsics.promote.frag
Normal file
79
Test/hlsl.intrinsics.promote.frag
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
struct PS_OUTPUT { float4 color : SV_Target0; };
|
||||
|
||||
int i;
|
||||
uint u;
|
||||
float f;
|
||||
bool b;
|
||||
|
||||
int2 i2;
|
||||
uint2 u2;
|
||||
float2 f2;
|
||||
bool2 b2;
|
||||
|
||||
Buffer <float> g_tTexbfs;
|
||||
Texture1D <float4> g_tTex1df4;
|
||||
uint upos;
|
||||
float fpos;
|
||||
|
||||
PS_OUTPUT main()
|
||||
{
|
||||
// Same shapes:
|
||||
|
||||
float r00 = max(b, f);
|
||||
uint r01 = max(b, u);
|
||||
int r02 = max(b, i);
|
||||
float r03 = max(i, f);
|
||||
float r04 = max(u, f);
|
||||
|
||||
float2 r10 = max(b2, f2);
|
||||
uint2 r11 = max(b2, u2);
|
||||
int2 r12 = max(b2, i2);
|
||||
float2 r13 = max(i2, f2);
|
||||
float2 r14 = max(u2, f2);
|
||||
|
||||
float2 r20 = clamp(i2, u2, f2); // 3 args, converts all to best type.
|
||||
uint2 r21 = clamp(b2, u2, b2);
|
||||
float2 r22 = clamp(b2, f2, b2);
|
||||
|
||||
// Mixed shapes:
|
||||
float2 r30 = max(b, f2);
|
||||
uint2 r31 = max(b, u2);
|
||||
int2 r32 = max(b, i2);
|
||||
float2 r33 = max(i, f2);
|
||||
float2 r34 = max(u, f2);
|
||||
|
||||
float2 r40 = clamp(i, u2, f2); // 3 args, converts all to best type.
|
||||
uint2 r41 = clamp(b2, u, b2);
|
||||
float2 r42 = clamp(b2, f, b);
|
||||
int2 r43 = clamp(i, i2, u2);
|
||||
|
||||
float r50 = g_tTexbfs.Load(upos);
|
||||
float r51 = g_tTexbfs.Load(fpos);
|
||||
|
||||
int MipLevel;
|
||||
|
||||
uint WidthU;
|
||||
uint HeightU;
|
||||
uint ElementsU;
|
||||
uint DepthU;
|
||||
uint NumberOfLevelsU;
|
||||
uint NumberOfSamplesU;
|
||||
|
||||
int WidthI;
|
||||
int HeightI;
|
||||
int ElementsI;
|
||||
int DepthI;
|
||||
int NumberOfLevelsI;
|
||||
int NumberOfSamplesI;
|
||||
|
||||
g_tTex1df4 . GetDimensions(WidthI);
|
||||
g_tTex1df4 . GetDimensions(6, WidthI, NumberOfLevelsU);
|
||||
g_tTex1df4 . GetDimensions(6, WidthU, NumberOfLevelsI);
|
||||
g_tTex1df4 . GetDimensions(6, WidthI, NumberOfLevelsI);
|
||||
|
||||
// max(i2, f2);
|
||||
PS_OUTPUT ps_output;
|
||||
ps_output.color = r00;
|
||||
return ps_output;
|
||||
};
|
49
Test/hlsl.intrinsics.promote.outputs.frag
Normal file
49
Test/hlsl.intrinsics.promote.outputs.frag
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
struct PS_OUTPUT { float4 color : SV_Target0; };
|
||||
|
||||
int i;
|
||||
uint u;
|
||||
float f;
|
||||
bool b;
|
||||
|
||||
int2 i2;
|
||||
uint2 u2;
|
||||
float2 f2;
|
||||
bool2 b2;
|
||||
|
||||
Buffer <float> g_tTexbfs;
|
||||
Texture1D <float4> g_tTex1df4;
|
||||
uint upos;
|
||||
float fpos;
|
||||
|
||||
PS_OUTPUT main()
|
||||
{
|
||||
int MipLevel;
|
||||
|
||||
uint WidthU;
|
||||
uint HeightU;
|
||||
uint ElementsU;
|
||||
uint DepthU;
|
||||
uint NumberOfLevelsU;
|
||||
uint NumberOfSamplesU;
|
||||
|
||||
int WidthI;
|
||||
int HeightI;
|
||||
int ElementsI;
|
||||
int DepthI;
|
||||
int NumberOfLevelsI;
|
||||
int NumberOfSamplesI;
|
||||
|
||||
saturate(fpos);
|
||||
|
||||
// Test output promotions
|
||||
g_tTex1df4 . GetDimensions(WidthI);
|
||||
g_tTex1df4 . GetDimensions(6, WidthI, NumberOfLevelsU);
|
||||
g_tTex1df4 . GetDimensions(6, WidthU, NumberOfLevelsI);
|
||||
g_tTex1df4 . GetDimensions(6, WidthI, NumberOfLevelsI);
|
||||
|
||||
// max(i2, f2);
|
||||
PS_OUTPUT ps_output;
|
||||
ps_output.color = 0;
|
||||
return ps_output;
|
||||
};
|
@ -10,6 +10,6 @@ struct PS_OUTPUT
|
||||
|
||||
void main(out PS_OUTPUT psout)
|
||||
{
|
||||
psout.Color = g_tScene[0].Sample(g_tSamp, 0.3) +
|
||||
g_tScene[1].Sample(g_tSamp, 0.3);
|
||||
psout.Color = g_tScene[0].Sample(g_tSamp, float2(0.3,0.4)) +
|
||||
g_tScene[1].Sample(g_tSamp, float2(0.3,0.4));
|
||||
}
|
||||
|
@ -10,6 +10,6 @@ struct PS_OUTPUT
|
||||
|
||||
void main(out PS_OUTPUT psout)
|
||||
{
|
||||
psout.Color = g_tScene[0].Sample(g_tSamp, 0.3) +
|
||||
g_tScene[1].Sample(g_tSamp, 0.3);
|
||||
psout.Color = g_tScene[0].Sample(g_tSamp, float2(0.3, 0.3)) +
|
||||
g_tScene[1].Sample(g_tSamp, float2(0.3, 0.3));
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "propagateNoContraction.h"
|
||||
|
||||
#include <cfloat>
|
||||
#include <utility>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
@ -575,6 +576,27 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||
case EOpDivAssign:
|
||||
case EOpModAssign:
|
||||
|
||||
case EOpAtan:
|
||||
case EOpClamp:
|
||||
case EOpCross:
|
||||
case EOpDistance:
|
||||
case EOpDot:
|
||||
case EOpDst:
|
||||
case EOpFaceForward:
|
||||
case EOpFma:
|
||||
case EOpFrexp:
|
||||
case EOpLdexp:
|
||||
case EOpMix:
|
||||
case EOpLit:
|
||||
case EOpMax:
|
||||
case EOpMin:
|
||||
case EOpModf:
|
||||
case EOpPow:
|
||||
case EOpReflect:
|
||||
case EOpRefract:
|
||||
case EOpSmoothStep:
|
||||
case EOpStep:
|
||||
|
||||
case EOpSequence:
|
||||
case EOpConstructStruct:
|
||||
|
||||
@ -833,6 +855,9 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||
if (profile == EEsProfile || version == 110)
|
||||
return false;
|
||||
|
||||
if (from == to)
|
||||
return true;
|
||||
|
||||
// TODO: Move more policies into language-specific handlers.
|
||||
// Some languages allow more general (or potentially, more specific) conversions under some conditions.
|
||||
if (source == EShSourceHlsl) {
|
||||
@ -901,6 +926,8 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||
return version >= 400;
|
||||
case EbtUint:
|
||||
return true;
|
||||
case EbtBool:
|
||||
return (source == EShSourceHlsl);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -908,6 +935,8 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
||||
switch (from) {
|
||||
case EbtInt:
|
||||
return true;
|
||||
case EbtBool:
|
||||
return (source == EShSourceHlsl);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -1747,6 +1776,9 @@ bool TIntermediate::promote(TIntermOperator* node)
|
||||
if (node->getAsBinaryNode())
|
||||
return promoteBinary(*node->getAsBinaryNode());
|
||||
|
||||
if (node->getAsAggregate())
|
||||
return promoteAggregate(*node->getAsAggregate());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2190,6 +2222,77 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// See TIntermediate::promote
|
||||
//
|
||||
bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
||||
{
|
||||
TOperator op = node.getOp();
|
||||
TIntermSequence& args = node.getSequence();
|
||||
const int numArgs = args.size();
|
||||
|
||||
// Presently, only hlsl does intrinsic promotions.
|
||||
if (getSource() != EShSourceHlsl)
|
||||
return true;
|
||||
|
||||
// set of opcodes that can be promoted in this manner.
|
||||
switch (op) {
|
||||
case EOpAtan:
|
||||
case EOpClamp:
|
||||
case EOpCross:
|
||||
case EOpDistance:
|
||||
case EOpDot:
|
||||
case EOpDst:
|
||||
case EOpFaceForward:
|
||||
// case EOpFindMSB: TODO: ??
|
||||
// case EOpFindLSB: TODO: ??
|
||||
case EOpFma:
|
||||
case EOpMod:
|
||||
case EOpFrexp:
|
||||
case EOpLdexp:
|
||||
case EOpMix:
|
||||
case EOpLit:
|
||||
case EOpMax:
|
||||
case EOpMin:
|
||||
case EOpModf:
|
||||
// case EOpGenMul: TODO: ??
|
||||
case EOpPow:
|
||||
case EOpReflect:
|
||||
case EOpRefract:
|
||||
// case EOpSinCos: TODO: ??
|
||||
case EOpSmoothStep:
|
||||
case EOpStep:
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: array and struct behavior
|
||||
|
||||
// Try converting all nodes to the given node's type
|
||||
TIntermSequence convertedArgs(numArgs, nullptr);
|
||||
|
||||
// Try to convert all types to the nonConvArg type.
|
||||
for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) {
|
||||
// Try converting all args to this arg's type
|
||||
for (int convArg = 0; convArg < numArgs; ++convArg) {
|
||||
convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(),
|
||||
args[convArg]->getAsTyped());
|
||||
}
|
||||
|
||||
// If we successfully converted all the args, use the result.
|
||||
if (std::all_of(convertedArgs.begin(), convertedArgs.end(),
|
||||
[](const TIntermNode* node) { return node != nullptr; })) {
|
||||
|
||||
std::swap(args, convertedArgs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void TIntermBinary::updatePrecision()
|
||||
{
|
||||
#ifdef AMD_EXTENSIONS
|
||||
|
@ -370,6 +370,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||
//
|
||||
void TIntermediate::finalCheck(TInfoSink& infoSink)
|
||||
{
|
||||
if (getTreeRoot() == nullptr)
|
||||
return;
|
||||
|
||||
if (source == EShSourceGlsl && numEntryPoints < 1)
|
||||
error(infoSink, "Missing entry point: Each stage requires one entry point");
|
||||
|
||||
|
@ -381,6 +381,7 @@ public:
|
||||
int addXfbBufferOffset(const TType&);
|
||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||
bool promote(TIntermOperator*);
|
||||
|
||||
protected:
|
||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||
@ -395,10 +396,10 @@ protected:
|
||||
bool userOutputUsed() const;
|
||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||
bool isSpecializationOperation(const TIntermOperator&) const;
|
||||
bool promote(TIntermOperator*);
|
||||
bool promoteUnary(TIntermUnary&);
|
||||
bool promoteBinary(TIntermBinary&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||
bool promoteAggregate(TIntermAggregate&);
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
|
@ -134,6 +134,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
|
||||
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
|
||||
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
|
||||
{"hlsl.intrinsics.promote.frag", "main"},
|
||||
{"hlsl.intrinsics.promote.down.frag", "main"},
|
||||
{"hlsl.intrinsics.promote.outputs.frag", "main"},
|
||||
{"hlsl.layout.frag", "main"},
|
||||
{"hlsl.load.2dms.dx10.frag", "main"},
|
||||
{"hlsl.load.array.dx10.frag", "main"},
|
||||
|
@ -2555,7 +2555,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
||||
//
|
||||
const TFunction* fnCandidate;
|
||||
bool builtIn;
|
||||
fnCandidate = findFunction(loc, *function, builtIn);
|
||||
fnCandidate = findFunction(loc, *function, builtIn, arguments);
|
||||
if (fnCandidate) {
|
||||
// This is a declared function that might map to
|
||||
// - a built-in operator,
|
||||
@ -2597,21 +2597,27 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
||||
}
|
||||
}
|
||||
|
||||
// for decompositions, since we want to operate on the function node, not the aggregate holding
|
||||
// output conversions.
|
||||
const TIntermTyped* fnNode = result;
|
||||
|
||||
decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions
|
||||
decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
|
||||
decomposeGeometryMethods(loc, result, arguments); // HLSL->AST geometry method decompositions
|
||||
|
||||
// Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore.
|
||||
// Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
|
||||
// Also, build the qualifier list for user function calls, which are always called with an aggregate.
|
||||
if (result->getAsAggregate()) {
|
||||
// We don't do this is if there has been a decomposition, which will have added its own conversions
|
||||
// for output parameters.
|
||||
if (result == fnNode && result->getAsAggregate()) {
|
||||
TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
|
||||
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
|
||||
qualifierList.push_back(qual);
|
||||
}
|
||||
result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
|
||||
result = addOutputArgumentConversions(*fnCandidate, *result->getAsOperator());
|
||||
}
|
||||
|
||||
decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions
|
||||
decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
|
||||
decomposeGeometryMethods(loc, result, arguments); // HLSL->AST geometry method decompositions
|
||||
}
|
||||
}
|
||||
|
||||
@ -2724,9 +2730,19 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI
|
||||
//
|
||||
// Returns a node of a subtree that evaluates to the return value of the function.
|
||||
//
|
||||
TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode)
|
||||
TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& function, TIntermOperator& intermNode)
|
||||
{
|
||||
TIntermSequence& arguments = intermNode.getSequence();
|
||||
assert (intermNode.getAsAggregate() != nullptr || intermNode.getAsUnaryNode() != nullptr);
|
||||
|
||||
const TSourceLoc& loc = intermNode.getLoc();
|
||||
|
||||
TIntermSequence argSequence; // temp sequence for unary node args
|
||||
|
||||
if (intermNode.getAsUnaryNode())
|
||||
argSequence.push_back(intermNode.getAsUnaryNode()->getOperand());
|
||||
|
||||
TIntermSequence& arguments = argSequence.empty() ? intermNode.getAsAggregate()->getSequence() : argSequence;
|
||||
|
||||
const auto needsConversion = [&](int argNum) {
|
||||
return function[argNum].type->getQualifier().isParamOutput() &&
|
||||
(*function[argNum].type != arguments[argNum]->getAsTyped()->getType() ||
|
||||
@ -2759,8 +2775,8 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu
|
||||
if (intermNode.getBasicType() != EbtVoid) {
|
||||
// do the "tempRet = function(...), " bit from above
|
||||
tempRet = makeInternalVariable("tempReturn", intermNode.getType());
|
||||
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
|
||||
conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
|
||||
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, loc);
|
||||
conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, loc);
|
||||
} else
|
||||
conversionTree = &intermNode;
|
||||
|
||||
@ -2775,7 +2791,7 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu
|
||||
// Make a temporary for what the function expects the argument to look like.
|
||||
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
|
||||
tempArg->getWritableType().getQualifier().makeTemporary();
|
||||
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
|
||||
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, loc);
|
||||
|
||||
// This makes the deepest level, the member-wise copy
|
||||
TIntermTyped* tempAssign = handleAssign(arguments[i]->getLoc(), EOpAssign, arguments[i]->getAsTyped(), tempArgNode);
|
||||
@ -2783,17 +2799,18 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu
|
||||
conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc());
|
||||
|
||||
// replace the argument with another node for the same tempArg variable
|
||||
arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc());
|
||||
arguments[i] = intermediate.addSymbol(*tempArg, loc);
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize the tree topology (see bigger comment above).
|
||||
if (tempRet) {
|
||||
// do the "..., tempRet" bit from above
|
||||
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
|
||||
conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc());
|
||||
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, loc);
|
||||
conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, loc);
|
||||
}
|
||||
conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
|
||||
|
||||
conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), loc);
|
||||
|
||||
return conversionTree;
|
||||
}
|
||||
@ -4339,7 +4356,8 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
|
||||
//
|
||||
// Return the function symbol if found, otherwise nullptr.
|
||||
//
|
||||
const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
|
||||
const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn,
|
||||
TIntermNode* args)
|
||||
{
|
||||
// const TFunction* function = nullptr;
|
||||
|
||||
@ -4445,9 +4463,81 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
||||
// send to the generic selector
|
||||
const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
|
||||
|
||||
if (bestMatch == nullptr)
|
||||
if (bestMatch == nullptr) {
|
||||
error(loc, "no matching overloaded function found", call.getName().c_str(), "");
|
||||
else if (tie)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// For builtins, we can convert across the arguments. This will happen in several steps:
|
||||
// Step 1: If there's an exact match, use it.
|
||||
// Step 2a: Otherwise, get the operator from the best match and promote arguments:
|
||||
// Step 2b: reconstruct the TFunction based on the new arg types
|
||||
// Step 3: Re-select after type promotion is applied, to find proper candidate.
|
||||
if (builtIn) {
|
||||
// Step 1: If there's an exact match, use it.
|
||||
if (call.getMangledName() == bestMatch->getMangledName())
|
||||
return bestMatch;
|
||||
|
||||
// Step 2a: Otherwise, get the operator from the best match and promote arguments as if we
|
||||
// are that kind of operator.
|
||||
if (args != nullptr) {
|
||||
// The arg list can be a unary node, or an aggregate. We have to handle both.
|
||||
// We will use the normal promote() facilities, which require an interm node.
|
||||
TIntermOperator* promote = nullptr;
|
||||
|
||||
if (call.getParamCount() == 1) {
|
||||
promote = new TIntermUnary(bestMatch->getBuiltInOp());
|
||||
promote->getAsUnaryNode()->setOperand(args->getAsTyped());
|
||||
} else {
|
||||
promote = new TIntermAggregate(bestMatch->getBuiltInOp());
|
||||
promote->getAsAggregate()->getSequence().swap(args->getAsAggregate()->getSequence());
|
||||
}
|
||||
|
||||
if (! intermediate.promote(promote))
|
||||
return nullptr;
|
||||
|
||||
// Obtain the promoted arg list.
|
||||
if (call.getParamCount() == 1) {
|
||||
args = promote->getAsUnaryNode()->getOperand();
|
||||
} else {
|
||||
promote->getAsAggregate()->getSequence().swap(args->getAsAggregate()->getSequence());
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2b: reconstruct the TFunction based on the new arg types
|
||||
TFunction convertedCall(&call.getName(), call.getType(), call.getBuiltInOp());
|
||||
|
||||
if (args->getAsAggregate()) {
|
||||
// Handle aggregates: put all args into the new function call
|
||||
for (int arg=0; arg<int(args->getAsAggregate()->getSequence().size()); ++arg) {
|
||||
// TODO: But for constness, we could avoid the new & shallowCopy, and use the pointer directly.
|
||||
TParameter param = { 0, new TType };
|
||||
param.type->shallowCopy(args->getAsAggregate()->getSequence()[arg]->getAsTyped()->getType());
|
||||
convertedCall.addParameter(param);
|
||||
}
|
||||
} else if (args->getAsUnaryNode()) {
|
||||
// Handle unaries: put all args into the new function call
|
||||
TParameter param = { 0, new TType };
|
||||
param.type->shallowCopy(args->getAsUnaryNode()->getOperand()->getAsTyped()->getType());
|
||||
convertedCall.addParameter(param);
|
||||
} else if (args->getAsTyped()) {
|
||||
// Handle bare e.g, floats, not in an aggregate.
|
||||
TParameter param = { 0, new TType };
|
||||
param.type->shallowCopy(args->getAsTyped()->getType());
|
||||
convertedCall.addParameter(param);
|
||||
} else {
|
||||
assert(0); // unknown argument list.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Step 3: Re-select after type promotion, to find proper candidate
|
||||
// send to the generic selector
|
||||
bestMatch = selectFunction(candidateList, convertedCall, convertible, better, tie);
|
||||
|
||||
// At this point, there should be no tie.
|
||||
}
|
||||
|
||||
if (tie)
|
||||
error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
|
||||
|
||||
return bestMatch;
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
|
||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&);
|
||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
|
||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||
TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
|
||||
void handleSemantic(TSourceLoc, TQualifier&, const TString& semantic);
|
||||
@ -125,7 +125,7 @@ public:
|
||||
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||
|
||||
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn, TIntermNode* args);
|
||||
void declareTypedef(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0);
|
||||
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, TType&, TIntermTyped* initializer = 0);
|
||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
||||
|
@ -558,8 +558,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
{ "AllMemoryBarrier", nullptr, nullptr, "-", "-", EShLangCS },
|
||||
{ "AllMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS },
|
||||
{ "any", "S", "B", "SVM", "BFIU", EShLangAll },
|
||||
{ "asdouble", "S", "D", "S,", "U,", EShLangAll },
|
||||
{ "asdouble", "V2", "D", "V2,", "U,", EShLangAll },
|
||||
{ "asdouble", "S", "D", "S,", "UI,", EShLangAll },
|
||||
{ "asdouble", "V2", "D", "V2,", "UI,", EShLangAll },
|
||||
{ "asfloat", nullptr, "F", "SVM", "BFIU", EShLangAll },
|
||||
{ "asin", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "asint", nullptr, "I", "SVM", "FU", EShLangAll },
|
||||
@ -572,7 +572,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
{ "clip", "-", "-", "SVM", "F", EShLangPS },
|
||||
{ "cos", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "cosh", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "countbits", nullptr, nullptr, "SV", "U", EShLangAll },
|
||||
{ "countbits", nullptr, nullptr, "SV", "UI", EShLangAll },
|
||||
{ "cross", nullptr, nullptr, "V3,", "F,", EShLangAll },
|
||||
{ "D3DCOLORtoUBYTE4", "V4", "I", "V4", "F", EShLangAll },
|
||||
{ "ddx", nullptr, nullptr, "SVM", "F", EShLangPS },
|
||||
@ -636,9 +636,9 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
{ "log10", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "log2", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "mad", nullptr, nullptr, "SVM,,", "DFUI,,", EShLangAll },
|
||||
{ "max", nullptr, nullptr, "SVM,", "FI,", EShLangAll },
|
||||
{ "min", nullptr, nullptr, "SVM,", "FI,", EShLangAll },
|
||||
{ "modf", nullptr, nullptr, "SVM,>", "FI,", EShLangAll },
|
||||
{ "max", nullptr, nullptr, "SVM,", "FIU,", EShLangAll },
|
||||
{ "min", nullptr, nullptr, "SVM,", "FIU,", EShLangAll },
|
||||
{ "modf", nullptr, nullptr, "SVM,>", "FIU,", EShLangAll },
|
||||
{ "msad4", "V4", "U", "S,V2,V4", "U,,", EShLangAll },
|
||||
{ "mul", "S", nullptr, "S,S", "FI,", EShLangAll },
|
||||
{ "mul", "V", nullptr, "S,V", "FI,", EShLangAll },
|
||||
@ -665,7 +665,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
{ "rcp", nullptr, nullptr, "SVM", "FD", EShLangAll },
|
||||
{ "reflect", nullptr, nullptr, "V,", "F,", EShLangAll },
|
||||
{ "refract", nullptr, nullptr, "V,V,S", "F,,", EShLangAll },
|
||||
{ "reversebits", nullptr, nullptr, "SV", "U", EShLangAll },
|
||||
{ "reversebits", nullptr, nullptr, "SV", "UI", EShLangAll },
|
||||
{ "round", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "rsqrt", nullptr, nullptr, "SVM", "F", EShLangAll },
|
||||
{ "saturate", nullptr, nullptr , "SVM", "F", EShLangAll },
|
||||
@ -735,7 +735,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
// RWTexture loads
|
||||
{ "Load", "V4", nullptr, "!#,V", "FIU,I", EShLangAll },
|
||||
// (RW)Buffer loads
|
||||
{ "Load", "V4", nullptr, "~*1,V", "FIU,I", EShLangAll },
|
||||
{ "Load", "V4", nullptr, "~*1,V", "FIU,I", EShLangAll },
|
||||
|
||||
{ "Gather", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
||||
{ "Gather", /* O*/ "V4", nullptr, "%@,S,V,V", "FIU,S,F,I", EShLangAll },
|
||||
|
Loading…
Reference in New Issue
Block a user