tests: Test mismatching RTV and pixel shader output types.

This commit is contained in:
Giovanni Mascellani 2024-10-22 12:53:19 +02:00 committed by Henri Verbeet
parent 7fbed358c9
commit 8d8e0fd55a
Notes: Henri Verbeet 2024-10-22 20:55:14 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1203
5 changed files with 232 additions and 9 deletions

View File

@ -206,6 +206,7 @@ vkd3d_shader_tests = \
tests/hlsl/return-implicit-conversion.shader_test \ tests/hlsl/return-implicit-conversion.shader_test \
tests/hlsl/return.shader_test \ tests/hlsl/return.shader_test \
tests/hlsl/round.shader_test \ tests/hlsl/round.shader_test \
tests/hlsl/rt-format-mismatch.shader_test \
tests/hlsl/rt-get-sample-info.shader_test \ tests/hlsl/rt-get-sample-info.shader_test \
tests/hlsl/sample-bias.shader_test \ tests/hlsl/sample-bias.shader_test \
tests/hlsl/sample-cmp.shader_test \ tests/hlsl/sample-cmp.shader_test \

View File

@ -716,7 +716,7 @@ static inline void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *t
struct d3d12_resource_readback rb; struct d3d12_resource_readback rb;
get_resource_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); get_resource_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_vec4_(line, &rb.rb, NULL, expected, max_diff); check_readback_data_vec_(line, &rb.rb, NULL, expected, max_diff, 4);
release_resource_readback(&rb); release_resource_readback(&rb);
} }

View File

