Files
vkd3d/tests/hlsl/clip-cull-distance.shader_test
Francisco Casas 32b622d7a5 vkd3d-shader/dxil: Also map destination write masks for system values.
Currently, on what we consider normalized vsir, destination write masks
are not relative to the signature element's mask, even though source
swizzles are. Also for most instructions, the source swizzles are masked
by the destination write mask, as given by vsir_src_is_masked().

The DXIL parser however, is not derelativizing the destination write
masks for system value signature elements, so we fix that to make it
consistent with how other front-ends are handled.

For instance, when the test introduced in commit
ca5bc63e5e is compiled to DXIL using DXC,
and then parsed using vkd3d-compiler, we get the following store
instructions:

    vs_6_0
    .input
    .param POSITION.xyzw, v0.xyzw, float
    .output
    .param SV_Position.xyzw, o0.xyzw, float, POS
    .param SV_CullDistance.x, o1.x, float, CULLDST
    .param SV_ClipDistance.y, o1.y, float, CLIPDST
    .descriptors
    .text
    label l1
        ...
        mov o1.x <v4:f32>, sr1 <s:f32>
        mov o2.x <v4:f32>, sr2 <s:f32> // Note the .x write mask!
        ret

whereas, when compiling using FXC and parsing the TPF using
vkd3d-compiler we get:

    vs_4_0
    .input
    .param POSITION.xyzw, v0.xyzw, float
    .output
    .param SV_POSITION.xyzw, o0.xyzw, float, POS
    .param SV_CULLDISTANCE.x, o1.x, float, CULLDST
    .param SV_CLIPDISTANCE.y, o1.y, float, CLIPDST
    .descriptors
    .text
    label l1
        mov o0.xyzw <v4:f32>, v0.xyzw <v4:f32>
        mov o1.x <v4:f32>, v0.x <v4:f32>
        mov o2.y <v4:f32>, v0.y <v4:f32> // Note the .y write mask.
        ret

This only really matters for cases where we have a system value semantic
whose mask doesn't start at .x, which is very rare. For instance, it
requires the clip/cull distance combo, which share registers, so one of
them pushes the other to start on another component.

According to the tests, the only thing relying on this behaviour is the
handling of private variables for system value semantics on the SPIR-V
backend, which expects destination write masks as if the element started
at .x even though it might not. This is modified then.
2025-10-29 13:14:54 +01:00

783 lines
20 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 input
{
float4 position : POSITION;
};
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
[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 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)
% 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)