From: Józef Kucia jkucia@codeweavers.com
The test is skipped when transform feedback is not supported by Vulkan implementation.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- tests/d3d12.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index f34b82c855d7..a2a40d665a9d 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -22454,6 +22454,111 @@ static void test_primitive_restart(void) destroy_test_context(&context); }
+static void test_vertex_shader_stream_output(void) +{ + D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc; + ID3D12Resource *counter_buffer, *so_buffer; + ID3D12GraphicsCommandList *command_list; + D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv; + ID3D12Resource *upload_buffer; + struct test_context_desc desc; + struct resource_readback rb; + struct test_context context; + ID3D12CommandQueue *queue; + unsigned int counter, i; + const struct vec4 *data; + ID3D12Device *device; + HRESULT hr; + + static const D3D12_SO_DECLARATION_ENTRY so_declaration[] = + { + {0, "SV_Position", 0, 0, 4, 0}, + }; + static const struct vec4 expected_output[] = + { + {-1.0f, 1.0f, 0.0f, 1.0f}, + { 3.0f, 1.0f, 0.0f, 1.0f}, + {-1.0f,-3.0f, 0.0f, 1.0f}, + }; + unsigned int strides[] = {16}; + + memset(&desc, 0, sizeof(desc)); + desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT; + desc.no_pipeline = true; + if (!init_test_context(&context, &desc)) + return; + device = context.device; + command_list = context.list; + queue = context.queue; + + init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, NULL, NULL); + pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration); + pso_desc.StreamOutput.pSODeclaration = so_declaration; + pso_desc.StreamOutput.pBufferStrides = strides; + pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides); + pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM; + hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, + &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + if (hr == E_NOTIMPL) + { + skip("Stream output is not supported.\n"); + destroy_test_context(&context); + return; + } + ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr); + + counter = 0; + upload_buffer = create_upload_buffer(device, sizeof(counter), &counter); + + counter_buffer = create_default_buffer(device, 32, + D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST); + so_buffer = create_default_buffer(device, 1024, + D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT); + sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer); + sobv.SizeInBytes = 1024; + sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer); + + ID3D12GraphicsCommandList_CopyBufferRegion(command_list, counter_buffer, 0, + upload_buffer, 0, sizeof(counter)); + + transition_resource_state(command_list, counter_buffer, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT); + + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, counter_buffer, + D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, so_buffer, + D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE); + + get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list); + counter = get_readback_uint(&rb, 0, 0, 0); + ok(counter == 3 * sizeof(struct vec4), "Got unexpected counter %u.\n", counter); + release_resource_readback(&rb); + reset_command_list(command_list, context.allocator); + get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list); + for (i = 0; i < ARRAY_SIZE(expected_output); ++i) + { + const struct vec4 *expected = &expected_output[i]; + data = get_readback_vec4(&rb, i, 0); + ok(compare_vec4(data, expected, 1), + "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n", + data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w); + } + release_resource_readback(&rb); + + ID3D12Resource_Release(counter_buffer); + ID3D12Resource_Release(upload_buffer); + ID3D12Resource_Release(so_buffer); + destroy_test_context(&context); +} + START_TEST(d3d12) { parse_args(argc, argv); @@ -22573,4 +22678,5 @@ START_TEST(d3d12) run_test(test_dual_source_blending); run_test(test_multisample_rendering); run_test(test_primitive_restart); + run_test(test_vertex_shader_stream_output); }