diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h index c9e31a61b..6e025298a 100644 --- a/SPIRV/GLSL.ext.KHR.h +++ b/SPIRV/GLSL.ext.KHR.h @@ -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 diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index eaa8cd3af..50806d091 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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; diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index bae43bdcc..03097d0cb 100755 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -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"; diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp index 91cb59eb3..c9f6f7165 100755 --- a/SPIRV/spirv.hpp +++ b/SPIRV/spirv.hpp @@ -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, diff --git a/Test/baseResults/spv.arbPostDepthCoverage.frag.out b/Test/baseResults/spv.arbPostDepthCoverage.frag.out new file mode 100644 index 000000000..1d92dbe60 --- /dev/null +++ b/Test/baseResults/spv.arbPostDepthCoverage.frag.out @@ -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 diff --git a/Test/baseResults/spv.arbPostDepthCoverage_Error.frag.out b/Test/baseResults/spv.arbPostDepthCoverage_Error.frag.out new file mode 100644 index 000000000..b210144da --- /dev/null +++ b/Test/baseResults/spv.arbPostDepthCoverage_Error.frag.out @@ -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 diff --git a/Test/baseResults/spv.extPostDepthCoverage.frag.out b/Test/baseResults/spv.extPostDepthCoverage.frag.out new file mode 100644 index 000000000..f2736565c --- /dev/null +++ b/Test/baseResults/spv.extPostDepthCoverage.frag.out @@ -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 diff --git a/Test/baseResults/spv.extPostDepthCoverage_Error.frag.out b/Test/baseResults/spv.extPostDepthCoverage_Error.frag.out new file mode 100644 index 000000000..9ce299f46 --- /dev/null +++ b/Test/baseResults/spv.extPostDepthCoverage_Error.frag.out @@ -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 diff --git a/Test/spv.arbPostDepthCoverage.frag b/Test/spv.arbPostDepthCoverage.frag new file mode 100644 index 000000000..03b61cb5e --- /dev/null +++ b/Test/spv.arbPostDepthCoverage.frag @@ -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]; +} diff --git a/Test/spv.arbPostDepthCoverage_Error.frag b/Test/spv.arbPostDepthCoverage_Error.frag new file mode 100644 index 000000000..652933b81 --- /dev/null +++ b/Test/spv.arbPostDepthCoverage_Error.frag @@ -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 () { + +} diff --git a/Test/spv.extPostDepthCoverage.frag b/Test/spv.extPostDepthCoverage.frag new file mode 100644 index 000000000..20aebc395 --- /dev/null +++ b/Test/spv.extPostDepthCoverage.frag @@ -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 () { +} diff --git a/Test/spv.extPostDepthCoverage_Error.frag b/Test/spv.extPostDepthCoverage_Error.frag new file mode 100644 index 000000000..25ce2e2e6 --- /dev/null +++ b/Test/spv.extPostDepthCoverage_Error.frag @@ -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 () { +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 00e20b531..4d7ab7219 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -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) diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 95bf1ab25..4bd42ac3c 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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", ""); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index ffc103e37..413a1b973 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -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" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index e9f9a6e16..a7c6009a6 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -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"; diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 7d0f1554a..ba7e0f59f 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -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) { diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 196cdf22d..9ca1557b5 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -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; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index f93182b75..4eacf58ca 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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 diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index a5d23d86a..268aa0b78 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -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",