From e05cc20ec20a154d94256c744a3837c23719c0f9 Mon Sep 17 00:00:00 2001 From: Pankaj Mistry Date: Tue, 21 Apr 2020 11:33:57 -0700 Subject: [PATCH] Add support for es extension GL_EXT_blend_func_extended * Introduces builtin variables gl_SecondaryFragColorEXT and gl_SecondaryFragDataEXT * Introduces builtin constant gl_MaxDualSourceDrawBuffersEXT * enables support for layout qualifier "index" in es profile --- StandAlone/ResourceLimits.cpp | 2 + Test/100.frag | 13 ++ Test/300.frag | 5 + Test/baseResults/100.frag.out | 159 +++++++++++++-------- Test/baseResults/300.frag.out | 20 ++- Test/baseResults/test.conf | 1 + glslang/Include/BaseTypes.h | 6 + glslang/Include/ResourceLimits.h | 1 + glslang/Include/glslang_c_interface.h | 1 + glslang/MachineIndependent/Initialize.cpp | 22 +++ glslang/MachineIndependent/ParseHelper.cpp | 4 +- glslang/MachineIndependent/Versions.cpp | 2 + glslang/MachineIndependent/Versions.h | 1 + glslang/OSDependent/Web/glslang.js.cpp | 1 + 14 files changed, 173 insertions(+), 65 deletions(-) diff --git a/StandAlone/ResourceLimits.cpp b/StandAlone/ResourceLimits.cpp index 028caa66d1..7c7f4c4e49 100644 --- a/StandAlone/ResourceLimits.cpp +++ b/StandAlone/ResourceLimits.cpp @@ -134,6 +134,7 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { /* .nonInductiveForLoops = */ 1, @@ -243,6 +244,7 @@ std::string GetDefaultTBuiltInResourceString() << "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n" << "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n" << "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n" + << "MaxDualSourceDrawBuffersEXT " << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n" << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n" << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n" << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n" diff --git a/Test/100.frag b/Test/100.frag index 0508ea999b..439fc6ca86 100644 --- a/Test/100.frag +++ b/Test/100.frag @@ -201,6 +201,19 @@ float fooinittest() return fooinit(); } +// Test extension GL_EXT_blend_func_extended +void blendFuncFail() // Error since extension GL_EXT_blend_func_extended is disabled +{ + gl_SecondaryFragColorEXT = vec4(1.0); + gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1); +} +#extension GL_EXT_blend_func_extended : enable +void blendFunc() +{ + gl_SecondaryFragColorEXT = vec4(1.0); + gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1); +} + // Test extra-function initializers const float fi1 = 3.0; const float fi2 = 4.0; diff --git a/Test/300.frag b/Test/300.frag index ab45c6dba6..279864a922 100644 --- a/Test/300.frag +++ b/Test/300.frag @@ -177,6 +177,11 @@ void testmixFail() int ival = mix(x, y, b); // Error since extenson GL_EXT_shader_integer_mix is disabled } +// Test layout qualifier "index" with extension GL_EXT_blend_func_extended +layout(location = 0, index = 1) out vec4 outVarFail; // Error Index supported with extension GL_EXT_blend_func_extended enabled +#extension GL_EXT_blend_func_extended : enable +layout(location = 0, index = 2) out vec4 outVarPass; + #ifndef GL_FRAGMENT_PRECISION_HIGH #error missing GL_FRAGMENT_PRECISION_HIGH #endif diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out index 8dd31e32bd..2ac60541ab 100644 --- a/Test/baseResults/100.frag.out +++ b/Test/baseResults/100.frag.out @@ -82,15 +82,19 @@ ERROR: 0:192: '.' : cannot apply to an array: nothing ERROR: 0:193: '.length' : not supported for this version or the enabled extensions ERROR: 0:194: '.' : cannot apply to an array: method ERROR: 0:194: 'a' : can't use function syntax on variable -ERROR: 0:214: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions -ERROR: 0:222: '#define' : names containing consecutive underscores are reserved, and an error if version < 300: A__B -ERROR: 0:223: 'a__b' : identifiers containing consecutive underscores ("__") are reserved, and an error if version < 300 +ERROR: 0:207: 'gl_SecondaryFragColorEXT' : required extension not requested: GL_EXT_blend_func_extended +ERROR: 0:208: 'gl_SecondaryFragDataEXT' : required extension not requested: GL_EXT_blend_func_extended +ERROR: 0:208: 'gl_MaxDualSourceDrawBuffersEXT' : required extension not requested: GL_EXT_blend_func_extended +ERROR: 0:227: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions +ERROR: 0:235: '#define' : names containing consecutive underscores are reserved, and an error if version < 300: A__B +ERROR: 0:236: 'a__b' : identifiers containing consecutive underscores ("__") are reserved, and an error if version < 300 ERROR: 0:3000: '#error' : line of this error should be 3000 ERROR: 0:3002: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON -ERROR: 79 compilation errors. No code generated. +ERROR: 82 compilation errors. No code generated. Shader version: 100 +Requested GL_EXT_blend_func_extended Requested GL_EXT_frag_depth Requested GL_EXT_shader_non_constant_global_initializers Requested GL_EXT_shader_texture_lod @@ -361,36 +365,76 @@ ERROR: node is still EOpNull! 0:201 Sequence 0:201 Branch: Return with expression 0:201 Function Call: fooinit( ( global mediump float) -0:209 Function Definition: fooinit( ( global mediump float) -0:209 Function Parameters: -0:211 Sequence -0:211 Branch: Return with expression -0:211 Constant: -0:211 12.000000 -0:214 Sequence -0:214 move second child to first child ( temp mediump int) -0:214 'init1' ( global mediump int) -0:214 Test condition and select ( temp mediump int) -0:214 Condition -0:214 'gl_FrontFacing' ( gl_FrontFacing bool Face) -0:214 true case +0:205 Function Definition: blendFuncFail( ( global void) +0:205 Function Parameters: +0:207 Sequence +0:207 move second child to first child ( temp mediump 4-component vector of float) +0:207 'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT) +0:207 Constant: +0:207 1.000000 +0:207 1.000000 +0:207 1.000000 +0:207 1.000000 +0:208 move second child to first child ( temp mediump 4-component vector of float) +0:208 direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT) +0:208 'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT) +0:208 Constant: +0:208 0 (const int) +0:208 Constant: +0:208 0.100000 +0:208 0.100000 +0:208 0.100000 +0:208 0.100000 +0:211 Function Definition: blendFunc( ( global void) +0:211 Function Parameters: +0:213 Sequence +0:213 move second child to first child ( temp mediump 4-component vector of float) +0:213 'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT) +0:213 Constant: +0:213 1.000000 +0:213 1.000000 +0:213 1.000000 +0:213 1.000000 +0:214 move second child to first child ( temp mediump 4-component vector of float) +0:214 direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT) +0:214 'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT) +0:214 Constant: +0:214 0 (const int) 0:214 Constant: -0:214 1 (const int) -0:214 false case -0:214 Constant: -0:214 2 (const int) -0:220 Sequence -0:220 move second child to first child ( temp mediump int) -0:220 'init2' ( global mediump int) -0:220 Test condition and select ( temp mediump int) -0:220 Condition -0:220 'gl_FrontFacing' ( gl_FrontFacing bool Face) -0:220 true case -0:220 Constant: -0:220 1 (const int) -0:220 false case -0:220 Constant: -0:220 2 (const int) +0:214 0.100000 +0:214 0.100000 +0:214 0.100000 +0:214 0.100000 +0:222 Function Definition: fooinit( ( global mediump float) +0:222 Function Parameters: +0:224 Sequence +0:224 Branch: Return with expression +0:224 Constant: +0:224 12.000000 +0:227 Sequence +0:227 move second child to first child ( temp mediump int) +0:227 'init1' ( global mediump int) +0:227 Test condition and select ( temp mediump int) +0:227 Condition +0:227 'gl_FrontFacing' ( gl_FrontFacing bool Face) +0:227 true case +0:227 Constant: +0:227 1 (const int) +0:227 false case +0:227 Constant: +0:227 2 (const int) +0:233 Sequence +0:233 move second child to first child ( temp mediump int) +0:233 'init2' ( global mediump int) +0:233 Test condition and select ( temp mediump int) +0:233 Condition +0:233 'gl_FrontFacing' ( gl_FrontFacing bool Face) +0:233 true case +0:233 Constant: +0:233 1 (const int) +0:233 false case +0:233 Constant: +0:233 2 (const int) 0:? Linker Objects 0:? 'a' ( global 3-element array of mediump int) 0:? 'uint' ( global mediump int) @@ -430,6 +474,7 @@ Linked fragment stage: Shader version: 100 +Requested GL_EXT_blend_func_extended Requested GL_EXT_frag_depth Requested GL_EXT_shader_non_constant_global_initializers Requested GL_EXT_shader_texture_lod @@ -520,30 +565,30 @@ ERROR: node is still EOpNull! 0:152 'f124' ( global mediump float) 0:152 Constant: 0:152 50000000000.000000 -0:214 Sequence -0:214 move second child to first child ( temp mediump int) -0:214 'init1' ( global mediump int) -0:214 Test condition and select ( temp mediump int) -0:214 Condition -0:214 'gl_FrontFacing' ( gl_FrontFacing bool Face) -0:214 true case -0:214 Constant: -0:214 1 (const int) -0:214 false case -0:214 Constant: -0:214 2 (const int) -0:220 Sequence -0:220 move second child to first child ( temp mediump int) -0:220 'init2' ( global mediump int) -0:220 Test condition and select ( temp mediump int) -0:220 Condition -0:220 'gl_FrontFacing' ( gl_FrontFacing bool Face) -0:220 true case -0:220 Constant: -0:220 1 (const int) -0:220 false case -0:220 Constant: -0:220 2 (const int) +0:227 Sequence +0:227 move second child to first child ( temp mediump int) +0:227 'init1' ( global mediump int) +0:227 Test condition and select ( temp mediump int) +0:227 Condition +0:227 'gl_FrontFacing' ( gl_FrontFacing bool Face) +0:227 true case +0:227 Constant: +0:227 1 (const int) +0:227 false case +0:227 Constant: +0:227 2 (const int) +0:233 Sequence +0:233 move second child to first child ( temp mediump int) +0:233 'init2' ( global mediump int) +0:233 Test condition and select ( temp mediump int) +0:233 Condition +0:233 'gl_FrontFacing' ( gl_FrontFacing bool Face) +0:233 true case +0:233 Constant: +0:233 1 (const int) +0:233 false case +0:233 Constant: +0:233 2 (const int) 0:? Linker Objects 0:? 'a' ( global 3-element array of mediump int) 0:? 'uint' ( global mediump int) diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out index 0b88aa33b4..50a6b075a0 100644 --- a/Test/baseResults/300.frag.out +++ b/Test/baseResults/300.frag.out @@ -41,15 +41,18 @@ ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, ERROR: 0:148: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) ERROR: 0:150: 'early_fragment_tests' : not supported for this version or the enabled extensions ERROR: 0:177: 'specific signature of builtin mix' : required extension not requested: GL_EXT_shader_integer_mix -ERROR: 0:184: 'invariant' : can only apply to an output -ERROR: 0:185: 'invariant' : can only apply to an output -ERROR: 0:186: 'invariant' : can only apply to an output -ERROR: 0:188: 'imageBuffer' : Reserved word. -ERROR: 0:188: '' : syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON -ERROR: 47 compilation errors. No code generated. +ERROR: 0:181: 'index layout qualifier on fragment output' : not supported for this version or the enabled extensions +ERROR: 0:183: 'index' : value must be 0 or 1 +ERROR: 0:189: 'invariant' : can only apply to an output +ERROR: 0:190: 'invariant' : can only apply to an output +ERROR: 0:191: 'invariant' : can only apply to an output +ERROR: 0:193: 'imageBuffer' : Reserved word. +ERROR: 0:193: '' : syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON +ERROR: 49 compilation errors. No code generated. Shader version: 300 +Requested GL_EXT_blend_func_extended Requested GL_EXT_shader_integer_mix using early_fragment_tests ERROR: node is still EOpNull! @@ -530,6 +533,8 @@ ERROR: node is still EOpNull! 0:? 'y' ( global mediump int) 0:? 'z' ( global mediump uint) 0:? 'w' ( global mediump uint) +0:? 'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float) +0:? 'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float) 0:? 'fooinv' ( invariant smooth in lowp 4-component vector of float) @@ -538,6 +543,7 @@ Linked fragment stage: ERROR: Linking fragment stage: when more than one fragment shader output, all must have location qualifiers Shader version: 300 +Requested GL_EXT_blend_func_extended Requested GL_EXT_shader_integer_mix using early_fragment_tests ERROR: node is still EOpNull! @@ -769,5 +775,7 @@ ERROR: node is still EOpNull! 0:? 'y' ( global mediump int) 0:? 'z' ( global mediump uint) 0:? 'w' ( global mediump uint) +0:? 'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float) +0:? 'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float) 0:? 'fooinv' ( invariant smooth in lowp 4-component vector of float) diff --git a/Test/baseResults/test.conf b/Test/baseResults/test.conf index cff77168ab..98b2a84165 100644 --- a/Test/baseResults/test.conf +++ b/Test/baseResults/test.conf @@ -90,6 +90,7 @@ MaxTaskWorkGroupSizeX_NV 32 MaxTaskWorkGroupSizeY_NV 1 MaxTaskWorkGroupSizeZ_NV 1 MaxMeshViewCountNV 4 +MaxDualSourceDrawBuffersEXT 1 nonInductiveForLoops 1 whileLoops 1 doWhileLoops 1 diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index 816b179486..b69eaebf2d 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -231,6 +231,9 @@ enum TBuiltInVariable { EbvFragSizeEXT, EbvFragInvocationCountEXT, + EbvSecondaryFragDataEXT, + EbvSecondaryFragColorEXT, + EbvViewportMaskNV, EbvSecondaryPositionNV, EbvSecondaryViewportMaskNV, @@ -433,6 +436,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvFragSizeEXT: return "FragSizeEXT"; case EbvFragInvocationCountEXT: return "FragInvocationCountEXT"; + case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT"; + case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV"; case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; diff --git a/glslang/Include/ResourceLimits.h b/glslang/Include/ResourceLimits.h index 106b21d9ca..b670cf163f 100644 --- a/glslang/Include/ResourceLimits.h +++ b/glslang/Include/ResourceLimits.h @@ -142,6 +142,7 @@ struct TBuiltInResource { int maxTaskWorkGroupSizeY_NV; int maxTaskWorkGroupSizeZ_NV; int maxMeshViewCountNV; + int maxDualSourceDrawBuffersEXT; TLimits limits; }; diff --git a/glslang/Include/glslang_c_interface.h b/glslang/Include/glslang_c_interface.h index 5a450e0e9c..50e95b7e81 100644 --- a/glslang/Include/glslang_c_interface.h +++ b/glslang/Include/glslang_c_interface.h @@ -148,6 +148,7 @@ typedef struct glslang_resource_s { int max_task_work_group_size_y_nv; int max_task_work_group_size_z_nv; int max_mesh_view_count_nv; + int maxDualSourceDrawBuffersEXT; glslang_limits_t limits; } glslang_resource_t; diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 5410f82ac4..36c35a80cc 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -6755,6 +6755,18 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } + if (version >= 100) { + // GL_EXT_blend_func_extended + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDualSourceDrawBuffersEXT = %d;", resources.maxDualSourceDrawBuffersEXT); + s.append(builtInConstant); + // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxDualSourceDrawBuffersEXT + if (language == EShLangFragment) { + s.append( + "mediump vec4 gl_SecondaryFragColorEXT;" + "mediump vec4 gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT];" + "\n"); + } + } } else { // non-ES profile @@ -9119,6 +9131,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); } + + // GL_EXT_blend_func_extended + if (profile == EEsProfile && version >= 100) { + symbolTable.setVariableExtensions("gl_MaxDualSourceDrawBuffersEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragColorEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragDataEXT", 1, &E_GL_EXT_blend_func_extended); + SpecialQualifier("gl_SecondaryFragColorEXT", EvqVaryingOut, EbvSecondaryFragColorEXT, symbolTable); + SpecialQualifier("gl_SecondaryFragDataEXT", EvqVaryingOut, EbvSecondaryFragDataEXT, symbolTable); + } + break; case EShLangTessControl: diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 137cb5e380..8bc7814871 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -5412,10 +5412,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi case EShLangFragment: if (id == "index") { - requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output"); + requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output"); const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output"); - + profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output"); // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1." if (value < 0 || value > 1) { value = 0; diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 82ccabc6e5..30313b24e9 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -306,6 +306,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable; extensionBehavior[E_GL_EXT_ray_query] = EBhDisable; extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable; + extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; @@ -365,6 +366,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_texture_buffer 1\n" "#define GL_EXT_texture_cube_map_array 1\n" "#define GL_EXT_shader_integer_mix 1\n" + "#define GL_EXT_blend_func_extended 1\n" // OES matching AEP "#define GL_OES_geometry_shader 1\n" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 7a9e67319b..cde6c23ccd 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -196,6 +196,7 @@ const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_prin const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing"; const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query"; const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling"; +const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended"; // Arrays of extensions for the above viewportEXTs duplications diff --git a/glslang/OSDependent/Web/glslang.js.cpp b/glslang/OSDependent/Web/glslang.js.cpp index 854d293a3b..f2306a6092 100644 --- a/glslang/OSDependent/Web/glslang.js.cpp +++ b/glslang/OSDependent/Web/glslang.js.cpp @@ -141,6 +141,7 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { /* .nonInductiveForLoops = */ 1,