diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index d09967a0..86b5ab75 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -1128,6 +1128,7 @@ struct test_context ID3D12CommandQueue *queue; ID3D12CommandAllocator *allocator; ID3D12GraphicsCommandList *list; + ID3D12GraphicsCommandList1 *list1; ID3D12PipelineState **pso; size_t pso_count, pso_capacity; @@ -1249,6 +1250,10 @@ static inline bool init_test_context_(unsigned int line, struct test_context *co context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list); ok_(line)(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr); + if (FAILED(hr = ID3D12GraphicsCommandList_QueryInterface(context->list, + &IID_ID3D12GraphicsCommandList1, (void**)&context->list1))) + context->list1 = NULL; + if (desc && desc->no_render_target) return true; @@ -1340,6 +1345,8 @@ static inline void destroy_test_context_(unsigned int line, struct test_context ID3D12CommandAllocator_Release(context->allocator); ID3D12CommandQueue_Release(context->queue); + if (context->list1) + ID3D12GraphicsCommandList1_Release(context->list1); ID3D12GraphicsCommandList_Release(context->list); destroy_pipeline_state_objects(context); free(context->pso); diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 60d7f8ce..464487a8 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -402,6 +402,10 @@ static void parse_require_directive(struct shader_runner *runner, const char *li { runner->require_wave_ops = true; } + else if (match_string(line, "depth-bounds", &line)) + { + runner->require_depth_bounds = true; + } else { fatal_error("Unknown require directive '%s'.\n", line); @@ -906,6 +910,14 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Resource not found.\n"); runner->ops->clear(runner, resource, &v); } + else if (match_string(line, "depth-bounds", &line)) + { + if (sscanf(line, "%f %f", &runner->depth_min, &runner->depth_max) != 2) + fatal_error("Malformed depth-bounds arguments '%s'.\n", line); + if (!runner->caps->depth_bounds) + fatal_error("depth-bounds set but runner does not support depth bounds testing."); + runner->depth_bounds = true; + } else if (match_string(line, "depth", &line)) { runner->depth_func = parse_comparison_func(line, &line); @@ -1595,6 +1607,8 @@ static bool check_capabilities(const struct shader_runner *runner, const struct return false; if (runner->require_wave_ops && !caps->wave_ops) return false; + if (runner->require_depth_bounds && !caps->depth_bounds) + return false; for (i = 0; i < ARRAY_SIZE(runner->require_format_caps); ++i) { @@ -1612,7 +1626,7 @@ static void trace_tags(const struct shader_runner_caps *caps) p = tags; rem = ARRAY_SIZE(tags); - rc = snprintf(p, rem, " tags:"); + rc = snprintf(p, rem, " tags:"); p += rc; rem -= rc; @@ -1626,7 +1640,7 @@ static void trace_tags(const struct shader_runner_caps *caps) p = tags; rem = ARRAY_SIZE(tags); - rc = snprintf(p, rem, " "); + rc = snprintf(p, rem, " "); --i; } p += rc; @@ -1644,7 +1658,7 @@ static void trace_format_cap(const struct shader_runner_caps *caps, enum format_ p = buffer; rem = ARRAY_SIZE(buffer); - rc = snprintf(p, rem, "%10s:", cap_name); + rc = snprintf(p, rem, "%14s:", cap_name); p += rc; rem -= rc; @@ -1660,7 +1674,7 @@ static void trace_format_cap(const struct shader_runner_caps *caps, enum format_ p = buffer; rem = ARRAY_SIZE(buffer); - rc = snprintf(p, rem, " "); + rc = snprintf(p, rem, " "); --i; } p += rc; @@ -1706,10 +1720,11 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c dxc_compiler ? "dxcompiler" : HLSL_COMPILER, caps->runner); if (caps->tag_count) trace_tags(caps); - trace(" float64: %u.\n", caps->float64); - trace(" int64: %u.\n", caps->int64); - trace(" rov: %u.\n", caps->rov); - trace(" wave_ops: %u.\n", caps->wave_ops); + trace(" float64: %u.\n", caps->float64); + trace(" int64: %u.\n", caps->int64); + trace(" rov: %u.\n", caps->rov); + trace(" wave-ops: %u.\n", caps->wave_ops); + trace(" depth-bounds: %u.\n", caps->depth_bounds); trace_format_cap(caps, FORMAT_CAP_UAV_LOAD, "uav-load"); if (!test_options.filename) @@ -1726,6 +1741,9 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c runner->alpha_test_func = VKD3D_SHADER_COMPARISON_FUNC_ALWAYS; runner->sample_mask = ~0u; + runner->depth_bounds = false; + runner->depth_min = 0.0f; + runner->depth_max = 1.0f; if ((testname = strrchr(test_options.filename, '/'))) ++testname; @@ -1969,6 +1987,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c runner->require_int64 = false; runner->require_rov = false; runner->require_wave_ops = false; + runner->require_depth_bounds = false; memset(runner->require_format_caps, 0, sizeof(runner->require_format_caps)); runner->compile_options = 0; test_action = TEST_ACTION_RUN; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index c4051bee..78d72ebe 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -146,6 +146,7 @@ struct shader_runner_caps bool int64; bool rov; bool wave_ops; + bool depth_bounds; uint32_t format_caps[DXGI_FORMAT_COUNT]; }; @@ -182,6 +183,7 @@ struct shader_runner bool require_int64; bool require_rov; bool require_wave_ops; + bool require_depth_bounds; uint32_t require_format_caps[DXGI_FORMAT_COUNT]; bool last_render_failed; @@ -207,6 +209,8 @@ struct shader_runner unsigned int compile_options; D3D12_COMPARISON_FUNC depth_func; + bool depth_bounds; + float depth_min, depth_max; enum vkd3d_shader_comparison_func alpha_test_func; float alpha_test_ref; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index a5598dfb..2159c678 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -751,6 +751,7 @@ static ID3D12PipelineState *create_pipeline_device2(struct d3d12_shader_runner * pipeline.dsv.depth_stencil_desc.DepthEnable = true; pipeline.dsv.depth_stencil_desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; pipeline.dsv.depth_stencil_desc.DepthFunc = runner->r.depth_func; + pipeline.dsv.depth_stencil_desc.DepthBoundsTestEnable = runner->r.depth_bounds; } } @@ -777,6 +778,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D10Blob *vs_code, *ps_code, *hs_code = NULL, *ds_code = NULL, *gs_code = NULL; D3D12_CPU_DESCRIPTOR_HANDLE rtvs[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D12GraphicsCommandList1 *command_list1 = test_context->list1; ID3D12GraphicsCommandList *command_list = test_context->list; ID3D12CommandQueue *queue = test_context->queue; ID3D12Device *device = test_context->device; @@ -894,6 +896,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, rtv_count, rtvs, false, dsv.ptr ? &dsv : NULL); + if (runner->r.depth_bounds) + ID3D12GraphicsCommandList1_OMSetDepthBounds(command_list1, runner->r.depth_min, runner->r.depth_max); ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect); ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, primitive_topology); @@ -971,6 +975,7 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, enum shader_model minimum_shader_model, enum shader_model maximum_shader_model) { ID3D12Device *device = runner->test_context.device; + D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2; D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; D3D12_FEATURE_DATA_D3D12_OPTIONS options; HRESULT hr; @@ -1001,6 +1006,8 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr); 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); + hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS2, &options2, sizeof(options2)); + ok(hr == S_OK, "Failed to check feature options2 support, hr %#x.\n", hr); #ifdef VKD3D_CROSSTEST runner->caps.runner = "d3d12.dll"; @@ -1013,6 +1020,7 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner, runner->caps.int64 = options1.Int64ShaderOps; runner->caps.rov = options.ROVsSupported; runner->caps.wave_ops = options1.WaveOps; + runner->caps.depth_bounds = options2.DepthBoundsTestSupported; for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i) { diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index de778ecf..0972e806 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -32,6 +32,7 @@ #include "shader_runner.h" #include "vkd3d_d3dcompiler.h" +static PFNGLDEPTHBOUNDSEXTPROC p_glDepthBoundsEXT; static PFNGLSPECIALIZESHADERPROC p_glSpecializeShader; enum shading_language @@ -133,6 +134,8 @@ static bool check_gl_extensions(struct gl_runner *runner) runner->caps.float64 = true; if (check_gl_extension("GL_ARB_gpu_shader_int64", count)) runner->caps.int64 = true; + if (check_gl_extension("GL_EXT_depth_bounds_test", count)) + runner->caps.depth_bounds = true; return true; } @@ -350,6 +353,7 @@ static bool gl_runner_init(struct gl_runner *runner, enum shading_language langu trace(" GL_VERSION: %s\n", glGetString(GL_VERSION)); trace("GL_SHADING_LANGUAGE_VERSION: %s\n", glsl_version); + p_glDepthBoundsEXT = (void *)eglGetProcAddress("glDepthBoundsEXT"); p_glSpecializeShader = (void *)eglGetProcAddress("glSpecializeShader"); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE); @@ -1143,6 +1147,11 @@ static bool gl_runner_draw(struct shader_runner *r, glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthFunc(get_compare_op_gl(runner->r.depth_func)); + if (runner->r.depth_bounds) + { + glEnable(GL_DEPTH_BOUNDS_TEST_EXT); + p_glDepthBoundsEXT(runner->r.depth_min, runner->r.depth_max); + } break; case RESOURCE_TYPE_TEXTURE: diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 95e27186..36773dcc 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -836,10 +836,10 @@ static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, ds_desc.depthTestEnable = VK_TRUE; ds_desc.depthWriteEnable = VK_TRUE; ds_desc.depthCompareOp = vk_compare_op_from_d3d12(runner->r.depth_func); - ds_desc.depthBoundsTestEnable = VK_FALSE; + ds_desc.depthBoundsTestEnable = runner->r.depth_bounds; ds_desc.stencilTestEnable = VK_FALSE; - ds_desc.minDepthBounds = 0.0f; - ds_desc.maxDepthBounds = 1.0f; + ds_desc.minDepthBounds = runner->r.depth_min; + ds_desc.maxDepthBounds = runner->r.depth_max; pipeline_desc.pDepthStencilState = &ds_desc; break; @@ -1818,6 +1818,12 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) runner->caps.int64 = true; } + if (ret_features->depthBounds) + { + features.depthBounds = VK_TRUE; + runner->caps.depth_bounds = true; + } + if (device_info.interlock_features.fragmentShaderSampleInterlock && device_info.interlock_features.fragmentShaderPixelInterlock) {