HLSL: Added support for tessellation control/evaluation shaders#2604
Open
xen2 wants to merge 4 commits intoKhronosGroup:mainfrom
Open
HLSL: Added support for tessellation control/evaluation shaders#2604xen2 wants to merge 4 commits intoKhronosGroup:mainfrom
xen2 wants to merge 4 commits intoKhronosGroup:mainfrom
Conversation
45525a9 to
86cba34
Compare
Contributor
Author
|
It seems to work well enough on my use cases (tested with D3D11 on various shaders incl flat & PN, with and without adjacent edge average displacement. |
Contributor
|
I need to get to this at some later point when I actually have time ... 1ksloc PRs of new difficult features takes a ton of energy and time to digest. |
Contributor
Author
|
No problem, I understand it is a big feature and it might take time to get improved/merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds hull shader (tesc) and domain shader (tese) code generation to the SPIRV-Cross HLSL backend.
This PR is built on top of #2603 which should be first merged in.
I also keep it as draft as I am still testing it in our project and refining it, but so far it worked well on several tessellation shaders our engine generates.
Please give me your thought regarding the general approach, would it be OK to merge it?
Hull shader (tesc) — function splitting
HLSL requires hull shader work split into a per-control-point entry point and a separate patch constant function, but SPIR-V expresses both as a single
main(). The compiler splits them using a redirected emission approach: rather than writing to the main output stream,emit_instruction()writes to one of two capture buffers (tesc_per_cp_bufferortesc_patch_buffer) based on aTescEmitPhasestate machine:OpAccessChainusinggl_InvocationIDis seen (output writes begin).OpFunctionCallto the patch constant function, or anOpStoreto a tess level/patch variable.if (gl_InvocationID == 0)construct; the closing brace is stripped and subsequent output is discarded.OpControlBarrieris suppressed entirely (hull shaders synchronize implicitly).After emission, the two buffers are assembled into
tesc_main()andtesc_main_patch(). A separatepatch_constant()wrapper callstesc_main_patch()and writes tess levels to theSPIRV_Cross_PatchConstantreturn struct.Note: The function splitting relies on the GLSL-to-SPIR-V compiler wrapping patch constant work in an
if (gl_InvocationID == 0) { ... }guard block. This is a limitation, but it is the pattern consistently emitted by both glslang and DXC when compiling GLSL/HLSL tessellation shaders to SPIR-V, so in practice it covers all real-world inputs.Domain shader (tese)
Nothing special, entry point signature:
[domain(...)] main(SPIRV_Cross_PatchConstant pc, const OutputPatch<SPIRV_Cross_Input, N> patch, float3/float2 domain : SV_DomainLocation).Patch-decorated inputs copy from
pc; per-CP inputs copy frompatch[i]in a loop.Other
SPIRV_Cross_PatchConstant: shared struct between tesc/tese with patch-decorated vars + tess level builtins (SV_TessFactor/SV_InsideTessFactor), sized by domain (tri: 3/1, quad: 4/2, isoline: 2/0).get_tesc_tese_flags(): merges execution mode flags from the other tessellation stage, since SPIR-V allows domain/spacing/winding modes on either entry point.input_cp_count: derived fromBuiltInPositioninput array size, with fallback to scanning other per-CP input arrays, thenoutput_vertices. Maybe there is a better way?SPIRV_Cross_PatchConstantgl_TessCoordassigned fromSV_DomainLocationat entry.