Commit f8203a0a by steve-lunarg

HLSL: cast non-int types to uint on Load/Store indexes

Some texture and SB operations can take non-integer indexes, which should be cast to integers before use if they are not already. This adds makeIntegerIndex() for the purpose. Int types are left alone. (This was done before for operator[], but needs to apply to some other things too, hence its extraction into common function now)
parent 67027189
spv.ssbo.autoassign.frag spv.ssbo.autoassign.frag
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 95 // Id's are bound by 99
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 88 91 EntryPoint Fragment 4 "main" 92 95
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source HLSL 500 Source HLSL 500
Name 4 "main" Name 4 "main"
...@@ -23,13 +23,13 @@ spv.ssbo.autoassign.frag ...@@ -23,13 +23,13 @@ spv.ssbo.autoassign.frag
MemberName 26(TestCB) 0 "W" MemberName 26(TestCB) 0 "W"
MemberName 26(TestCB) 1 "H" MemberName 26(TestCB) 1 "H"
Name 28 "" Name 28 ""
Name 55 "SB1"
MemberName 55(SB1) 0 "@data"
Name 57 "SB1" Name 57 "SB1"
Name 86 "pos" MemberName 57(SB1) 0 "@data"
Name 88 "pos" Name 59 "SB1"
Name 91 "@entryPointOutput" Name 90 "pos"
Name 92 "param" Name 92 "pos"
Name 95 "@entryPointOutput"
Name 96 "param"
MemberDecorate 14(BufType) 0 NonWritable MemberDecorate 14(BufType) 0 NonWritable
MemberDecorate 14(BufType) 0 Offset 0 MemberDecorate 14(BufType) 0 Offset 0
MemberDecorate 14(BufType) 1 NonWritable MemberDecorate 14(BufType) 1 NonWritable
...@@ -45,13 +45,13 @@ spv.ssbo.autoassign.frag ...@@ -45,13 +45,13 @@ spv.ssbo.autoassign.frag
Decorate 26(TestCB) Block Decorate 26(TestCB) Block
Decorate 28 DescriptorSet 0 Decorate 28 DescriptorSet 0
Decorate 28 Binding 15 Decorate 28 Binding 15
Decorate 54 ArrayStride 32 Decorate 56 ArrayStride 32
MemberDecorate 55(SB1) 0 Offset 0 MemberDecorate 57(SB1) 0 Offset 0
Decorate 55(SB1) BufferBlock Decorate 57(SB1) BufferBlock
Decorate 57(SB1) DescriptorSet 0 Decorate 59(SB1) DescriptorSet 0
Decorate 57(SB1) Binding 31 Decorate 59(SB1) Binding 31
Decorate 88(pos) Location 0 Decorate 92(pos) Location 0
Decorate 91(@entryPointOutput) Location 0 Decorate 95(@entryPointOutput) Location 0
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -73,26 +73,26 @@ spv.ssbo.autoassign.frag ...@@ -73,26 +73,26 @@ spv.ssbo.autoassign.frag
28: 27(ptr) Variable Uniform 28: 27(ptr) Variable Uniform
29: TypePointer Uniform 21(int) 29: TypePointer Uniform 21(int)
34: 21(int) Constant 0 34: 21(int) Constant 0
38: TypePointer Uniform 7(fvec4) 39: TypePointer Uniform 7(fvec4)
50: 19(int) Constant 1 52: 19(int) Constant 1
54: TypeRuntimeArray 14(BufType) 56: TypeRuntimeArray 14(BufType)
55(SB1): TypeStruct 54 57(SB1): TypeStruct 56
56: TypePointer Uniform 55(SB1) 58: TypePointer Uniform 57(SB1)
57(SB1): 56(ptr) Variable Uniform 59(SB1): 58(ptr) Variable Uniform
87: TypePointer Input 7(fvec4) 91: TypePointer Input 7(fvec4)
88(pos): 87(ptr) Variable Input 92(pos): 91(ptr) Variable Input
90: TypePointer Output 7(fvec4) 94: TypePointer Output 7(fvec4)
91(@entryPointOutput): 90(ptr) Variable Output 95(@entryPointOutput): 94(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
86(pos): 8(ptr) Variable Function 90(pos): 8(ptr) Variable Function
92(param): 8(ptr) Variable Function 96(param): 8(ptr) Variable Function
89: 7(fvec4) Load 88(pos) 93: 7(fvec4) Load 92(pos)
Store 86(pos) 89 Store 90(pos) 93
93: 7(fvec4) Load 86(pos) 97: 7(fvec4) Load 90(pos)
Store 92(param) 93 Store 96(param) 97
94: 7(fvec4) FunctionCall 11(@main(vf4;) 92(param) 98: 7(fvec4) FunctionCall 11(@main(vf4;) 96(param)
Store 91(@entryPointOutput) 94 Store 95(@entryPointOutput) 98
Return Return
FunctionEnd FunctionEnd
11(@main(vf4;): 7(fvec4) Function None 9 11(@main(vf4;): 7(fvec4) Function None 9
...@@ -108,47 +108,51 @@ spv.ssbo.autoassign.frag ...@@ -108,47 +108,51 @@ spv.ssbo.autoassign.frag
35: 23(ptr) AccessChain 10(pos) 34 35: 23(ptr) AccessChain 10(pos) 34
36: 6(float) Load 35 36: 6(float) Load 35
37: 6(float) FAdd 33 36 37: 6(float) FAdd 33 36
39: 38(ptr) AccessChain 18(SB0) 20 37 20 38: 21(int) ConvertFToU 37
40: 7(fvec4) Load 39 40: 39(ptr) AccessChain 18(SB0) 20 38 20
41: 23(ptr) AccessChain 10(pos) 22 41: 7(fvec4) Load 40
42: 6(float) Load 41 42: 23(ptr) AccessChain 10(pos) 22
43: 29(ptr) AccessChain 28 20 43: 6(float) Load 42
44: 21(int) Load 43 44: 29(ptr) AccessChain 28 20
45: 6(float) ConvertUToF 44 45: 21(int) Load 44
46: 6(float) FMul 42 45 46: 6(float) ConvertUToF 45
47: 23(ptr) AccessChain 10(pos) 34 47: 6(float) FMul 43 46
48: 6(float) Load 47 48: 23(ptr) AccessChain 10(pos) 34
49: 6(float) FAdd 46 48 49: 6(float) Load 48
51: 38(ptr) AccessChain 18(SB0) 20 49 50 50: 6(float) FAdd 47 49
52: 7(fvec4) Load 51 51: 21(int) ConvertFToU 50
53: 7(fvec4) FAdd 40 52 53: 39(ptr) AccessChain 18(SB0) 20 51 52
Store 13(vTmp) 53 54: 7(fvec4) Load 53
58: 23(ptr) AccessChain 10(pos) 22 55: 7(fvec4) FAdd 41 54
59: 6(float) Load 58 Store 13(vTmp) 55
60: 29(ptr) AccessChain 28 20 60: 23(ptr) AccessChain 10(pos) 22
61: 21(int) Load 60 61: 6(float) Load 60
62: 6(float) ConvertUToF 61 62: 29(ptr) AccessChain 28 20
63: 6(float) FMul 59 62 63: 21(int) Load 62
64: 23(ptr) AccessChain 10(pos) 34 64: 6(float) ConvertUToF 63
65: 6(float) Load 64 65: 6(float) FMul 61 64
66: 6(float) FAdd 63 65 66: 23(ptr) AccessChain 10(pos) 34
67: 38(ptr) AccessChain 57(SB1) 20 66 20 67: 6(float) Load 66
68: 7(fvec4) Load 67 68: 6(float) FAdd 65 67
69: 23(ptr) AccessChain 10(pos) 22 69: 21(int) ConvertFToU 68
70: 6(float) Load 69 70: 39(ptr) AccessChain 59(SB1) 20 69 20
71: 29(ptr) AccessChain 28 20 71: 7(fvec4) Load 70
72: 21(int) Load 71 72: 23(ptr) AccessChain 10(pos) 22
73: 6(float) ConvertUToF 72 73: 6(float) Load 72
74: 6(float) FMul 70 73 74: 29(ptr) AccessChain 28 20
75: 23(ptr) AccessChain 10(pos) 34 75: 21(int) Load 74
76: 6(float) Load 75 76: 6(float) ConvertUToF 75
77: 6(float) FAdd 74 76 77: 6(float) FMul 73 76
78: 38(ptr) AccessChain 57(SB1) 20 77 50 78: 23(ptr) AccessChain 10(pos) 34
79: 7(fvec4) Load 78 79: 6(float) Load 78
80: 7(fvec4) FAdd 68 79 80: 6(float) FAdd 77 79
81: 7(fvec4) Load 13(vTmp) 81: 21(int) ConvertFToU 80
82: 7(fvec4) FAdd 81 80 82: 39(ptr) AccessChain 59(SB1) 20 81 52
Store 13(vTmp) 82 83: 7(fvec4) Load 82
83: 7(fvec4) Load 13(vTmp) 84: 7(fvec4) FAdd 71 83
ReturnValue 83 85: 7(fvec4) Load 13(vTmp)
86: 7(fvec4) FAdd 85 84
Store 13(vTmp) 86
87: 7(fvec4) Load 13(vTmp)
ReturnValue 87
FunctionEnd FunctionEnd
struct sb_t
{
float4 color;
uint2 threadId;
};
RWTexture2D<float4> outtx;
ConsumeStructuredBuffer<sb_t> csb : register(u1);
RWStructuredBuffer<float4> rwsb;
[numthreads(1, 1, 1)]
void main(uint3 nThreadId : SV_DispatchThreadID)
{
sb_t data = csb.Consume();
float2 coord = float2(data.threadId.xy);
outtx[coord] = data.color;
rwsb[coord.x] = rwsb.Load(coord.y);
}
...@@ -249,6 +249,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -249,6 +249,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.structbuffer.atomics.frag", "main"}, {"hlsl.structbuffer.atomics.frag", "main"},
{"hlsl.structbuffer.byte.frag", "main"}, {"hlsl.structbuffer.byte.frag", "main"},
{"hlsl.structbuffer.coherent.frag", "main"}, {"hlsl.structbuffer.coherent.frag", "main"},
{"hlsl.structbuffer.floatidx.comp", "main"},
{"hlsl.structbuffer.incdec.frag", "main"}, {"hlsl.structbuffer.incdec.frag", "main"},
{"hlsl.structbuffer.fn.frag", "main"}, {"hlsl.structbuffer.fn.frag", "main"},
{"hlsl.structbuffer.rw.frag", "main"}, {"hlsl.structbuffer.rw.frag", "main"},
......
...@@ -713,27 +713,38 @@ TIntermTyped* HlslParseContext::handleBracketOperator(const TSourceLoc& loc, TIn ...@@ -713,27 +713,38 @@ TIntermTyped* HlslParseContext::handleBracketOperator(const TSourceLoc& loc, TIn
} }
// //
// Handle seeing a base[index] dereference in the grammar. // Cast index value to a uint if it isn't already (for operator[], load indexes, etc)
// TIntermTyped* HlslParseContext::makeIntegerIndex(TIntermTyped* index)
TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{ {
TIntermTyped* result = handleBracketOperator(loc, base, index);
if (result != nullptr)
return result; // it was handled as an operator[]
const TBasicType indexBasicType = index->getType().getBasicType(); const TBasicType indexBasicType = index->getType().getBasicType();
const int vecSize = index->getType().getVectorSize();
// We can use int types directly as the index
if (indexBasicType == EbtInt || indexBasicType == EbtUint ||
indexBasicType == EbtInt64 || indexBasicType == EbtUint64)
return index;
// Cast index to unsigned integer if it isn't one. // Cast index to unsigned integer if it isn't one.
if (indexBasicType != EbtInt && indexBasicType != EbtUint && return intermediate.addConversion(EOpConstructUint, TType(EbtUint, EvqTemporary, vecSize), index);
indexBasicType != EbtInt64 && indexBasicType != EbtUint64) }
index = intermediate.addConversion(EOpConstructUint, TType(EbtUint), index);
//
// Handle seeing a base[index] dereference in the grammar.
//
TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{
index = makeIntegerIndex(index);
if (index == nullptr) { if (index == nullptr) {
error(loc, " unknown undex type ", "", ""); error(loc, " unknown undex type ", "", "");
return nullptr; return nullptr;
} }
TIntermTyped* result = handleBracketOperator(loc, base, index);
if (result != nullptr)
return result; // it was handled as an operator[]
bool flattened = false; bool flattened = false;
int indexValue = 0; int indexValue = 0;
if (index->getQualifier().storage == EvqConst) { if (index->getQualifier().storage == EvqConst) {
...@@ -2570,7 +2581,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte ...@@ -2570,7 +2581,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
switch (op) { switch (op) {
case EOpMethodLoad: case EOpMethodLoad:
{ {
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // index TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
// Byte address buffers index in bytes (only multiples of 4 permitted... not so much a byte address // Byte address buffers index in bytes (only multiples of 4 permitted... not so much a byte address
// buffer then, but that's what it calls itself. // buffer then, but that's what it calls itself.
...@@ -2596,7 +2607,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte ...@@ -2596,7 +2607,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
case EOpMethodLoad3: case EOpMethodLoad3:
case EOpMethodLoad4: case EOpMethodLoad4:
{ {
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // index TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
TOperator constructOp = EOpNull; TOperator constructOp = EOpNull;
int size = 0; int size = 0;
...@@ -2654,7 +2665,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte ...@@ -2654,7 +2665,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
case EOpMethodStore3: case EOpMethodStore3:
case EOpMethodStore4: case EOpMethodStore4:
{ {
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // address TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
TIntermTyped* argValue = argAggregate->getSequence()[2]->getAsTyped(); // value TIntermTyped* argValue = argAggregate->getSequence()[2]->getAsTyped(); // value
// Index into the array to find the item being loaded. // Index into the array to find the item being loaded.
...@@ -2761,7 +2772,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte ...@@ -2761,7 +2772,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
TIntermSequence& sequence = argAggregate->getSequence(); TIntermSequence& sequence = argAggregate->getSequence();
TIntermTyped* argIndex = sequence[1]->getAsTyped(); // index TIntermTyped* argIndex = makeIntegerIndex(sequence[1]->getAsTyped()); // index
argIndex = intermediate.addBinaryNode(EOpRightShift, argIndex, intermediate.addConstantUnion(2, loc, true), argIndex = intermediate.addBinaryNode(EOpRightShift, argIndex, intermediate.addConstantUnion(2, loc, true),
loc, TType(EbtInt)); loc, TType(EbtInt));
......
...@@ -250,6 +250,7 @@ protected: ...@@ -250,6 +250,7 @@ protected:
TVariable* getSplitIoVar(int id) const; TVariable* getSplitIoVar(int id) const;
void addInterstageIoToLinkage(); void addInterstageIoToLinkage();
void addPatchConstantInvocation(); void addPatchConstantInvocation();
TIntermTyped* makeIntegerIndex(TIntermTyped*);
void fixBuiltInIoType(TType&); void fixBuiltInIoType(TType&);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment