Implement SPV_KHR_post_depth_coverage

Added support for both extension GL_ARB_post_depth_coverage and GL_EXT_post_depth_coverage.
This commit is contained in:
chaoc 2017-06-30 17:14:30 -07:00
parent 994660208c
commit c120452754
20 changed files with 185 additions and 6 deletions

View File

@ -32,7 +32,7 @@ enum Op;
enum Capability;
static const int GLSLextKHRVersion = 100;
static const int GLSLextKHRRevision = 1;
static const int GLSLextKHRRevision = 2;
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
@ -41,5 +41,6 @@ static const char* const E_SPV_KHR_multiview = "SPV_KHR_multi
static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters";
static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_storage";
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
#endif // #ifndef GLSLextKHR_H

View File

@ -980,6 +980,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
if (glslangIntermediate->getEarlyFragmentTests())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests);
if (glslangIntermediate->getPostDepthCoverage()) {
builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage);
builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage);
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
}
switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;

View File

@ -175,6 +175,7 @@ const char* ExecutionModeString(int mode)
case 31: return "ContractionOff";
case 32: return "Bad";
case 4446: return "PostDepthCoverage";
case ExecutionModeCeiling:
default: return "Bad";
}
@ -843,6 +844,7 @@ const char* CapabilityString(int info)
case 5009: return "ImageGatherBiasLodAMD";
#endif
case 4447: return "SampleMaskPostDepthCoverage";
#ifdef NV_EXTENSIONS
case 5251: return "GeometryShaderPassthroughNV";
case 5254: return "ShaderViewportIndexLayerNV";

View File

@ -47,11 +47,11 @@ namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10000
#define SPV_REVISION 10
#define SPV_REVISION 11
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010000;
static const unsigned int Revision = 10;
static const unsigned int Revision = 11;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@ -122,6 +122,7 @@ enum ExecutionMode {
ExecutionModeOutputTriangleStrip = 29,
ExecutionModeVecTypeHint = 30,
ExecutionModeContractionOff = 31,
ExecutionModePostDepthCoverage = 4446,
ExecutionModeMax = 0x7fffffff,
};
@ -628,6 +629,7 @@ enum Capability {
CapabilityMultiView = 4439,
CapabilityVariablePointersStorageBuffer = 4441,
CapabilityVariablePointers = 4442,
CapabilitySampleMaskPostDepthCoverage = 4447,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
CapabilityShaderViewportIndexLayerNV = 5254,

View File

@ -0,0 +1,43 @@
spv.arbPostDepthCoverage.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 18
Capability Shader
Capability SampleRateShading
Capability SampleMaskPostDepthCoverage
Extension "SPV_KHR_post_depth_coverage"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 8 13
ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 EarlyFragmentTests
ExecutionMode 4 PostDepthCoverage
Source GLSL 450
SourceExtension "GL_ARB_post_depth_coverage"
SourceExtension "GL_EXT_post_depth_coverage"
Name 4 "main"
Name 8 "readSampleMaskIn"
Name 13 "gl_SampleMaskIn"
Decorate 8(readSampleMaskIn) Location 0
Decorate 13(gl_SampleMaskIn) Flat
Decorate 13(gl_SampleMaskIn) BuiltIn SampleMask
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Output 6(int)
8(readSampleMaskIn): 7(ptr) Variable Output
9: TypeInt 32 0
10: 9(int) Constant 1
11: TypeArray 6(int) 10
12: TypePointer Input 11
13(gl_SampleMaskIn): 12(ptr) Variable Input
14: 6(int) Constant 0
15: TypePointer Input 6(int)
4(main): 2 Function None 3
5: Label
16: 15(ptr) AccessChain 13(gl_SampleMaskIn) 14
17: 6(int) Load 16
Store 8(readSampleMaskIn) 17
Return
FunctionEnd

View File

@ -0,0 +1,7 @@
spv.arbPostDepthCoverage_Error.frag
ERROR: 0:7: 'early_fragment_tests' : can only apply to a standalone qualifier
ERROR: 0:7: 'post_depth_coverage' : can only apply to a standalone qualifier
ERROR: 2 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,23 @@
spv.extPostDepthCoverage.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 6
Capability Shader
Capability SampleMaskPostDepthCoverage
Extension "SPV_KHR_post_depth_coverage"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 EarlyFragmentTests
ExecutionMode 4 PostDepthCoverage
Source ESSL 310
SourceExtension "GL_EXT_post_depth_coverage"
Name 4 "main"
2: TypeVoid
3: TypeFunction 2
4(main): 2 Function None 3
5: Label
Return
FunctionEnd

View File

@ -0,0 +1,4 @@
spv.extPostDepthCoverage_Error.frag
ERROR: Linking fragment stage: post_depth_coverage requires early_fragment_tests
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,13 @@
#version 450
#extension GL_ARB_post_depth_coverage : enable
#extension GL_EXT_post_depth_coverage : enable //according to ARB_post_depth_coverage,
//if both enabled, this one should be ignored
precision highp int;
layout(post_depth_coverage) in;
layout (location = 0) out int readSampleMaskIn;
void main () {
readSampleMaskIn = gl_SampleMaskIn[0];
}

View File

@ -0,0 +1,12 @@
#version 310 es
#extension GL_ARB_post_depth_coverage : enable
precision highp float;
layout(post_depth_coverage, location = 0) in float a; // should fail since post_depth_coverage may only
// be declared on in only (not with variable declarations)
void main () {
}

View File

@ -0,0 +1,9 @@
#version 310 es
#extension GL_EXT_post_depth_coverage : enable
layout(post_depth_coverage) in;
layout(early_fragment_tests) in;
void main () {
}

View File

@ -0,0 +1,9 @@
#version 450
#extension GL_EXT_post_depth_coverage : enable
layout(post_depth_coverage) in; // should fail since for GL_EXT_post_depth_coverage
// explicit declaration of early_fragment_tests is required
void main () {
}

View File

@ -968,6 +968,7 @@ struct TShaderQualifiers {
int localSize[3]; // compute shader
int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize
bool earlyFragmentTests; // fragment input
bool postDepthCoverage; // fragment input
TLayoutDepth layoutDepth;
bool blendEquation; // true if any blend equation was specified
@ -992,6 +993,7 @@ struct TShaderQualifiers {
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
earlyFragmentTests = false;
postDepthCoverage = false;
layoutDepth = EldNone;
blendEquation = false;
#ifdef NV_EXTENSIONS
@ -1029,6 +1031,8 @@ struct TShaderQualifiers {
}
if (src.earlyFragmentTests)
earlyFragmentTests = true;
if (src.postDepthCoverage)
postDepthCoverage = true;
if (src.layoutDepth)
layoutDepth = src.layoutDepth;
if (src.blendEquation)

View File

@ -4015,6 +4015,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.earlyFragmentTests = true;
return;
}
if (id == "post_depth_coverage") {
requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage");
if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) {
publicType.shaderQualifiers.earlyFragmentTests = true;
}
publicType.shaderQualifiers.postDepthCoverage = true;
return;
}
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) {
if (id == TQualifier::getLayoutDepthString(depth)) {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier");
@ -4788,6 +4796,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
error(loc, message, "invocations", "");
if (shaderQualifiers.earlyFragmentTests)
error(loc, message, "early_fragment_tests", "");
if (shaderQualifiers.postDepthCoverage)
error(loc, message, "post_depth_coverage", "");
for (int i = 0; i < 3; ++i) {
if (shaderQualifiers.localSize[i] > 1)
error(loc, message, "local_size", "");
@ -6282,6 +6292,12 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
else
error(loc, "can only apply to 'in'", "early_fragment_tests", "");
}
if (publicType.shaderQualifiers.postDepthCoverage) {
if (publicType.qualifier.storage == EvqVaryingIn)
intermediate.setPostDepthCoverage();
else
error(loc, "can only apply to 'in'", "post_coverage_coverage", "");
}
if (publicType.shaderQualifiers.blendEquation) {
if (publicType.qualifier.storage != EvqVaryingOut)
error(loc, "can only apply to 'out'", "blend equation", "");

View File

@ -181,9 +181,11 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_stencil_export] = EBhDisable;
// 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_EXT_shader_non_constant_global_initializers] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -316,8 +318,10 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_ARB_sparse_texture_clamp 1\n"
"#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_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"
#ifdef AMD_EXTENSIONS
"#define GL_AMD_shader_ballot 1\n"

View File

@ -135,6 +135,7 @@ const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export";
// 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_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
@ -142,6 +143,12 @@ const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_lo
// EXT extensions
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";
// Arrays of extensions for the above viewportEXTs duplications
const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage };
const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]);
// OVR extensions
const char* const E_GL_OVR_multiview = "GL_OVR_multiview";

