summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2025-02-19 20:43:00 -0800
committerGitHub <noreply@github.com>2025-02-19 20:43:00 -0800
commit0460eb6a0b9e62c3145ab9c43d03751e19a49d8e (patch)
tree7a136d30a6f0a82ecdcf91b4da606e98b98fb148
parenta02379208f8906272d3fd773d4b5cfe8eec3be3b (diff)
Force inline functions that takes InputPatch and OutputPatch (#6407)
This commit inlines functions that takes InputPatch and OutputPatch as the function parameter. Co-authored-by: Yong He <yonghe@outlook.com>
-rw-r--r--source/slang/slang-ir-specialize-resources.cpp4
-rw-r--r--source/slang/slang-ir.cpp5
-rw-r--r--tests/spirv/tessellation-patch-as-argument.slang100
3 files changed, 109 insertions, 0 deletions
diff --git a/source/slang/slang-ir-specialize-resources.cpp b/source/slang/slang-ir-specialize-resources.cpp
index 2aafaaf31..871ba2c24 100644
--- a/source/slang/slang-ir-specialize-resources.cpp
+++ b/source/slang/slang-ir-specialize-resources.cpp
@@ -1359,6 +1359,10 @@ bool isIllegalGLSLParameterType(IRType* type)
return true;
if (as<IRDynamicResourceType>(type))
return true;
+ if (as<IRHLSLInputPatchType>(type))
+ return true;
+ if (as<IRHLSLOutputPatchType>(type))
+ return true;
return false;
}
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 07e8b2742..cdabb1ac2 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -5259,6 +5259,11 @@ IRInst* IRBuilder::emitElementAddress(IRInst* basePtr, IRInst* index)
SLANG_ASSERT(as<IRIntLit>(index));
type = (IRType*)tupleType->getOperand(getIntVal(index));
}
+ else if (auto hlslInputPatchType = as<IRHLSLInputPatchType>(valueType))
+ {
+ type = hlslInputPatchType->getElementType();
+ }
+
SLANG_RELEASE_ASSERT(type);
auto inst = createInst<IRGetElementPtr>(
this,
diff --git a/tests/spirv/tessellation-patch-as-argument.slang b/tests/spirv/tessellation-patch-as-argument.slang
new file mode 100644
index 000000000..685a8d632
--- /dev/null
+++ b/tests/spirv/tessellation-patch-as-argument.slang
@@ -0,0 +1,100 @@
+//TEST:SIMPLE(filecheck=HULL): -target spirv -stage hull -entry hullMain
+//TEST:SIMPLE(filecheck=DOMAIN): -target spirv -stage domain -entry domainMain
+
+// Testing if `InputPatch` and `OutputPatch` can be used as function arguments.
+// `[ForceInline]` can be used to workaround but it should work without it.
+
+// HULL: OpEntryPoint TessellationControl %hullMain
+// HULL: = OpVariable %{{[a-zA-Z_0-9]*}} Input
+
+// DOMAIN: OpEntryPoint TessellationEvaluation %domainMain
+// DOMAIN: = OpVariable %{{[a-zA-Z_0-9]*}} Output
+
+struct VS_OUT
+{
+ float3 position : POSITION;
+};
+
+struct HS_OUT
+{
+ float3 position : POSITION;
+};
+
+struct HSC_OUT
+{
+ float EdgeTessFactor[4] : SV_TessFactor;
+ float InsideTessFactor[2] : SV_InsideTessFactor;
+};
+
+struct DS_OUT
+{
+ float4 position : SV_Position;
+};
+
+
+VS_OUT GetInputPatch(InputPatch<VS_OUT, 4> patch, int index)
+{
+ return patch[index];
+}
+
+// Hull Shader (HS)
+[domain("quad")]
+[partitioning("integer")]
+[outputtopology("triangle_cw")]
+[outputcontrolpoints(4)]
+[patchconstantfunc("constants")]
+HS_OUT hullMain(InputPatch<VS_OUT, 4> patch, uint i : SV_OutputControlPointID)
+{
+ HS_OUT o;
+ o.position = patch[i].position;
+ return o;
+}
+
+HSC_OUT constants(InputPatch<VS_OUT, 4> patch)
+{
+ float3 p0 = GetInputPatch(patch, 0).position;
+ float3 p1 = patch[1].position;
+ float3 p2 = patch[2].position;
+ float3 p3 = patch[3].position;
+
+ HSC_OUT o;
+ o.EdgeTessFactor[0] = dot(p0, p1);
+ o.EdgeTessFactor[1] = dot(p0, p3);
+ o.EdgeTessFactor[2] = dot(p2, p3);
+ o.EdgeTessFactor[3] = dot(p1, p2);
+ o.InsideTessFactor[0] = lerp(o.EdgeTessFactor[1], o.EdgeTessFactor[3], 0.5);
+ o.InsideTessFactor[1] = lerp(o.EdgeTessFactor[0], o.EdgeTessFactor[2], 0.5);
+ return o;
+}
+
+HS_OUT GetOutputPatch(const OutputPatch<HS_OUT, 4> patch, int index)
+{
+ return patch[index];
+}
+
+[domain("quad")]
+DS_OUT domainMain(
+ float2 uv : SV_DomainLocation, // Tessellated coordinates (u, v)
+ const OutputPatch<HS_OUT, 4> patch, // Control points from the hull shader
+ const HSC_OUT patchConstants // Patch constants calculated by the hull shader
+)
+{
+ DS_OUT o;
+
+ // Interpolate the position of the tessellated point within the patch
+ float3 p0 = GetOutputPatch(patch, 0).position;
+ float3 p1 = patch[1].position;
+ float3 p2 = patch[2].position;
+ float3 p3 = patch[3].position;
+
+ // Bilinear interpolation of the position in the quad
+ float3 interpolatedPosition =
+ p0 * (1 - uv.x) * (1 - uv.y)
+ + p1 * uv.x * (1 - uv.y)
+ + p3 * uv.x * uv.y
+ + p2 * (1 - uv.x) * uv.y;
+
+ // Output final position in clip space
+ o.position = float4(interpolatedPosition, 1.0);
+ return o;
+}