Implement GL_EXT_subgroup_uniform_control_flow.

This commit is contained in:
John Kessenich 2020-06-05 04:15:43 -06:00 committed by Alan Baker
parent 1fa21491bc
commit 848d3a9447
18 changed files with 3956 additions and 3703 deletions

View File

@ -51,5 +51,6 @@ static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_q
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
#endif // #ifndef GLSLextKHR_H

View File

@ -1526,6 +1526,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
}
#ifndef GLSLANG_WEB
if (glslangIntermediate->getSubgroupUniformControlFlow()) {
builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
}
#endif
unsigned int mode;
switch (glslangIntermediate->getStage()) {
case EShLangVertex:

View File

@ -188,6 +188,7 @@ const char* ExecutionModeString(int mode)
case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";

View File

@ -150,6 +150,7 @@ enum ExecutionMode {
ExecutionModeSubgroupsPerWorkgroupId = 37,
ExecutionModeLocalSizeId = 38,
ExecutionModeLocalSizeHintId = 39,
ExecutionModeSubgroupUniformControlFlowKHR = 4421,
ExecutionModePostDepthCoverage = 4446,
ExecutionModeDenormPreserve = 4459,
ExecutionModeDenormFlushToZero = 4460,

View File

@ -0,0 +1,23 @@
spv.subgroupUniformControlFlow.vert
WARNING: 0:7: '' : attribute with arguments not recognized, skipping
Validation failed
// Module Version 10000
// Generated by (magic number): 8000a
// Id's are bound by 6
Capability Shader
Extension "SPV_KHR_subgroup_uniform_control_flow"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main"
ExecutionMode 4 SubgroupUniformControlFlow
Source GLSL 460
SourceExtension "GL_EXT_subgroup_uniform_control_flow"
Name 4 "main"
2: TypeVoid
3: TypeFunction 2
4(main): 2 Function None 3
5: Label
Return
FunctionEnd

View File

@ -0,0 +1,11 @@
#version 460
#ifdef GL_EXT_subgroup_uniform_control_flow
#extension GL_EXT_subgroup_uniform_control_flow : enable
[[random(4)]] void main() [[subgroup_uniform_control_flow]]
{
}
#endif

View File

@ -470,6 +470,8 @@ public:
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
// Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
#endif
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);

View File

@ -251,6 +251,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -415,6 +416,7 @@ void TParseVersions::getPreamble(std::string& preamble)
}
if (version >= 310) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
}
} else { // !isEsProfile()
@ -546,6 +548,7 @@ void TParseVersions::getPreamble(std::string& preamble)
}
if (version >= 140) {
preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
}
#endif // GLSLANG_WEB
}

View File

@ -204,6 +204,7 @@ const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_s
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
// Arrays of extensions for the above viewportEXTs duplications

View File

@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
return EatPeelCount;
else if (name == "partial_count")
return EatPartialCount;
else if (name == "subgroup_uniform_control_flow")
return EatSubgroupUniformControlFlow;
else
return EatNone;
}
@ -341,6 +343,29 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
}
}
//
// Function attributes
//
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
{
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
if (it->size() > 0) {
warn(loc, "attribute with arguments not recognized, skipping", "", "");
continue;
}
switch (it->name) {
case EatSubgroupUniformControlFlow:
intermediate.setSubgroupUniformControlFlow();
break;
default:
warn(loc, "attribute does not apply to a function", "", "");
break;
}
}
}
} // end namespace glslang
#endif // GLSLANG_WEB

View File

@ -118,7 +118,8 @@ namespace glslang {
EatFormatR8ui,
EatFormatUnknown,
EatNonWritable,
EatNonReadable
EatNonReadable,
EatSubgroupUniformControlFlow,
};
class TIntermAggregate;

View File

@ -944,6 +944,25 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
}
| function_declarator RIGHT_PAREN attribute {
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
}
;
function_declarator
@ -3713,6 +3732,7 @@ selection_statement
}
GLSLANG_WEB_EXCLUDE_ON
| attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2;
}
@ -3760,6 +3780,7 @@ switch_statement
}
GLSLANG_WEB_EXCLUDE_ON
| attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2;
}
@ -3824,6 +3845,7 @@ iteration_statement
}
GLSLANG_WEB_EXCLUDE_ON
| attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2);
$$ = $2;
}
@ -4027,7 +4049,6 @@ GLSLANG_WEB_EXCLUDE_ON
attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3;
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
}
attribute_list

View File

@ -944,6 +944,25 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
}
| function_declarator RIGHT_PAREN attribute {
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
}
;
function_declarator
@ -3713,6 +3732,7 @@ selection_statement
}
| attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2;
}
@ -3760,6 +3780,7 @@ switch_statement
}
| attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2;
}
@ -3824,6 +3845,7 @@ iteration_statement
}
| attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2);
$$ = $2;
}
@ -4027,7 +4049,6 @@ function_definition
attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3;
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
}
attribute_list

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.7.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify

View File

@ -1487,6 +1487,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
if (xfbMode)
infoSink.debug << "in xfb mode\n";
if (getSubgroupUniformControlFlow())
infoSink.debug << "subgroup_uniform_control_flow\n";
switch (language) {
case EShLangVertex:
break;

View File

@ -328,6 +328,7 @@ public:
textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false),
binaryDoubleOutput(false),
subgroupUniformControlFlow(false),
usePhysicalStorageBuffer(false),
uniformLocationBase(0)
#endif
@ -864,6 +865,9 @@ public:
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
#endif // GLSLANG_WEB
void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
@ -1115,6 +1119,7 @@ protected:
bool needToLegalize;
bool binaryDoubleOutput;
bool subgroupUniformControlFlow;
bool usePhysicalStorageBuffer;
std::unordered_map<std::string, int> uniformLocationOverrides;

View File

@ -443,6 +443,7 @@ INSTANTIATE_TEST_SUITE_P(
"spv.specConstant.int8.comp",
"spv.storageBuffer.vert",
"spv.terminate.frag",
"spv.subgroupUniformControlFlow.vert",
"spv.precise.tese",
"spv.precise.tesc",
"spv.viewportindex.tese",