summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-spirv.cpp21
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp55
2 files changed, 53 insertions, 23 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index a5a77e148..0a755cd6d 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -6211,11 +6211,24 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
requireSPIRVCapability(SpvCapabilityFragmentBarycentricKHR);
ensureExtensionDeclaration(
UnownedStringSlice("SPV_KHR_fragment_shader_barycentric"));
- return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInBaryCoordKHR, inst);
- // TODO: There is also the `gl_BaryCoordNoPerspNV` builtin, which
- // we ought to use if the `noperspective` modifier has been
- // applied to this varying input.
+ auto interpolationModeDecor =
+ inst->findDecoration<IRInterpolationModeDecoration>();
+ if (interpolationModeDecor &&
+ interpolationModeDecor->getMode() == IRInterpolationMode::NoPerspective)
+ {
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInBaryCoordNoPerspKHR,
+ inst);
+ }
+ else
+ {
+ return getBuiltinGlobalVar(
+ inst->getFullType(),
+ SpvBuiltInBaryCoordKHR,
+ inst);
+ }
}
else if (semanticName == "sv_cullprimitive")
{
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index dce85efd3..d1a534c66 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -391,6 +391,20 @@ GLSLSystemValueInfo* getMeshOutputIndicesSystemValueInfo(
SLANG_UNREACHABLE("Unhandled mesh output indices type");
}
+// Hold the in-stack linked list that represents the access chain
+// to the current global varying parameter being created.
+// e.g. if the user code has:
+// struct Params { in float member; }
+// void main(in Params inParams);
+// Then the `outerParamInfo` when we get to `createSimpleGLSLVarying` for `member`
+// will be: {IRStructField member} -> {IRParam inParams} -> {IRFunc main}.
+//
+struct OuterParamInfoLink
+{
+ IRInst* outerParam;
+ OuterParamInfoLink* next;
+};
+
GLSLSystemValueInfo* getGLSLSystemValueInfo(
GLSLLegalizationContext* context,
CodeGenContext* codeGenContext,
@@ -399,7 +413,8 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
Stage stage,
IRType* type,
GlobalVaryingDeclarator* declarator,
- GLSLSystemValueInfo* inStorage)
+ GLSLSystemValueInfo* inStorage,
+ OuterParamInfoLink* outerParamInfo)
{
SLANG_UNUSED(codeGenContext);
@@ -864,11 +879,26 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
context->requireGLSLVersion(ProfileVersion::GLSL_450);
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
- // applied to this varying input.
+ // Search for nointerpolation keyword to use no-perspective variant of BaryCoord
+ for (auto paramInfo = outerParamInfo; paramInfo; paramInfo = paramInfo->next)
+ {
+ auto outerParam = paramInfo->outerParam;
+ auto decorParent = outerParam;
+ if (auto field = as<IRStructField>(decorParent))
+ decorParent = field->getKey();
+ auto interpolation = decorParent->findDecoration<IRInterpolationModeDecoration>();
+ if (!interpolation || interpolation->getMode() != IRInterpolationMode::NoPerspective)
+ continue;
+ name = "gl_BaryCoordNoPerspEXT";
+ break;
+ }
+
+ requiredType = builder->getVectorType(
+ builder->getBasicType(BaseType::Float),
+ builder->getIntValue(builder->getIntType(), 3));
}
else if (semanticName == "sv_cullprimitive")
{
@@ -938,20 +968,6 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
return nullptr;
}
-// Hold the in-stack linked list that represents the access chain
-// to the current global varying parameter being created.
-// e.g. if the user code has:
-// struct Params { in float member; }
-// void main(in Params inParams);
-// Then the `outerParamInfo` when we get to `createSimpleGLSLVarying` for `member`
-// will be: {IRStructField member} -> {IRParam inParams} -> {IRFunc main}.
-//
-struct OuterParamInfoLink
-{
- IRInst* outerParam;
- OuterParamInfoLink* next;
-};
-
void createVarLayoutForLegalizedGlobalParam(
GLSLLegalizationContext* context,
IRInst* globalParam,
@@ -1318,7 +1334,8 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
stage,
inType,
declarator,
- &systemValueInfoStorage);
+ &systemValueInfoStorage,
+ outerParamInfo);
{