tests/shader_runner: Pass the runner capabilities to run_shader_tests().

Allowing these to be checked by run_shader_tests() itself, instead of
reimplementing those checks in each individual runner.
This commit is contained in:
Henri Verbeet 2024-02-19 16:47:11 +01:00 committed by Alexandre Julliard
parent 7b41abaa1b
commit 930fbcbb26
Notes: Alexandre Julliard 2024-02-19 23:00:22 +01:00
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/658
7 changed files with 94 additions and 132 deletions

View File

@ -1309,8 +1309,22 @@ static enum parse_state read_shader_directive(struct shader_runner *runner, enum
return state;
}
void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler,
enum shader_model minimum_shader_model, enum shader_model maximum_shader_model)
static bool check_requirements(const struct shader_runner *runner, const struct shader_runner_caps *caps)
{
if (runner->maximum_shader_model < runner->minimum_shader_model)
return false;
if (runner->require_float64 && !caps->float64)
return false;
if (runner->require_int64 && !caps->int64)
return false;
if (runner->require_rov && !caps->rov)
return false;
return true;
}
void run_shader_tests(struct shader_runner *runner, const struct shader_runner_caps *caps,
const struct shader_runner_ops *ops, void *dxc_compiler)
{
size_t shader_source_size = 0, shader_source_len = 0;
struct resource_params current_resource;
@ -1332,8 +1346,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
memset(runner, 0, sizeof(*runner));
runner->ops = ops;
runner->minimum_shader_model = minimum_shader_model;
runner->maximum_shader_model = maximum_shader_model;
runner->minimum_shader_model = caps->minimum_shader_model;
runner->maximum_shader_model = caps->maximum_shader_model;
if ((testname = strrchr(test_options.filename, '/')))
++testname;
@ -1360,8 +1374,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
break;
case STATE_REQUIRE:
if (runner->maximum_shader_model < runner->minimum_shader_model
|| !runner->ops->check_requirements(runner))
if (!check_requirements(runner, caps))
skip_tests = true;
break;
@ -1512,8 +1525,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
else if (!strcmp(line, "[require]\n"))
{
state = STATE_REQUIRE;
runner->minimum_shader_model = minimum_shader_model;
runner->maximum_shader_model = maximum_shader_model;
runner->minimum_shader_model = caps->minimum_shader_model;
runner->maximum_shader_model = caps->maximum_shader_model;
runner->require_float64 = false;
runner->require_int64 = false;
runner->require_rov = false;

View File

@ -117,6 +117,15 @@ struct input_element
#define MAX_RESOURCES 32
#define MAX_SAMPLERS 32
struct shader_runner_caps
{
enum shader_model minimum_shader_model;
enum shader_model maximum_shader_model;
bool float64;
bool int64;
bool rov;
};
struct shader_runner
{
const struct shader_runner_ops *ops;
@ -152,9 +161,6 @@ struct shader_runner
struct shader_runner_ops
{
/* Returns false if unable to run the given tests. If NULL, all tests are
* run. */
bool (*check_requirements)(struct shader_runner *runner);
struct resource *(*create_resource)(struct shader_runner *runner, const struct resource_params *params);
void (*destroy_resource)(struct shader_runner *runner, struct resource *resource);
bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count);
@ -177,8 +183,8 @@ HRESULT dxc_compiler_compile_shader(void *dxc_compiler, enum shader_type type, u
struct sampler *shader_runner_get_sampler(struct shader_runner *runner, unsigned int slot);
struct resource *shader_runner_get_resource(struct shader_runner *runner, enum resource_type type, unsigned int slot);
void run_shader_tests(struct shader_runner *runner, const struct shader_runner_ops *ops, void *dxc_compiler,
enum shader_model minimum_shader_model, enum shader_model maximum_shader_model);
void run_shader_tests(struct shader_runner *runner, const struct shader_runner_caps *caps,
const struct shader_runner_ops *ops, void *dxc_compiler);
#ifdef _WIN32
void run_shader_tests_d3d9(void);

View File

@ -65,15 +65,13 @@ static struct d3d11_resource *d3d11_resource(struct resource *r)
struct d3d11_shader_runner
{
struct shader_runner r;
struct shader_runner_caps caps;
ID3D11Device *device;
HWND window;
IDXGISwapChain *swapchain;
ID3D11DeviceContext *immediate_context;
ID3D11RasterizerState *rasterizer_state;
bool supports_float64;
bool supports_rov;
};
static struct d3d11_shader_runner *d3d11_shader_runner(struct shader_runner *r)
@ -277,17 +275,20 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner)
return FALSE;
}
runner->caps.minimum_shader_model = SHADER_MODEL_4_0;
runner->caps.maximum_shader_model = SHADER_MODEL_5_1;
hr = ID3D11Device_CheckFeatureSupport(runner->device, D3D11_FEATURE_DOUBLES,
&doubles, sizeof(doubles));
ok(hr == S_OK, "Failed to check double precision feature support, hr %#lx.\n", hr);
trace("DoublePrecisionFloatShaderOps: %u.\n", doubles.DoublePrecisionFloatShaderOps);
runner->supports_float64 = doubles.DoublePrecisionFloatShaderOps;
runner->caps.float64 = doubles.DoublePrecisionFloatShaderOps;
hr = ID3D11Device_CheckFeatureSupport(runner->device,
D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2));
ok(hr == S_OK, "Got hr %#lx.\n", hr);
trace("ROVsSupported: %u.\n", options2.ROVsSupported);
runner->supports_rov = options2.ROVsSupported;
runner->caps.rov = options2.ROVsSupported;
rt_width = RENDER_TARGET_WIDTH;
rt_height = RENDER_TARGET_HEIGHT;
@ -336,18 +337,6 @@ static void destroy_test_context(struct d3d11_shader_runner *runner)
ok(!ref, "Device has %lu references left.\n", ref);
}
static bool d3d11_runner_check_requirements(struct shader_runner *r)
{
struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
if (runner->r.require_float64 && !runner->supports_float64)
return false;
if (runner->r.require_rov && !runner->supports_rov)
return false;
return true;
}
static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags, unsigned int size, const void *data)
{
D3D11_SUBRESOURCE_DATA resource_data;
@ -794,7 +783,6 @@ static void d3d11_runner_release_readback(struct shader_runner *r, struct resour
static const struct shader_runner_ops d3d11_runner_ops =
{
.check_requirements = d3d11_runner_check_requirements,
.create_resource = d3d11_runner_create_resource,
.destroy_resource = d3d11_runner_destroy_resource,
.dispatch = d3d11_runner_dispatch,
@ -820,7 +808,7 @@ void run_shader_tests_d3d11(void)
init_adapter_info();
if (init_test_context(&runner))
{
run_shader_tests(&runner.r, &d3d11_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1);
run_shader_tests(&runner.r, &runner.caps, &d3d11_runner_ops, NULL);
destroy_test_context(&runner);
}
}

View File

@ -50,6 +50,7 @@ static struct d3d12_resource *d3d12_resource(struct resource *r)
struct d3d12_shader_runner
{
struct shader_runner r;
struct shader_runner_caps caps;
struct test_context test_context;
@ -60,9 +61,6 @@ struct d3d12_shader_runner
ID3D12GraphicsCommandList *compute_list;
IDxcCompiler3 *dxc_compiler;
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1;
};
static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r)
@ -107,22 +105,6 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons
return blob;
}
static bool d3d12_runner_check_requirements(struct shader_runner *r)
{
struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
if (runner->r.require_float64 && !runner->options.DoublePrecisionFloatShaderOps)
return false;
if (runner->r.require_int64 && !runner->options1.Int64ShaderOps)
return false;
if (runner->r.require_rov && !runner->options.ROVsSupported)
return false;
return true;
}
#define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2)
static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params)
@ -628,7 +610,6 @@ static void d3d12_runner_release_readback(struct shader_runner *r, struct resour
static const struct shader_runner_ops d3d12_runner_ops =
{
.check_requirements = d3d12_runner_check_requirements,
.create_resource = d3d12_runner_create_resource,
.destroy_resource = d3d12_runner_destroy_resource,
.dispatch = d3d12_runner_dispatch,
@ -637,6 +618,28 @@ static const struct shader_runner_ops d3d12_runner_ops =
.release_readback = d3d12_runner_release_readback,
};
static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner)
{
ID3D12Device *device = runner->test_context.device;
D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1;
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
HRESULT hr;
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr);
trace("DoublePrecisionFloatShaderOps: %u.\n", options.DoublePrecisionFloatShaderOps);
trace("ROVsSupported: %u.\n", options.ROVsSupported);
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1));
ok(hr == S_OK, "Failed to check feature options1 support, hr %#x.\n", hr);
trace("Int64ShaderOps: %u.\n", options1.Int64ShaderOps);
runner->caps.minimum_shader_model = SHADER_MODEL_4_0;
runner->caps.maximum_shader_model = SHADER_MODEL_5_1;
runner->caps.float64 = options.DoublePrecisionFloatShaderOps;
runner->caps.int64 = options1.Int64ShaderOps;
runner->caps.rov = options.ROVsSupported;
}
void run_shader_tests_d3d12(void *dxc_compiler)
{
static const struct test_context_desc desc =
@ -654,6 +657,8 @@ void run_shader_tests_d3d12(void *dxc_compiler)
init_adapter_info();
if (!init_test_context(&runner.test_context, &desc))
return;
d3d12_runner_init_caps(&runner);
device = runner.test_context.device;
runner.dxc_compiler = dxc_compiler;
@ -669,25 +674,14 @@ void run_shader_tests_d3d12(void *dxc_compiler)
runner.compute_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&runner.compute_list);
ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS,
&runner.options, sizeof(runner.options));
ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr);
trace("DoublePrecisionFloatShaderOps: %u.\n", runner.options.DoublePrecisionFloatShaderOps);
trace("ROVsSupported: %u.\n", runner.options.ROVsSupported);
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1,
&runner.options1, sizeof(runner.options1));
ok(hr == S_OK, "Failed to check feature options1 support, hr %#x.\n", hr);
trace("Compiling SM4-SM5 shaders with %s and executing with %s\n", HLSL_COMPILER, SHADER_RUNNER);
run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, SHADER_MODEL_4_0, SHADER_MODEL_5_1);
run_shader_tests(&runner.r, &runner.caps, &d3d12_runner_ops, NULL);
if (dxc_compiler)
{
trace("Int64ShaderOps: %u.\n", runner.options1.Int64ShaderOps);
runner.caps.minimum_shader_model = SHADER_MODEL_6_0;
runner.caps.maximum_shader_model = SHADER_MODEL_6_0;
trace("Compiling SM6 shaders with dxcompiler and executing with %s\n", SHADER_RUNNER);
run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, SHADER_MODEL_6_0, SHADER_MODEL_6_0);
run_shader_tests(&runner.r, &runner.caps, &d3d12_runner_ops, dxc_compiler);
}
ID3D12GraphicsCommandList_Release(runner.compute_list);

