[require] shader model >= 5.0 tessellation-shader [vertex shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; void main(uint id : SV_VertexID, out data output) { float2 coords = float2((id << 1) & 2, id & 2); output.position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); output.r = 0.0; output.g = 1.0; output.b = 0.0; } [hull shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; struct patch_constant_data { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; void patch_constant(InputPatch input, out patch_constant_data output) { output.edges[0] = output.edges[1] = output.edges[2] = 1.0f; output.inside = 1.0f; } [domain("tri")] [outputcontrolpoints(3)] [partitioning("integer")] [outputtopology("triangle_cw")] [patchconstantfunc("patch_constant")] data main(InputPatch input, uint i : SV_OutputControlPointID) { return input[i]; } [domain shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; struct patch_constant_data { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; [domain("tri")] void main(patch_constant_data input, float3 tess_coord : SV_DomainLocation, const OutputPatch patch, out data output) { output.position = tess_coord.x * patch[0].position + tess_coord.y * patch[1].position + tess_coord.z * patch[2].position; output.r = tess_coord.x * patch[0].r + tess_coord.y * patch[1].r + tess_coord.z * patch[2].r; output.g = tess_coord.x * patch[0].g + tess_coord.y * patch[1].g + tess_coord.z * patch[2].g; output.b = tess_coord.x * patch[0].b + tess_coord.y * patch[1].b + tess_coord.z * patch[2].b; } [pixel shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; float4 main(data input) : sv_target { return float4(input.r, input.g, input.b, 1.0); } [test] % llvmpipe currently segfaults due to a bug during shader compilation in the driver. if(!llvmpipe) todo(glsl | mvk & vulkan) draw 3 control point patch list 3 if(!llvmpipe) todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0) % Passthrough hull shader control point function. [hull shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; struct patch_constant_data { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; void patch_constant(InputPatch input, out patch_constant_data output) { output.edges[0] = output.edges[1] = output.edges[2] = 1.0f; output.inside = 1.0f; } [domain("tri")] [outputcontrolpoints(3)] [partitioning("integer")] [outputtopology("triangle_cw")] [patchconstantfunc("patch_constant")] void main(InputPatch input) { } [test] % DXC doesn't generate a passthrough control point phase like FXC does if(!llvmpipe & sm<6) todo(glsl | mvk & vulkan) draw 3 control point patch list 3 if(!llvmpipe & sm<6) todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0) [require] shader model >= 5.0 shader model < 5.1 tessellation-shader [hull shader dxbc-tpf-hex] % As above, but with some DCL_INDEXRANGE instructions that skip a signature % element (i.e., it has "dcl_indexrange o0.z 3" at some point, but o1.z does % not exist). This must be kept in compiled form rather than source code % because we want to test a specific quirk of the code generated by the native % d3dcompiler. It should be converted to assembly as soon as that's available, % though. % struct data % { % float4 position : SV_Position; % float r : RED; % float g : GREEN; % float b : BLUE; % }; % % struct patch_constant_data % { % float edges[3] : SV_TessFactor; % float inside : SV_InsideTessFactor; % float2 x : X; % float1 y : Y; % float2 z : Z; % }; % % void patch_constant(InputPatch input, out patch_constant_data output) % { % output.edges[0] = output.edges[1] = output.edges[2] = 1.0f; % output.inside = 1.0f; % output.x = 0.0f; % output.y = 0.0f; % output.z = 0.0f; % } % % [domain("tri")] % [outputcontrolpoints(3)] % [partitioning("integer")] % [outputtopology("triangle_cw")] % [patchconstantfunc("patch_constant")] % data main(InputPatch input, uint i : SV_OutputControlPointID) % { % return input[i]; % } % hs_5_0 % hs_decls % dcl_input_control_point_count 3 % dcl_output_control_point_count 3 % dcl_tessellator_domain domain_tri % dcl_tessellator_partitioning partitioning_integer % dcl_tessellator_output_primitive output_triangle_cw % dcl_globalFlags refactoringAllowed % hs_fork_phase % dcl_hs_fork_phase_instance_count 3 % dcl_input vForkInstanceID % dcl_output_siv o0.x, finalTriUeq0EdgeTessFactor % dcl_output_siv o1.x, finalTriVeq0EdgeTessFactor % dcl_output_siv o2.x, finalTriWeq0EdgeTessFactor % dcl_temps 1 % dcl_indexrange o0.x 3 % mov r0.x, vForkInstanceID.x % mov o[r0.x + 0].x, l(1.000000) % ret % hs_fork_phase % dcl_output_siv o3.x, finalTriInsideTessFactor % mov o3.x, l(1.000000) % ret % hs_fork_phase % dcl_hs_fork_phase_instance_count 3 % dcl_input vForkInstanceID % dcl_output o0.y % dcl_output o1.y % dcl_output o2.y % dcl_temps 1 % dcl_indexrange o0.y 3 % mov r0.x, vForkInstanceID.x % mov o[r0.x + 0].y, l(0) % ret % hs_fork_phase % dcl_hs_fork_phase_instance_count 2 % dcl_input vForkInstanceID % dcl_output o0.z % dcl_output o2.z % dcl_temps 1 % dcl_indexrange o0.z 3 % ult r0.x, vForkInstanceID.x, l(1) % movc r0.x, r0.x, l(0), l(2) % mov o[r0.x + 0].z, l(0) % ret 43425844 d3d22934 2b8d40fb cc30d02f 0b5acd69 00000001 0000053c 00000006 00000038 000000b0 0000013c 000001c8 000002a8 000004a0 46454452 00000070 00000000 00000000 00000000 0000003c 48530500 00000100 0000003c 31314452 0000003c 00000018 00000020 00000028 00000024 0000000c 00000000 7263694d 666f736f 52282074 4c482029 53204c53 65646168 6f432072 6c69706d 31207265 2e302e30 31303031 36312e31 00343833 4e475349 00000084 00000004 00000008 00000068 00000000 00000001 00000003 00000000 00000f0f 00000074 00000000 00000000 00000003 00000001 00000101 00000078 00000000 00000000 00000003 00000001 00000202 0000007e 00000000 00000000 00000003 00000001 00000404 505f5653 7469736f 006e6f69 00444552 45455247 4c42004e ab004555 4e47534f 00000084 00000004 00000008 00000068 00000000 00000001 00000003 00000000 0000000f 00000074 00000000 00000000 00000003 00000001 00000e01 00000078 00000000 00000000 00000003 00000001 00000d02 0000007e 00000000 00000000 00000003 00000001 00000b04 505f5653 7469736f 006e6f69 00444552 45455247 4c42004e ab004555 47534350 000000d8 00000007 00000008 000000b0 00000000 0000000d 00000003 00000000 00000e01 000000be 00000000 00000000 00000003 00000000 00000906 000000b0 00000001 0000000d 00000003 00000001 00000e01 000000c0 00000000 00000000 00000003 00000001 00000d02 000000b0 00000002 0000000d 00000003 00000002 00000e01 000000c2 00000000 00000000 00000003 00000002 00000906 000000c4 00000000 0000000e 00000003 00000003 00000e01 545f5653 46737365 6f746361 00580072 005a0059 495f5653 6469736e 73655465 63614673 00726f74 58454853 000001f0 00030050 0000007c 01000071 01001893 01001894 01001095 01000896 01001897 0100086a 01000073 02000099 00000003 0200005f 00017000 04000067 00102012 00000000 00000011 04000067 00102012 00000001 00000012 04000067 00102012 00000002 00000013 02000068 00000001 0400005b 00102012 00000000 00000003 04000036 00100012 00000000 0001700a 06000036 00902012 0010000a 00000000 00004001 3f800000 0100003e 01000073 04000067 00102012 00000003 00000014 05000036 00102012 00000003 00004001 3f800000 0100003e 01000073 02000099 00000003 0200005f 00017000 03000065 00102022 00000000 03000065 00102022 00000001 03000065 00102022 00000002 02000068 00000001 0400005b 00102022 00000000 00000003 04000036 00100012 00000000 0001700a 06000036 00902022 0010000a 00000000 00004001 00000000 0100003e 01000073 02000099 00000002 0200005f 00017000 03000065 00102042 00000000 03000065 00102042 00000002 02000068 00000001 0400005b 00102042 00000000 00000003 0600004f 00100012 00000000 0001700a 00004001 00000001 09000037 00100012 00000000 0010000a 00000000 00004001 00000000 00004001 00000002 06000036 00902042 0010000a 00000000 00004001 00000000 0100003e 54415453 00000094 0000000c 00000001 00000000 00000004 00000000 00000000 00000001 00000004 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000006 00000001 00000000 00000000 0000000a 00000000 00000000 00000000 00000000 00000000 00000000 00000003 00000003 00000001 00000002 00000000 00000000 00000000 [domain shader] struct data { float4 position : SV_Position; float r : RED; float g : GREEN; float b : BLUE; }; struct patch_constant_data { float edges[3] : SV_TessFactor; float inside : SV_InsideTessFactor; float2 x : X; float1 y : Y; float2 z : Z; }; [domain("tri")] void main(patch_constant_data input, float3 tess_coord : SV_DomainLocation, const OutputPatch patch, out data output) { output.position = tess_coord.x * patch[0].position + tess_coord.y * patch[1].position + tess_coord.z * patch[2].position; output.r = tess_coord.x * patch[0].r + tess_coord.y * patch[1].r + tess_coord.z * patch[2].r; output.g = tess_coord.x * patch[0].g + tess_coord.y * patch[1].g + tess_coord.z * patch[2].g; output.b = tess_coord.x * patch[0].b + tess_coord.y * patch[1].b + tess_coord.z * patch[2].b; } [test] if(!llvmpipe) todo(glsl | mvk & vulkan) draw 3 control point patch list 3 if(!llvmpipe) todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)