HLSL: use LOD form of ImageQuerySize when needed.

The non-LOD form of image size query is prohibited in certain cases:
see the OpImageQuerySize and OpImageQuerySizeLod sections of the SPIR-V
spec for details.  Sometimes we were generating the non-LOD form when
we should have been using the LOD form.  Sometimes the LOD form is required
even if the underlying HLSL query did not supply a MIP level itself,
in which case level 0 is now queried.
This commit is contained in:
steve-lunarg 2017-03-07 19:30:25 -07:00
parent 057df2935a
commit 3ce4536ac8
5 changed files with 1004 additions and 892 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ Shader version: 450
0:21 'sizeQueryTemp' (temp uint) 0:21 'sizeQueryTemp' (temp uint)
0:21 textureSize (temp uint) 0:21 textureSize (temp uint)
0:21 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) 0:21 'g_tTex1df4' (layout(binding=0 ) uniform texture1D)
0:21 Constant:
0:21 0 (const int)
0:21 move second child to first child (temp uint) 0:21 move second child to first child (temp uint)
0:21 'WidthU' (temp uint) 0:21 'WidthU' (temp uint)
0:21 'sizeQueryTemp' (temp uint) 0:21 'sizeQueryTemp' (temp uint)
@ -66,6 +68,8 @@ Shader version: 450
0:21 'sizeQueryTemp' (temp uint) 0:21 'sizeQueryTemp' (temp uint)
0:21 textureSize (temp uint) 0:21 textureSize (temp uint)
0:21 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) 0:21 'g_tTex1df4' (layout(binding=0 ) uniform texture1D)
0:21 Constant:
0:21 0 (const int)
0:21 move second child to first child (temp uint) 0:21 move second child to first child (temp uint)
0:21 'WidthU' (temp uint) 0:21 'WidthU' (temp uint)
0:21 'sizeQueryTemp' (temp uint) 0:21 'sizeQueryTemp' (temp uint)
@ -125,10 +129,10 @@ Shader version: 450
Name 10 "@main(" Name 10 "@main("
Name 14 "sizeQueryTemp" Name 14 "sizeQueryTemp"
Name 17 "g_tTex1df4" Name 17 "g_tTex1df4"
Name 21 "WidthU" Name 22 "WidthU"
Name 23 "sizeQueryTemp" Name 24 "sizeQueryTemp"
Name 28 "NumberOfLevelsU" Name 29 "NumberOfLevelsU"
Name 32 "vsout" Name 33 "vsout"
Name 42 "@entryPointOutput_Pos" Name 42 "@entryPointOutput_Pos"
Name 47 "g_sSamp" Name 47 "g_sSamp"
Decorate 17(g_tTex1df4) DescriptorSet 0 Decorate 17(g_tTex1df4) DescriptorSet 0
@ -148,9 +152,9 @@ Shader version: 450
16: TypePointer UniformConstant 15 16: TypePointer UniformConstant 15
17(g_tTex1df4): 16(ptr) Variable UniformConstant 17(g_tTex1df4): 16(ptr) Variable UniformConstant
19: TypeInt 32 1 19: TypeInt 32 1
25: 12(int) Constant 6 20: 19(int) Constant 0
31: TypePointer Function 8(VS_OUTPUT) 26: 12(int) Constant 6
33: 19(int) Constant 0 32: TypePointer Function 8(VS_OUTPUT)
34: 6(float) Constant 0 34: 6(float) Constant 0
35: 7(fvec4) ConstantComposite 34 34 34 34 35: 7(fvec4) ConstantComposite 34 34 34 34
36: TypePointer Function 7(fvec4) 36: TypePointer Function 7(fvec4)
@ -169,25 +173,25 @@ Shader version: 450
10(@main():8(VS_OUTPUT) Function None 9 10(@main():8(VS_OUTPUT) Function None 9
11: Label 11: Label
14(sizeQueryTemp): 13(ptr) Variable Function 14(sizeQueryTemp): 13(ptr) Variable Function
21(WidthU): 13(ptr) Variable Function 22(WidthU): 13(ptr) Variable Function
23(sizeQueryTemp): 13(ptr) Variable Function 24(sizeQueryTemp): 13(ptr) Variable Function
28(NumberOfLevelsU): 13(ptr) Variable Function 29(NumberOfLevelsU): 13(ptr) Variable Function
32(vsout): 31(ptr) Variable Function 33(vsout): 32(ptr) Variable Function
18: 15 Load 17(g_tTex1df4) 18: 15 Load 17(g_tTex1df4)
20: 19(int) ImageQuerySize 18 21: 19(int) ImageQuerySizeLod 18 20
Store 14(sizeQueryTemp) 20 Store 14(sizeQueryTemp) 21
22: 12(int) Load 14(sizeQueryTemp) 23: 12(int) Load 14(sizeQueryTemp)
Store 21(WidthU) 22 Store 22(WidthU) 23
24: 15 Load 17(g_tTex1df4) 25: 15 Load 17(g_tTex1df4)
26: 19(int) ImageQuerySizeLod 24 25 27: 19(int) ImageQuerySizeLod 25 26
Store 23(sizeQueryTemp) 26 Store 24(sizeQueryTemp) 27
27: 12(int) Load 23(sizeQueryTemp) 28: 12(int) Load 24(sizeQueryTemp)
Store 21(WidthU) 27 Store 22(WidthU) 28
29: 15 Load 17(g_tTex1df4) 30: 15 Load 17(g_tTex1df4)
30: 19(int) ImageQueryLevels 29 31: 19(int) ImageQueryLevels 30
Store 28(NumberOfLevelsU) 30 Store 29(NumberOfLevelsU) 31
37: 36(ptr) AccessChain 32(vsout) 33 37: 36(ptr) AccessChain 33(vsout) 20
Store 37 35 Store 37 35
38:8(VS_OUTPUT) Load 32(vsout) 38:8(VS_OUTPUT) Load 33(vsout)
ReturnValue 38 ReturnValue 38
FunctionEnd FunctionEnd

View File

@ -364,6 +364,8 @@ gl_FragCoord origin is upper left
0:70 'sizeQueryTemp' (temp uint) 0:70 'sizeQueryTemp' (temp uint)
0:70 textureSize (temp uint) 0:70 textureSize (temp uint)
0:70 'g_tTex1df4' (uniform texture1D) 0:70 'g_tTex1df4' (uniform texture1D)
0:70 Constant:
0:70 0 (const int)
0:70 move second child to first child (temp int) 0:70 move second child to first child (temp int)
0:70 'WidthI' (temp int) 0:70 'WidthI' (temp int)
0:70 Convert uint to int (temp int) 0:70 Convert uint to int (temp int)
@ -808,6 +810,8 @@ gl_FragCoord origin is upper left
0:70 'sizeQueryTemp' (temp uint) 0:70 'sizeQueryTemp' (temp uint)
0:70 textureSize (temp uint) 0:70 textureSize (temp uint)
0:70 'g_tTex1df4' (uniform texture1D) 0:70 'g_tTex1df4' (uniform texture1D)
0:70 Constant:
0:70 0 (const int)
0:70 move second child to first child (temp int) 0:70 move second child to first child (temp int)
0:70 'WidthI' (temp int) 0:70 'WidthI' (temp int)
0:70 Convert uint to int (temp int) 0:70 Convert uint to int (temp int)
@ -1284,7 +1288,7 @@ gl_FragCoord origin is upper left
276: 6(float) CompositeExtract 275 0 276: 6(float) CompositeExtract 275 0
Store 268(r51) 276 Store 268(r51) 276
281: 278 Load 280(g_tTex1df4) 281: 278 Load 280(g_tTex1df4)
282: 14(int) ImageQuerySize 281 282: 14(int) ImageQuerySizeLod 281 53
Store 277(sizeQueryTemp) 282 Store 277(sizeQueryTemp) 282
284: 15(int) Load 277(sizeQueryTemp) 284: 15(int) Load 277(sizeQueryTemp)
285: 14(int) Bitcast 284 285: 14(int) Bitcast 284

View File

@ -19,6 +19,8 @@ gl_FragCoord origin is upper left
0:40 'sizeQueryTemp' (temp uint) 0:40 'sizeQueryTemp' (temp uint)
0:40 textureSize (temp uint) 0:40 textureSize (temp uint)
0:40 'g_tTex1df4' (uniform texture1D) 0:40 'g_tTex1df4' (uniform texture1D)
0:40 Constant:
0:40 0 (const int)
0:40 move second child to first child (temp int) 0:40 move second child to first child (temp int)
0:40 'WidthI' (temp int) 0:40 'WidthI' (temp int)
0:40 Convert uint to int (temp int) 0:40 Convert uint to int (temp int)
@ -121,6 +123,8 @@ gl_FragCoord origin is upper left
0:40 'sizeQueryTemp' (temp uint) 0:40 'sizeQueryTemp' (temp uint)
0:40 textureSize (temp uint) 0:40 textureSize (temp uint)
0:40 'g_tTex1df4' (uniform texture1D) 0:40 'g_tTex1df4' (uniform texture1D)
0:40 Constant:
0:40 0 (const int)
0:40 move second child to first child (temp int) 0:40 move second child to first child (temp int)
0:40 'WidthI' (temp int) 0:40 'WidthI' (temp int)
0:40 Convert uint to int (temp int) 0:40 Convert uint to int (temp int)
@ -229,14 +233,14 @@ gl_FragCoord origin is upper left
Name 19 "" Name 19 ""
Name 28 "sizeQueryTemp" Name 28 "sizeQueryTemp"
Name 31 "g_tTex1df4" Name 31 "g_tTex1df4"
Name 35 "WidthI" Name 36 "WidthI"
Name 38 "sizeQueryTemp" Name 39 "sizeQueryTemp"
Name 44 "NumberOfLevelsU" Name 45 "NumberOfLevelsU"
Name 47 "sizeQueryTemp" Name 48 "sizeQueryTemp"
Name 50 "WidthU" Name 51 "WidthU"
Name 52 "NumberOfLevelsI" Name 53 "NumberOfLevelsI"
Name 56 "sizeQueryTemp" Name 57 "sizeQueryTemp"
Name 65 "ps_output" Name 66 "ps_output"
Name 74 "color" Name 74 "color"
Name 80 "g_tTexbfs" Name 80 "g_tTexbfs"
MemberDecorate 17($Global) 0 Offset 0 MemberDecorate 17($Global) 0 Offset 0
@ -276,10 +280,10 @@ gl_FragCoord origin is upper left
29: TypeImage 6(float) 1D sampled format:Unknown 29: TypeImage 6(float) 1D sampled format:Unknown
30: TypePointer UniformConstant 29 30: TypePointer UniformConstant 29
31(g_tTex1df4): 30(ptr) Variable UniformConstant 31(g_tTex1df4): 30(ptr) Variable UniformConstant
34: TypePointer Function 12(int) 33: 12(int) Constant 0
40: 13(int) Constant 6 35: TypePointer Function 12(int)
64: TypePointer Function 8(PS_OUTPUT) 41: 13(int) Constant 6
66: 12(int) Constant 0 65: TypePointer Function 8(PS_OUTPUT)
67: 7(fvec4) ConstantComposite 24 24 24 24 67: 7(fvec4) ConstantComposite 24 24 24 24
68: TypePointer Function 7(fvec4) 68: TypePointer Function 7(fvec4)
73: TypePointer Output 7(fvec4) 73: TypePointer Output 7(fvec4)
@ -298,53 +302,53 @@ gl_FragCoord origin is upper left
10(@main():8(PS_OUTPUT) Function None 9 10(@main():8(PS_OUTPUT) Function None 9
11: Label 11: Label
28(sizeQueryTemp): 27(ptr) Variable Function 28(sizeQueryTemp): 27(ptr) Variable Function
35(WidthI): 34(ptr) Variable Function 36(WidthI): 35(ptr) Variable Function
38(sizeQueryTemp): 27(ptr) Variable Function 39(sizeQueryTemp): 27(ptr) Variable Function
44(NumberOfLevelsU): 27(ptr) Variable Function 45(NumberOfLevelsU): 27(ptr) Variable Function
47(sizeQueryTemp): 27(ptr) Variable Function 48(sizeQueryTemp): 27(ptr) Variable Function
50(WidthU): 27(ptr) Variable Function 51(WidthU): 27(ptr) Variable Function
52(NumberOfLevelsI): 34(ptr) Variable Function 53(NumberOfLevelsI): 35(ptr) Variable Function
56(sizeQueryTemp): 27(ptr) Variable Function 57(sizeQueryTemp): 27(ptr) Variable Function
65(ps_output): 64(ptr) Variable Function 66(ps_output): 65(ptr) Variable Function
22: 21(ptr) AccessChain 19 20 22: 21(ptr) AccessChain 19 20
23: 6(float) Load 22 23: 6(float) Load 22
26: 6(float) ExtInst 1(GLSL.std.450) 43(FClamp) 23 24 25 26: 6(float) ExtInst 1(GLSL.std.450) 43(FClamp) 23 24 25
32: 29 Load 31(g_tTex1df4) 32: 29 Load 31(g_tTex1df4)
33: 12(int) ImageQuerySize 32 34: 12(int) ImageQuerySizeLod 32 33
Store 28(sizeQueryTemp) 33 Store 28(sizeQueryTemp) 34
36: 13(int) Load 28(sizeQueryTemp) 37: 13(int) Load 28(sizeQueryTemp)
37: 12(int) Bitcast 36 38: 12(int) Bitcast 37
Store 35(WidthI) 37 Store 36(WidthI) 38
39: 29 Load 31(g_tTex1df4) 40: 29 Load 31(g_tTex1df4)
41: 12(int) ImageQuerySizeLod 39 40 42: 12(int) ImageQuerySizeLod 40 41
Store 38(sizeQueryTemp) 41 Store 39(sizeQueryTemp) 42
42: 13(int) Load 38(sizeQueryTemp) 43: 13(int) Load 39(sizeQueryTemp)
43: 12(int) Bitcast 42 44: 12(int) Bitcast 43
Store 35(WidthI) 43 Store 36(WidthI) 44
45: 29 Load 31(g_tTex1df4) 46: 29 Load 31(g_tTex1df4)
46: 12(int) ImageQueryLevels 45 47: 12(int) ImageQueryLevels 46
Store 44(NumberOfLevelsU) 46 Store 45(NumberOfLevelsU) 47
48: 29 Load 31(g_tTex1df4) 49: 29 Load 31(g_tTex1df4)
49: 12(int) ImageQuerySizeLod 48 40 50: 12(int) ImageQuerySizeLod 49 41
Store 47(sizeQueryTemp) 49 Store 48(sizeQueryTemp) 50
51: 13(int) Load 47(sizeQueryTemp) 52: 13(int) Load 48(sizeQueryTemp)
Store 50(WidthU) 51 Store 51(WidthU) 52
53: 29 Load 31(g_tTex1df4) 54: 29 Load 31(g_tTex1df4)
54: 12(int) ImageQueryLevels 53 55: 12(int) ImageQueryLevels 54
55: 12(int) Bitcast 54 56: 12(int) Bitcast 55
Store 52(NumberOfLevelsI) 55 Store 53(NumberOfLevelsI) 56
57: 29 Load 31(g_tTex1df4) 58: 29 Load 31(g_tTex1df4)
58: 12(int) ImageQuerySizeLod 57 40 59: 12(int) ImageQuerySizeLod 58 41
Store 56(sizeQueryTemp) 58 Store 57(sizeQueryTemp) 59
59: 13(int) Load 56(sizeQueryTemp) 60: 13(int) Load 57(sizeQueryTemp)
60: 12(int) Bitcast 59 61: 12(int) Bitcast 60
Store 35(WidthI) 60 Store 36(WidthI) 61
61: 29 Load 31(g_tTex1df4) 62: 29 Load 31(g_tTex1df4)
62: 12(int) ImageQueryLevels 61 63: 12(int) ImageQueryLevels 62
63: 12(int) Bitcast 62 64: 12(int) Bitcast 63
Store 52(NumberOfLevelsI) 63 Store 53(NumberOfLevelsI) 64
69: 68(ptr) AccessChain 65(ps_output) 66 69: 68(ptr) AccessChain 66(ps_output) 33
Store 69 67 Store 69 67
70:8(PS_OUTPUT) Load 65(ps_output) 70:8(PS_OUTPUT) Load 66(ps_output)
ReturnValue 70 ReturnValue 70
FunctionEnd FunctionEnd

View File

@ -2701,6 +2701,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
const TSampler& sampler = texType.getSampler(); const TSampler& sampler = texType.getSampler();
const TSamplerDim dim = sampler.dim; const TSamplerDim dim = sampler.dim;
const bool isImage = sampler.isImage(); const bool isImage = sampler.isImage();
const bool isMs = sampler.isMultiSample();
const int numArgs = (int)argAggregate->getSequence().size(); const int numArgs = (int)argAggregate->getSequence().size();
int numDims = 0; int numDims = 0;
@ -2711,6 +2712,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
case Esd3D: numDims = 3; break; // W, H, D case Esd3D: numDims = 3; break; // W, H, D
case EsdCube: numDims = 2; break; // W, H (cube) case EsdCube: numDims = 2; break; // W, H (cube)
case EsdBuffer: numDims = 1; break; // W (buffers) case EsdBuffer: numDims = 1; break; // W (buffers)
case EsdRect: numDims = 2; break; // W, H (rect)
default: default:
assert(0 && "unhandled texture dimension"); assert(0 && "unhandled texture dimension");
} }
@ -2719,17 +2721,31 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
if (sampler.isArrayed()) if (sampler.isArrayed())
++numDims; ++numDims;
// Establish whether we're querying mip levels // Establish whether the method itself is querying mip levels. This can be false even
const bool mipQuery = (numArgs > (numDims + 1)) && (!sampler.isMultiSample()); // if the underlying query requires a MIP level, due to the available HLSL method overloads.
const bool mipQuery = (numArgs > (numDims + 1 + (isMs ? 1 : 0)));
// Establish whether we must use the LOD form of query (even if the method did not supply a mip level to query).
// True if:
// 1. 1D/2D/3D/Cube AND multisample==0 AND NOT image (those can be sent to the non-LOD query)
// or,
// 2. There is a LOD (because the non-LOD query cannot be used in that case, per spec)
const bool mipRequired =
((dim == Esd1D || dim == Esd2D || dim == Esd3D || dim == EsdCube) && !isMs && !isImage) || // 1...
mipQuery; // 2...
// AST assumes integer return. Will be converted to float if required. // AST assumes integer return. Will be converted to float if required.
TIntermAggregate* sizeQuery = new TIntermAggregate(isImage ? EOpImageQuerySize : EOpTextureQuerySize); TIntermAggregate* sizeQuery = new TIntermAggregate(isImage ? EOpImageQuerySize : EOpTextureQuerySize);
sizeQuery->getSequence().push_back(argTex); sizeQuery->getSequence().push_back(argTex);
// If we're querying an explicit LOD, add the LOD, which is always arg #1
if (mipQuery) { // If we're building an LOD query, add the LOD.
TIntermTyped* queryLod = argAggregate->getSequence()[1]->getAsTyped(); if (mipRequired) {
// If the base HLSL query had no MIP level given, use level 0.
TIntermTyped* queryLod = mipQuery ? argAggregate->getSequence()[1]->getAsTyped() :
intermediate.addConstantUnion(0, loc, true);
sizeQuery->getSequence().push_back(queryLod); sizeQuery->getSequence().push_back(queryLod);
} }
sizeQuery->setType(TType(EbtUint, EvqTemporary, numDims)); sizeQuery->setType(TType(EbtUint, EvqTemporary, numDims));
sizeQuery->setLoc(loc); sizeQuery->setLoc(loc);