Commit 033ae528 by John Kessenich

GLSL: Implement nonuniformEXT keyword, declarations, and constructor.

parent a3bf9121
......@@ -393,6 +393,7 @@ enum Decoration {
DecorationPassthroughNV = 5250,
DecorationViewportRelativeNV = 5252,
DecorationSecondaryViewportRelativeNV = 5256,
DecorationNonUniformEXT = 5300,
DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635,
DecorationMax = 0x7fffffff,
......@@ -688,6 +689,18 @@ enum Capability {
CapabilityShaderStereoViewNV = 5259,
CapabilityPerViewAttributesNV = 5260,
CapabilityFragmentFullyCoveredEXT = 5265,
CapabilityShaderNonUniformEXT = 5301,
CapabilityRuntimeDescriptorArrayEXT = 5302,
CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
CapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
CapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
......
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:17: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:23: 'constructor' : too many arguments
ERROR: 0:23: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:24: 'constructor' : not enough data provided for construction
ERROR: 0:24: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 8 compilation errors. No code generated.
Shader version: 450
ERROR: node is still EOpNull!
0:10 Function Definition: foo(i1; ( global void)
0:10 Function Parameters:
0:10 'nupi' ( nonuniform in int)
0:14 Function Definition: main( ( global void)
0:14 Function Parameters:
0:? Sequence
0:19 Function Call: foo(i1; ( global void)
0:19 'nu_li' ( nonuniform temp int)
0:22 move second child to first child ( temp int)
0:22 'nu_li' ( nonuniform temp int)
0:22 add ( temp int)
0:22 'a' ( nonuniform temp int)
0:22 component-wise multiply ( nonuniform temp int)
0:22 'a' ( temp int)
0:22 Constant:
0:22 2 (const int)
0:23 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:? Linker Objects
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)
0:? 'nu_uv4' ( nonuniform uniform 4-component vector of float)
0:? 'nu_constf' ( nonuniform const float)
0:? 1.000000
Linked fragment stage:
Shader version: 450
ERROR: node is still EOpNull!
0:10 Function Definition: foo(i1; ( global void)
0:10 Function Parameters:
0:10 'nupi' ( nonuniform in int)
0:14 Function Definition: main( ( global void)
0:14 Function Parameters:
0:? Sequence
0:19 Function Call: foo(i1; ( global void)
0:19 'nu_li' ( nonuniform temp int)
0:22 move second child to first child ( temp int)
0:22 'nu_li' ( nonuniform temp int)
0:22 add ( temp int)
0:22 'a' ( nonuniform temp int)
0:22 component-wise multiply ( nonuniform temp int)
0:22 'a' ( temp int)
0:22 Constant:
0:22 2 (const int)
0:23 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:? Linker Objects
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)
0:? 'nu_uv4' ( nonuniform uniform 4-component vector of float)
0:? 'nu_constf' ( nonuniform const float)
0:? 1.000000
#version 450
nonuniformEXT in vec4 nu_inv4;
nonuniformEXT float nu_gf;
nonuniformEXT out vec4 nu_outv4; // ERROR, out
nonuniformEXT uniform vec4 nu_uv4; // ERROR, uniform
nonuniformEXT const float nu_constf = 1.0; // ERROR, const
void foo(nonuniformEXT int nupi)
{
}
void main()
{
nonuniformEXT int nu_li;
nonuniformEXT const int nu_ci = 2; // ERROR, const
foo(nu_li);
int a;
nu_li = nonuniformEXT(a) + nonuniformEXT(a * 2);
nu_li = nonuniformEXT(a, a); // ERROR, too many arguments
nu_li = nonuniformEXT(); // ERROR, no arguments
}
\ No newline at end of file
......@@ -437,6 +437,7 @@ public:
clearInterstage();
clearMemory();
specConstant = false;
nonUniform = false;
clearLayout();
}
......@@ -470,7 +471,7 @@ public:
// Drop just the storage qualification, which perhaps should
// never be done, as it is fundamentally inconsistent, but need to
// explore what downstream consumers need.
// E.g., in a deference, it is an inconsistency between:
// E.g., in a dereference, it is an inconsistency between:
// A) partially dereferenced resource is still in the storage class it started in
// B) partially dereferenced resource is a new temporary object
// If A, then nothing should change, if B, then everything should change, but this is half way.
......@@ -478,6 +479,7 @@ public:
{
storage = EvqTemporary;
specConstant = false;
nonUniform = false;
}
const char* semanticName;
......@@ -502,6 +504,7 @@ public:
bool readonly : 1;
bool writeonly : 1;
bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant
bool nonUniform : 1;
bool isMemory() const
{
......@@ -833,6 +836,10 @@ public:
// true front-end constant.
return specConstant;
}
bool isNonUniform() const
{
return nonUniform;
}
bool isFrontEndConstant() const
{
// True if the front-end knows the final constant value.
......@@ -1692,6 +1699,8 @@ public:
appendStr(" writeonly");
if (qualifier.specConstant)
appendStr(" specialization-constant");
if (qualifier.nonUniform)
appendStr(" nonuniform");
appendStr(" ");
appendStr(getStorageQualifierString());
if (isArray()) {
......
......@@ -703,6 +703,7 @@ enum TOperator {
EOpConstructF16Mat4x4,
EOpConstructStruct,
EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
EOpConstructGuardEnd,
//
......
......@@ -1816,6 +1816,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
{
TOperator op = EOpNull;
if (type.getQualifier().nonUniform)
return EOpConstructNonuniform;
switch (type.getBasicType()) {
case EbtStruct:
op = EOpConstructStruct;
......
......@@ -2579,12 +2579,15 @@ void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& t
//
void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
{
bool nonuniformOkay = false;
// move from parameter/unknown qualifiers to pipeline in/out qualifiers
switch (qualifier.storage) {
case EvqIn:
profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs");
profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs");
qualifier.storage = EvqVaryingIn;
nonuniformOkay = true;
break;
case EvqOut:
profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
......@@ -2595,10 +2598,17 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
qualifier.storage = EvqVaryingIn;
error(loc, "cannot use 'inout' at global scope", "", "");
break;
case EvqGlobal:
case EvqTemporary:
nonuniformOkay = true;
break;
default:
break;
}
if (!nonuniformOkay && qualifier.nonUniform)
error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
invariantCheck(loc, qualifier);
}
......@@ -2847,6 +2857,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly);
MERGE_SINGLETON(specConstant);
MERGE_SINGLETON(nonUniform);
if (repeated)
error(loc, "replicated qualifiers", "", "");
......@@ -3669,7 +3680,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
trackLinkage(*block);
}
void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
{
switch (qualifier) {
case EvqConst:
......@@ -3715,8 +3726,10 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
else
warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
}
if (qualifier.isNonUniform())
type.getQualifier().nonUniform = qualifier.nonUniform;
paramCheckFix(loc, qualifier.storage, type);
paramCheckFixStorage(loc, qualifier.storage, type);
}
void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
......@@ -5867,6 +5880,11 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
basicOp = EOpConstructBool;
break;
case EOpConstructNonuniform:
node->getWritableType().getQualifier().nonUniform = true;
return node;
break;
default:
error(loc, "unsupported construction", "", "");
......
......@@ -363,7 +363,7 @@ public:
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
void nestedBlockCheck(const TSourceLoc&);
void nestedStructCheck(const TSourceLoc&);
......
......@@ -341,6 +341,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["const"] = CONST;
(*KeywordMap)["uniform"] = UNIFORM;
(*KeywordMap)["nonuniformEXT"] = NONUNIFORM;
(*KeywordMap)["in"] = IN;
(*KeywordMap)["out"] = OUT;
(*KeywordMap)["inout"] = INOUT;
......@@ -857,6 +858,7 @@ int TScanContext::tokenizeIdentifier()
switch (keyword) {
case CONST:
case UNIFORM:
case NONUNIFORM:
case IN:
case OUT:
case INOUT:
......
......@@ -199,6 +199,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
......@@ -351,6 +352,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n"
"#define GL_EXT_control_flow_attributes 1\n"
"#define GL_EXT_nonuniform_qualifier 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
......
......@@ -157,6 +157,7 @@ const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
// Arrays of extensions for the above viewportEXTs duplications
......
......@@ -140,7 +140,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> U8VEC2 U8VEC3 U8VEC4
%token <lex> VEC2 VEC3 VEC4
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
......@@ -268,6 +268,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm> array_specifier
%type <interm.type> precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier
%type <interm.type> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.type> non_uniform_qualifier
%type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> single_type_qualifier
......@@ -473,6 +474,11 @@ function_identifier
$$.function = new TFunction(&empty, TType(EbtVoid), EOpNull);
}
}
| non_uniform_qualifier {
// Constructor
$$.intermNode = 0;
$$.function = parseContext.handleConstructorCall($1.loc, $1);
}
;
unary_expression
......@@ -966,7 +972,7 @@ parameter_declaration
$$ = $1;
parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);
parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier());
}
//
......@@ -986,7 +992,7 @@ parameter_declaration
$$ = $1;
parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type);
parseContext.paramCheckFix($1.loc, EvqTemporary, *$$.param.type);
parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type);
parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier());
}
;
......@@ -1211,6 +1217,9 @@ single_type_qualifier
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
| non_uniform_qualifier {
$$ = $1;
}
;
storage_qualifier
......@@ -1331,6 +1340,13 @@ storage_qualifier
}
;
non_uniform_qualifier
: NONUNIFORM {
$$.init($1.loc);
$$.qualifier.nonUniform = true;
}
;
type_name_list
: IDENTIFIER {
// TODO
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -184,6 +184,7 @@ INSTANTIATE_TEST_CASE_P(
"loopsArtificial.frag",
"matrix.frag",
"matrix2.frag",
"nonuniform.frag",
"newTexture.frag",
"Operations.frag",
"overlongLiteral.frag",
......
......@@ -6560,6 +6560,7 @@ void HlslParseContext::mergeQualifiers(TQualifier& dst, const TQualifier& src)
MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly);
MERGE_SINGLETON(specConstant);
MERGE_SINGLETON(nonUniform);
}
// used to flatten the sampler type space into a single dimension
......
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