View File

@ -50,6 +50,7 @@ static struct d3d9_resource *d3d9_resource(struct resource *r)
struct d3d9_shader_runner
{
struct shader_runner r;
struct shader_runner_caps caps;
IDirect3DDevice9 *device;
HWND window;
@ -154,6 +155,9 @@ static bool init_test_context(struct d3d9_shader_runner *runner)
return false;
}
runner->caps.minimum_shader_model = SHADER_MODEL_2_0;
runner->caps.maximum_shader_model = SHADER_MODEL_3_0;
return true;
}
@ -189,19 +193,6 @@ static D3DTEXTUREADDRESS sampler_address_to_d3d9(D3D12_TEXTURE_ADDRESS_MODE addr
vkd3d_unreachable();
}
static bool d3d9_runner_check_requirements(struct shader_runner *r)
{
struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
if (runner->r.minimum_shader_model >= SHADER_MODEL_4_0)
return false;
if (runner->r.require_rov)
return false;
return true;
}
static struct resource *d3d9_runner_create_resource(struct shader_runner *r, const struct resource_params *params)
{
struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
@ -535,7 +526,6 @@ static void d3d9_runner_release_readback(struct shader_runner *r, struct resourc
static const struct shader_runner_ops d3d9_runner_ops =
{
.check_requirements = d3d9_runner_check_requirements,
.create_resource = d3d9_runner_create_resource,
.destroy_resource = d3d9_runner_destroy_resource,
.dispatch = d3d9_runner_dispatch,
@ -551,16 +541,18 @@ void run_shader_tests_d3d9(void)
trace("Compiling SM2-SM3 shaders with %s and executing with d3d9.dll\n", HLSL_COMPILER);
d3d9_module = LoadLibraryA("d3d9.dll");
if (d3d9_module)
{
pDirect3DCreate9 = (void *)GetProcAddress(d3d9_module, "Direct3DCreate9");
if (!(d3d9_module = LoadLibraryA("d3d9.dll")))
return;
init_adapter_info();
init_test_context(&runner);
run_shader_tests(&runner.r, &d3d9_runner_ops, NULL, SHADER_MODEL_2_0, SHADER_MODEL_3_0);
pDirect3DCreate9 = (void *)GetProcAddress(d3d9_module, "Direct3DCreate9");
init_adapter_info();
if (init_test_context(&runner))
{
run_shader_tests(&runner.r, &runner.caps, &d3d9_runner_ops, NULL);
destroy_test_context(&runner);
}
FreeLibrary(d3d9_module);
}

View File

@ -58,12 +58,7 @@ static struct gl_resource *gl_resource(struct resource *r)
struct gl_runner
{
struct shader_runner r;
struct
{
bool float64;
bool int64;
} caps;
struct shader_runner_caps caps;
EGLDisplay display;
EGLContext context;
@ -230,6 +225,8 @@ static bool gl_runner_init(struct gl_runner *runner)
eglTerminate(display);
continue;
}
runner->caps.minimum_shader_model = SHADER_MODEL_4_0;
runner->caps.maximum_shader_model = SHADER_MODEL_5_1;
trace("Using device %u.\n", i);
runner->display = display;
@ -289,20 +286,6 @@ static void gl_runner_cleanup(struct gl_runner *runner)
ok(ret, "Failed to terminate EGL display connection.\n");
}
static bool gl_runner_check_requirements(struct shader_runner *r)
{
struct gl_runner *runner = gl_runner(r);
if (r->require_float64 && !runner->caps.float64)
return false;
if (r->require_int64 && !runner->caps.int64)
return false;
if (r->require_rov)
return false;
return true;
}
static const struct format_info *get_format_info(enum DXGI_FORMAT format)
{
size_t i;
@ -1033,7 +1016,6 @@ static void gl_runner_release_readback(struct shader_runner *runner, struct reso
static const struct shader_runner_ops gl_runner_ops =
{
.check_requirements = gl_runner_check_requirements,
.create_resource = gl_runner_create_resource,
.destroy_resource = gl_runner_destroy_resource,
.dispatch = gl_runner_dispatch,
@ -1053,7 +1035,7 @@ void run_shader_tests_gl(void)
goto done;
trace("Compiling SM4-SM5 shaders with vkd3d-shader and executing with OpenGL\n");
run_shader_tests(&runner.r, &gl_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1);
run_shader_tests(&runner.r, &runner.caps, &gl_runner_ops, NULL);
gl_runner_cleanup(&runner);
done:
vkd3d_test_name = test_name;

View File

@ -55,6 +55,7 @@ DECLARE_VK_PFN(vkGetInstanceProcAddr)
struct vulkan_shader_runner
{
struct shader_runner r;
struct shader_runner_caps caps;
VkInstance instance;
VkPhysicalDevice phys_device;
@ -72,9 +73,6 @@ struct vulkan_shader_runner
uint32_t binding;
} samplers[MAX_SAMPLERS];
bool supports_float64;
bool supports_int64;
DECLARE_VK_PFN(vkCreateInstance);
#define VK_INSTANCE_PFN DECLARE_VK_PFN
#define VK_DEVICE_PFN DECLARE_VK_PFN
@ -86,20 +84,6 @@ static struct vulkan_shader_runner *vulkan_shader_runner(struct shader_runner *r
return CONTAINING_RECORD(r, struct vulkan_shader_runner, r);
}
static bool vulkan_runner_check_requirements(struct shader_runner *r)
{
struct vulkan_shader_runner *runner = vulkan_shader_runner(r);
if (runner->r.require_float64 && !runner->supports_float64)
return false;
if (runner->r.require_int64 && !runner->supports_int64)
return false;
if (runner->r.require_rov)
return false;
return true;
}
#define VK_CALL(f) (runner->f)
static void begin_command_buffer(struct vulkan_shader_runner *runner)
@ -1225,7 +1209,6 @@ static void vulkan_runner_release_readback(struct shader_runner *r, struct resou
static const struct shader_runner_ops vulkan_runner_ops =
{
.check_requirements = vulkan_runner_check_requirements,
.create_resource = vulkan_runner_create_resource,
.destroy_resource = vulkan_runner_destroy_resource,
.dispatch = vulkan_runner_dispatch,
@ -1396,13 +1379,13 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
if (ret_features.shaderFloat64)
{
features.shaderFloat64 = VK_TRUE;
runner->supports_float64 = true;
runner->caps.float64 = true;
}
trace("shaderInt64: %u.\n", ret_features.shaderInt64);
if (ret_features.shaderInt64)
{
features.shaderInt64 = VK_TRUE;
runner->supports_int64 = true;
runner->caps.int64 = true;
}
if ((vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device))))
@ -1470,11 +1453,15 @@ void run_shader_tests_vulkan(void)
if (!init_vulkan_runner(&runner))
return;
runner.caps.minimum_shader_model = SHADER_MODEL_2_0;
runner.caps.maximum_shader_model = SHADER_MODEL_3_0;
trace("Compiling SM2-SM3 shaders with vkd3d-shader and executing with Vulkan\n");
run_shader_tests(&runner.r, &vulkan_runner_ops, NULL, SHADER_MODEL_2_0, SHADER_MODEL_3_0);
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
runner.caps.minimum_shader_model = SHADER_MODEL_4_0;
runner.caps.maximum_shader_model = SHADER_MODEL_5_1;
trace("Compiling SM4-SM5 shaders with vkd3d-shader and executing with Vulkan\n");
run_shader_tests(&runner.r, &vulkan_runner_ops, NULL, SHADER_MODEL_4_0, SHADER_MODEL_5_1);
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
cleanup_vulkan_runner(&runner);
}