From 1c5443c693d5845c6ef370924a60084a11a4ebac Mon Sep 17 00:00:00 2001 From: Piers Daniell <pdaniell@nvidia.com> Date: Wed, 13 Dec 2017 13:07:22 -0700 Subject: [PATCH] Add implementation of SPV_EXT_fragment_fully_covered This implementation uses the GLSL extension GL_NV_conservative_raster_underestimation to generate the new SPIR-V FullyCoveredEXT built in. --- SPIRV/GLSL.ext.EXT.h | 39 ++++++++++++++++++++++ SPIRV/GlslangToSpv.cpp | 5 +++ SPIRV/doc.cpp | 5 +++ Test/baseResults/spv.fullyCovered.frag.out | 37 ++++++++++++++++++++ Test/spv.fullyCovered.frag | 9 +++++ glslang/Include/BaseTypes.h | 2 ++ glslang/MachineIndependent/Initialize.cpp | 14 ++++++++ glslang/MachineIndependent/ParseHelper.cpp | 2 +- glslang/MachineIndependent/Versions.cpp | 2 ++ glslang/MachineIndependent/Versions.h | 1 + gtests/Spv.FromFile.cpp | 1 + 11 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 SPIRV/GLSL.ext.EXT.h create mode 100644 Test/baseResults/spv.fullyCovered.frag.out create mode 100644 Test/spv.fullyCovered.frag diff --git a/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h new file mode 100644 index 000000000..e879714d0 --- /dev/null +++ b/SPIRV/GLSL.ext.EXT.h @@ -0,0 +1,39 @@ +/* +** Copyright (c) 2014-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +#ifndef GLSLextEXT_H +#define GLSLextEXT_H + +enum BuiltIn; +enum Op; +enum Capability; + +static const int GLSLextEXTVersion = 100; +static const int GLSLextEXTRevision = 1; + +static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered"; + +#endif // #ifndef GLSLextEXT_H diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 34465f5a2..4ae52861e 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -44,6 +44,7 @@ namespace spv { #include "GLSL.std.450.h" #include "GLSL.ext.KHR.h" + #include "GLSL.ext.EXT.h" #ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" #endif @@ -646,6 +647,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityPerViewAttributesNV); } return spv::BuiltInViewportMaskPerViewNV; + case glslang::EbvFragFullyCoveredNV: + builder.addExtension(spv::E_SPV_EXT_fragment_fully_covered); + builder.addCapability(spv::CapabilityFragmentFullyCoveredEXT); + return spv::BuiltInFullyCoveredEXT; #endif default: return spv::BuiltInMax; diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index f9d5254c7..7d817b492 100755 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -49,6 +49,7 @@ namespace spv { extern "C" { // Include C-based headers that don't have a namespace #include "GLSL.ext.KHR.h" + #include "GLSL.ext.EXT.h" #ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" #endif @@ -351,6 +352,8 @@ const char* BuiltInString(int builtIn) case 5262: return "ViewportMaskPerViewNV"; #endif + case 5264: return "FullyCoveredEXT"; + case BuiltInCeiling: default: return "Bad"; } @@ -862,6 +865,8 @@ const char* CapabilityString(int info) case 5260: return "PerViewAttributesNV"; #endif + case 5265: return "FragmentFullyCoveredEXT"; + case CapabilityCeiling: default: return "Bad"; } diff --git a/Test/baseResults/spv.fullyCovered.frag.out b/Test/baseResults/spv.fullyCovered.frag.out new file mode 100644 index 000000000..4df1c5541 --- /dev/null +++ b/Test/baseResults/spv.fullyCovered.frag.out @@ -0,0 +1,37 @@ +spv.fullyCovered.frag +// Module Version 10000 +// Generated by (magic number): 80002 +// Id's are bound by 18 + + Capability Shader + Capability FragmentFullyCoveredEXT + Extension "SPV_EXT_fragment_fully_covered" + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 9 12 + ExecutionMode 4 OriginUpperLeft + Source GLSL 450 + SourceExtension "GL_NV_conservative_raster_underestimation" + Name 4 "main" + Name 9 "color" + Name 12 "gl_FragFullyCoveredNV" + Decorate 12(gl_FragFullyCoveredNV) BuiltIn FullyCoveredEXT + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(color): 8(ptr) Variable Output + 10: TypeBool + 11: TypePointer Input 10(bool) +12(gl_FragFullyCoveredNV): 11(ptr) Variable Input + 14: 6(float) Constant 0 + 15: 6(float) Constant 1065353216 + 4(main): 2 Function None 3 + 5: Label + 13: 10(bool) Load 12(gl_FragFullyCoveredNV) + 16: 6(float) Select 13 15 14 + 17: 7(fvec4) CompositeConstruct 16 14 14 14 + Store 9(color) 17 + Return + FunctionEnd diff --git a/Test/spv.fullyCovered.frag b/Test/spv.fullyCovered.frag new file mode 100644 index 000000000..c7f30853d --- /dev/null +++ b/Test/spv.fullyCovered.frag @@ -0,0 +1,9 @@ +#version 450 + +#extension GL_NV_conservative_raster_underestimation : enable + +out vec4 color; + +void main() { + color = vec4(gl_FragFullyCoveredNV, 0, 0, 0); +} diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index 0a46a7c0f..050c2c4b9 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -218,6 +218,7 @@ enum TBuiltInVariable { EbvSecondaryViewportMaskNV, EbvPositionPerViewNV, EbvViewportMaskPerViewNV, + EbvFragFullyCoveredNV, #endif // HLSL built-ins that live only temporarily, until they get remapped @@ -355,6 +356,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; case EbvPositionPerViewNV: return "PositionPerViewNV"; case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; #endif default: return "unknown built-in variable"; } diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 40f46b353..dd1fc299c 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -3963,6 +3963,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in vec3 gl_BaryCoordPullModelAMD;" ); #endif + +#ifdef NV_EXTENSIONS + if (version >= 430) + stageBuiltins[EShLangFragment].append( + "in bool gl_FragFullyCoveredNV;" + ); +#endif } else { // ES profile @@ -5858,6 +5865,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } #endif +#ifdef NV_EXTENSIONS + if (profile != EEsProfile && version >= 430) { + symbolTable.setVariableExtensions("gl_FragFullyCoveredNV", 1, &E_GL_NV_conservative_raster_underestimation); + BuiltInVariable("gl_FragFullyCoveredNV", EbvFragFullyCoveredNV, symbolTable); + } +#endif + symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth); if (profile == EEsProfile && version < 320) { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 733b74dab..a24949795 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2560,7 +2560,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali // now, knowing it is a shader in/out, do all the in/out semantic checks - if (publicType.basicType == EbtBool) { + if (publicType.basicType == EbtBool && !parsingBuiltins) { error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), ""); return; } diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index b1893b37e..225c71ccb 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -212,6 +212,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_NV_stereo_view_rendering] = EBhDisable; extensionBehavior[E_GL_NVX_multiview_per_view_attributes] = EBhDisable; extensionBehavior[E_GL_NV_shader_atomic_int64] = EBhDisable; + extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable; #endif // AEP @@ -345,6 +346,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_NV_geometry_shader_passthrough 1\n" "#define GL_NV_viewport_array2 1\n" "#define GL_NV_shader_atomic_int64 1\n" + "#define GL_NV_conservative_raster_underestimation 1\n" #endif ; diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index bd57103af..493c03b28 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -183,6 +183,7 @@ const char* const E_GL_NV_viewport_array2 = "GL_NV_viewpor const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering"; const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes"; const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64"; +const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation"; // Arrays of extensions for the above viewportEXTs duplications diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 4a396273d..f19d85e9e 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -249,6 +249,7 @@ INSTANTIATE_TEST_CASE_P( "spv.flowControl.frag", "spv.forLoop.frag", "spv.forwardFun.frag", + "spv.fullyCovered.frag", "spv.functionCall.frag", "spv.functionNestedOpaque.vert", "spv.functionSemantics.frag", -- GitLab