View File

@ -1085,6 +1085,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
infoSink.debug << "gl_FragCoord origin is upper left\n";
if (earlyFragmentTests)
infoSink.debug << "using early_fragment_tests\n";
if (postDepthCoverage)
infoSink.debug << "using post_depth_coverage\n";
if (depthLayout != EldNone)
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
if (blendEquations != 0) {

View File

@ -101,6 +101,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
if (! earlyFragmentTests)
earlyFragmentTests = unit.earlyFragmentTests;
if (!postDepthCoverage)
postDepthCoverage = unit.postDepthCoverage;
if (depthLayout == EldNone)
depthLayout = unit.depthLayout;
else if (depthLayout != unit.depthLayout)
@ -485,6 +488,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:
// for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in
// ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage
// requiring explicit early_fragment_tests
if (getPostDepthCoverage() && !getEarlyFragmentTests())
error(infoSink, "post_depth_coverage requires early_fragment_tests");
break;
case EShLangCompute:
break;

View File

@ -164,8 +164,8 @@ public:
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), depthReplacing(false), blendEquations(0),
xfbMode(false), multiStream(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
blendEquations(0), xfbMode(false), multiStream(false),
#ifdef NV_EXTENSIONS
layoutOverrideCoverage(false),
geoPassthroughEXT(false),
@ -403,6 +403,8 @@ public:
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; }
bool setDepth(TLayoutDepth d)
{
if (depthLayout != EldNone)
@ -513,6 +515,7 @@ protected:
int localSize[3];
int localSizeSpecId[3];
bool earlyFragmentTests;
bool postDepthCoverage;
TLayoutDepth depthLayout;
bool depthReplacing;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift

View File

@ -226,6 +226,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.aggOps.frag",
"spv.always-discard.frag",
"spv.always-discard2.frag",
"spv.arbPostDepthCoverage.frag",
"spv.arbPostDepthCoverage_Error.frag",
"spv.bitCast.frag",
"spv.bool.vert",
"spv.boolInBlock.frag",
@ -242,6 +244,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.drawParams.vert",
"spv.doWhileLoop.frag",
"spv.earlyReturnDiscard.frag",
"spv.extPostDepthCoverage.frag",
"spv.extPostDepthCoverage_Error.frag",
"spv.flowControl.frag",
"spv.forLoop.frag",
"spv.forwardFun.frag",