@ -0,0 +1,199 @@
[require]
shader model >= 4.0
% Let's try to mismatch the shader target output with the RTV type in various
% ways. All of them appears to be valid: the bits are copied as-is, without
% being interpreted. Excessive bits are discarded, missing bits are left
% undefined. The warnings emitted by the native validator suggest that it is
% not an error to rely on these behaviours.
[rtv 0]
% The default, but just to be explicit.
format r32g32b32a32-float
size (2d, 640, 480)
[pixel shader]
float4 main() : sv_target
{
return float4(22.0, -22.0, 1.0e100, -1.0e100);
}
[test]
draw quad
probe (0, 0) rgba (22.0, -22.0, 1.0e100, -1.0e100)
[pixel shader]
uint4 main() : sv_target
{
return uint4(0, 22, 0xfeedcafe, ~0u);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rgbaui (0, 22, 0xfeedcafe, 0xffffffff)
[pixel shader]
int4 main() : sv_target
{
return int4(0, 22, -22, -1000);
}
[test]
todo(mvk & vulkan | glsl) draw quad
todo(mvk) probe (0, 0) rgbai (0, 22, -22, -1000)
[pixel shader]
float2 main() : sv_target
{
return float2(22.0, -22.0);
}
[test]
draw quad
probe (0, 0) rg (22.0, -22.0)
[rtv 0]
format r32g32b32a32-uint
size (2d, 640, 480)
[pixel shader]
float4 main() : sv_target
{
return float4(22.0, -22.0, 1.0e100, -1.0e100);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rgba (22.0, -22.0, 1.0e100, -1.0e100)
[pixel shader]
uint4 main() : sv_target
{
return uint4(0, 22, 0xfeedcafe, ~0u);
}
[test]
draw quad
probe (0, 0) rgbaui (0, 22, 0xfeedcafe, 0xffffffff)
[pixel shader]
int4 main() : sv_target
{
return int4(0, 22, -22, -1000);
}
[test]
todo(mvk & vulkan | glsl) draw quad
todo(mvk) probe (0, 0) rgbai (0, 22, -22, -1000)
[pixel shader]
float2 main() : sv_target
{
return float2(22.0, -22.0);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rg (22.0, -22.0)
[rtv 0]
format r32g32b32a32-sint
size (2d, 640, 480)
[pixel shader]
float4 main() : sv_target
{
return float4(22.0, -22.0, 1.0e100, -1.0e100);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rgba (22.0, -22.0, 1.0e100, -1.0e100)
[pixel shader]
uint4 main() : sv_target
{
return uint4(0, 22, 0xfeedcafe, ~0u);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rgbaui (0, 22, 0xfeedcafe, 0xffffffff)
[pixel shader]
int4 main() : sv_target
{
return int4(0, 22, -22, -1000);
}
[test]
todo(glsl) draw quad
probe (0, 0) rgbai (0, 22, -22, -1000)
[pixel shader]
float2 main() : sv_target
{
return float2(22.0, -22.0);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) rg (22.0, -22.0)
[rtv 0]
format r32-uint
size (2d, 640, 480)
[pixel shader]
float4 main() : sv_target
{
return float4(22.0, -22.0, 1.0e100, -1.0e100);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) r (22.0)
[pixel shader]
uint4 main() : sv_target
{
return uint4(22, 0, 0xfeedcafe, ~0u);
}
[test]
draw quad
probe (0, 0) rui (22)
[pixel shader]
int4 main() : sv_target
{
return int4(-22, 22, 0, -1000);
}
[test]
todo(mvk & vulkan | glsl) draw quad
todo(mvk) probe (0, 0) ri (-22)
[pixel shader]
float2 main() : sv_target
{
return float2(22.0, -22.0);
}
[test]
todo(mvk & vulkan) draw quad
todo(mvk) probe (0, 0) r (22.0)
% For the avoidance of doubt, 64 bit types cannot be used as target outputs.
[pixel shader fail]
double2 main() : sv_target
{
return 0;
}
[pixel shader fail]
uint64_t2 main() : sv_target
{
return 0;
}

View File

@ -1138,6 +1138,17 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
ulps = 0; ulps = 0;
todo_if(runner->is_todo) check_readback_data_vec4(rb, &rect, &v, ulps); todo_if(runner->is_todo) check_readback_data_vec4(rb, &rect, &v, ulps);
} }
else if (match_string(line, "rg", &line))
{
struct vec4 v;
ret = sscanf(line, "( %f , %f ) %u", &v.x, &v.y, &ulps);
if (ret < 2)
fatal_error("Malformed probe arguments '%s'.\n", line);
if (ret < 3)
ulps = 0;
todo_if(runner->is_todo) check_readback_data_vec2(rb, &rect, &v, ulps);
}
else if (match_string(line, "rui", &line) || (is_signed = match_string(line, "ri", &line))) else if (match_string(line, "rui", &line) || (is_signed = match_string(line, "ri", &line)))
{ {
unsigned int expect; unsigned int expect;

View File

@ -203,12 +203,23 @@ static inline bool compare_uvec4(const struct uvec4 *v1, const struct uvec4 *v2)
return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w;
} }
static inline bool compare_vec(const struct vec4 *v1, const struct vec4 *v2,
unsigned int ulps, unsigned component_count)
{
if (component_count > 0 && !compare_float(v1->x, v2->x, ulps))
return false;
if (component_count > 1 && !compare_float(v1->y, v2->y, ulps))
return false;
if (component_count > 2 && !compare_float(v1->z, v2->z, ulps))
return false;
if (component_count > 3 && !compare_float(v1->w, v2->w, ulps))
return false;
return true;
}
static inline bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps) static inline bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps)
{ {
return compare_float(v1->x, v2->x, ulps) return compare_vec(v1, v2, ulps, 4);
&& compare_float(v1->y, v2->y, ulps)
&& compare_float(v1->z, v2->z, ulps)
&& compare_float(v1->w, v2->w, ulps);
} }
static inline void set_rect(RECT *rect, int left, int top, int right, int bottom) static inline void set_rect(RECT *rect, int left, int top, int right, int bottom)
@ -377,9 +388,10 @@ static inline void check_readback_data_uint64_(unsigned int line, struct resourc
ok_(line)(all_match, "Got 0x%016"PRIx64", expected 0x%016"PRIx64" at (%u, %u).\n", got, expected, x, y); ok_(line)(all_match, "Got 0x%016"PRIx64", expected 0x%016"PRIx64" at (%u, %u).\n", got, expected, x, y);
} }
#define check_readback_data_vec4(a, b, c, d) check_readback_data_vec4_(__LINE__, a, b, c, d) #define check_readback_data_vec2(a, b, c, d) check_readback_data_vec_(__LINE__, a, b, c, d, 2)
static inline void check_readback_data_vec4_(unsigned int line, const struct resource_readback *rb, #define check_readback_data_vec4(a, b, c, d) check_readback_data_vec_(__LINE__, a, b, c, d, 4)
const RECT *rect, const struct vec4 *expected, unsigned int max_diff) static inline void check_readback_data_vec_(unsigned int line, const struct resource_readback *rb,
const RECT *rect, const struct vec4 *expected, unsigned int max_diff, unsigned component_count)
{ {
RECT r = {0, 0, rb->width, rb->height}; RECT r = {0, 0, rb->width, rb->height};
unsigned int x = 0, y = 0; unsigned int x = 0, y = 0;
@ -394,7 +406,7 @@ static inline void check_readback_data_vec4_(unsigned int line, const struct res
for (x = r.left; x < r.right; ++x) for (x = r.left; x < r.right; ++x)
{ {
got = *get_readback_vec4(rb, x, y); got = *get_readback_vec4(rb, x, y);
if (!compare_vec4(&got, expected, max_diff)) if (!compare_vec(&got, expected, max_diff, component_count))
{ {
all_match = false; all_match = false;
break; break;