Commit ba6170b5 by Jeff Bolz

Implement GL_EXT_demote_to_helper_invocation

parent 4162de4b
......@@ -34,5 +34,6 @@ static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shade
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
#endif // #ifndef GLSLextEXT_H
......@@ -3111,6 +3111,12 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.clearAccessChain();
break;
case glslang::EOpDemote:
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
break;
default:
assert(0);
break;
......@@ -7610,6 +7616,13 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
builder.createNoResultOp(spv::OpEndInvocationInterlockEXT);
return 0;
case glslang::EOpIsHelperInvocation:
{
std::vector<spv::Id> args; // Dummy arguments
spv::Id id = builder.createOp(spv::OpIsHelperInvocationEXT, typeId, args);
return id;
}
default:
logger->missingFunctionality("unknown operation with no arguments");
return 0;
......
......@@ -1367,6 +1367,8 @@ const char* OpcodeString(int op)
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV";
case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV";
case OpDemoteToHelperInvocationEXT: return "OpDemoteToHelperInvocationEXT";
case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT";
case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT";
case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT";
......@@ -2784,6 +2786,8 @@ void Parameterize()
InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'");
InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'");
InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false);
}
}; // end spv namespace
......@@ -455,6 +455,7 @@ enum Decoration {
DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635,
DecorationUserSemantic = 5635,
DecorationUserTypeGOOGLE = 5636,
DecorationMax = 0x7fffffff,
};
......@@ -845,6 +846,7 @@ enum Capability {
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
CapabilityShaderSMBuiltinsNV = 5373,
CapabilityFragmentShaderPixelInterlockEXT = 5378,
CapabilityDemoteToHelperInvocationEXT = 5379,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
......@@ -1233,6 +1235,8 @@ enum Op {
OpCooperativeMatrixLengthNV = 5362,
OpBeginInvocationInterlockEXT = 5364,
OpEndInvocationInterlockEXT = 5365,
OpDemoteToHelperInvocationEXT = 5380,
OpIsHelperInvocationEXT = 5381,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
......@@ -1907,6 +1911,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break;
case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
......
spv.conditionalDemote.frag
Validation failed
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 38
Capability Shader
Capability Bad
Extension "SPV_EXT_demote_to_helper_invocation"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 17 36
ExecutionMode 4 OriginUpperLeft
Source GLSL 460
SourceExtension "GL_EXT_demote_to_helper_invocation"
Name 4 "main"
Name 9 "v"
Name 13 "tex"
Name 17 "coord"
Name 33 "x"
Name 36 "o"
Decorate 13(tex) DescriptorSet 0
Decorate 13(tex) Binding 0
Decorate 17(coord) Location 0
Decorate 36(o) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
10: TypeImage 6(float) 2D sampled format:Unknown
11: TypeSampledImage 10
12: TypePointer UniformConstant 11
13(tex): 12(ptr) Variable UniformConstant
15: TypeVector 6(float) 2
16: TypePointer Input 15(fvec2)
17(coord): 16(ptr) Variable Input
21: 6(float) Constant 1036831949
22: 6(float) Constant 1045220557
23: 6(float) Constant 1050253722
24: 6(float) Constant 1053609165
25: 7(fvec4) ConstantComposite 21 22 23 24
26: TypeBool
27: TypeVector 26(bool) 4
32: TypePointer Function 26(bool)
35: TypePointer Output 7(fvec4)
36(o): 35(ptr) Variable Output
4(main): 2 Function None 3
5: Label
9(v): 8(ptr) Variable Function
33(x): 32(ptr) Variable Function
14: 11 Load 13(tex)
18: 15(fvec2) Load 17(coord)
19: 7(fvec4) ImageSampleImplicitLod 14 18
Store 9(v) 19
20: 7(fvec4) Load 9(v)
28: 27(bvec4) FOrdEqual 20 25
29: 26(bool) All 28
SelectionMerge 31 None
BranchConditional 29 30 31
30: Label
DemoteToHelperInvocationEXT
Branch 31
31: Label
34: 26(bool) IsHelperInvocationEXT
Store 33(x) 34
37: 7(fvec4) Load 9(v)
Store 36(o) 37
Return
FunctionEnd
spv.demoteDisabled.frag
ERROR: 0:9: 'demote' : undeclared identifier
ERROR: 1 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link
#version 460 core
#extension GL_EXT_demote_to_helper_invocation : enable
layout(set = 0, binding = 0) uniform sampler2D tex;
layout(location = 0) in vec2 coord;
layout(location = 0) out vec4 o;
void main (void)
{
vec4 v = texture(tex, coord);
if (v == vec4(0.1,0.2,0.3,0.4))
demote;
bool x = helperInvocationEXT();
o = v;
}
#version 460 core
void main (void)
{
{
int demote = 0;
demote;
}
demote;
}
......@@ -624,6 +624,8 @@ enum TOperator {
EOpBeginInvocationInterlock, // Fragment only
EOpEndInvocationInterlock, // Fragment only
EOpIsHelperInvocation,
//
// Branch
//
......@@ -634,6 +636,7 @@ enum TOperator {
EOpContinue,
EOpCase,
EOpDefault,
EOpDemote, // Fragment only
//
// Constructors
......
......@@ -5034,6 +5034,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"void beginInvocationInterlockARB(void);"
"void endInvocationInterlockARB(void);");
stageBuiltins[EShLangFragment].append(
"bool helperInvocationEXT();"
"\n");
#ifdef AMD_EXTENSIONS
// GL_AMD_shader_explicit_vertex_parameter
if (profile != EEsProfile && version >= 450) {
......@@ -8641,6 +8645,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_StorageSemanticsImage", 1, &E_GL_KHR_memory_scope_semantics);
symbolTable.setVariableExtensions("gl_StorageSemanticsOutput", 1, &E_GL_KHR_memory_scope_semantics);
}
symbolTable.setFunctionExtensions("helperInvocationEXT", 1, &E_GL_EXT_demote_to_helper_invocation);
break;
case EShLangCompute:
......@@ -9295,6 +9301,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("findLSB", EOpFindLSB);
symbolTable.relateToOperator("findMSB", EOpFindMSB);
symbolTable.relateToOperator("helperInvocationEXT", EOpIsHelperInvocation);
if (PureOperatorBuiltins) {
symbolTable.relateToOperator("imageSize", EOpImageQuerySize);
symbolTable.relateToOperator("imageSamples", EOpImageQuerySamples);
......
......@@ -356,6 +356,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["default"] = DEFAULT;
(*KeywordMap)["if"] = IF;
(*KeywordMap)["else"] = ELSE;
(*KeywordMap)["demote"] = DEMOTE;
(*KeywordMap)["discard"] = DISCARD;
(*KeywordMap)["return"] = RETURN;
(*KeywordMap)["void"] = VOID;
......@@ -1621,6 +1622,12 @@ int TScanContext::tokenizeIdentifier()
return keyword;
return identifierOrType();
case DEMOTE:
if (parseContext.extensionTurnedOn(E_GL_EXT_demote_to_helper_invocation))
return keyword;
else
return identifierOrType();
default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
return 0;
......
......@@ -211,6 +211,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable;
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
......@@ -394,6 +395,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_fragment_invocation_density 1\n"
"#define GL_EXT_buffer_reference 1\n"
"#define GL_EXT_buffer_reference2 1\n"
"#define GL_EXT_demote_to_helper_invocation 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
......
......@@ -173,6 +173,7 @@ const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_blo
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2";
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
// Arrays of extensions for the above viewportEXTs duplications
......
......@@ -128,7 +128,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> ATTRIBUTE VARYING
%token <lex> FLOAT16_T FLOAT FLOAT32_T DOUBLE FLOAT64_T
%token <lex> CONST BOOL INT UINT INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE DEMOTE
%token <lex> BVEC2 BVEC3 BVEC4
%token <lex> IVEC2 IVEC3 IVEC4
%token <lex> UVEC2 UVEC3 UVEC4
......@@ -265,7 +265,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement
%type <interm.intermNode> iteration_statement iteration_statement_nonattributed jump_statement statement_no_new_scope statement_scoped
%type <interm.intermNode> iteration_statement iteration_statement_nonattributed jump_statement statement_no_new_scope statement_scoped demote_statement
%type <interm> single_declaration init_declarator_list
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
......@@ -3416,6 +3416,15 @@ simple_statement
| case_label { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
| demote_statement { $$ = $1; }
;
demote_statement
: DEMOTE SEMICOLON {
parseContext.requireStage($1.loc, EShLangFragment, "demote");
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote");
$$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc);
}
;
compound_statement
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1098,6 +1098,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
default: out.debug.message(EPrefixError, "Bad aggregation op");
}
......@@ -1392,6 +1394,7 @@ bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
case EOpContinue: out.debug << "Branch: Continue"; break;
case EOpReturn: out.debug << "Branch: Return"; break;
case EOpCase: out.debug << "case: "; break;
case EOpDemote: out.debug << "Demote"; break;
case EOpDefault: out.debug << "default: "; break;
default: out.debug << "Branch: Unknown Branch"; break;
}
......
......@@ -294,6 +294,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.bufferhandle9.frag",
"spv.bufferhandle_Error.frag",
"spv.builtInXFB.vert",
"spv.conditionalDemote.frag",
"spv.conditionalDiscard.frag",
"spv.constStruct.vert",
"spv.constConstruct.vert",
......@@ -304,6 +305,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.dataOut.frag",
"spv.dataOutIndirect.frag",
"spv.dataOutIndirect.vert",
"spv.demoteDisabled.frag",
"spv.deepRvalue.frag",
"spv.depthOut.frag",
"spv.discard-dce.frag",
......
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