mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
Arrays are allowed for clip/cull distance semantics. Their maximum size is 2 since that's the maximum amount of registers allowed for clip/cull distances. Indirect addressing of these arrays is allowed on shader model 6. These tests are introduced after the transformation of clip/cull input/outputs into arrays in vsir since otherwise they segfault.
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)
|