Support GL_ARB_fragment_shader_interlock
This commit is contained in:
parent
a549bb8175
commit
c6f0ce8dbc
19 changed files with 336 additions and 5 deletions
|
|
@ -5030,6 +5030,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
}
|
||||
|
||||
stageBuiltins[EShLangFragment].append(
|
||||
"void beginInvocationInterlockARB(void);"
|
||||
"void endInvocationInterlockARB(void);");
|
||||
|
||||
#ifdef AMD_EXTENSIONS
|
||||
// GL_AMD_shader_explicit_vertex_parameter
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
|
|
@ -9539,6 +9543,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
if (profile != EEsProfile)
|
||||
symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex);
|
||||
#endif
|
||||
|
||||
symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock);
|
||||
symbolTable.relateToOperator("endInvocationInterlockARB", EOpEndInvocationInterlock);
|
||||
|
||||
break;
|
||||
|
||||
case EShLangCompute:
|
||||
|
|
|
|||
|
|
@ -1410,6 +1410,44 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
|
|||
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
|
||||
}
|
||||
break;
|
||||
case EOpBeginInvocationInterlock:
|
||||
if (language != EShLangFragment)
|
||||
error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", "");
|
||||
if (! inMain)
|
||||
error(loc, "beginInvocationInterlockARB() must be in main()", "", "");
|
||||
else if (postEntryPointReturn)
|
||||
error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", "");
|
||||
if (controlFlowNestingLevel > 0)
|
||||
error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", "");
|
||||
|
||||
if (beginInvocationInterlockCount > 0)
|
||||
error(loc, "beginInvocationInterlockARB() must only be called once", "", "");
|
||||
if (endInvocationInterlockCount > 0)
|
||||
error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
|
||||
|
||||
beginInvocationInterlockCount++;
|
||||
|
||||
// default to pixel_interlock_ordered
|
||||
if (intermediate.getInterlockOrdering() == EioNone)
|
||||
intermediate.setInterlockOrdering(EioPixelInterlockOrdered);
|
||||
break;
|
||||
case EOpEndInvocationInterlock:
|
||||
if (language != EShLangFragment)
|
||||
error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", "");
|
||||
if (! inMain)
|
||||
error(loc, "endInvocationInterlockARB() must be in main()", "", "");
|
||||
else if (postEntryPointReturn)
|
||||
error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", "");
|
||||
if (controlFlowNestingLevel > 0)
|
||||
error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", "");
|
||||
|
||||
if (endInvocationInterlockCount > 0)
|
||||
error(loc, "endInvocationInterlockARB() must only be called once", "", "");
|
||||
if (beginInvocationInterlockCount == 0)
|
||||
error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", "");
|
||||
|
||||
endInvocationInterlockCount++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -4945,6 +4983,17 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
return;
|
||||
}
|
||||
}
|
||||
for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) {
|
||||
if (id == TQualifier::getInterlockOrderingString(order)) {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier");
|
||||
requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order));
|
||||
if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered)
|
||||
requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order));
|
||||
publicType.shaderQualifiers.interlockOrdering = order;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (id.compare(0, 13, "blend_support") == 0) {
|
||||
bool found = false;
|
||||
for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
|
||||
|
|
@ -5945,6 +5994,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
|
|||
error(loc, message, "blend equation", "");
|
||||
if (shaderQualifiers.numViews != TQualifier::layoutNotSet)
|
||||
error(loc, message, "num_views", "");
|
||||
if (shaderQualifiers.interlockOrdering != EioNone)
|
||||
error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
|
||||
}
|
||||
|
||||
// Correct and/or advance an object's offset layout qualifier.
|
||||
|
|
@ -7874,6 +7925,14 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
|
|||
if (publicType.qualifier.storage != EvqVaryingOut)
|
||||
error(loc, "can only apply to 'out'", "blend equation", "");
|
||||
}
|
||||
if (publicType.shaderQualifiers.interlockOrdering) {
|
||||
if (publicType.qualifier.storage == EvqVaryingIn) {
|
||||
if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering))
|
||||
error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
|
||||
}
|
||||
else
|
||||
error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), "");
|
||||
}
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (publicType.shaderQualifiers.layoutDerivativeGroupQuads &&
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ public:
|
|||
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||
postEntryPointReturn(false),
|
||||
contextPragma(true, false),
|
||||
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
|
||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||
limits(resources.limits),
|
||||
globalUniformBlock(nullptr),
|
||||
|
|
@ -182,6 +183,8 @@ public:
|
|||
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||
TList<int> switchLevel;
|
||||
struct TPragma contextPragma;
|
||||
int beginInvocationInterlockCount;
|
||||
int endInvocationInterlockCount;
|
||||
|
||||
protected:
|
||||
TParseContextBase(TParseContextBase&);
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
||||
extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_fragment_shader_interlock] = EBhDisable;
|
||||
|
||||
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
||||
|
|
@ -379,6 +380,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_ARB_shader_stencil_export 1\n"
|
||||
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
||||
"#define GL_ARB_post_depth_coverage 1\n"
|
||||
"#define GL_ARB_fragment_shader_interlock 1\n"
|
||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||
"#define GL_EXT_post_depth_coverage 1\n"
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil
|
|||
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
||||
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
|
||||
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
|
||||
const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock";
|
||||
|
||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||
|
|
|
|||
|
|
@ -1502,6 +1502,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||
}
|
||||
infoSink.debug << "\n";
|
||||
}
|
||||
if (interlockOrdering != EioNone)
|
||||
infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
|
||||
break;
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ public:
|
|||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
||||
pixelCenterInteger(false), originUpperLeft(false),
|
||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
||||
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
||||
hlslFunctionality1(false),
|
||||
blendEquations(0), xfbMode(false), multiStream(false),
|
||||
|
|
@ -608,6 +608,15 @@ public:
|
|||
void setPointMode() { pointMode = true; }
|
||||
bool getPointMode() const { return pointMode; }
|
||||
|
||||
bool setInterlockOrdering(TInterlockOrdering o)
|
||||
{
|
||||
if (interlockOrdering != EioNone)
|
||||
return interlockOrdering == o;
|
||||
interlockOrdering = o;
|
||||
return true;
|
||||
}
|
||||
TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; }
|
||||
|
||||
bool setLocalSize(int dim, int size)
|
||||
{
|
||||
if (localSize[dim] > 1)
|
||||
|
|
@ -826,6 +835,7 @@ protected:
|
|||
bool originUpperLeft;
|
||||
TVertexSpacing vertexSpacing;
|
||||
TVertexOrder vertexOrder;
|
||||
TInterlockOrdering interlockOrdering;
|
||||
bool pointMode;
|
||||
int localSize[3];
|
||||
int localSizeSpecId[3];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue