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_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_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_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 #endif // #ifndef GLSLextKHR_H

View File

@ -1526,6 +1526,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR); 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; unsigned int mode;
switch (glslangIntermediate->getStage()) { switch (glslangIntermediate->getStage()) {
case EShLangVertex: case EShLangVertex:

View File

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

View File

@ -150,6 +150,7 @@ enum ExecutionMode {
ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeSubgroupsPerWorkgroupId = 37,
ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeId = 38,
ExecutionModeLocalSizeHintId = 39, ExecutionModeLocalSizeHintId = 39,
ExecutionModeSubgroupUniformControlFlowKHR = 4421,
ExecutionModePostDepthCoverage = 4446, ExecutionModePostDepthCoverage = 4446,
ExecutionModeDenormPreserve = 4459, ExecutionModeDenormPreserve = 4459,
ExecutionModeDenormFlushToZero = 4460, 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*); void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
// Determine loop control from attributes // Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
#endif #endif
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); 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_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
// #line and #include // #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -415,6 +416,7 @@ void TParseVersions::getPreamble(std::string& preamble)
} }
if (version >= 310) { if (version >= 310) {
preamble += "#define GL_EXT_null_initializer 1\n"; preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
} }
} else { // !isEsProfile() } else { // !isEsProfile()
@ -546,6 +548,7 @@ void TParseVersions::getPreamble(std::string& preamble)
} }
if (version >= 140) { if (version >= 140) {
preamble += "#define GL_EXT_null_initializer 1\n"; preamble += "#define GL_EXT_null_initializer 1\n";
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
} }
#endif // GLSLANG_WEB #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_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_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_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 // Arrays of extensions for the above viewportEXTs duplications

View File

@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
return EatPeelCount; return EatPeelCount;
else if (name == "partial_count") else if (name == "partial_count")
return EatPartialCount; return EatPartialCount;
else if (name == "subgroup_uniform_control_flow")
return EatSubgroupUniformControlFlow;
else else
return EatNone; 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 } // end namespace glslang
#endif // GLSLANG_WEB #endif // GLSLANG_WEB

View File

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

View File

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

View File

@ -944,6 +944,25 @@ function_prototype
$$.function = $1; $$.function = $1;
$$.loc = $2.loc; $$.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 function_declarator
@ -3713,6 +3732,7 @@ selection_statement
} }
| attribute selection_statement_nonattributed { | attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2); parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -3760,6 +3780,7 @@ switch_statement
} }
| attribute switch_statement_nonattributed { | attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2); parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -3824,6 +3845,7 @@ iteration_statement
} }
| attribute iteration_statement_nonattributed { | attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2); parseContext.handleLoopAttributes(*$1, $2);
$$ = $2; $$ = $2;
} }
@ -4027,7 +4049,6 @@ function_definition
attribute attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3; $$ = $3;
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
} }
attribute_list 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 /* 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. Inc.
This program is free software: you can redistribute it and/or modify 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) if (xfbMode)
infoSink.debug << "in xfb mode\n"; infoSink.debug << "in xfb mode\n";
if (getSubgroupUniformControlFlow())
infoSink.debug << "subgroup_uniform_control_flow\n";
switch (language) { switch (language) {
case EShLangVertex: case EShLangVertex:
break; break;

View File

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

View File

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