diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-19 08:32:44 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-20 10:09:25 -0700 |
| commit | 76dca35b3fabbe77d4c01640423bdf5ce93d27d4 (patch) | |
| tree | 5ed8f2cdebc6fb29e76048d920fa41c27b27f7d9 /tests | |
| parent | f07c01ceb012b9b325a8ecebd12cdd5797d8d5b3 (diff) | |
Translate NV single-pass stereo extension from Slang to GLSL
- The easy part here is treating `NV_` prefixed semantics as another case of "system-value" semantics
- Mapping the new semantics (`NV_X_RIGHT` and `NV_VIEWPORT_MASK`) to their GLSL equivalents is harder
- Instead of a single "right-eye vertex" output, GLSL defines an array of per-view positions
- Instead of a vector of masks, GLSL defines an array of per-view masks
- Another point here is that a lot of semantics that appear as `uint` in HLSL are `int` in GLSL, which can lead to conversion issues.
- The approach here is to have the lowering pass introduce a notion of assignment with "fixups," which will try to cast things as needed
- When assigning to a simple value with the "wrong" type, introduce a cast
- When assigning to an array from a vector, break out multiple assignments of individual vector/array elements
- In order to facilitate the above, I needed to add actual types to the magic expressions I introduce to represent GLSL builtin variables. These were taken by scanning the online documentation for GL, so they might not be perfect.
- Major issues with the approach in this change:
- No attempt is being made here to check that the original declaration used a type appropriate to the semantic. The assumption is that this logic only ever triggers for Slang entry points, or GLSL entry points using a Slang `struct` type for input/output (and for right now Slang code is only ever written by "understanding" developers)
- In the case of a Slang entry point, we always copy varying parameters in/out around the call to `main_`, so this approach should handle calls to functions with `out` or `in out` parameters okay, but it is *not* robust to cases where we don't want to copy in all the entry point parameters first thing (e.g., a GS), so that will have to change
- In the GLSL case (or if we revise the approach to Slang entry points), there is going to be a problem if these converted varying parameters are ever passed as arguments to `out` or `in out` parameters. In these cases we need to do more sleight-of-hand to reify a temporary variable and do the necessary copy-in/copy-out. Being able to do that logic relies on having correct information about callees, which requires having robust semantic analysis of the function body. There is only so much we can do...
- A better long-term approach would not rely on an ad-hoc "fixup" conversion during assignment, but would instead implement the GLSL builtin variables as, effectively, global "property" declarations that have both `get` and `set` accessors, and then tunnel a reference to such a property down through lowering, where it can lower to uses of the "getter" or "setter" as appropriate in context (and the result type of the getter/setter can be what we'd want/expect).
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/nv-extensions/multi-view-per-view-attributes.slang | 17 | ||||
| -rw-r--r-- | tests/nv-extensions/multi-view-per-view-attributes.slang.glsl | 44 |
2 files changed, 61 insertions, 0 deletions
diff --git a/tests/nv-extensions/multi-view-per-view-attributes.slang b/tests/nv-extensions/multi-view-per-view-attributes.slang new file mode 100644 index 000000000..ca398ba16 --- /dev/null +++ b/tests/nv-extensions/multi-view-per-view-attributes.slang @@ -0,0 +1,17 @@ +//TEST:CROSS_COMPILE: -profile vs_5_0 -entry main -target spirv-assembly + +struct VS_OUT +{ + float4 left : SV_Position; + float4 right : NV_X_RIGHT; + uint4 mask : NV_VIEWPORT_MASK; +}; + +VS_OUT main(float4 ll, float4 rr) +{ + VS_OUT res; + res.left = ll; + res.right = rr; + res.mask = 0x1; + return res; +}
\ No newline at end of file diff --git a/tests/nv-extensions/multi-view-per-view-attributes.slang.glsl b/tests/nv-extensions/multi-view-per-view-attributes.slang.glsl new file mode 100644 index 000000000..4e2609834 --- /dev/null +++ b/tests/nv-extensions/multi-view-per-view-attributes.slang.glsl @@ -0,0 +1,44 @@ +#version 450 +//TEST_IGNORE_FILE: + +#extension GL_NVX_multiview_per_view_attributes : require + +struct VS_OUT +{ + vec4 left; + vec4 right; + uvec4 mask; +}; + +VS_OUT main_(vec4 ll, vec4 rr) +{ + VS_OUT res; + res.left = ll; + res.right = rr; + res.mask = uvec4(0x1); + return res; +} + +layout(location = 0) +in vec4 SLANG_in_ll; + +layout(location = 1) +in vec4 SLANG_in_rr; + +void main() +{ + vec4 ll = SLANG_in_ll; + vec4 rr = SLANG_in_rr; + + VS_OUT main_result = main_(ll, rr); + + uvec4 SLANG_tmp_0 = main_result.mask; + + gl_Position = main_result.left; + gl_PositionPerViewNV[1] = main_result.right; + gl_ViewportMaskPerViewNV[0] = int(SLANG_tmp_0.x); + gl_ViewportMaskPerViewNV[1] = int(SLANG_tmp_0.y); + gl_ViewportMaskPerViewNV[2] = int(SLANG_tmp_0.z); + gl_ViewportMaskPerViewNV[3] = int(SLANG_tmp_0.w); + gl_PositionPerViewNV[0] = gl_Position; +} |
