tests: Test alpha test.

This commit is contained in:
Elizabeth Figura 2024-05-17 19:53:12 -05:00 committed by Henri Verbeet
parent 7e868f1f4b
commit 5a53b73995
Notes: Henri Verbeet 2024-07-11 17:16:48 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/870
6 changed files with 129 additions and 9 deletions

View File

@ -48,6 +48,7 @@ vkd3d_cross_tests = \
vkd3d_shader_tests = \ vkd3d_shader_tests = \
tests/hlsl/abs.shader_test \ tests/hlsl/abs.shader_test \
tests/hlsl/all.shader_test \ tests/hlsl/all.shader_test \
tests/hlsl/alpha-test.shader_test \
tests/hlsl/angle-unit.shader_test \ tests/hlsl/angle-unit.shader_test \
tests/hlsl/annotations.shader_test \ tests/hlsl/annotations.shader_test \
tests/hlsl/any.shader_test \ tests/hlsl/any.shader_test \

View File

@ -0,0 +1,78 @@
% Testing equality comparison is a bit tricky here. The alpha test ref is
% fed through a UNORM in d3d, so we can only pass a value that's a multiple of
% 1/255 from 0 to 1. While we can quantize to an integer from 0-255, dividing
% back down by 255 yields slightly inconsistent results. Fortunately, testing
% 1.0 works and is a lot more reliable.
[require]
shader model < 4.0
[vertex shader]
void main(inout float4 pos : position, out float alpha : texcoord)
{
alpha = pos.x;
}
[pixel shader]
float4 main(float alpha : texcoord) : sv_target
{
return float4(0, 1, 0, floor((alpha + 1) * 2 + 0.5) / 2);
}
[test]
alpha test always
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (0, 1, 0, 0.5)
probe (320, 0) rgba (0, 1, 0, 1.0)
probe (480, 0) rgba (0, 1, 0, 1.5)
alpha test equal 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (1, 0, 0, 1)
probe (320, 0) rgba (0, 1, 0, 1.0)
probe (480, 0) rgba (1, 0, 0, 1)
alpha test not equal 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (0, 1, 0, 0.5)
probe (320, 0) rgba (1, 0, 0, 1)
probe (480, 0) rgba (0, 1, 0, 1.5)
alpha test greater 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (1, 0, 0, 1)
probe (320, 0) rgba (1, 0, 0, 1)
probe (480, 0) rgba (0, 1, 0, 1.5)
alpha test greater equal 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (1, 0, 0, 1)
probe (320, 0) rgba (0, 1, 0, 1.0)
probe (480, 0) rgba (0, 1, 0, 1.5)
alpha test less equal 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (0, 1, 0, 0.5)
probe (320, 0) rgba (0, 1, 0, 1.0)
probe (480, 0) rgba (1, 0, 0, 1)
alpha test less 1.0
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (0, 1, 0, 0.5)
probe (320, 0) rgba (1, 0, 0, 1)
probe (480, 0) rgba (1, 0, 0, 1)
alpha test never
clear rtv 0 1 0 0 1
draw quad
probe (160, 0) rgba (1, 0, 0, 1)
probe (320, 0) rgba (1, 0, 0, 1)
probe (480, 0) rgba (1, 0, 0, 1)

View File

@ -394,7 +394,7 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t
fatal_error("Unknown format '%s'.\n", line); fatal_error("Unknown format '%s'.\n", line);
} }
static D3D12_COMPARISON_FUNC parse_comparison_func(const char *line) static D3D12_COMPARISON_FUNC parse_comparison_func(const char *line, const char **rest)
{ {
static const struct static const struct
{ {
@ -416,7 +416,7 @@ static D3D12_COMPARISON_FUNC parse_comparison_func(const char *line)
for (i = 0; i < ARRAY_SIZE(funcs); ++i) for (i = 0; i < ARRAY_SIZE(funcs); ++i)
{ {
if (match_string(line, funcs[i].string, &line)) if (match_string(line, funcs[i].string, rest))
return funcs[i].func; return funcs[i].func;
} }
@ -483,7 +483,7 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line)
else if (match_string(line, "comparison", &line)) else if (match_string(line, "comparison", &line))
{ {
sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT; sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT;
sampler->func = parse_comparison_func(line); sampler->func = parse_comparison_func(line, &line);
return; return;
} }
else else
@ -868,6 +868,8 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
if (sscanf(line, "%u %f %f %f %f", &slot, &v.x, &v.y, &v.z, &v.w) < 5) if (sscanf(line, "%u %f %f %f %f", &slot, &v.x, &v.y, &v.z, &v.w) < 5)
fatal_error("Malformed rtv clear arguments '%s'.\n", line); fatal_error("Malformed rtv clear arguments '%s'.\n", line);
set_default_target(runner);
if (!(resource = shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, slot))) if (!(resource = shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, slot)))
fatal_error("Resource not found.\n"); fatal_error("Resource not found.\n");
runner->ops->clear(runner, resource, &v); runner->ops->clear(runner, resource, &v);
@ -886,7 +888,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
} }
else if (match_string(line, "depth", &line)) else if (match_string(line, "depth", &line))
{ {
runner->depth_func = parse_comparison_func(line); runner->depth_func = parse_comparison_func(line, &line);
} }
else if (match_string(line, "draw quad", &line)) else if (match_string(line, "draw quad", &line))
{ {
@ -1247,6 +1249,12 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
read_uint(&line, &sample_mask, false); read_uint(&line, &sample_mask, false);
runner->sample_mask = sample_mask; runner->sample_mask = sample_mask;
} }
else if (match_string(line, "alpha test", &line))
{
runner->alpha_test_func = (enum vkd3d_shader_comparison_func)parse_comparison_func(line, &line);
runner->alpha_test_ref = strtof(line, &rest);
line = rest;
}
else else
{ {
fatal_error("Unknown test directive '%s'.\n", line); fatal_error("Unknown test directive '%s'.\n", line);
@ -1636,6 +1644,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
runner->caps = caps; runner->caps = caps;
runner->minimum_shader_model = caps->minimum_shader_model; runner->minimum_shader_model = caps->minimum_shader_model;
runner->maximum_shader_model = caps->maximum_shader_model; runner->maximum_shader_model = caps->maximum_shader_model;
runner->alpha_test_func = VKD3D_SHADER_COMPARISON_FUNC_ALWAYS;
runner->sample_mask = ~0u; runner->sample_mask = ~0u;

View File

@ -197,6 +197,9 @@ struct shader_runner
unsigned int compile_options; unsigned int compile_options;
D3D12_COMPARISON_FUNC depth_func; D3D12_COMPARISON_FUNC depth_func;
enum vkd3d_shader_comparison_func alpha_test_func;
float alpha_test_ref;
}; };
struct shader_runner_ops struct shader_runner_ops

View File

@ -326,7 +326,15 @@ static bool d3d9_runner_dispatch(struct shader_runner *r, unsigned int x, unsign
static void d3d9_runner_clear(struct shader_runner *r, struct resource *resource, const struct vec4 *clear_value) static void d3d9_runner_clear(struct shader_runner *r, struct resource *resource, const struct vec4 *clear_value)
{ {
fatal_error("Clears are not implemented.\n"); struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
unsigned int colour;
HRESULT hr;
colour = vkd3d_make_u32(vkd3d_make_u16(clear_value->z * 255.0, clear_value->y * 255.0),
vkd3d_make_u16(clear_value->x * 255.0, clear_value->w * 255.0));
hr = IDirect3DDevice9_ColorFill(runner->device, d3d9_resource(resource)->surface, NULL, colour);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
} }
static bool d3d9_runner_draw(struct shader_runner *r, static bool d3d9_runner_draw(struct shader_runner *r,
@ -448,6 +456,15 @@ static bool d3d9_runner_draw(struct shader_runner *r,
ok(hr == D3D_OK, "Failed to set sampler state, hr %#lx.\n", hr); ok(hr == D3D_OK, "Failed to set sampler state, hr %#lx.\n", hr);
} }
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
/* The members of enum vkd3d_shader_parameter_alpha_test_func are
* compatible with D3DCMPFUNC. */
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, runner->r.alpha_test_func);
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, runner->r.alpha_test_ref * 255.0);
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration); hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
ok(hr == D3D_OK, "Failed to create vertex declaration, hr %#lx.\n", hr); ok(hr == D3D_OK, "Failed to create vertex declaration, hr %#lx.\n", hr);
hr = IDirect3DDevice9_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), &vs); hr = IDirect3DDevice9_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), &vs);

View File

@ -443,6 +443,7 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour
{ {
struct vkd3d_shader_spirv_target_info spirv_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO}; struct vkd3d_shader_spirv_target_info spirv_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO};
struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO}; struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO};
struct vkd3d_shader_parameter_info parameter_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO};
struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO}; struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO};
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS]; struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS];
@ -450,7 +451,7 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour
enum vkd3d_shader_spirv_extension spirv_extensions[2]; enum vkd3d_shader_spirv_extension spirv_extensions[2];
struct vkd3d_shader_resource_binding *binding; struct vkd3d_shader_resource_binding *binding;
struct vkd3d_shader_compile_option options[3]; struct vkd3d_shader_compile_option options[3];
struct vkd3d_shader_parameter parameters[1]; struct vkd3d_shader_parameter1 parameters[3];
struct vkd3d_shader_compile_option *option; struct vkd3d_shader_compile_option *option;
unsigned int i, compile_options; unsigned int i, compile_options;
char profile[7]; char profile[7];
@ -594,6 +595,7 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour
binding->binding.count = 1; binding->binding.count = 1;
} }
interface_info.next = &parameter_info;
interface_info.bindings = bindings; interface_info.bindings = bindings;
interface_info.push_constant_buffer_count = 1; interface_info.push_constant_buffer_count = 1;
@ -604,12 +606,22 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour
parameters[0].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32; parameters[0].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
parameters[0].u.immediate_constant.u.u32 = runner->r.sample_count; parameters[0].u.immediate_constant.u.u32 = runner->r.sample_count;
spirv_info.parameter_count = ARRAY_SIZE(parameters); parameters[1].name = VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC;
spirv_info.parameters = parameters; parameters[1].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
parameters[1].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
parameters[1].u.immediate_constant.u.u32 = runner->r.alpha_test_func;
parameters[2].name = VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF;
parameters[2].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
parameters[2].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32;
parameters[2].u.immediate_constant.u.f32 = runner->r.alpha_test_ref;
parameter_info.parameter_count = ARRAY_SIZE(parameters);
parameter_info.parameters = parameters;
if (!strcmp(type, "vs")) if (!strcmp(type, "vs"))
{ {
interface_info.next = &runner->vs_signatures; parameter_info.next = &runner->vs_signatures;
runner->vs_signatures.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; runner->vs_signatures.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO;
runner->vs_signatures.next = NULL; runner->vs_signatures.next = NULL;