GlslangToSpv: Pass the pointer directly into the client function for opaque types

For opaque types such as samplers, images, and atomic counters, we want to
reference the actual object in the child function.  For a long time, we
used a shadow variable and made a copy of the image/sampler.  In 76d0ac1a,
this was changed to not shadow samplers.  However, this didn't cover all
opaque types and it also didn't get the pointer storage classes right.
This commit fixes both of these issues.

Fixes #324
This commit is contained in:
Jason Ekstrand 2016-06-08 13:54:48 -07:00
parent 228546a8af
commit ed15ef1a5b
2 changed files with 44 additions and 43 deletions

View File

@ -2272,7 +2272,9 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
for (int p = 0; p < (int)parameters.size(); ++p) {
const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
spv::Id typeId = convertGlslangToSpvType(paramType);
if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
if (paramType.isOpaque())
typeId = builder.makePointer(TranslateStorageClass(paramType), typeId);
else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
else
constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId());
@ -2688,8 +2690,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
builder.clearAccessChain();
glslangArgs[a]->traverse(this);
argTypes.push_back(&paramType);
// keep outputs as and samplers l-values, evaluate input-only as r-values
if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.getBasicType() == glslang::EbtSampler) {
// keep outputs as and opaque objects l-values, evaluate input-only as r-values
if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.isOpaque()) {
// save l-value
lValues.push_back(builder.getAccessChain());
} else {
@ -2708,7 +2710,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
for (int a = 0; a < (int)glslangArgs.size(); ++a) {
const glslang::TType& paramType = glslangArgs[a]->getAsTyped()->getType();
spv::Id arg;
if (paramType.getBasicType() == glslang::EbtSampler) {
if (paramType.isOpaque()) {
builder.setAccessChain(lValues[lValueCount]);
arg = builder.accessChainGetLValue();
++lValueCount;

View File

@ -7,13 +7,13 @@ Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 68
// Id's are bound by 67
Capability Shader
Capability InputAttachment
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 15 27 54
EntryPoint Fragment 4 "main" 15 27 53
ExecutionMode 4 OriginUpperLeft
Source GLSL 400
Name 4 "main"
@ -24,27 +24,27 @@ Linked fragment stage:
Name 30 "sub"
Name 35 "subMS"
Name 42 "isub"
Name 46 "isubMS"
Name 54 "ucolor"
Name 57 "usub"
Name 62 "usubMS"
Name 45 "isubMS"
Name 53 "ucolor"
Name 56 "usub"
Name 61 "usubMS"
Decorate 30(sub) DescriptorSet 0
Decorate 30(sub) InputAttachmentIndex 1
Decorate 35(subMS) DescriptorSet 0
Decorate 35(subMS) InputAttachmentIndex 2
Decorate 42(isub) DescriptorSet 0
Decorate 42(isub) InputAttachmentIndex 3
Decorate 46(isubMS) DescriptorSet 0
Decorate 46(isubMS) InputAttachmentIndex 4
Decorate 57(usub) DescriptorSet 0
Decorate 57(usub) InputAttachmentIndex 5
Decorate 62(usubMS) DescriptorSet 0
Decorate 62(usubMS) InputAttachmentIndex 6
Decorate 45(isubMS) DescriptorSet 0
Decorate 45(isubMS) InputAttachmentIndex 4
Decorate 56(usub) DescriptorSet 0
Decorate 56(usub) InputAttachmentIndex 5
Decorate 61(usubMS) DescriptorSet 0
Decorate 61(usubMS) InputAttachmentIndex 6
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeImage 6(int) SubpassData multi-sampled nonsampled format:Unknown
8: TypePointer Function 7
8: TypePointer UniformConstant 7
9: TypeFunction 2 8(ptr)
13: TypeVector 6(int) 4
14: TypePointer Output 13(ivec4)
@ -66,18 +66,17 @@ Linked fragment stage:
40: TypeImage 6(int) SubpassData nonsampled format:Unknown
41: TypePointer UniformConstant 40
42(isub): 41(ptr) Variable UniformConstant
45: TypePointer UniformConstant 7
46(isubMS): 45(ptr) Variable UniformConstant
51: TypeInt 32 0
52: TypeVector 51(int) 4
53: TypePointer Output 52(ivec4)
54(ucolor): 53(ptr) Variable Output
55: TypeImage 51(int) SubpassData nonsampled format:Unknown
56: TypePointer UniformConstant 55
57(usub): 56(ptr) Variable UniformConstant
60: TypeImage 51(int) SubpassData multi-sampled nonsampled format:Unknown
61: TypePointer UniformConstant 60
62(usubMS): 61(ptr) Variable UniformConstant
45(isubMS): 8(ptr) Variable UniformConstant
50: TypeInt 32 0
51: TypeVector 50(int) 4
52: TypePointer Output 51(ivec4)
53(ucolor): 52(ptr) Variable Output
54: TypeImage 50(int) SubpassData nonsampled format:Unknown
55: TypePointer UniformConstant 54
56(usub): 55(ptr) Variable UniformConstant
59: TypeImage 50(int) SubpassData multi-sampled nonsampled format:Unknown
60: TypePointer UniformConstant 59
61(usubMS): 60(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
31: 28 Load 30(sub)
@ -91,20 +90,20 @@ Linked fragment stage:
43: 40 Load 42(isub)
44: 13(ivec4) ImageRead 43 20
Store 15(icolor) 44
47: 7 Load 46(isubMS)
48: 13(ivec4) ImageRead 47 20 Sample 17
49: 13(ivec4) Load 15(icolor)
50: 13(ivec4) IAdd 49 48
Store 15(icolor) 50
58: 55 Load 57(usub)
59: 52(ivec4) ImageRead 58 20
Store 54(ucolor) 59
63: 60 Load 62(usubMS)
64: 52(ivec4) ImageRead 63 20 Sample 17
65: 52(ivec4) Load 54(ucolor)
66: 52(ivec4) IAdd 65 64
Store 54(ucolor) 66
67: 2 FunctionCall 11(foo(iIPM1;) 46(isubMS)
46: 7 Load 45(isubMS)
47: 13(ivec4) ImageRead 46 20 Sample 17
48: 13(ivec4) Load 15(icolor)
49: 13(ivec4) IAdd 48 47
Store 15(icolor) 49
57: 54 Load 56(usub)
58: 51(ivec4) ImageRead 57 20
Store 53(ucolor) 58
62: 59 Load 61(usubMS)
63: 51(ivec4) ImageRead 62 20 Sample 17
64: 51(ivec4) Load 53(ucolor)
65: 51(ivec4) IAdd 64 63
Store 53(ucolor) 65
66: 2 FunctionCall 11(foo(iIPM1;) 45(isubMS)
Return
FunctionEnd
11(foo(iIPM1;): 2 Function None 9