diff options
| author | Samuel Kogler <skogler@users.noreply.github.com> | 2023-03-16 19:05:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-16 11:05:33 -0700 |
| commit | b92f2805855282cb717c21345dab8ffdc3f1fdd2 (patch) | |
| tree | 94eb39cf53114fa971917625d398eb03e1629b63 /source/slang | |
| parent | e960534a5b5a26a2b6d6c27586fc2dad88594b93 (diff) | |
Support GL_EXT_fragment_shader_barycentric (#2704)
* Support GL_EXT_fragment_shader_barycentric
* Support pervertex with GL_EXT_fragment_shader_barycentric
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 12 | ||||
| -rw-r--r-- | source/slang/slang-capability-defs.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-capability.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 71 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-glsl-legalize.cpp | 33 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 4 |
7 files changed, 101 insertions, 32 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 633c3d87e..d417e3b7c 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -2274,9 +2274,9 @@ matrix<T, N, M> fwidth(matrix<T, N, M> x) __generic<T : __BuiltinType> [__readNone] __target_intrinsic(hlsl) -__target_intrinsic(glsl, "$0[$1]") +__target_intrinsic(GL_NV_fragment_shader_barycentric, "$0[$1]") +__target_intrinsic(GL_EXT_fragment_shader_barycentric, "$0[$1]") __glsl_version(450) -__glsl_extension(GL_NV_fragment_shader_barycentric) T GetAttributeAtVertex(T attribute, uint vertexIndex); /// Get the value of a vertex attribute at a specific vertex. @@ -2296,9 +2296,9 @@ T GetAttributeAtVertex(T attribute, uint vertexIndex); __generic<T : __BuiltinType, let N : int> [__readNone] __target_intrinsic(hlsl) -__target_intrinsic(glsl, "$0[$1]") +__target_intrinsic(GL_NV_fragment_shader_barycentric, "$0[$1]") +__target_intrinsic(GL_EXT_fragment_shader_barycentric, "$0[$1]") __glsl_version(450) -__glsl_extension(GL_NV_fragment_shader_barycentric) vector<T,N> GetAttributeAtVertex(vector<T,N> attribute, uint vertexIndex); /// Get the value of a vertex attribute at a specific vertex. @@ -2318,9 +2318,9 @@ vector<T,N> GetAttributeAtVertex(vector<T,N> attribute, uint vertexIndex); __generic<T : __BuiltinType, let N : int, let M : int> [__readNone] __target_intrinsic(hlsl) -__target_intrinsic(glsl, "$0[$1]") +__target_intrinsic(GL_NV_fragment_shader_barycentric, "$0[$1]") +__target_intrinsic(GL_EXT_fragment_shader_barycentric, "$0[$1]") __glsl_version(450) -__glsl_extension(GL_NV_fragment_shader_barycentric) matrix<T,N,M> GetAttributeAtVertex(matrix<T,N,M> attribute, uint vertexIndex); diff --git a/source/slang/slang-capability-defs.h b/source/slang/slang-capability-defs.h index fc60f4dfa..14173b6bc 100644 --- a/source/slang/slang-capability-defs.h +++ b/source/slang/slang-capability-defs.h @@ -87,6 +87,11 @@ SLANG_CAPABILITY_ATOM1(GLSLRayTracing, __glslRayTracing, Abstract,None,0, SLANG_CAPABILITY_ATOM1(GL_NV_ray_tracing, GL_NV_ray_tracing, Concrete,RayTracingExtension,0, GLSLRayTracing) SLANG_CAPABILITY_ATOM2(GL_EXT_ray_tracing, GL_EXT_ray_tracing, Concrete,RayTracingExtension,1, GLSLRayTracing, SPIRV_1_4) +SLANG_CAPABILITY_ATOM1(GLSLFragmentShaderBarycentric, __glslFragmentShaderBarycentric, Abstract, None, 0, GLSL) +SLANG_CAPABILITY_ATOM1(GL_NV_fragment_shader_barycentric, GL_NV_fragment_shader_barycentric, Concrete, FragmentShaderBarycentricExtension, 0, GLSLFragmentShaderBarycentric) +SLANG_CAPABILITY_ATOM1(GL_EXT_fragment_shader_barycentric, GL_EXT_fragment_shader_barycentric, Concrete, FragmentShaderBarycentricExtension, 1, GLSLFragmentShaderBarycentric) + + #undef SLANG_CAPABILITY_ATOM0 #undef SLANG_CAPABILITY_ATOM1 #undef SLANG_CAPABILITY_ATOM2 diff --git a/source/slang/slang-capability.cpp b/source/slang/slang-capability.cpp index 0b82cb92c..235e211e5 100644 --- a/source/slang/slang-capability.cpp +++ b/source/slang/slang-capability.cpp @@ -67,6 +67,10 @@ enum class CapabilityAtomConflictMask : uint32_t // Capability atoms that represent GLSL ray tracing extensions conflict with // one another (we only want to use one such extension at a time). RayTracingExtension = 1 << 1, + + // Capability atoms that represent GLSL fragment shader barycentric extensions conflict with + // one another (we only want to use one such extension at a time). + FragmentShaderBarycentricExtension = 1 << 2, }; // For simplicity in building up our data structure representing diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 13eb6e2f6..d0154ab91 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -80,6 +80,27 @@ void GLSLSourceEmitter::_requireRayTracing() m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_460); } +void GLSLSourceEmitter::_requireFragmentShaderBarycentric() +{ + // There is more than one extension that provides barycentric coords in fragment shaders, + // and we need to pick which one to enable. + // + // By default, we will use the `GL_EXT_fragment_shader_barycentric` extension, but if + // the user has explicitly opted in to the `GL_NV_fragment_shader_barycentric` extension + // we will use that one instead. + + if( getTargetCaps().implies(CapabilityAtom::GL_NV_fragment_shader_barycentric) ) + { + m_glslExtensionTracker->requireExtension(UnownedStringSlice::fromLiteral("GL_NV_fragment_shader_barycentric")); + } + else + { + m_glslExtensionTracker->requireExtension(UnownedStringSlice::fromLiteral("GL_EXT_fragment_shader_barycentric")); + } + m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450); +} + + void GLSLSourceEmitter::_requireGLSLExtension(const UnownedStringSlice& name) { m_glslExtensionTracker->requireExtension(name); @@ -2250,27 +2271,40 @@ void GLSLSourceEmitter::emitRateQualifiersImpl(IRRate* rate) } } -static UnownedStringSlice _getInterpolationModifierText(IRInterpolationMode mode, Stage stage, bool isInput) +bool GLSLSourceEmitter::_maybeEmitInterpolationModifierText(IRInterpolationMode mode, Stage stage, bool isInput) { switch (mode) { - case IRInterpolationMode::NoInterpolation: return UnownedStringSlice::fromLiteral("flat"); - case IRInterpolationMode::NoPerspective: return UnownedStringSlice::fromLiteral("noperspective"); - case IRInterpolationMode::Linear: return UnownedStringSlice::fromLiteral("smooth"); - case IRInterpolationMode::Sample: return UnownedStringSlice::fromLiteral("sample"); - case IRInterpolationMode::Centroid: return UnownedStringSlice::fromLiteral("centroid"); - + case IRInterpolationMode::NoInterpolation: + m_writer->emit("flat "); return true; + case IRInterpolationMode::NoPerspective: + m_writer->emit("noperspective "); return true; + case IRInterpolationMode::Linear: + m_writer->emit("smooth "); return true; + case IRInterpolationMode::Sample: + m_writer->emit("sample "); return true; + case IRInterpolationMode::Centroid: + m_writer->emit("centroid "); return true; case IRInterpolationMode::PerVertex: - if( stage == Stage::Fragment ) + if( stage == Stage::Fragment && isInput) { - if( isInput ) + _requireFragmentShaderBarycentric(); + if (getTargetCaps().implies(CapabilityAtom::GL_NV_fragment_shader_barycentric)) { - return UnownedStringSlice::fromLiteral("pervertexNV"); + m_writer->emit("pervertexNV "); + } + else + { + m_writer->emit("pervertexEXT "); } } - return UnownedStringSlice::fromLiteral("flat"); - - default: return UnownedStringSlice(); + else + { + m_writer->emit("flat "); + } + return true; + default: + return false; } } @@ -2293,14 +2327,8 @@ void GLSLSourceEmitter::emitInterpolationModifiersImpl(IRInst* varInst, IRType* continue; auto decoration = (IRInterpolationModeDecoration*)dd; - const UnownedStringSlice slice = _getInterpolationModifierText(decoration->getMode(), stage, isInput); - if (slice.getLength()) - { - m_writer->emit(slice); - m_writer->emitChar(' '); - anyModifiers = true; - } + anyModifiers |= _maybeEmitInterpolationModifierText(decoration->getMode(), stage, isInput); switch( decoration->getMode() ) { @@ -2312,8 +2340,7 @@ void GLSLSourceEmitter::emitInterpolationModifiersImpl(IRInst* varInst, IRType* { if( isInput ) { - _requireGLSLVersion(ProfileVersion::GLSL_450); - _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NV_fragment_shader_barycentric")); + _requireFragmentShaderBarycentric(); } } break; diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h index 6a18fe035..99259463b 100644 --- a/source/slang/slang-emit-glsl.h +++ b/source/slang/slang-emit-glsl.h @@ -67,6 +67,8 @@ protected: void _maybeEmitGLSLBuiltin(IRGlobalParam* var, UnownedStringSlice name); + bool _maybeEmitInterpolationModifierText(IRInterpolationMode mode, Stage stage, bool isInput); + void _requireGLSLExtension(const UnownedStringSlice& name); void _requireGLSLVersion(ProfileVersion version); @@ -108,6 +110,8 @@ protected: void _requireRayTracing(); + void _requireFragmentShaderBarycentric(); + void _emitSpecialFloatImpl(IRType* type, const char* valueExpr); RefPtr<GLSLExtensionTracker> m_glslExtensionTracker; diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 9c16f40ac..986f98c84 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -448,6 +448,7 @@ GLSLSystemValueInfo* getMeshOutputIndicesSystemValueInfo( GLSLSystemValueInfo* getGLSLSystemValueInfo( GLSLLegalizationContext* context, + CodeGenContext* codeGenContext, IRVarLayout* varLayout, LayoutResourceKind kind, Stage stage, @@ -843,9 +844,16 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( else if (semanticName == "sv_barycentrics") { context->requireGLSLVersion(ProfileVersion::GLSL_450); - context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NV_fragment_shader_barycentric")); - - name = "gl_BaryCoordNV"; + if (codeGenContext->getTargetCaps().implies(CapabilityAtom::GL_NV_fragment_shader_barycentric)) + { + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NV_fragment_shader_barycentric")); + name = "gl_BaryCoordNV"; + } + else + { + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_EXT_fragment_shader_barycentric")); + name = "gl_BaryCoordEXT"; + } // TODO: There is also the `gl_BaryCoordNoPerspNV` builtin, which // we ought to use if the `noperspective` modifier has been @@ -874,6 +882,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( ScalarizedVal createSimpleGLSLGlobalVarying( GLSLLegalizationContext* context, + CodeGenContext* codeGenContext, IRBuilder* builder, IRType* inType, IRVarLayout* inVarLayout, @@ -889,6 +898,7 @@ ScalarizedVal createSimpleGLSLGlobalVarying( GLSLSystemValueInfo systemValueInfoStorage; auto systemValueInfo = getGLSLSystemValueInfo( context, + codeGenContext, inVarLayout, kind, stage, @@ -1040,6 +1050,7 @@ ScalarizedVal createSimpleGLSLGlobalVarying( ScalarizedVal createGLSLGlobalVaryingsImpl( GLSLLegalizationContext* context, + CodeGenContext* codeGenContext, IRBuilder* builder, IRType* type, IRVarLayout* varLayout, @@ -1059,12 +1070,14 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( { return createSimpleGLSLGlobalVarying( context, + codeGenContext, builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); } else if( as<IRVectorType>(type) ) { return createSimpleGLSLGlobalVarying( context, + codeGenContext, builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); } else if( as<IRMatrixType>(type) ) @@ -1072,6 +1085,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( // TODO: a matrix-type varying should probably be handled like an array of rows return createSimpleGLSLGlobalVarying( context, + codeGenContext, builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); } else if( auto arrayType = as<IRArrayType>(type) ) @@ -1091,6 +1105,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createGLSLGlobalVaryingsImpl( context, + codeGenContext, builder, elementType, varLayout, @@ -1133,6 +1148,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createGLSLGlobalVaryingsImpl( context, + codeGenContext, builder, elementType, varLayout, @@ -1153,6 +1169,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createGLSLGlobalVaryingsImpl( context, + codeGenContext, builder, elementType, varLayout, @@ -1214,6 +1231,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( auto fieldVal = createGLSLGlobalVaryingsImpl( context, + codeGenContext, builder, field->getFieldType(), fieldLayout, @@ -1240,11 +1258,13 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( // Default case is to fall back on the simple behavior return createSimpleGLSLGlobalVarying( context, + codeGenContext, builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); } ScalarizedVal createGLSLGlobalVaryings( GLSLLegalizationContext* context, + CodeGenContext* codeGenContext, IRBuilder* builder, IRType* type, IRVarLayout* layout, @@ -1261,6 +1281,7 @@ ScalarizedVal createGLSLGlobalVaryings( } return createGLSLGlobalVaryingsImpl( context, + codeGenContext, builder, type, layout, layout->getTypeLayout(), kind, stage, bindingIndex, bindingSpace, nullptr, leafVar); } @@ -1722,6 +1743,7 @@ void legalizeMeshOutputParam( auto globalOutputVal = createGLSLGlobalVaryings( context, + codeGenContext, builder, meshOutputType, paramLayout, @@ -2140,6 +2162,7 @@ void legalizeEntryPointParameterForGLSL( auto globalOutputVal = createGLSLGlobalVaryings( context, + codeGenContext, builder, valueType, paramLayout, @@ -2305,6 +2328,7 @@ void legalizeEntryPointParameterForGLSL( // side and one for the `out` side. auto globalInputVal = createGLSLGlobalVaryings( context, + codeGenContext, builder, valueType, paramLayout, LayoutResourceKind::VaryingInput, stage, pp); assign(builder, localVal, globalInputVal); @@ -2320,6 +2344,7 @@ void legalizeEntryPointParameterForGLSL( // when the function is done. We create them here. auto globalOutputVal = createGLSLGlobalVaryings( context, + codeGenContext, builder, valueType, paramLayout, LayoutResourceKind::VaryingOutput, stage, pp); // Now we need to iterate over all the blocks in the function looking @@ -2361,6 +2386,7 @@ void legalizeEntryPointParameterForGLSL( auto globalValue = createGLSLGlobalVaryings( context, + codeGenContext, builder, paramType, paramLayout, LayoutResourceKind::VaryingInput, stage, pp); // Next we need to replace uses of the parameter with @@ -2455,6 +2481,7 @@ void legalizeEntryPointForGLSL( auto resultGlobal = createGLSLGlobalVaryings( &context, + codeGenContext, &builder, resultType, entryPointLayout->getResultLayout(), diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 60bc087de..fea9a1c71 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -712,9 +712,11 @@ struct OptionsParser " code accordingly.\n" " Currently defined capabilities are:\n" "\n" - " spriv_1_{0,1,2,3,4,5} - minimum supported SPIR-V version\n" + " spirv_1_{0,1,2,3,4,5} - minimum supported SPIR-V version\n" " GL_NV_ray_tracing - enables the GL_NV_ray_tracing extension\n" " GL_EXT_ray_tracing - enables the GL_EXT_ray_tracing extension\n" + " GL_NV_fragment_shader_barycentric - enables the GL_NV_fragment_shader_barycentric extension\n" + " GL_EXT_fragment_shader_barycentric - enables the GL_EXT_fragment_shader_barycentric extension\n" "\n"; #undef EXECUTABLE_EXTENSION |
