Commit 3ea188e1 by John Kessenich

Nonuniform: Finish semantic checking.

parent ee572e38
......@@ -1508,12 +1508,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
if (node->getOp() == glslang::EOpArrayLength) {
// Quite special; won't want to evaluate the operand.
// Currently, the front-end does not allow .length() on an array until it is sized,
// except for the last block membeor of an SSBO.
// TODO: If this changes, link-time sized arrays might show up here, and need their
// size extracted.
// Normal .length() would have been constant folded by the front-end.
// So, this has to be block.lastMember.length(). ??
// So, this has to be block.lastMember.length().
// SPV wants "block" and member number as the operands, go get them.
//?? depends if size was determined while linking, and on what the rules allow applying .length() to
glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
block->traverse(this);
unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
......
......@@ -51,7 +51,7 @@ ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:157: 'assign' : cannot convert from ' const float' to ' temp int'
ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:158: 'assign' : cannot convert from ' const float' to ' temp int'
WARNING: 0:161: '[]' : assuming array size of one for compile-time checking of binding numbers for unsized array
WARNING: 0:161: '[]' : assuming binding count of one for compile-time checking of binding numbers for unsized array
ERROR: 51 compilation errors. No code generated.
......
nonuniform.frag
ERROR: 0:6: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:7: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:8: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:18: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:24: 'constructor' : too many arguments
ERROR: 0:24: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:25: 'constructor' : not enough data provided for construction
ERROR: 0:25: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:28: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 0:29: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 0:10: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:11: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:12: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:22: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:28: 'constructor' : too many arguments
ERROR: 0:28: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:29: 'constructor' : not enough data provided for construction
ERROR: 0:29: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:32: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 0:33: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 10 compilation errors. No code generated.
Shader version: 450
Requested GL_EXT_nonuniform_qualifier
ERROR: node is still EOpNull!
0:10 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:10 Function Parameters:
0:10 'nupi' ( nonuniform in int)
0:10 'f' ( nonuniform out int)
0:12 Sequence
0:12 Branch: Return with expression
0:12 'nupi' ( nonuniform in int)
0:15 Function Definition: main( ( global void)
0:15 Function Parameters:
0:14 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:14 Function Parameters:
0:14 'nupi' ( nonuniform in int)
0:14 'f' ( nonuniform out int)
0:16 Sequence
0:16 Branch: Return with expression
0:16 'nupi' ( nonuniform in int)
0:19 Function Definition: main( ( global void)
0:19 Function Parameters:
0:? Sequence
0:20 Function Call: foo(i1;i1; ( nonuniform temp int)
0:20 'nu_li' ( nonuniform temp int)
0:20 'nu_li' ( nonuniform temp int)
0:23 move second child to first child ( temp int)
0:23 'nu_li' ( nonuniform temp int)
0:23 add ( nonuniform temp int)
0:23 'a' ( nonuniform temp int)
0:23 component-wise multiply ( nonuniform temp int)
0:23 'a' ( temp int)
0:23 Constant:
0:23 2 (const int)
0:24 Function Call: foo(i1;i1; ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:25 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:27 move second child to first child ( temp int)
0:27 'nu_li' ( nonuniform temp int)
0:27 add ( nonuniform temp int)
0:27 'a' ( nonuniform temp int)
0:27 component-wise multiply ( nonuniform temp int)
0:27 'a' ( temp int)
0:27 Constant:
0:27 2 (const int)
0:28 'nu_li' ( nonuniform temp int)
0:29 'nu_li' ( nonuniform temp int)
0:? Linker Objects
0:? 'nonuniformEXT' ( global int)
0:? 'nu_inv4' ( smooth nonuniform in 4-component vector of float)
0:? 'nu_gf' ( nonuniform temp float)
0:? 'nu_outv4' ( nonuniform out 4-component vector of float)
......@@ -52,31 +54,33 @@ Linked fragment stage:
Shader version: 450
Requested GL_EXT_nonuniform_qualifier
ERROR: node is still EOpNull!
0:10 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:10 Function Parameters:
0:10 'nupi' ( nonuniform in int)
0:10 'f' ( nonuniform out int)
0:12 Sequence
0:12 Branch: Return with expression
0:12 'nupi' ( nonuniform in int)
0:15 Function Definition: main( ( global void)
0:15 Function Parameters:
0:14 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:14 Function Parameters:
0:14 'nupi' ( nonuniform in int)
0:14 'f' ( nonuniform out int)
0:16 Sequence
0:16 Branch: Return with expression
0:16 'nupi' ( nonuniform in int)
0:19 Function Definition: main( ( global void)
0:19 Function Parameters:
0:? Sequence
0:20 Function Call: foo(i1;i1; ( nonuniform temp int)
0:20 'nu_li' ( nonuniform temp int)
0:20 'nu_li' ( nonuniform temp int)
0:23 move second child to first child ( temp int)
0:23 'nu_li' ( nonuniform temp int)
0:23 add ( nonuniform temp int)
0:23 'a' ( nonuniform temp int)
0:23 component-wise multiply ( nonuniform temp int)
0:23 'a' ( temp int)
0:23 Constant:
0:23 2 (const int)
0:24 Function Call: foo(i1;i1; ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:25 'nu_li' ( nonuniform temp int)
0:27 move second child to first child ( temp int)
0:27 'nu_li' ( nonuniform temp int)
0:27 add ( nonuniform temp int)
0:27 'a' ( nonuniform temp int)
0:27 component-wise multiply ( nonuniform temp int)
0:27 'a' ( temp int)
0:27 Constant:
0:27 2 (const int)
0:28 'nu_li' ( nonuniform temp int)
0:29 'nu_li' ( nonuniform temp int)
0:? Linker Objects
0:? 'nonuniformEXT' ( global int)
0:? 'nu_inv4' ( smooth nonuniform in 4-component vector of float)
0:? 'nu_gf' ( nonuniform temp float)
0:? 'nu_outv4' ( nonuniform out 4-component vector of float)
......
......@@ -48,7 +48,7 @@ spv.nonuniform.frag
Name 97 "bname"
MemberName 97(bname) 0 "b"
Name 100 "storageBuffer"
Name 111 "sampledImage"
Name 110 "sampledImage"
Name 125 "storageImage"
Name 137 "inputAttachment"
Name 147 "uniformTexelBuffer"
......@@ -93,10 +93,10 @@ spv.nonuniform.frag
Decorate 100(storageBuffer) Binding 4
Decorate 101 DecorationNonUniformEXT
Decorate 103 DecorationNonUniformEXT
Decorate 111(sampledImage) DescriptorSet 0
Decorate 111(sampledImage) Binding 5
Decorate 112 DecorationNonUniformEXT
Decorate 115 DecorationNonUniformEXT
Decorate 110(sampledImage) DescriptorSet 0
Decorate 110(sampledImage) Binding 5
Decorate 111 DecorationNonUniformEXT
Decorate 114 DecorationNonUniformEXT
Decorate 125(storageImage) DescriptorSet 0
Decorate 125(storageImage) Binding 6
Decorate 126 DecorationNonUniformEXT
......@@ -172,15 +172,15 @@ spv.nonuniform.frag
98: TypeRuntimeArray 97(bname)
99: TypePointer Uniform 98
100(storageBuffer): 99(ptr) Variable Uniform
107: TypeImage 28(float) 2D sampled format:Unknown
108: TypeSampledImage 107
109: TypeRuntimeArray 108
110: TypePointer UniformConstant 109
111(sampledImage): 110(ptr) Variable UniformConstant
113: TypePointer UniformConstant 108
116: TypeVector 28(float) 2
117: 28(float) Constant 1056964608
118: 116(fvec2) ConstantComposite 117 117
106: TypeImage 28(float) 2D sampled format:Unknown
107: TypeSampledImage 106
108: TypeRuntimeArray 107
109: TypePointer UniformConstant 108
110(sampledImage): 109(ptr) Variable UniformConstant
112: TypePointer UniformConstant 107
115: TypeVector 28(float) 2
116: 28(float) Constant 1056964608
117: 115(fvec2) ConstantComposite 116 116
122: TypeImage 28(float) 2D nonsampled format:R32f
123: TypeRuntimeArray 122
124: TypePointer UniformConstant 123
......@@ -270,13 +270,14 @@ spv.nonuniform.frag
104: 28(float) Load 30(b)
105: 28(float) FAdd 104 103
Store 30(b) 105
106: 28(float) Load 30(b)
112: 6(int) Load 90(nu_ii)
114: 113(ptr) AccessChain 111(sampledImage) 112
115: 108 Load 114
119: 31(fvec4) ImageSampleImplicitLod 115 118
120: 28(float) CompositeExtract 119 0
121: 28(float) FAdd 106 120
111: 6(int) Load 90(nu_ii)
113: 112(ptr) AccessChain 110(sampledImage) 111
114: 107 Load 113
118: 31(fvec4) ImageSampleImplicitLod 114 117
119: 28(float) CompositeExtract 118 0
120: 28(float) Load 30(b)
121: 28(float) FAdd 120 119
Store 30(b) 121
126: 6(int) Load 90(nu_ii)
128: 127(ptr) AccessChain 125(storageImage) 126
129: 122 Load 128
......
#version 450
int nonuniformEXT;
#extension GL_EXT_nonuniform_qualifier : enable
nonuniformEXT in vec4 nu_inv4;
nonuniformEXT float nu_gf;
......
......@@ -30,6 +30,15 @@ uniform aun {
float aub[];
};
layout(binding=1) uniform samplerBuffer uniformTexelBufferDyn[];
layout(binding=2, r32f) uniform imageBuffer storageTexelBufferDyn[];
layout(binding=3) uniform uname { float a; } uniformBuffer[];
layout(binding=4) buffer bname { float b; } storageBuffer[];
layout(binding=5) uniform sampler2D sampledImage[];
layout(binding=6, r32f) uniform image2D storageImage[];
layout(binding=8) uniform samplerBuffer uniformTexelBuffer[];
layout(binding=9, r32f) uniform imageBuffer storageTexelBuffer[];
int i;
void main()
......@@ -78,4 +87,22 @@ void main()
aub.length(); // ERROR
aba.length(); // ERROR
abb.length();
uniformTexelBufferDyn[1];
storageTexelBufferDyn[1];
uniformBuffer[1];
storageBuffer[1];
sampledImage[1];
storageImage[1];
uniformTexelBuffer[1];
storageTexelBuffer[1];
uniformTexelBufferDyn[i]; // ERROR, need extension
storageTexelBufferDyn[i]; // ERROR, need extension
uniformBuffer[i]; // ERROR, need extension
storageBuffer[i]; // ERROR, need extension
sampledImage[i]; // ERROR, need extension
storageImage[i]; // ERROR, need extension
uniformTexelBuffer[i]; // ERROR, need extension
storageTexelBuffer[i]; // ERROR, need extension
}
......@@ -37,7 +37,7 @@ void main()
b += imageLoad(storageTexelBufferDyn[dyn_i], 1).x;
b += uniformBuffer[nu_ii].a;
b += storageBuffer[nu_ii].b;
b + texture(sampledImage[nu_ii], vec2(0.5)).x;
b += texture(sampledImage[nu_ii], vec2(0.5)).x;
b += imageLoad(storageImage[nu_ii], ivec2(1)).x;
b += subpassLoad(inputAttachment[nu_ii]).x;
b += texelFetch(uniformTexelBuffer[nu_ii], 1).x;
......
......@@ -392,15 +392,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
else {
// it is okay for a run-time sized array
bool runtimeSized = isRuntimeSizable(*base);
if (!runtimeSized && /*?? base->getType().isOpaque() && */ base->getQualifier().isUniformOrBuffer()) {
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
runtimeSized = true;
}
if (!runtimeSized)
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
checkRuntimeSizable(loc, *base);
}
// ?? add correct run-time array semantics
base->getWritableType().setArrayVariablyIndexed();
}
if (base->getBasicType() == EbtBlock) {
......@@ -1252,7 +1245,6 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
else if (isRuntimeLength(*intermNode->getAsTyped())) {
//?? possible run-time arary
// Create a unary op and let the back end handle it
return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
} else
......@@ -3300,11 +3292,25 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
checkIoArraysConsistency(loc);
}
// Policy decision for whether a node could potentially be sized at runtime.
bool TParseContext::isRuntimeSizable(const TIntermTyped& base) const
// Policy and error check for needing a runtime sized array.
void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base)
{
// runtime length implies runtime sizeable, so no problem
if (isRuntimeLength(base))
return;
// check for additional things allowed by GL_EXT_nonuniform_qualifier
if (base.getBasicType() == EbtSampler ||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
else
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
}
// Policy decision for whether a run-time .length() is allowed.
bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
{
const TType& type = base.getType();
if (type.getQualifier().storage == EvqBuffer) {
if (base.getType().getQualifier().storage == EvqBuffer) {
// in a buffer block
const TIntermBinary* binary = base.getAsBinaryNode();
if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
......@@ -3319,12 +3325,6 @@ bool TParseContext::isRuntimeSizable(const TIntermTyped& base) const
return false;
}
// Policy decision for whether a run-time .length() is allowed.
bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
{
return isRuntimeSizable(base);
}
// Returns true if the first argument to the #line directive is the line number for the next line.
//
// Desktop, pre-version 3.30: "After processing this directive
......@@ -4721,7 +4721,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
lastBinding += type.getCumulativeArraySize();
else {
lastBinding += 1;
warn(loc, "assuming array size of one for compile-time checking of binding numbers for unsized array", "[]", "");
if (spvVersion.vulkan == 0)
warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", "");
}
}
}
......
......@@ -427,7 +427,7 @@ protected:
TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
bool isRuntimeSizable(const TIntermTyped&) const;
void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&);
bool isRuntimeLength(const TIntermTyped&) const;
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
......
......@@ -858,7 +858,6 @@ int TScanContext::tokenizeIdentifier()
switch (keyword) {
case CONST:
case UNIFORM:
case NONUNIFORM: //?? check for extension
case IN:
case OUT:
case INOUT:
......@@ -875,6 +874,12 @@ int TScanContext::tokenizeIdentifier()
case CASE:
return keyword;
case NONUNIFORM:
if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
return keyword;
else
return identifierOrType();
case SWITCH:
case DEFAULT:
if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
......
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