summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2020-02-24 11:46:59 -0800
committerGitHub <noreply@github.com>2020-02-24 11:46:59 -0800
commit777ac2bdde2db8ec3f24034022acfb893924de5a (patch)
tree666380ea9eb583a3b204ea17678c5133c1f0503c
parentf2c221ebf654d924cc71041c46c8d2ca4d589f52 (diff)
Fix support for SV_Coverage on GLSL path (#1239)
There were two overlapping issues here: 1. We always mapped `SV_Coverage` to `gl_SampleMask`, even though `gl_SampleMaskIn` is the correct built-in variable to use for an input varying. 2. We treated `gl_SampleMask` like it was a scalar shader input, when it and `gl_SampleMaskIn` are actually arrays of indeterminate size (as a byproduct of trying to future-proof for implementations that might support hundreds or thousands of samples per pixel...) The fix here is simple: map to either `gl_SampleMask[0]` or `gl_SampleMaskIn[0]` as appropriate. I suppose that this approach doesn't handle the possibility of eventually supporting >32 samples per pixel by having something like `uint2 coverage : SV_Coverage`, but I think we can cross that bridge when we come to it.
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp18
-rw-r--r--tests/cross-compile/sv-coverage.slang13
-rw-r--r--tests/cross-compile/sv-coverage.slang.glsl19
3 files changed, 45 insertions, 5 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index 2c889f341..170027405 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -300,16 +300,24 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
}
else if(semanticName == "sv_coverage")
{
- // TODO: deal with `gl_SampleMaskIn` when used as an input.
-
- // TODO: type conversion is required here.
-
// uint in hlsl, int in glsl
// https://www.opengl.org/sdk/docs/manglsl/docbook4/xhtml/gl_SampleMask.xml
requiredType = builder->getBasicType(BaseType::Int);
- name = "gl_SampleMask";
+ // Note: `gl_SampleMask` is actually an *array* of `int`,
+ // rather than a single scalar. Because HLSL `SV_Coverage`
+ // on allows for a 32 bits worth of coverage, we will
+ // only use the first array element in the generated GLSL.
+
+ if( kind == LayoutResourceKind::VaryingInput )
+ {
+ name = "gl_SampleMaskIn[0]";
+ }
+ else
+ {
+ name = "gl_SampleMask[0]";
+ }
}
else if(semanticName == "sv_depth")
{
diff --git a/tests/cross-compile/sv-coverage.slang b/tests/cross-compile/sv-coverage.slang
new file mode 100644
index 000000000..3bae3ea8a
--- /dev/null
+++ b/tests/cross-compile/sv-coverage.slang
@@ -0,0 +1,13 @@
+// sv-coverage.slang
+
+//TEST:CROSS_COMPILE:-target spirv-assembly -entry main -stage fragment
+
+float4 main(
+ in float4 color : COLOR,
+ in uint inputCoverage : SV_Coverage,
+ out uint outputCoverage : SV_Coverage)
+ : SV_Target
+{
+ outputCoverage = inputCoverage ^ 1;
+ return color;
+}
diff --git a/tests/cross-compile/sv-coverage.slang.glsl b/tests/cross-compile/sv-coverage.slang.glsl
new file mode 100644
index 000000000..04728e81b
--- /dev/null
+++ b/tests/cross-compile/sv-coverage.slang.glsl
@@ -0,0 +1,19 @@
+// sv-coverage.slang.glsl
+#version 450
+
+layout(location = 0)
+out vec4 _S1;
+
+layout(location = 0)
+in vec4 _S2;
+
+void main()
+{
+ uint _S3 = uint(gl_SampleMaskIn[0]);
+ uint _S4;
+
+ _S4 = _S3 ^ uint(1);
+ _S1 = _S2;
+ gl_SampleMask[0] = int(_S4);
+ return;
+}