Includes !782 to prevent the 32-bit Windows CI crashing.
-- v9: vkd3d-shader/dxil: Support SV_Depth, SV_DepthGreaterEqual and SV_DepthLessEqual. tests/hlsl: Add pixel shader depth-out tests.
From: Conor McCarthy cmccarthy@codeweavers.com
Fixes invalid read in the GL runner. --- tests/hlsl/calculate-lod.shader_test | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/tests/hlsl/calculate-lod.shader_test b/tests/hlsl/calculate-lod.shader_test index 88325af61..74533cfeb 100644 --- a/tests/hlsl/calculate-lod.shader_test +++ b/tests/hlsl/calculate-lod.shader_test @@ -15,6 +15,10 @@ levels 3 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 +0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 + +0.5 0.5 0.5 0.5
[pixel shader todo] sampler s;
From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/d3d12_test_utils.h | 6 + tests/hlsl/depth-out.shader_test | 102 +++++++++++++++++ tests/shader_runner.c | 110 ++++++++++++------ tests/shader_runner.h | 6 + tests/shader_runner_d3d11.c | 30 ++++- tests/shader_runner_d3d12.c | 38 ++++++- tests/shader_runner_d3d9.c | 7 ++ tests/shader_runner_gl.c | 26 ++++- tests/shader_runner_vulkan.c | 185 +++++++++++++++++++++---------- 10 files changed, 420 insertions(+), 91 deletions(-) create mode 100644 tests/hlsl/depth-out.shader_test
diff --git a/Makefile.am b/Makefile.am index f823cbc85..ccc4af392 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,6 +87,7 @@ vkd3d_shader_tests = \ tests/hlsl/cross.shader_test \ tests/hlsl/d3dcolor-to-ubyte4.shader_test \ tests/hlsl/ddxddy.shader_test \ + tests/hlsl/depth-out.shader_test \ tests/hlsl/determinant.shader_test \ tests/hlsl/discard.shader_test \ tests/hlsl/distance.shader_test \ diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index 4fe6fa716..60512aec6 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -1245,6 +1245,12 @@ static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_rtv_handle(struct test_context return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, offset); }
+static inline D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_dsv_handle(struct test_context *context, + ID3D12DescriptorHeap *heap, unsigned int offset) +{ + return get_cpu_handle(context->device, heap, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, offset); +} + static inline D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_descriptor_handle(struct test_context *context, ID3D12DescriptorHeap *heap, unsigned int offset) { diff --git a/tests/hlsl/depth-out.shader_test b/tests/hlsl/depth-out.shader_test new file mode 100644 index 000000000..b26830fc6 --- /dev/null +++ b/tests/hlsl/depth-out.shader_test @@ -0,0 +1,102 @@ +[require] +shader model >= 4.0 + +[dsv] +size (2d, 640, 480) + +[pixel shader] +float depth; + +float main() : SV_Depth +{ + return depth; +} + +[test] +uniform 0 float 0.0 +dsv clear 1.0 +depth less +todo(sm>=6 | glsl) draw quad +probe dsv all r (0.0) + +uniform 0 float 0.75 +todo(sm>=6 | glsl) draw quad +probe dsv all r (0.75) + +dsv clear 0.5 +depth greater +todo(sm>=6 | glsl) draw quad +probe dsv all r (0.75) + +depth less +todo(sm>=6 | glsl) draw quad +probe dsv all r (0.5) + + +[require] +shader model >= 5.0 + +[rtv 0] +format r32g32b32a32 float +size (2d, 640, 480) + +[vertex shader] +float2 depth; + +void main(float4 in_position : POSITION, out float4 out_position : SV_Position) +{ + out_position = in_position; + out_position.z = depth.x; +} + +[pixel shader todo] +float2 depth; + +float4 main(out float out_depth : SV_DepthLessEqual) : SV_Target +{ + out_depth = depth.y; + return float4(0.0f, 1.0f, 0.0f, 1.0f); +} + +[test] +uniform 0 float4 0.7 0.7 0.0 0.0 +rtv clear 1.0 1.0 1.0 1.0 +dsv clear 0.5 +depth greater equal +todo draw quad +probe all rgba (0.0, 1.0, 0.0, 1.0) +probe dsv all r (0.7) + +uniform 0 float4 0.7 0.4 0.0 0.0 +todo draw quad +probe all rgba (1.0, 1.0, 1.0, 1.0) +probe dsv all r (0.5) + + +[pixel shader todo] +float2 depth; + +float4 main(out float out_depth : SV_DepthGreaterEqual) : SV_Target +{ + out_depth = depth.y; + return float4(0.0f, 1.0f, 0.0f, 1.0f); +} + +[test] +uniform 0 float4 0.7 0.7 0.0 0.0 +rtv clear 1.0 1.0 1.0 1.0 +dsv clear 0.5 +depth greater equal +todo draw quad +probe all rgba (0.0, 1.0, 0.0, 1.0) +probe dsv all r (0.7) + +uniform 0 float4 0.4 0.6 0.0 0.0 +todo draw quad +probe all rgba (0.0, 1.0, 0.0, 1.0) +probe dsv all r (0.6) + +uniform 0 float4 0.4 0.4 0.0 0.0 +todo draw quad +probe all rgba (1.0, 1.0, 1.0, 1.0) +probe dsv all r (0.5) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index f800ded32..416322389 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -381,6 +381,35 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t fatal_error("Unknown format '%s'.\n", line); }
+static D3D12_COMPARISON_FUNC parse_comparison_func(const char *line) +{ + static const struct + { + const char *string; + D3D12_COMPARISON_FUNC func; + } + funcs[] = + { + {"less equal", D3D12_COMPARISON_FUNC_LESS_EQUAL}, + {"not equal", D3D12_COMPARISON_FUNC_NOT_EQUAL}, + {"greater equal", D3D12_COMPARISON_FUNC_GREATER_EQUAL}, + {"never", D3D12_COMPARISON_FUNC_NEVER}, + {"less", D3D12_COMPARISON_FUNC_LESS}, + {"equal", D3D12_COMPARISON_FUNC_EQUAL}, + {"greater", D3D12_COMPARISON_FUNC_GREATER}, + {"always", D3D12_COMPARISON_FUNC_ALWAYS}, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(funcs); ++i) + { + if (match_string(line, funcs[i].string, &line)) + return funcs[i].func; + } + + fatal_error("Unknown comparison func '%s'.\n", line); +} + static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest) { if (match_string(line, "border", rest)) @@ -440,35 +469,9 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line) } else if (match_string(line, "comparison", &line)) { - static const struct - { - const char *string; - D3D12_COMPARISON_FUNC func; - } - funcs[] = - { - {"less equal", D3D12_COMPARISON_FUNC_LESS_EQUAL}, - {"not equal", D3D12_COMPARISON_FUNC_NOT_EQUAL}, - {"greater equal", D3D12_COMPARISON_FUNC_GREATER_EQUAL}, - {"never", D3D12_COMPARISON_FUNC_NEVER}, - {"less", D3D12_COMPARISON_FUNC_LESS}, - {"equal", D3D12_COMPARISON_FUNC_EQUAL}, - {"greater", D3D12_COMPARISON_FUNC_GREATER}, - {"always", D3D12_COMPARISON_FUNC_ALWAYS}, - }; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(funcs); ++i) - { - if (match_string(line, funcs[i].string, &line)) - { - sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT; - sampler->func = funcs[i].func; - return; - } - } - - fatal_error("Unknown sampler func '%s'.\n", line); + sampler->filter |= D3D12_FILTER_REDUCTION_TYPE_COMPARISON << D3D12_FILTER_REDUCTION_TYPE_SHIFT; + sampler->func = parse_comparison_func(line); + return; } else { @@ -618,6 +621,12 @@ struct resource *shader_runner_get_resource(struct shader_runner *runner, enum r return NULL; }
+static bool shader_runner_has_target(struct shader_runner *runner) +{ + return shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0) + || shader_runner_get_resource(runner, RESOURCE_TYPE_DEPTH_STENCIL, 0); +} + static void set_resource(struct shader_runner *runner, struct resource *resource) { size_t i; @@ -798,6 +807,27 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
runner->last_render_failed = !runner->ops->dispatch(runner, x, y, z); } + else if (match_string(line, "rtv clear", &line)) + { + struct vec4 v; + + if (sscanf(line, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w) < 4) + fatal_error("Malformed rtv clear arguments '%s'.\n", line); + memcpy(runner->rtv_clear_value, &v, sizeof(runner->rtv_clear_value)); + runner->clear_rtv = true; + } + else if (match_string(line, "dsv clear", &line)) + { + float x; + + if (!sscanf(line, "%f", &x)) + fatal_error("Malformed dsv clear arguments '%s'.\n", line); + runner->dsv_clear_value = x; + } + else if (match_string(line, "depth", &line)) + { + runner->comparison = parse_comparison_func(line); + } else if (match_string(line, "draw quad", &line)) { struct resource_params params; @@ -818,7 +848,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) " return pos;\n" "}";
- if (!shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0)) + if (!shader_runner_has_target(runner)) { memset(¶ms, 0, sizeof(params)); params.slot = 0; @@ -868,7 +898,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) struct resource_params params; unsigned int vertex_count;
- if (!shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0)) + if (!shader_runner_has_target(runner)) { memset(¶ms, 0, sizeof(params)); params.slot = 0; @@ -929,6 +959,10 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
resource = shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, slot); } + else if (match_string(line, "dsv", &line)) + { + resource = shader_runner_get_resource(runner, RESOURCE_TYPE_DEPTH_STENCIL, 0); + } else { resource = shader_runner_get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); @@ -1734,6 +1768,20 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c current_resource.texel_size = 16; current_resource.level_count = 1; } + else if (!strcmp(line, "[dsv]\n")) + { + state = STATE_RESOURCE; + + memset(¤t_resource, 0, sizeof(current_resource)); + + current_resource.slot = 0; + current_resource.type = RESOURCE_TYPE_DEPTH_STENCIL; + current_resource.format = DXGI_FORMAT_D32_FLOAT; + current_resource.is_shadow = true; + current_resource.data_type = TEXTURE_DATA_FLOAT; + current_resource.texel_size = 4; + current_resource.level_count = 1; + } else if (sscanf(line, "[srv %u]\n", &index)) { state = STATE_RESOURCE; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 2f7e8fb25..ecc59f75e 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -69,6 +69,7 @@ struct sampler enum resource_type { RESOURCE_TYPE_RENDER_TARGET, + RESOURCE_TYPE_DEPTH_STENCIL, RESOURCE_TYPE_TEXTURE, RESOURCE_TYPE_UAV, RESOURCE_TYPE_VERTEX_BUFFER, @@ -178,6 +179,11 @@ struct shader_runner size_t input_element_count, input_element_capacity;
unsigned int compile_options; + + bool clear_rtv; + float rtv_clear_value[4]; + float dsv_clear_value; + D3D12_COMPARISON_FUNC comparison; };
struct shader_runner_ops diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index b26d6a36b..f847d795b 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -47,6 +47,7 @@ struct d3d11_resource ID3D11Buffer *buffer; ID3D11Texture2D *texture; ID3D11RenderTargetView *rtv; + ID3D11DepthStencilView *dsv; ID3D11ShaderResourceView *srv; ID3D11UnorderedAccessView *uav; bool is_uav_counter; @@ -377,6 +378,8 @@ static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; else if (params->type == RESOURCE_TYPE_RENDER_TARGET) desc.BindFlags = D3D11_BIND_RENDER_TARGET; + else if (params->type == RESOURCE_TYPE_DEPTH_STENCIL) + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; else desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
@@ -407,6 +410,8 @@ static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav); else if (params->type == RESOURCE_TYPE_RENDER_TARGET) hr = ID3D11Device_CreateRenderTargetView(device, resource->resource, NULL, &resource->rtv); + else if (params->type == RESOURCE_TYPE_DEPTH_STENCIL) + hr = ID3D11Device_CreateDepthStencilView(device, resource->resource, NULL, &resource->dsv); else hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); @@ -462,6 +467,7 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co switch (params->type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_TEXTURE: if (params->dimension == RESOURCE_DIMENSION_BUFFER) init_resource_srv_buffer(runner, resource, params); @@ -492,6 +498,8 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour ID3D11Resource_Release(resource->resource); if (resource->rtv) ID3D11RenderTargetView_Release(resource->rtv); + if (resource->dsv) + ID3D11DepthStencilView_Release(resource->dsv); if (resource->srv) ID3D11ShaderResourceView_Release(resource->srv); if (resource->uav) @@ -561,6 +569,7 @@ static bool d3d11_runner_dispatch(struct shader_runner *r, unsigned int x, unsig break;
case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: break; } @@ -592,7 +601,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; unsigned int min_uav_slot = ARRAY_SIZE(uavs); + ID3D11DepthStencilState *ds_state = NULL; + D3D11_DEPTH_STENCIL_DESC ds_desc = {0}; ID3D11Device *device = runner->device; + ID3D11DepthStencilView *dsv = NULL; ID3D10Blob *vs_code, *ps_code; unsigned int rtv_count = 0; ID3D11Buffer *cb = NULL; @@ -637,6 +649,19 @@ static bool d3d11_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_RENDER_TARGET: rtvs[resource->r.slot] = resource->rtv; rtv_count = max(rtv_count, resource->r.slot + 1); + if (runner->r.clear_rtv) + ID3D11DeviceContext_ClearRenderTargetView(context, resource->rtv, runner->r.rtv_clear_value); + break; + + case RESOURCE_TYPE_DEPTH_STENCIL: + dsv = resource->dsv; + ID3D11DeviceContext_ClearDepthStencilView(context, dsv, D3D11_CLEAR_DEPTH, runner->r.dsv_clear_value, 0); + ds_desc.DepthEnable = TRUE; + ds_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + ds_desc.DepthFunc = runner->r.comparison; + hr = ID3D11Device_CreateDepthStencilState(device, &ds_desc, &ds_state); + ok(hr == S_OK, "Failed to create depth/stencil state, hr %#lx.\n", hr); + ID3D11DeviceContext_OMSetDepthStencilState(context, ds_state, 0); break;
case RESOURCE_TYPE_TEXTURE: @@ -655,7 +680,7 @@ static bool d3d11_runner_draw(struct shader_runner *r, } }
- ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, rtv_count, rtvs, NULL, + ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, rtv_count, rtvs, dsv, min_uav_slot, ARRAY_SIZE(uavs) - min_uav_slot, &uavs[min_uav_slot], NULL);
for (i = 0; i < runner->r.sampler_count; ++i) @@ -705,6 +730,8 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11VertexShader_Release(vs); if (cb) ID3D11Buffer_Release(cb); + if (ds_state) + ID3D11DepthStencilState_Release(ds_state);
return true; } @@ -728,6 +755,7 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade switch (resource->r.type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_UAV: if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) { diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 56844ae36..c95f7066e 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -46,7 +46,7 @@ struct d3d12_shader_runner
struct test_context test_context;
- ID3D12DescriptorHeap *heap, *rtv_heap; + ID3D12DescriptorHeap *heap, *rtv_heap, *dsv_heap;
ID3D12CommandQueue *compute_queue; ID3D12CommandAllocator *compute_allocator; @@ -142,6 +142,16 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot)); break;
+ case RESOURCE_TYPE_DEPTH_STENCIL: + if (!runner->dsv_heap) + runner->dsv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1); + + resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, + params->format, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_RESOURCE_STATE_DEPTH_WRITE); + ID3D12Device_CreateDepthStencilView(device, resource->resource, + NULL, get_cpu_dsv_handle(test_context, runner->dsv_heap, 0)); + break; + case RESOURCE_TYPE_TEXTURE: if (!runner->heap) runner->heap = create_gpu_descriptor_heap(device, @@ -309,6 +319,7 @@ static ID3D12RootSignature *d3d12_runner_create_root_signature(struct d3d12_shad break;
case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: break; } @@ -406,6 +417,7 @@ static bool d3d12_runner_dispatch(struct shader_runner *r, unsigned int x, unsig break;
case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: break; } @@ -439,6 +451,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D12CommandQueue *queue = test_context->queue; D3D12_INPUT_ELEMENT_DESC *input_element_descs; ID3D12Device *device = test_context->device; + D3D12_CPU_DESCRIPTOR_HANDLE dsv = {0}; ID3D10Blob *vs_code, *ps_code; unsigned int uniform_index; unsigned int rtv_count = 0; @@ -475,6 +488,14 @@ static bool d3d12_runner_draw(struct shader_runner *r, pso_desc.NumRenderTargets = max(pso_desc.NumRenderTargets, resource->r.slot + 1); pso_desc.BlendState.RenderTarget[resource->r.slot].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; } + else if (resource->r.type == RESOURCE_TYPE_DEPTH_STENCIL) + { + assert(!resource->r.slot); + pso_desc.DSVFormat = resource->r.format; + pso_desc.DepthStencilState.DepthEnable = true; + pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + pso_desc.DepthStencilState.DepthFunc = runner->r.comparison; + } }
pso_desc.VS.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); @@ -533,6 +554,15 @@ static bool d3d12_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_RENDER_TARGET: rtvs[resource->r.slot] = get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot); rtv_count = max(rtv_count, resource->r.slot + 1); + if (runner->r.clear_rtv) + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[resource->r.slot], + runner->r.rtv_clear_value, 0, NULL); + break; + + case RESOURCE_TYPE_DEPTH_STENCIL: + dsv = get_cpu_dsv_handle(test_context, runner->dsv_heap, 0); + ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv, + D3D12_CLEAR_FLAG_DEPTH, runner->r.dsv_clear_value, 0, 0, NULL); break;
case RESOURCE_TYPE_TEXTURE: @@ -557,7 +587,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, } }
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, rtv_count, rtvs, false, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, rtv_count, rtvs, false, dsv.ptr ? &dsv : NULL);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect); ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); @@ -585,6 +615,8 @@ static struct resource_readback *d3d12_runner_get_resource_readback(struct shade
if (resource->r.type == RESOURCE_TYPE_RENDER_TARGET) state = D3D12_RESOURCE_STATE_RENDER_TARGET; + else if (resource->r.type == RESOURCE_TYPE_DEPTH_STENCIL) + state = D3D12_RESOURCE_STATE_DEPTH_WRITE; else state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
@@ -686,5 +718,7 @@ void run_shader_tests_d3d12(void *dxc_compiler) ID3D12DescriptorHeap_Release(runner.heap); if (runner.rtv_heap) ID3D12DescriptorHeap_Release(runner.rtv_heap); + if (runner.dsv_heap) + ID3D12DescriptorHeap_Release(runner.dsv_heap); destroy_test_context(&runner.test_context); } diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index e4e1c6435..70b3d4cdb 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -224,6 +224,10 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con ok(hr == D3D_OK, "Failed to create render target, hr %#lx.\n", hr); break;
+ case RESOURCE_TYPE_DEPTH_STENCIL: + fatal_error("DSVs are not supported.\n"); + break; + case RESOURCE_TYPE_TEXTURE: { if (params->dimension == RESOURCE_DIMENSION_BUFFER) @@ -382,6 +386,9 @@ static bool d3d9_runner_draw(struct shader_runner *r, ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr); break;
+ case RESOURCE_TYPE_DEPTH_STENCIL: + vkd3d_unreachable(); + case RESOURCE_TYPE_TEXTURE: assert(resource->r.dimension != RESOURCE_DIMENSION_BUFFER);
diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index 2045950e3..8533eef70 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -334,6 +334,7 @@ static const struct format_info *get_format_info(enum DXGI_FORMAT format, bool i {DXGI_FORMAT_R32G32_SINT, 2, true, false, GL_RG32I, GL_RG_INTEGER, GL_INT}, {DXGI_FORMAT_R32_FLOAT, 1, false, false, GL_R32F, GL_RED, GL_FLOAT}, {DXGI_FORMAT_R32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, + {DXGI_FORMAT_D32_FLOAT, 1, false, true, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, {DXGI_FORMAT_R32_UINT, 1, true, false, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, {DXGI_FORMAT_R32_SINT, 1, true, false, GL_R32I, GL_RED_INTEGER, GL_INT}, }; @@ -394,6 +395,7 @@ static struct resource *gl_runner_create_resource(struct shader_runner *r, const switch (params->type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: if (params->dimension == RESOURCE_DIMENSION_BUFFER) @@ -419,6 +421,7 @@ static void gl_runner_destroy_resource(struct shader_runner *r, struct resource switch (resource->r.type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: if (res->dimension == RESOURCE_DIMENSION_BUFFER) @@ -705,6 +708,7 @@ static bool gl_runner_dispatch(struct shader_runner *r, unsigned int x, unsigned switch (resource->r.type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: case RESOURCE_TYPE_TEXTURE: break; @@ -897,6 +901,7 @@ static bool gl_runner_draw(struct shader_runner *r, struct gl_runner *runner = gl_runner(r); struct vkd3d_shader_code vs_dxbc; uint8_t *attribute_offsets[32]; + GLbitfield clear_mask = 0; struct { GLuint id; @@ -995,6 +1000,21 @@ static bool gl_runner_draw(struct shader_runner *r, draw_buffers[resource->r.slot] = GL_COLOR_ATTACHMENT0 + resource->r.slot; if (resource->r.slot >= rt_count) rt_count = resource->r.slot + 1; + if (runner->r.clear_rtv) + { + float *colour = runner->r.rtv_clear_value; + glClearColor(colour[0], colour[1], colour[2], colour[3]); + clear_mask |= GL_COLOR_BUFFER_BIT; + } + break; + + case RESOURCE_TYPE_DEPTH_STENCIL: + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, resource->id, 0); + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthFunc(get_compare_op_gl(runner->r.comparison)); + glClearDepthf(runner->r.dsv_clear_value); + clear_mask |= GL_DEPTH_BUFFER_BIT; break;
case RESOURCE_TYPE_TEXTURE: @@ -1028,6 +1048,9 @@ static bool gl_runner_draw(struct shader_runner *r, } }
+ if (clear_mask) + glClear(clear_mask); + glViewport(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT); glScissor(0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT); glDrawBuffers(rt_count, draw_buffers); @@ -1092,7 +1115,8 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r struct gl_resource *resource = gl_resource(res); struct resource_readback *rb;
- if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.type != RESOURCE_TYPE_UAV) + if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.type != RESOURCE_TYPE_DEPTH_STENCIL + && resource->r.type != RESOURCE_TYPE_UAV) fatal_error("Unhandled resource type %#x.\n", resource->r.type);
rb = malloc(sizeof(*rb)); diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index a3bbf170c..dfc69da1e 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -118,7 +118,7 @@ static void end_command_buffer(struct vulkan_shader_runner *runner) }
static void transition_image_layout(struct vulkan_shader_runner *runner, - VkImage image, VkImageLayout src_layout, VkImageLayout dst_layout) + VkImage image, VkImageAspectFlags aspect_mask, VkImageLayout src_layout, VkImageLayout dst_layout) { VkImageMemoryBarrier barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
@@ -129,7 +129,7 @@ static void transition_image_layout(struct vulkan_shader_runner *runner, barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.aspectMask = aspect_mask; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; barrier.subresourceRange.baseArrayLayer = 0; @@ -238,7 +238,8 @@ static VkImage create_2d_image(const struct vulkan_shader_runner *runner, uint32 return image; }
-static VkImageView create_2d_image_view(const struct vulkan_shader_runner *runner, VkImage image, VkFormat format) +static VkImageView create_2d_image_view(const struct vulkan_shader_runner *runner, VkImage image, VkFormat format, + VkImageAspectFlags aspect_mask) { VkImageViewCreateInfo view_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; VkImageView view; @@ -250,7 +251,7 @@ static VkImageView create_2d_image_view(const struct vulkan_shader_runner *runne view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + view_info.subresourceRange.aspectMask = aspect_mask; view_info.subresourceRange.baseMipLevel = 0; view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; view_info.subresourceRange.baseArrayLayer = 0; @@ -280,12 +281,12 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
resource->image = create_2d_image(runner, params->width, params->height, params->level_count, usage, format, &resource->memory); - resource->image_view = create_2d_image_view(runner, resource->image, format); + resource->image_view = create_2d_image_view(runner, resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT);
if (!params->data) { begin_command_buffer(runner); - transition_image_layout(runner, resource->image, + transition_image_layout(runner, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, layout); end_command_buffer(runner); return; @@ -299,7 +300,7 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_
begin_command_buffer(runner);
- transition_image_layout(runner, resource->image, + transition_image_layout(runner, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
for (unsigned int level = 0; level < params->level_count; ++level) @@ -321,7 +322,7 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_ buffer_offset += level_width * level_height * params->texel_size; }
- transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout); + transition_image_layout(runner, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
end_command_buffer(runner);
@@ -373,14 +374,28 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
resource->image = create_2d_image(runner, params->width, params->height, params->level_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory); - resource->image_view = create_2d_image_view(runner, resource->image, format); + resource->image_view = create_2d_image_view(runner, resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT);
begin_command_buffer(runner); - transition_image_layout(runner, resource->image, + transition_image_layout(runner, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); end_command_buffer(runner); break;
+ case RESOURCE_TYPE_DEPTH_STENCIL: + format = vkd3d_get_vk_format(params->format); + + resource->image = create_2d_image(runner, params->width, params->height, params->level_count, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format, + &resource->memory); + resource->image_view = create_2d_image_view(runner, resource->image, format, VK_IMAGE_ASPECT_DEPTH_BIT); + + begin_command_buffer(runner); + transition_image_layout(runner, resource->image, VK_IMAGE_ASPECT_DEPTH_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + end_command_buffer(runner); + break; + case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: if (params->dimension == RESOURCE_DIMENSION_BUFFER) @@ -541,6 +556,7 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour switch (resource->r.type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: break;
@@ -669,6 +685,31 @@ static VkPipelineLayout create_pipeline_layout(const struct vulkan_shader_runner return pipeline_layout; }
+static enum VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) +{ + switch (op) + { + case D3D12_COMPARISON_FUNC_NEVER: + return VK_COMPARE_OP_NEVER; + case D3D12_COMPARISON_FUNC_LESS: + return VK_COMPARE_OP_LESS; + case D3D12_COMPARISON_FUNC_EQUAL: + return VK_COMPARE_OP_EQUAL; + case D3D12_COMPARISON_FUNC_LESS_EQUAL: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case D3D12_COMPARISON_FUNC_GREATER: + return VK_COMPARE_OP_GREATER; + case D3D12_COMPARISON_FUNC_NOT_EQUAL: + return VK_COMPARE_OP_NOT_EQUAL; + case D3D12_COMPARISON_FUNC_GREATER_EQUAL: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + case D3D12_COMPARISON_FUNC_ALWAYS: + return VK_COMPARE_OP_ALWAYS; + default: + fatal_error("Unhandled compare op %#x.\n", op); + } +} + static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, VkRenderPass render_pass, VkPipelineLayout pipeline_layout, D3D_PRIMITIVE_TOPOLOGY primitive_topology) { @@ -684,6 +725,7 @@ static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, VkGraphicsPipelineCreateInfo pipeline_desc = {.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; VkPipelineColorBlendAttachmentState attachment_desc[MAX_RESOURCES] = {0}; VkVertexInputAttributeDescription input_attributes[32]; + VkPipelineDepthStencilStateCreateInfo ds_desc = {0}; VkVertexInputBindingDescription input_bindings[32]; VkPipelineShaderStageCreateInfo stage_desc[2]; struct vkd3d_shader_code vs_dxbc; @@ -745,6 +787,20 @@ static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; break;
+ case RESOURCE_TYPE_DEPTH_STENCIL: + ds_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + ds_desc.pNext = NULL; + ds_desc.flags = 0; + ds_desc.depthTestEnable = VK_TRUE; + ds_desc.depthWriteEnable = VK_TRUE; + ds_desc.depthCompareOp = vk_compare_op_from_d3d12(runner->r.comparison); + ds_desc.depthBoundsTestEnable = VK_FALSE; + ds_desc.stencilTestEnable = VK_FALSE; + ds_desc.minDepthBounds = 0.0f; + ds_desc.maxDepthBounds = 1.0f; + pipeline_desc.pDepthStencilState = &ds_desc; + break; + case RESOURCE_TYPE_VERTEX_BUFFER: { VkVertexInputBindingDescription *binding = &input_bindings[input_desc.vertexBindingDescriptionCount++]; @@ -841,31 +897,6 @@ static VkSamplerAddressMode vk_address_mode_from_d3d12(D3D12_TEXTURE_ADDRESS_MOD } }
-static enum VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) -{ - switch (op) - { - case D3D12_COMPARISON_FUNC_NEVER: - return VK_COMPARE_OP_NEVER; - case D3D12_COMPARISON_FUNC_LESS: - return VK_COMPARE_OP_LESS; - case D3D12_COMPARISON_FUNC_EQUAL: - return VK_COMPARE_OP_EQUAL; - case D3D12_COMPARISON_FUNC_LESS_EQUAL: - return VK_COMPARE_OP_LESS_OR_EQUAL; - case D3D12_COMPARISON_FUNC_GREATER: - return VK_COMPARE_OP_GREATER; - case D3D12_COMPARISON_FUNC_NOT_EQUAL: - return VK_COMPARE_OP_NOT_EQUAL; - case D3D12_COMPARISON_FUNC_GREATER_EQUAL: - return VK_COMPARE_OP_GREATER_OR_EQUAL; - case D3D12_COMPARISON_FUNC_ALWAYS: - return VK_COMPARE_OP_ALWAYS; - default: - fatal_error("Unhandled compare op %#x.\n", op); - } -} - static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_runner *runner) { VkDescriptorSetLayoutCreateInfo set_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; @@ -887,6 +918,7 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r switch (resource->r.type) { case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: case RESOURCE_TYPE_VERTEX_BUFFER: break;
@@ -1018,6 +1050,7 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo break;
case RESOURCE_TYPE_RENDER_TARGET: + case RESOURCE_TYPE_DEPTH_STENCIL: break; } } @@ -1036,44 +1069,58 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn { VkRenderPassCreateInfo render_pass_desc = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; VkFramebufferCreateInfo fb_desc = {.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; + VkAttachmentReference ds_ref = {0}, color_refs[MAX_RESOURCES] = {0}; VkAttachmentDescription attachment_descs[MAX_RESOURCES] = {0}; - VkAttachmentReference color_refs[MAX_RESOURCES] = {0}; VkSubpassDescription subpass_desc = {0}; - VkImageView rtvs[MAX_RESOURCES]; - unsigned int rt_count = 0; + VkImageView views[MAX_RESOURCES]; + unsigned int color_ref_count = 0, view_count = 0; + VkImageLayout layout; unsigned int i; + bool is_ds;
for (i = 0; i < runner->r.resource_count; ++i) { const struct vulkan_resource *resource = vulkan_resource(runner->r.resources[i]); - VkAttachmentDescription *attachment_desc = &attachment_descs[rt_count]; - VkAttachmentReference *color_ref = &color_refs[rt_count]; + VkAttachmentDescription *attachment_desc = &attachment_descs[view_count]; + VkAttachmentReference *color_ref = &color_refs[color_ref_count];
- if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET) + if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.type != RESOURCE_TYPE_DEPTH_STENCIL) continue;
+ is_ds = resource->r.type == RESOURCE_TYPE_DEPTH_STENCIL; + layout = is_ds ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment_desc->format = vkd3d_get_vk_format(resource->r.format); attachment_desc->samples = VK_SAMPLE_COUNT_1_BIT; - attachment_desc->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment_desc->loadOp = (is_ds || runner->r.clear_rtv) + ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; attachment_desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment_desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment_desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_desc->initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachment_desc->finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment_desc->initialLayout = layout; + attachment_desc->finalLayout = layout;
- color_ref->attachment = rt_count; - color_ref->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - rtvs[rt_count] = resource->image_view; + if (is_ds) + { + ds_ref.attachment = view_count; + ds_ref.layout = layout; + subpass_desc.pDepthStencilAttachment = &ds_ref; + } + else + { + color_ref->attachment = view_count; + color_ref->layout = layout; + ++color_ref_count; + }
- ++rt_count; + views[view_count++] = resource->image_view; }
subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass_desc.colorAttachmentCount = rt_count; + subpass_desc.colorAttachmentCount = color_ref_count; subpass_desc.pColorAttachments = color_refs;
- render_pass_desc.attachmentCount = rt_count; + render_pass_desc.attachmentCount = view_count; render_pass_desc.pAttachments = attachment_descs; render_pass_desc.subpassCount = 1; render_pass_desc.pSubpasses = &subpass_desc; @@ -1081,8 +1128,8 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn VK_CALL(vkCreateRenderPass(runner->device, &render_pass_desc, NULL, render_pass));
fb_desc.renderPass = *render_pass; - fb_desc.attachmentCount = rt_count; - fb_desc.pAttachments = rtvs; + fb_desc.attachmentCount = view_count; + fb_desc.pAttachments = views; fb_desc.width = RENDER_TARGET_WIDTH; fb_desc.height = RENDER_TARGET_HEIGHT; fb_desc.layers = 1; @@ -1140,6 +1187,7 @@ static bool vulkan_runner_draw(struct shader_runner *r,
static const VkRect2D rt_rect = {.extent.width = RENDER_TARGET_WIDTH, .extent.height = RENDER_TARGET_HEIGHT}; VkRenderPassBeginInfo pass_begin_desc = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}; + union VkClearValue clear_values[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; VkCommandBuffer cmd_buffer = runner->cmd_buffer; VkDescriptorSetLayout set_layout; VkPipelineLayout pipeline_layout; @@ -1164,6 +1212,25 @@ static bool vulkan_runner_draw(struct shader_runner *r, pass_begin_desc.renderPass = render_pass; pass_begin_desc.framebuffer = fb; pass_begin_desc.renderArea = rt_rect; + pass_begin_desc.clearValueCount = 0; + pass_begin_desc.pClearValues = clear_values; + for (i = 0; i < runner->r.resource_count; ++i) + { + const struct resource *resource = runner->r.resources[i]; + + if (resource->type == RESOURCE_TYPE_RENDER_TARGET) + { + memcpy(clear_values[pass_begin_desc.clearValueCount].color.float32, runner->r.rtv_clear_value, + sizeof(clear_values[0].color.float32)); + ++pass_begin_desc.clearValueCount; + } + else if (resource->type == RESOURCE_TYPE_DEPTH_STENCIL) + { + clear_values[pass_begin_desc.clearValueCount].depthStencil.depth = runner->r.dsv_clear_value; + clear_values[pass_begin_desc.clearValueCount].depthStencil.stencil = 0; + ++pass_begin_desc.clearValueCount; + } + }
VK_CALL(vkCmdBeginRenderPass(cmd_buffer, &pass_begin_desc, VK_SUBPASS_CONTENTS_INLINE));
@@ -1205,6 +1272,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad struct vulkan_resource_readback *rb = malloc(sizeof(*rb)); struct vulkan_resource *resource = vulkan_resource(res); VkDevice device = runner->device; + VkImageAspectFlags aspect_mask; VkBufferImageCopy region = {0}; VkImageLayout layout;
@@ -1228,16 +1296,21 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad } else { + aspect_mask = (resource->r.type == RESOURCE_TYPE_DEPTH_STENCIL) + ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + if (resource->r.type == RESOURCE_TYPE_RENDER_TARGET) layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + else if (resource->r.type == RESOURCE_TYPE_DEPTH_STENCIL) + layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; else layout = VK_IMAGE_LAYOUT_GENERAL;
begin_command_buffer(runner);
- transition_image_layout(runner, resource->image, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + transition_image_layout(runner, resource->image, aspect_mask, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.aspectMask = aspect_mask; region.imageSubresource.layerCount = 1; region.imageExtent.width = resource->r.width; region.imageExtent.height = resource->r.height; @@ -1246,7 +1319,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
- transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout); + transition_image_layout(runner, resource->image, aspect_mask, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout);
end_command_buffer(runner);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 70 +++++++++++++++++++++++++++----- tests/hlsl/depth-out.shader_test | 18 ++++---- 2 files changed, 68 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index da8ba662d..0ce91b479 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -794,7 +794,7 @@ struct sm6_parser
struct vkd3d_shader_dst_param *output_params; struct vkd3d_shader_dst_param *input_params; - uint32_t input_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20]; + uint32_t io_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
struct sm6_function *functions; size_t function_count; @@ -3599,6 +3599,22 @@ static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_par src_param_init_from_value(&src_params[i], operands[i]); }
+static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( + enum vkd3d_shader_sysval_semantic sysval_semantic) +{ + switch (sysval_semantic) + { + case VKD3D_SHADER_SV_DEPTH: + return VKD3DSPR_DEPTHOUT; + case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: + return VKD3DSPR_DEPTHOUTGE; + case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: + return VKD3DSPR_DEPTHOUTLE; + default: + return VKD3DSPR_INVALID; + } +} + static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) { @@ -3611,6 +3627,13 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade e = &s->elements[i];
param = ¶ms[i]; + + if (e->register_index == UINT_MAX) + { + dst_param_io_init(param, e, register_type_from_dxil_semantic_kind(e->sysval_semantic)); + continue; + } + dst_param_io_init(param, e, reg_type); count = 0; if (e->register_count > 1) @@ -4551,16 +4574,16 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); }
-static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, +static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count) { struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins;
- if (!bitmap_is_set(sm6->input_regs_declared, reg_type)) + if (!bitmap_is_set(sm6->io_regs_declared, reg_type)) { - bitmap_set(sm6->input_regs_declared, reg_type); - ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INPUT); + bitmap_set(sm6->io_regs_declared, reg_type); + ins = sm6_parser_add_instruction(sm6, handler_idx); dst_param = &ins->declaration.dst; vsir_register_init(&dst_param->reg, reg_type, data_type, 0); dst_param_init_vector(dst_param, component_count); @@ -4724,7 +4747,7 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i vkd3d_unreachable(); }
- sm6_parser_dcl_register_builtin(sm6, reg_type, VKD3D_DATA_UINT, component_count); + sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count); vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -5349,6 +5372,12 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr if (e->register_count > 1) register_index_address_init(&dst_param->reg.idx[0], operands[1], sm6);
+ if (e->register_index == UINT_MAX) + { + sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_OUTPUT, dst_param->reg.type, + dst_param->reg.data_type, vsir_write_mask_component_count(e->mask)); + } + if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) src_param_init_from_value(src_param, value); } @@ -7683,6 +7712,9 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] = [SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION, [SEMANTIC_KIND_ISFRONTFACE] = VKD3D_SHADER_SV_IS_FRONT_FACE, [SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_TARGET, + [SEMANTIC_KIND_DEPTH] = VKD3D_SHADER_SV_DEPTH, + [SEMANTIC_KIND_DEPTHLESSEQUAL] = VKD3D_SHADER_SV_DEPTH_LESS_EQUAL, + [SEMANTIC_KIND_DEPTHGREATEREQUAL] = VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL, };
static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind) @@ -8449,6 +8481,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const const struct sm6_metadata_node *node, *element_node; struct signature_element *elements, *e; unsigned int values[10]; + bool is_register;
if (!m) return VKD3D_OK; @@ -8557,7 +8590,18 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const column_count = values[7]; e->register_index = values[8]; e->target_location = e->register_index; - if (e->register_index > MAX_REG_OUTPUT || e->register_count > MAX_REG_OUTPUT - e->register_index) + + if ((is_register = e->register_index == UINT_MAX)) + { + if (register_type_from_dxil_semantic_kind(e->sysval_semantic) == VKD3DSPR_INVALID) + { + WARN("Unhandled I/O register semantic kind %u.\n", j); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, + "DXIL semantic kind %u is unhandled for an I/O register.", j); + return VKD3D_ERROR_INVALID_SHADER; + } + } + else if (e->register_index > MAX_REG_OUTPUT || e->register_count > MAX_REG_OUTPUT - e->register_index) { WARN("Invalid row start %u with row count %u.\n", e->register_index, e->register_count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, @@ -8565,8 +8609,9 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const e->register_index, e->register_count); return VKD3D_ERROR_INVALID_SHADER; } + index = values[9]; - if (index >= VKD3D_VEC4_SIZE || column_count > VKD3D_VEC4_SIZE - index) + if (index != UINT8_MAX && (index >= VKD3D_VEC4_SIZE || column_count > VKD3D_VEC4_SIZE - index)) { WARN("Invalid column start %u with count %u.\n", index, column_count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, @@ -8576,10 +8621,13 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
e->mask = vkd3d_write_mask_from_component_count(column_count); e->used_mask = e->mask; - e->mask <<= index; - signature_element_read_additional_element_values(e, element_node, sm6); - e->used_mask <<= index; + + if (index != UINT8_MAX) + { + e->mask <<= index; + e->used_mask <<= index; + }
m = element_node->operands[4]; if (!sm6_metadata_value_is_node(m)) diff --git a/tests/hlsl/depth-out.shader_test b/tests/hlsl/depth-out.shader_test index b26830fc6..41c8033e2 100644 --- a/tests/hlsl/depth-out.shader_test +++ b/tests/hlsl/depth-out.shader_test @@ -16,20 +16,20 @@ float main() : SV_Depth uniform 0 float 0.0 dsv clear 1.0 depth less -todo(sm>=6 | glsl) draw quad +todo(glsl) draw quad probe dsv all r (0.0)
uniform 0 float 0.75 -todo(sm>=6 | glsl) draw quad +todo(glsl) draw quad probe dsv all r (0.75)
dsv clear 0.5 depth greater -todo(sm>=6 | glsl) draw quad +todo(glsl) draw quad probe dsv all r (0.75)
depth less -todo(sm>=6 | glsl) draw quad +todo(glsl) draw quad probe dsv all r (0.5)
@@ -63,12 +63,12 @@ uniform 0 float4 0.7 0.7 0.0 0.0 rtv clear 1.0 1.0 1.0 1.0 dsv clear 0.5 depth greater equal -todo draw quad +todo(sm<6 | glsl) draw quad probe all rgba (0.0, 1.0, 0.0, 1.0) probe dsv all r (0.7)
uniform 0 float4 0.7 0.4 0.0 0.0 -todo draw quad +todo(sm<6 | glsl) draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) probe dsv all r (0.5)
@@ -87,16 +87,16 @@ uniform 0 float4 0.7 0.7 0.0 0.0 rtv clear 1.0 1.0 1.0 1.0 dsv clear 0.5 depth greater equal -todo draw quad +todo(sm<6 | glsl) draw quad probe all rgba (0.0, 1.0, 0.0, 1.0) probe dsv all r (0.7)
uniform 0 float4 0.4 0.6 0.0 0.0 -todo draw quad +todo(sm<6 | glsl) draw quad probe all rgba (0.0, 1.0, 0.0, 1.0) probe dsv all r (0.6)
uniform 0 float4 0.4 0.4 0.0 0.0 -todo draw quad +todo(sm<6 | glsl) draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) probe dsv all r (0.5)
Updated the test commit message, and added RTV clear to the GL runner. The GL changes are untested until compiler support is added, so they could be omitted, but do obviate the need to add to `caps` just to skip GL.