diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2020-02-24 11:46:59 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-24 11:46:59 -0800 |
| commit | 777ac2bdde2db8ec3f24034022acfb893924de5a (patch) | |
| tree | 666380ea9eb583a3b204ea17678c5133c1f0503c | |
| parent | f2c221ebf654d924cc71041c46c8d2ca4d589f52 (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.cpp | 18 | ||||
| -rw-r--r-- | tests/cross-compile/sv-coverage.slang | 13 | ||||
| -rw-r--r-- | tests/cross-compile/sv-coverage.slang.glsl | 19 |
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; +} |
