From d66b30729029bdb43892e05c9c80fd56ac95a24f Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 24 Feb 2021 08:21:37 -0800 Subject: Add support for GetAttributeAtVertex for D3D (#1725) This operation was added along with the `SV_Barycentrics` system-value input, and allows for a `nointerpolation` varying input to a fragment shader to be fetched at a specific vertex index within the primitive that is causing the fragment shader to be invoked. This change adds support for the new operations in the standard library, and also includes a test case to make sure that we emit it correctly when producing HLSL/DXIL. This change also includes a small bug fix to our emission logic for function parameters so that we properly emit layout-related attributes for varying parameters declared directly on an entry point. (Note that most attribute end up being declared in `struct` types in existing HLSL shaders, and our IR passes produce only global variables for attributes on GLSL; the only case this affects is inidividual scalar/vector attributes declared declared as entry-point parameters, when outputting HLSL) Note that this change only adds support for the new function on the HLSL/DXIL path, and doesn't yet add any cross-compilation support for GLSL/SPIR-V. The reason for this is that the equivalent GLSL feature(s) appear to use a different model to the HLSL version, and we need to invent a suitable approach to align them to make portable code possible. --- source/slang/hlsl.meta.slang | 55 ++++++++++++++++++++++++++++++++++++++ source/slang/slang-emit-c-like.cpp | 12 +++++++++ 2 files changed, 67 insertions(+) (limited to 'source') diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index a9280d9ad..adbe6f9c8 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -1805,6 +1805,61 @@ matrix fwidth(matrix x) MATRIX_MAP_UNARY(T, N, M, fwidth, x); } +/// Get the value of a vertex attribute at a specific vertex. +/// +/// The `GetAttributeAtVertex()` function can be used in a fragment shader +/// to get the value of the given `attribute` at the vertex of the primitive +/// that corresponds to the given `vertexIndex`. +/// +/// Note that the `attribute` must have been a declared varying input to +/// the fragment shader with the `nointerpolation` modifier. +/// +/// This function can be applied to scalars, vectors, and matrices of +/// built-in scalar types. +/// +/// Note: these functions are not curently implemented for Vulkan/SPIR-V output. +/// +__generic +[__readNone] +T GetAttributeAtVertex(T attribute, uint vertexIndex); + +/// Get the value of a vertex attribute at a specific vertex. +/// +/// The `GetAttributeAtVertex()` function can be used in a fragment shader +/// to get the value of the given `attribute` at the vertex of the primitive +/// that corresponds to the given `vertexIndex`. +/// +/// Note that the `attribute` must have been a declared varying input to +/// the fragment shader with the `nointerpolation` modifier. +/// +/// This function can be applied to scalars, vectors, and matrices of +/// built-in scalar types. +/// +/// Note: these functions are not curently implemented for Vulkan/SPIR-V output. +/// +__generic +[__readNone] +vector GetAttributeAtVertex(vector attribute, uint vertexIndex); + +/// Get the value of a vertex attribute at a specific vertex. +/// +/// The `GetAttributeAtVertex()` function can be used in a fragment shader +/// to get the value of the given `attribute` at the vertex of the primitive +/// that corresponds to the given `vertexIndex`. +/// +/// Note that the `attribute` must have been a declared varying input to +/// the fragment shader with the `nointerpolation` modifier. +/// +/// This function can be applied to scalars, vectors, and matrices of +/// built-in scalar types. +/// +/// Note: these functions are not curently implemented for Vulkan/SPIR-V output. +/// +__generic +[__readNone] +matrix GetAttributeAtVertex(matrix attribute, uint vertexIndex); + + // Get number of samples in render target uint GetRenderTargetSampleCount(); diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 0bd6efad3..d099af255 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -2663,6 +2663,18 @@ void CLikeSourceEmitter::emitSimpleFuncParamImpl(IRParam* param) auto paramName = getName(param); auto paramType = param->getDataType(); + if(auto layoutDecoration = param->findDecoration() ) + { + auto layout = as(layoutDecoration->getLayout()); + SLANG_ASSERT(layout); + + if(layout->usesResourceKind(LayoutResourceKind::VaryingInput) + || layout->usesResourceKind(LayoutResourceKind::VaryingOutput)) + { + emitInterpolationModifiers(param, paramType, layout); + } + } + emitParamType(paramType, paramName); emitSemantics(param); } -- cgit v1.2.3