summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-glsl-legalize.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2021-03-03 11:45:39 -0800
committerGitHub <noreply@github.com>2021-03-03 11:45:39 -0800
commit13ff0bd345990c0fdfb7b52ebd5339cddb04889e (patch)
treeae3773d4f3475439a55603007b3908e31c6c31fb /source/slang/slang-ir-glsl-legalize.cpp
parentd6ae67160c33460bf952c9959077dc481a16eca2 (diff)
Add GLSL/SPIR-V support got GetAttributeAtVertex (#1733)
This change allows varying fragment shader inputs to be declared in a way that allows the `GetAttributeAtVertex` operation to compile to valid code for both D3D and GLSL/SPIR-V/Vulkan. The key is that rather than just use ordinary `nointerpolation`-qualified inputs the code must declare these varying inputs with a new `pervertex` qualifier that marks them as *only* being usable with `GetAttributeAtVertex`. The `pervertex`-tagged inputs then translate to GLSL inputs using the `pervertexNV` qualifier Note that this change does *not* include any enforcement of the requirements around how these qualifiers are used (and the compiler doesn't have enforcement for the existing operations like `EvaluateAttributeAtCentroid`). The underlying problem is that the inerpolation-mode qualifiers and explicit interpolation functions in HLSL constitute a kind of rate-qualified type system, but without any systematic rules. It seems wasteful to encode a bunch of ad hoc rules for this stuff as special cases in the compiler when the clear right answer is to implement a systematic approach to rates.
Diffstat (limited to 'source/slang/slang-ir-glsl-legalize.cpp')
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp48
1 files changed, 32 insertions, 16 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index 48aafc887..ae6521076 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -609,7 +609,8 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
Stage stage,
UInt bindingIndex,
UInt bindingSpace,
- GlobalVaryingDeclarator* declarator)
+ GlobalVaryingDeclarator* declarator,
+ IRInst* leafVar)
{
// Check if we have a system value on our hands.
GLSLSystemValueInfo systemValueInfoStorage;
@@ -685,6 +686,14 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
auto globalParam = addGlobalParam(builder->getModule(), paramType);
moveValueBefore(globalParam, builder->getFunc());
+ if( leafVar )
+ {
+ if( auto interpolationModeDecor = leafVar->findDecoration<IRInterpolationModeDecoration>() )
+ {
+ builder->addInterpolationModeDecoration(globalParam, interpolationModeDecor->getMode());
+ }
+ }
+
ScalarizedVal val = isOutput ? ScalarizedVal::address(globalParam) : ScalarizedVal::value(globalParam);
if( systemValueInfo )
@@ -729,7 +738,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
Stage stage,
UInt bindingIndex,
UInt bindingSpace,
- GlobalVaryingDeclarator* declarator)
+ GlobalVaryingDeclarator* declarator,
+ IRInst* leafVar)
{
if (as<IRVoidType>(type))
{
@@ -739,20 +749,20 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
{
return createSimpleGLSLGlobalVarying(
context,
- builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator);
+ builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar);
}
else if( as<IRVectorType>(type) )
{
return createSimpleGLSLGlobalVarying(
context,
- builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator);
+ builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar);
}
else if( as<IRMatrixType>(type) )
{
// TODO: a matrix-type varying should probably be handled like an array of rows
return createSimpleGLSLGlobalVarying(
context,
- builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator);
+ builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar);
}
else if( auto arrayType = as<IRArrayType>(type) )
{
@@ -779,7 +789,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
stage,
bindingIndex,
bindingSpace,
- &arrayDeclarator);
+ &arrayDeclarator,
+ leafVar);
}
else if( auto streamType = as<IRHLSLStreamOutputType>(type))
{
@@ -798,7 +809,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
stage,
bindingIndex,
bindingSpace,
- declarator);
+ declarator,
+ leafVar);
}
else if(auto structType = as<IRStructType>(type))
{
@@ -849,7 +861,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
stage,
fieldBindingIndex,
fieldBindingSpace,
- declarator);
+ declarator,
+ field->getKey());
if (fieldVal.flavor != ScalarizedVal::Flavor::none)
{
ScalarizedTupleValImpl::Element element;
@@ -866,7 +879,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl(
// Default case is to fall back on the simple behavior
return createSimpleGLSLGlobalVarying(
context,
- builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator);
+ builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar);
}
ScalarizedVal createGLSLGlobalVaryings(
@@ -875,7 +888,8 @@ ScalarizedVal createGLSLGlobalVaryings(
IRType* type,
IRVarLayout* layout,
LayoutResourceKind kind,
- Stage stage)
+ Stage stage,
+ IRInst* leafVar)
{
UInt bindingIndex = 0;
UInt bindingSpace = 0;
@@ -886,7 +900,7 @@ ScalarizedVal createGLSLGlobalVaryings(
}
return createGLSLGlobalVaryingsImpl(
context,
- builder, type, layout, layout->getTypeLayout(), kind, stage, bindingIndex, bindingSpace, nullptr);
+ builder, type, layout, layout->getTypeLayout(), kind, stage, bindingIndex, bindingSpace, nullptr, leafVar);
}
ScalarizedVal extractField(
@@ -1377,7 +1391,8 @@ void legalizeEntryPointParameterForGLSL(
valueType,
paramLayout,
LayoutResourceKind::VaryingOutput,
- stage);
+ stage,
+ pp);
// TODO: a GS output stream might be passed into other
// functions, so that we should really be modifying
@@ -1533,7 +1548,7 @@ void legalizeEntryPointParameterForGLSL(
// side and one for the `out` side.
auto globalInputVal = createGLSLGlobalVaryings(
context,
- builder, valueType, paramLayout, LayoutResourceKind::VaryingInput, stage);
+ builder, valueType, paramLayout, LayoutResourceKind::VaryingInput, stage, pp);
assign(builder, localVal, globalInputVal);
}
@@ -1548,7 +1563,7 @@ void legalizeEntryPointParameterForGLSL(
// when the function is done. We create them here.
auto globalOutputVal = createGLSLGlobalVaryings(
context,
- builder, valueType, paramLayout, LayoutResourceKind::VaryingOutput, stage);
+ builder, valueType, paramLayout, LayoutResourceKind::VaryingOutput, stage, pp);
// Now we need to iterate over all the blocks in the function looking
// for any `return*` instructions, so that we can write to the output variable
@@ -1591,7 +1606,7 @@ void legalizeEntryPointParameterForGLSL(
auto globalValue = createGLSLGlobalVaryings(
context,
- builder, paramType, paramLayout, LayoutResourceKind::VaryingInput, stage);
+ builder, paramType, paramLayout, LayoutResourceKind::VaryingInput, stage, pp);
// Next we need to replace uses of the parameter with
// references to the variable(s). We are going to do that
@@ -1693,7 +1708,8 @@ void legalizeEntryPointForGLSL(
resultType,
entryPointLayout->getResultLayout(),
LayoutResourceKind::VaryingOutput,
- stage);
+ stage,
+ func);
for( auto bb = func->getFirstBlock(); bb; bb = bb->getNextBlock() )
{