diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2021-03-03 11:45:39 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-03 11:45:39 -0800 |
| commit | 13ff0bd345990c0fdfb7b52ebd5339cddb04889e (patch) | |
| tree | ae3773d4f3475439a55603007b3908e31c6c31fb /source/slang/slang-ir-glsl-legalize.cpp | |
| parent | d6ae67160c33460bf952c9959077dc481a16eca2 (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.cpp | 48 |
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() ) { |
