mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
Takes care of transforming clip/cull system values from the Direct3D convention of 2 4-component registers, into the SPIR-V/GLSL convention of 8-element scalar float arrays. This fixes SPIR-V validation errors in clip-cull-distance.shader_test, as well as segfaults on Mesa 25.1.1-arch1.2 if those shaders are executed regardless. We create indexable temporaries of the appropriate size, and replace accesses to clip/cull I/O signature elements with accesses to those temporaries. The existing clip/cull signature elements are then replaced with new scalar signature element arrays, and we copy the contents of those I/O signature elements to/from the corresponding temporaries at the start/end of the vsir program. It is worth pointing out that the current implementation assumes that every instance of the control point phase of a hull shader only writes to the output registers of its control point, given by vOutputControlPointID, and not to other control points. Shader compilation will fail if that constraint is violated.
879 lines
23 KiB
Plaintext
879 lines
23 KiB
Plaintext
[require]
|
|
shader model >= 4.0
|
|
cull-distance
|
|
|
|
[input layout]
|
|
0 r32g32-float POSITION
|
|
|
|
% 9 triangles, on a 3x3 arrangement.
|
|
[vb 0]
|
|
-0.52 -0.52
|
|
-0.46 -0.50
|
|
-0.50 -0.46
|
|
|
|
-0.52 -0.02
|
|
-0.46 0.00
|
|
-0.50 0.04
|
|
|
|
-0.52 0.48
|
|
-0.46 0.50
|
|
-0.50 0.54
|
|
|
|
-0.02 -0.52
|
|
0.04 -0.50
|
|
0.00 -0.46
|
|
|
|
-0.02 -0.02
|
|
0.04 0.00
|
|
0.00 0.04
|
|
|
|
-0.02 0.48
|
|
0.04 0.50
|
|
0.00 0.54
|
|
|
|
0.48 -0.52
|
|
0.54 -0.50
|
|
0.50 -0.46
|
|
|
|
0.48 -0.02
|
|
0.54 0.00
|
|
0.50 0.04
|
|
|
|
0.48 0.48
|
|
0.54 0.50
|
|
0.50 0.54
|
|
|
|
[rtv 0]
|
|
format r32g32b32a32-float
|
|
size (2d, 640, 480)
|
|
|
|
[vertex shader todo]
|
|
struct vertex
|
|
{
|
|
float4 position : SV_POSITION;
|
|
float cull : SV_CULLDISTANCE;
|
|
float clip : SV_CLIPDISTANCE;
|
|
};
|
|
|
|
void main(float4 position : POSITION, out vertex vertex)
|
|
{
|
|
vertex.position = position;
|
|
// All 3 triangles on the left column are removed by culling.
|
|
// All 3 triangles on the bottom row are removed by clipping.
|
|
// The triangles on the middle row will be partially removed by clipping.
|
|
vertex.cull = position.x;
|
|
vertex.clip = position.y;
|
|
}
|
|
|
|
[pixel shader]
|
|
float4 main(const in float4 position : SV_Position) : SV_Target
|
|
{
|
|
return float4(1.0f, 1.0f, 1.0f, 1.0f);
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 0.0 0.0 0.0 1.0
|
|
todo(sm<6) draw triangle list 27
|
|
probe rtv 0 (160, 120) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 1.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 1.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 239) f32(1.0, 1.0, 1.0, 1.0)
|
|
|
|
[require]
|
|
shader model >= 4.0
|
|
shader model < 4.1
|
|
cull-distance
|
|
|
|
% Same as previous vertex shader, but already compiled with FXC.
|
|
[vertex shader dxbc-tpf-hex]
|
|
43425844 0ec8a95b 7857d61f 02c08472 6edf4bf9 00000001 00000170 % DXBC header
|
|
00000003 0000002c 00000060 000000e4 %
|
|
4e475349 0000002c 00000001 00000008 % .input
|
|
00000020 00000000 00000000 00000003 00000000 00000f0f % .param POSITION.xyzw, v0.xyzw, float
|
|
49534f50 4e4f4954 ababab00 % "POSITION"
|
|
4e47534f 0000007c 00000003 00000008 % .output
|
|
00000050 00000000 00000001 00000003 00000000 0000000f % .param SV_POSITION.xyzw, o0.xyzw, float, POS
|
|
0000005c 00000000 00000003 00000003 00000001 00000e01 % .param SV_CULLDISTANCE.x, o1.x, float, CULLDST
|
|
0000006c 00000000 00000002 00000003 00000001 00000d02 % .param SV_CLIPDISTANCE.y, o1.y, float, CLIPDST
|
|
505f5653 5449534f 004e4f49 % "SV_POSITION"
|
|
435f5653 444c4c55 41545349 0045434e % "SV_CULLDISTANCE"
|
|
435f5653 4450494c 41545349 0045434e % "SV_CLIPDISTANCE"
|
|
52444853 00000084 00010040 00000021 % .text vs_4_0
|
|
0300005f 001010f2 00000000 % dcl_input v0.xyzw
|
|
04000067 001020f2 00000000 00000001 % dcl_output_siv o0.xyzw, position
|
|
04000067 00102012 00000001 00000003 % dcl_output_siv o1.x, cull_distance
|
|
04000067 00102022 00000001 00000002 % dcl_output_siv o1.y, clip_distance
|
|
05000036 001020f2 00000000 00101e46 00000000 % mov o0.xyzw, v0.xyzw
|
|
05000036 00102012 00000001 0010100a 00000000 % mov o1.x, v0.x
|
|
05000036 00102022 00000001 0010101a 00000000 % mov o1.y, v0.y
|
|
0100003e % ret
|
|
|
|
[pixel shader]
|
|
float4 main(const in float4 position : SV_Position) : SV_Target
|
|
{
|
|
return float4(1.0f, 1.0f, 1.0f, 1.0f);
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 0.0 0.0 0.0 1.0
|
|
todo(glsl) draw triangle list 27
|
|
probe rtv 0 (160, 120) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 1.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 1.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 239) f32(1.0, 1.0, 1.0, 1.0)
|
|
|
|
[require]
|
|
shader model >= 4.0
|
|
cull-distance
|
|
|
|
% Test clip/cull distance inputs.
|
|
[vertex shader todo]
|
|
struct vertex_data
|
|
{
|
|
float4 position : SV_POSITION;
|
|
float3 cullA : SV_CULLDISTANCE;
|
|
float2 clip : SV_CLIPDISTANCE;
|
|
float cullB : SV_CULLDISTANCE1;
|
|
};
|
|
|
|
void main(float4 position : POSITION, out vertex_data vertex)
|
|
{
|
|
vertex.position = position;
|
|
vertex.cullA = float3(10, 20, 30);
|
|
vertex.clip = float2(40, 50);
|
|
vertex.cullB = -position.x; // Removes all 3 triangles on the right column.
|
|
}
|
|
|
|
[pixel shader todo]
|
|
struct vertex_data
|
|
{
|
|
float4 position : SV_POSITION;
|
|
float3 cullA : SV_CULLDISTANCE;
|
|
float2 clip : SV_CLIPDISTANCE;
|
|
float cullB : SV_CULLDISTANCE1;
|
|
};
|
|
|
|
float4 main(struct vertex_data vertex) : SV_Target
|
|
{
|
|
// Interpolated cull distance is quantized since there is a variation of
|
|
// many ULPs across drivers.
|
|
return float4(vertex.cullA.xz, vertex.clip.y, round(10000 * vertex.cullB));
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 0.0 0.0 0.0 1.0
|
|
todo(sm<6) draw triangle list 27
|
|
probe rtv 0 (160, 120) f32(10.0, 30.0, 50.0, 4984)
|
|
probe rtv 0 (160, 240) f32(10.0, 30.0, 50.0, 4984)
|
|
probe rtv 0 (160, 360) f32(10.0, 30.0, 50.0, 4984)
|
|
probe rtv 0 (320, 120) f32(10.0, 30.0, 50.0, -16)
|
|
probe rtv 0 (320, 240) f32(10.0, 30.0, 50.0, -16)
|
|
probe rtv 0 (320, 360) f32(10.0, 30.0, 50.0, -16)
|
|
probe rtv 0 (480, 120) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
|
|
[vertex shader fail(sm<6)]
|
|
struct vertex_data
|
|
{
|
|
float4 position : SV_POSITION; // o0.xyzw
|
|
float3 clipA : SV_CLIPDISTANCE2; // o1.xyz
|
|
float2 clipB : SV_CLIPDISTANCE1; // o2.xy
|
|
float cull : SV_CULLDISTANCE; // o1.w
|
|
float clipC : SV_CLIPDISTANCE0; // o2.z
|
|
};
|
|
|
|
void main(float4 position : POSITION, out vertex_data vertex)
|
|
{
|
|
vertex.position = position;
|
|
vertex.clipA = float3(10, 20, 30);
|
|
vertex.clipB = float2(40, 50);
|
|
vertex.cull = 1.0;
|
|
vertex.clipC = -position.x; // Removes all pixels on the right side of the render target.
|
|
}
|
|
|
|
[pixel shader fail(sm<6)]
|
|
struct vertex_data
|
|
{
|
|
float4 position : SV_POSITION; // v0.xyzw
|
|
float3 clipA : SV_CLIPDISTANCE2; // v1.xyz
|
|
float2 clipB : SV_CLIPDISTANCE1; // v2.xy
|
|
float cull : SV_CULLDISTANCE; // v1.w
|
|
float clipC : SV_CLIPDISTANCE0; // v2.z
|
|
};
|
|
|
|
float4 main(struct vertex_data vertex) : SV_Target
|
|
{
|
|
return float4(vertex.clipA.z, vertex.clipB.y, vertex.cull, round(10000 * vertex.clipC));
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 0.0 0.0 0.0 1.0
|
|
todo(sm<6) draw triangle list 27
|
|
probe rtv 0 (160, 120) f32(30.0, 50.0, 1.0, 4984)
|
|
probe rtv 0 (160, 240) f32(30.0, 50.0, 1.0, 4984)
|
|
probe rtv 0 (160, 360) f32(30.0, 50.0, 1.0, 4984)
|
|
probe rtv 0 (319, 120) f32(30.0, 50.0, 1.0, 16)
|
|
probe rtv 0 (319, 240) f32(30.0, 50.0, 1.0, 16)
|
|
probe rtv 0 (319, 360) f32(30.0, 50.0, 1.0, 16)
|
|
probe rtv 0 (320, 120) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0)
|
|
|
|
[require]
|
|
shader model >= 4.0
|
|
|
|
[input layout]
|
|
0 r32g32-float POSITION
|
|
1 r32-float CLIP_DISTANCE
|
|
|
|
[vb 0]
|
|
-1.0 -1.0
|
|
-1.0 1.0
|
|
1.0 -1.0
|
|
1.0 1.0
|
|
|
|
[vb 1]
|
|
1.0
|
|
1.0
|
|
1.0
|
|
1.0
|
|
|
|
[rtv 0]
|
|
format r32g32b32a32-float
|
|
size (2d, 640, 480)
|
|
|
|
[vertex shader todo]
|
|
struct input
|
|
{
|
|
float4 position : POSITION;
|
|
float distance : CLIP_DISTANCE;
|
|
};
|
|
|
|
struct vertex
|
|
{
|
|
float4 position : SV_POSITION;
|
|
float clip : SV_ClipDistance;
|
|
};
|
|
|
|
void main(input vin, out vertex vertex)
|
|
{
|
|
vertex.position = vin.position;
|
|
vertex.clip = vin.distance;
|
|
}
|
|
|
|
[pixel shader]
|
|
float4 main(const in float4 position : SV_Position) : SV_Target
|
|
{
|
|
return float4(0.0f, 1.0f, 0.0f, 1.0f);
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 1.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
[vb 1]
|
|
0.0
|
|
0.0
|
|
0.0
|
|
0.0
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 1.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
[vb 1]
|
|
-1.0
|
|
-1.0
|
|
-1.0
|
|
-1.0
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 1.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe (0, 0, 640, 480) rgba(1.0, 1.0, 1.0, 1.0)
|
|
|
|
[vb 1]
|
|
1.0
|
|
1.0
|
|
-1.0
|
|
-1.0
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 1.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (160, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(1.0, 1.0, 1.0, 1.0)
|
|
|
|
[vb 1]
|
|
-1.0
|
|
1.0
|
|
-1.0
|
|
1.0
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 1.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(1.0, 1.0, 1.0, 1.0)
|
|
|
|
% A single clip distance.
|
|
|
|
[vertex shader todo]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float clip : SV_ClipDistance;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.clip = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
% A single clip distance, disguised as an array.
|
|
|
|
[vertex shader todo]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float clip[1] : SV_ClipDistance1;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.clip[0] = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
% Two clip distances.
|
|
|
|
[vertex shader todo]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
% Five clip distances.
|
|
|
|
[vertex shader todo]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float3 clip2 : SV_ClipDistance1;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
|
|
o.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6 | msl) draw triangle strip 4
|
|
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
|
|
|
|
[require]
|
|
shader model >= 4.0
|
|
cull-distance
|
|
|
|
% Now it works. Here all the cull distances are effectively ignored, because
|
|
% they do not leave the only triangle entirely on one side. (Also, they
|
|
% coincide with other clip distances.)
|
|
|
|
[vertex shader todo]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float3 clip2 : SV_ClipDistance1;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
|
|
o.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
o.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
|
|
o.cull.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
o.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
o.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
|
|
[require]
|
|
shader model >= 4.0
|
|
cull-distance
|
|
geometry-shader
|
|
|
|
% Let clip and cull distances go through a geometry shader.
|
|
|
|
[geometry shader todo]
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float3 clip2 : SV_ClipDistance1;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
[maxvertexcount(3)]
|
|
void main(triangle vs_out input[3], inout TriangleStream<vs_out> stream)
|
|
{
|
|
unsigned int i;
|
|
vs_out output;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
output = input[i];
|
|
stream.Append(output);
|
|
}
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
|
|
% Generate clip and cull distances in the geometry shader.
|
|
|
|
[vertex shader]
|
|
static const float2 vertices[3] =
|
|
{
|
|
{-1.0f, 1.0f},
|
|
{ 3.0f, 1.0f},
|
|
{-1.0f, -3.0f},
|
|
};
|
|
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
uint id : VERTEXID;
|
|
};
|
|
|
|
void main(uint id : SV_VertexID, out vs_out o)
|
|
{
|
|
const float2 pos = vertices[id];
|
|
o.position = float4(pos, 0.0f, 1.0f);
|
|
o.id = id;
|
|
}
|
|
|
|
[geometry shader todo]
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
uint id : VERTEXID;
|
|
};
|
|
|
|
struct gs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float3 clip2 : SV_ClipDistance1;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
|
|
{
|
|
gs_out output;
|
|
|
|
output.position = pos;
|
|
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
output.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
|
|
output.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
output.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
output.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
|
|
output.cull.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
output.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
output.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
|
|
stream.Append(output);
|
|
}
|
|
|
|
[maxvertexcount(3)]
|
|
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
emit_position(input[i].position, stream);
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
|
|
% Now let's test cull distances for real: we remove the clip distances they
|
|
% duplicate and use the geometry shader to create many little triangles around
|
|
% the test points; first we check that we're drawing properly disabling all
|
|
% clipping and culling.
|
|
|
|
[geometry shader todo]
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
uint id : VERTEXID;
|
|
};
|
|
|
|
struct gs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
|
|
{
|
|
gs_out output;
|
|
|
|
output.position = pos;
|
|
output.clip = 1.0f;
|
|
output.cull = 1.0f;
|
|
output.cull2 = 1.0f;
|
|
|
|
stream.Append(output);
|
|
}
|
|
|
|
static const float4 displacements[3] =
|
|
{
|
|
{ 0.01f, 0.01f, 0.0f, 0.0f},
|
|
{-0.02f, 0.01f, 0.0f, 0.0f},
|
|
{ 0.01f, -0.02f, 0.0f, 0.0f},
|
|
};
|
|
|
|
[maxvertexcount(27)]
|
|
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
|
|
{
|
|
unsigned int i, j;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
for (j = 0; j < 3; ++j)
|
|
{
|
|
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
pos.x = 0.5f - 0.5f * i;
|
|
pos.y = 0.5f - 0.5f * j;
|
|
|
|
emit_position(pos + displacements[0], stream);
|
|
emit_position(pos + displacements[1], stream);
|
|
emit_position(pos + displacements[2], stream);
|
|
|
|
stream.RestartStrip();
|
|
}
|
|
}
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
|
|
|
|
% Then we add clipping and culling: at first only a few distances.
|
|
|
|
[geometry shader todo]
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
uint id : VERTEXID;
|
|
};
|
|
|
|
struct gs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
|
|
{
|
|
gs_out output;
|
|
|
|
output.position = pos;
|
|
output.clip = 1.0f;
|
|
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
output.cull = 1.0f;
|
|
output.cull.x = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
|
|
output.cull2 = 1.0f;
|
|
|
|
stream.Append(output);
|
|
}
|
|
|
|
static const float4 displacements[3] =
|
|
{
|
|
{ 0.01f, 0.01f, 0.0f, 0.0f},
|
|
{-0.02f, 0.01f, 0.0f, 0.0f},
|
|
{ 0.01f, -0.02f, 0.0f, 0.0f},
|
|
};
|
|
|
|
[maxvertexcount(27)]
|
|
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
|
|
{
|
|
unsigned int i, j;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
for (j = 0; j < 3; ++j)
|
|
{
|
|
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
pos.x = 0.5f - 0.5f * i;
|
|
pos.y = 0.5f - 0.5f * j;
|
|
|
|
emit_position(pos + displacements[0], stream);
|
|
emit_position(pos + displacements[1], stream);
|
|
emit_position(pos + displacements[2], stream);
|
|
|
|
stream.RestartStrip();
|
|
}
|
|
}
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 360) f32(0.0, 1.0, 0.0, 1.0)
|
|
|
|
% Then enough to get rid of nearly all test points.
|
|
|
|
[geometry shader todo]
|
|
struct vs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
uint id : VERTEXID;
|
|
};
|
|
|
|
struct gs_out
|
|
{
|
|
float4 position : SV_Position;
|
|
float2 clip : SV_ClipDistance;
|
|
float2 cull2 : SV_CullDistance1;
|
|
float1 cull : SV_CullDistance;
|
|
};
|
|
|
|
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
|
|
{
|
|
gs_out output;
|
|
|
|
output.position = pos;
|
|
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
|
|
output.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
|
|
output.cull.x = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
|
|
output.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
|
|
output.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
|
|
|
|
stream.Append(output);
|
|
}
|
|
|
|
static const float4 displacements[3] =
|
|
{
|
|
{ 0.05f, 0.05f, 0.0f, 0.0f},
|
|
{-0.1f, 0.05f, 0.0f, 0.0f},
|
|
{ 0.05f, -0.1f, 0.0f, 0.0f},
|
|
};
|
|
|
|
[maxvertexcount(27)]
|
|
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
|
|
{
|
|
unsigned int i, j;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
{
|
|
for (j = 0; j < 3; ++j)
|
|
{
|
|
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
pos.x = 0.5f - 0.5f * i;
|
|
pos.y = 0.5f - 0.5f * j;
|
|
|
|
emit_position(pos + displacements[0], stream);
|
|
emit_position(pos + displacements[1], stream);
|
|
emit_position(pos + displacements[2], stream);
|
|
|
|
stream.RestartStrip();
|
|
}
|
|
}
|
|
}
|
|
|
|
[test]
|
|
clear rtv 0 1.0 1.0 0.0 1.0
|
|
todo(sm<6) draw triangle strip 4
|
|
probe rtv 0 (160, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (160, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 240) f32(0.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (320, 360) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 120) f32(1.0, 1.0, 0.0, 1.0)
|
|
probe rtv 0 (480, 240) f32(1.0, 1.0, 0.0, 1.0)
|
|
bug(mesa<23.3) probe rtv 0 (480, 360) f32(1.0, 1.0, 0.0, 1.0)
|