From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/command.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 4273a665e800..847581c03b65 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -3372,6 +3372,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor) { struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); + const struct d3d12_rtv_desc *rtv_desc; + const struct d3d12_dsv_desc *dsv_desc; unsigned int i;
TRACE("iface %p, render_target_descriptor_count %u, render_target_descriptors %p, " @@ -3390,7 +3392,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi list->fb_height = 0; for (i = 0; i < render_target_descriptor_count; ++i) { - const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(render_target_descriptors[i]); + if (single_descriptor_handle) + rtv_desc = d3d12_rtv_desc_from_cpu_handle(*render_target_descriptors) + i; + else + rtv_desc = d3d12_rtv_desc_from_cpu_handle(render_target_descriptors[i]);
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
@@ -3403,7 +3408,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
if (depth_stencil_descriptor) { - const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(*depth_stencil_descriptor); + dsv_desc = d3d12_dsv_desc_from_cpu_handle(*depth_stencil_descriptor);
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- tests/d3d12.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 80d22333875c..6580f9d2476c 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -3968,6 +3968,133 @@ static void test_draw_indexed_instanced(void) destroy_test_context(&context); }
+static void test_multiple_render_targets(void) +{ + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f}; + D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc; + ID3D12GraphicsCommandList *command_list; + D3D12_CPU_DESCRIPTOR_HANDLE rtvs[3]; + ID3D12Resource *render_targets[2]; + struct test_context_desc desc; + struct test_context context; + ID3D12CommandQueue *queue; + unsigned int i; + HRESULT hr; + + static const DWORD ps_code[] = + { +#if 0 + void main(out float4 target0 : SV_Target0, out float4 target1 : SV_Target1, + out float4 target2 : SV_Target2) + { + target0 = float4(1.0f, 0.0f, 0.0f, 1.0f); + target1 = float4(2.0f, 0.0f, 0.0f, 1.0f); + target2 = float4(3.0f, 0.0f, 0.0f, 1.0f); + } +#endif + 0x43425844, 0xc4325131, 0x8ba4a693, 0x08d15431, 0xcb990885, 0x00000001, 0x0000013c, 0x00000003, + 0x0000002c, 0x0000003c, 0x000000a0, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x0000005c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x00000050, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000050, + 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, + 0x58454853, 0x00000094, 0x00000050, 0x00000025, 0x0100086a, 0x03000065, 0x001020f2, 0x00000000, + 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x08000036, 0x001020f2, + 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2, + 0x00000001, 0x00004002, 0x40000000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2, + 0x00000002, 0x00004002, 0x40400000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, + }; + static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)}; + + memset(&desc, 0, sizeof(desc)); + desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.rt_descriptor_count = ARRAY_SIZE(rtvs); + desc.no_pipeline = true; + if (!init_test_context(&context, &desc)) + return; + command_list = context.list; + queue = context.queue; + + init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL); + pso_desc.NumRenderTargets = ARRAY_SIZE(rtvs); + for (i = 0; i < ARRAY_SIZE(rtvs); ++i) + pso_desc.RTVFormats[i] = desc.rt_format; + hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, + &IID_ID3D12PipelineState, (void **)&context.pipeline_state); + ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr); + + rtvs[0] = get_cpu_rtv_handle(&context, context.rtv_heap, 2); + rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 0); + rtvs[2] = get_cpu_rtv_handle(&context, context.rtv_heap, 1); + + create_render_target(&context, &desc, &render_targets[0], &rtvs[0]); + create_render_target(&context, &desc, &render_targets[1], &rtvs[2]); + + for (i = 0; i < ARRAY_SIZE(rtvs); ++i) + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], white, 0, NULL); + + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), rtvs, FALSE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, render_targets[0], + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, render_targets[1], + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + + expected_vec4.x = 2.0f; + check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + expected_vec4.x = 1.0f; + check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + expected_vec4.x = 3.0f; + check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + transition_resource_state(command_list, render_targets[0], + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + transition_resource_state(command_list, render_targets[1], + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), &context.rtv, TRUE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, render_targets[0], + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, render_targets[1], + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + + expected_vec4.x = 1.0f; + check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + expected_vec4.x = 3.0f; + check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + expected_vec4.x = 2.0f; + check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0); + reset_command_list(command_list, context.allocator); + + for (i = 0; i < ARRAY_SIZE(render_targets); ++i) + ID3D12Resource_Release(render_targets[i]); + destroy_test_context(&context); +} + static void test_append_aligned_element(void) { ID3D12GraphicsCommandList *command_list; @@ -17391,6 +17518,7 @@ START_TEST(d3d12) run_test(test_clear_unordered_access_view); run_test(test_draw_instanced); run_test(test_draw_indexed_instanced); + run_test(test_multiple_render_targets); run_test(test_append_aligned_element); run_test(test_gpu_virtual_address); run_test(test_fragment_coords);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/resource.c | 7 +++++++ libs/vkd3d/utils.c | 1 + 2 files changed, 8 insertions(+)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 712ff9c748f6..77f4f0d14a9b 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1001,6 +1001,13 @@ static VkResult vkd3d_create_texture_view(struct d3d12_device *device, view_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; view_desc.components.a = VK_COMPONENT_SWIZZLE_ZERO; } + else if (format->dxgi_format == DXGI_FORMAT_A8_UNORM) + { + view_desc.components.r = VK_COMPONENT_SWIZZLE_ZERO; + view_desc.components.g = VK_COMPONENT_SWIZZLE_ZERO; + view_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; + view_desc.components.a = VK_COMPONENT_SWIZZLE_R; + } else { view_desc.components.r = VK_COMPONENT_SWIZZLE_R; diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c index a326cae583ac..b3a8027b6048 100644 --- a/libs/vkd3d/utils.c +++ b/libs/vkd3d/utils.c @@ -50,6 +50,7 @@ static const struct vkd3d_format vkd3d_formats[] = {DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, 1, 1, 1, 1, COLOR}, {DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT, 1, 1, 1, 1, COLOR}, {DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM, 1, 1, 1, 1, COLOR}, + {DXGI_FORMAT_A8_UNORM, VK_FORMAT_R8_UNORM, 1, 1, 1, 1, COLOR}, {DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, 4, 1, 1, 1, COLOR}, {DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM, 4, 1, 1, 1, COLOR}, {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, 4, 1, 1, 1, COLOR},
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
The Vulkan spec says that image views must be created with the identity swizzle for attachments and storage images.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/resource.c | 74 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 26 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 77f4f0d14a9b..e0ceb4c211b0 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -977,10 +977,52 @@ static bool vkd3d_create_buffer_view(struct d3d12_device *device, offset * element_size, size * element_size, vk_view); }
+static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components, + const struct vkd3d_format *format, bool allowed_swizzle) +{ + if (format->vk_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) + { + if (allowed_swizzle) + { + components->r = VK_COMPONENT_SWIZZLE_ZERO; + components->g = VK_COMPONENT_SWIZZLE_R; + components->b = VK_COMPONENT_SWIZZLE_ZERO; + components->a = VK_COMPONENT_SWIZZLE_ZERO; + return; + } + else + { + FIXME("Stencil swizzle is not supported for format %#x.\n", + format->dxgi_format); + } + } + + if (format->dxgi_format == DXGI_FORMAT_A8_UNORM) + { + if (allowed_swizzle) + { + components->r = VK_COMPONENT_SWIZZLE_ZERO; + components->g = VK_COMPONENT_SWIZZLE_ZERO; + components->b = VK_COMPONENT_SWIZZLE_ZERO; + components->a = VK_COMPONENT_SWIZZLE_R; + return; + } + else + { + FIXME("Alpha swizzle is not supported.\n"); + } + } + + components->r = VK_COMPONENT_SWIZZLE_R; + components->g = VK_COMPONENT_SWIZZLE_G; + components->b = VK_COMPONENT_SWIZZLE_B; + components->a = VK_COMPONENT_SWIZZLE_A; +} + static VkResult vkd3d_create_texture_view(struct d3d12_device *device, struct d3d12_resource *resource, const struct vkd3d_format *format, VkImageViewType view_type, uint32_t miplevel_idx, uint32_t miplevel_count, uint32_t layer_idx, uint32_t layer_count, - VkImageView *vk_view) + bool allowed_swizzle, VkImageView *vk_view) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct VkImageViewCreateInfo view_desc; @@ -994,27 +1036,7 @@ static VkResult vkd3d_create_texture_view(struct d3d12_device *device, view_desc.image = resource->u.vk_image; view_desc.viewType = view_type; view_desc.format = format->vk_format; - if (format->vk_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) - { - view_desc.components.r = VK_COMPONENT_SWIZZLE_ZERO; - view_desc.components.g = VK_COMPONENT_SWIZZLE_R; - view_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; - view_desc.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } - else if (format->dxgi_format == DXGI_FORMAT_A8_UNORM) - { - view_desc.components.r = VK_COMPONENT_SWIZZLE_ZERO; - view_desc.components.g = VK_COMPONENT_SWIZZLE_ZERO; - view_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; - view_desc.components.a = VK_COMPONENT_SWIZZLE_R; - } - else - { - view_desc.components.r = VK_COMPONENT_SWIZZLE_R; - view_desc.components.g = VK_COMPONENT_SWIZZLE_G; - view_desc.components.b = VK_COMPONENT_SWIZZLE_B; - view_desc.components.a = VK_COMPONENT_SWIZZLE_A; - } + vkd3d_set_view_swizzle_for_format(&view_desc.components, format, allowed_swizzle); view_desc.subresourceRange.aspectMask = format->vk_aspect_mask; view_desc.subresourceRange.baseMipLevel = miplevel_idx; view_desc.subresourceRange.levelCount = miplevel_count; @@ -1149,7 +1171,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor, vk_view_type = resource->desc.DepthOrArraySize > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; if (vkd3d_create_texture_view(device, resource, format, vk_view_type, - 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS, &view->u.vk_image_view) < 0) + 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS, true, &view->u.vk_image_view) < 0) { vkd3d_free(view); return; @@ -1292,7 +1314,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor, return;
if (vkd3d_create_texture_view(device, resource, format, vk_view_type, - miplevel_idx, 1, layer_idx, layer_count, &view->u.vk_image_view) < 0) + miplevel_idx, 1, layer_idx, layer_count, false, &view->u.vk_image_view) < 0) { vkd3d_free(view); return; @@ -1527,7 +1549,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0; if (vkd3d_create_texture_view(device, resource, format, VK_IMAGE_VIEW_TYPE_2D, - miplevel_idx, 1, 0, 1, &rtv_desc->vk_view) < 0) + miplevel_idx, 1, 0, 1, false, &rtv_desc->vk_view) < 0) return;
rtv_desc->format = format->vk_format; @@ -1586,7 +1608,7 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev
miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0; if (vkd3d_create_texture_view(device, resource, format, VK_IMAGE_VIEW_TYPE_2D, - miplevel_idx, 1, 0, 1, &dsv_desc->vk_view) < 0) + miplevel_idx, 1, 0, 1, false, &dsv_desc->vk_view) < 0) return;
dsv_desc->format = format->vk_format;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- tests/d3d12.c | 108 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 33 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 6580f9d2476c..a513142e5140 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -9071,14 +9071,14 @@ static void test_texture(void) ID3D12GraphicsCommandList *command_list; D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; - D3D12_SUBRESOURCE_DATA texture_data; struct test_context_desc desc; struct resource_readback rb; struct test_context context; + unsigned int x_step, y_step; ID3D12DescriptorHeap *heap; ID3D12CommandQueue *queue; ID3D12Resource *texture; - unsigned int x, y; + unsigned int i, x, y;
static const DWORD ps_code[] = { @@ -9108,15 +9108,51 @@ static void test_texture(void) }; static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)}; static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; - static const unsigned int bitmap_data[] = + static const unsigned int r8g8b8a8_data[] = { 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00, 0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, }; + static const uint8_t a8_data[] = + { + 0x00, 0xff, 0x7f, 0xf0, + 0x0f, 0x11, 0x00, 0x00, + 0xff, 0xf0, 0x0f, 0xff, + 0xfa, 0xfe, 0xaa, 0xcc, + }; + static const unsigned int a8_expected_data[] = + { + 0x00000000, 0xff000000, 0x7f000000, 0xf0000000, + 0x0f000000, 0x11000000, 0x00000000, 0x00000000, + 0xff000000, 0xf0000000, 0x0f000000, 0xff000000, + 0xfa000000, 0xfe000000, 0xaa000000, 0xcc000000, + }; + static const struct + { + unsigned int width; + unsigned int height; + DXGI_FORMAT format; + D3D12_SUBRESOURCE_DATA data; + const unsigned int *expected_data; + } + tests[] = + { + { + 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM, + {r8g8b8a8_data, 4 * sizeof(*r8g8b8a8_data), 16 * sizeof(*r8g8b8a8_data)}, + r8g8b8a8_data, + }, + { + 4, 4, DXGI_FORMAT_A8_UNORM, + {a8_data, 4 * sizeof(*a8_data), 16 * sizeof(*a8_data)}, + a8_expected_data, + }, + };
memset(&desc, 0, sizeof(desc)); + desc.rt_width = desc.rt_height = 32; desc.no_root_signature = true; if (!init_test_context(&context, &desc)) return; @@ -9132,46 +9168,52 @@ static void test_texture(void) cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap); gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
- texture = create_texture(context.device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_STATE_COPY_DEST); - texture_data.pData = bitmap_data; - texture_data.RowPitch = 4 * sizeof(*bitmap_data); - texture_data.SlicePitch = texture_data.RowPitch * 4; - upload_texture_data(texture, &texture_data, 1, queue, command_list); - reset_command_list(command_list, context.allocator); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + texture = create_texture(context.device, + tests[i].width, tests[i].height, tests[i].format, D3D12_RESOURCE_STATE_COPY_DEST); + upload_texture_data(texture, &tests[i].data, 1, queue, command_list); + reset_command_list(command_list, context.allocator);
- transition_resource_state(command_list, texture, - D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + transition_resource_state(command_list, texture, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- ID3D12Device_CreateShaderResourceView(context.device, texture, NULL, cpu_handle); + ID3D12Device_CreateShaderResourceView(context.device, texture, NULL, cpu_handle);
- ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, red, 0, NULL); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, red, 0, NULL);
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); - ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); - ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); - ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
- transition_resource_state(command_list, context.render_target, - D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); - for (y = 0; y < 4; ++y) - { - for (x = 0; x < 4; ++x) + x_step = desc.rt_width / tests[i].width; + y_step = desc.rt_height / tests[i].height; + get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + for (y = 0; y < tests[i].height; ++y) { - unsigned int color = get_readback_uint(&rb, 4 + 8 * x, 4 + 8 * y); - ok(compare_color(color, bitmap_data[4 * y + x], 1), - "Got color 0x%08x, expected 0x%08x at (%u, %u).\n", color, bitmap_data[4 * y + x], x, y); + for (x = 0; x < tests[i].width; ++x) + { + unsigned int color = get_readback_uint(&rb, x * x_step + x_step / 2, y * y_step + y_step / 2); + ok(compare_color(color, tests[i].expected_data[tests[i].width * y + x], 1), + "Got color 0x%08x, expected 0x%08x at (%u, %u).\n", + color, tests[i].expected_data[tests[i].width * y + x], x, y); + } } + release_resource_readback(&rb); + + ID3D12Resource_Release(texture); + reset_command_list(command_list, context.allocator); } - release_resource_readback(&rb);
- ID3D12Resource_Release(texture); ID3D12DescriptorHeap_Release(heap); destroy_test_context(&context); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Rendering to A8_UNORM doesn't work yet, because we cannot easily swizzle components for render target image views.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Our test framework is quite weak when it comes to todo() handling, we probably should consider adopting wine/test.h.
--- tests/d3d12.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 9 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index a513142e5140..c140a2663973 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -143,6 +143,11 @@ static bool compare_uvec4(const struct uvec4* v1, const struct uvec4 *v2) return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; }
+static bool compare_uint8(uint8_t a, uint8_t b, unsigned int max_diff) +{ + return abs(a - b) <= max_diff; +} + static bool compare_uint16(uint16_t a, uint16_t b, unsigned int max_diff) { return abs(a - b) <= max_diff; @@ -648,6 +653,7 @@ static unsigned int format_size(DXGI_FORMAT format) switch (format) { case DXGI_FORMAT_UNKNOWN: + case DXGI_FORMAT_A8_UNORM: return 1; case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: @@ -857,6 +863,11 @@ static void *get_readback_data(struct resource_readback *rb, unsigned int x, uns return &((BYTE *)rb->data)[rb->row_pitch * y + x * element_size]; }
+static uint8_t get_readback_uint8(struct resource_readback *rb, unsigned int x, unsigned int y) +{ + return *(uint8_t *)get_readback_data(rb, x, y, sizeof(uint8_t)); +} + static uint16_t get_readback_uint16(struct resource_readback *rb, unsigned int x, unsigned int y) { return *(uint16_t *)get_readback_data(rb, x, y, sizeof(uint16_t)); @@ -935,6 +946,47 @@ static void check_sub_resource_float_(unsigned int line, ID3D12Resource *texture release_resource_readback(&rb); }
+#define check_readback_data_uint8(a, b, c, d) check_readback_data_uint8_(__LINE__, a, b, c, d) +static void check_readback_data_uint8_(unsigned int line, struct resource_readback *rb, + const RECT *rect, uint8_t expected, unsigned int max_diff) +{ + RECT r = {0, 0, rb->width, rb->height}; + unsigned int x = 0, y; + bool all_match = true; + uint8_t got = 0; + + if (rect) + r = *rect; + + for (y = r.top; y < r.bottom; ++y) + { + for (x = r.left; x < r.right; ++x) + { + got = get_readback_uint8(rb, x, y); + if (!compare_uint8(got, expected, max_diff)) + { + all_match = false; + break; + } + } + if (!all_match) + break; + } + todo_(line)(all_match, "Got 0x%02x, expected 0x%02x at (%u, %u).\n", got, expected, x, y); +} + +#define check_sub_resource_uint8(a, b, c, d, e, f) check_sub_resource_uint8_(__LINE__, a, b, c, d, e, f) +static void check_sub_resource_uint8_(unsigned int line, ID3D12Resource *texture, + unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, + uint8_t expected, unsigned int max_diff) +{ + struct resource_readback rb; + + get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list); + check_readback_data_uint8_(line, &rb, NULL, expected, max_diff); + release_resource_readback(&rb); +} + #define check_readback_data_uint16(a, b, c, d) check_readback_data_uint16_(__LINE__, a, b, c, d) static void check_readback_data_uint16_(unsigned int line, struct resource_readback *rb, const RECT *rect, uint16_t expected, unsigned int max_diff) @@ -1343,6 +1395,7 @@ struct test_context_desc bool no_render_target; bool no_root_signature; bool no_pipeline; + const D3D12_SHADER_BYTECODE *ps; };
struct test_context @@ -1472,7 +1525,7 @@ static bool init_test_context_(unsigned int line, struct test_context *context,
context->pipeline_state = create_pipeline_state_(line, device, context->root_signature, context->render_target_desc.Format, - NULL, NULL, NULL); + NULL, desc ? desc->ps : NULL, NULL);
return true; } @@ -4450,15 +4503,12 @@ static void test_fragment_coords(void)
memset(&desc, 0, sizeof(desc)); desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT; - desc.no_pipeline = true; + desc.ps = &ps; if (!init_test_context(&context, &desc)) return; command_list = context.list; queue = context.queue;
- context.pipeline_state = create_pipeline_state(context.device, - context.root_signature, desc.rt_format, NULL, &ps, NULL); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); @@ -4678,15 +4728,12 @@ static void test_scissor(void) memset(&desc, 0, sizeof(desc)); desc.rt_width = 640; desc.rt_height = 480; - desc.no_pipeline = true; + desc.ps = &ps; if (!init_test_context(&context, &desc)) return; command_list = context.list; queue = context.queue;
- context.pipeline_state = create_pipeline_state(context.device, - context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL); - set_rect(&scissor_rect, 160, 120, 480, 360);
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, red, 0, NULL); @@ -17516,6 +17563,57 @@ static void test_geometry_shader(void) destroy_test_context(&context); }
+static void test_render_a8(void) +{ + static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + ID3D12GraphicsCommandList *command_list; + struct test_context_desc desc; + struct test_context context; + ID3D12CommandQueue *queue; + + static const DWORD ps_code[] = + { +#if 0 + void main(out float4 target : SV_Target) + { + target = float4(0.0f, 0.25f, 0.5f, 1.0f); + } +#endif + 0x43425844, 0x2f09e5ff, 0xaa135d5e, 0x7860f4b5, 0x5c7b8cbc, 0x00000001, 0x000000b4, 0x00000003, + 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f, + 0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, + 0x00000000, 0x3e800000, 0x3f000000, 0x3f800000, 0x0100003e, + }; + static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)}; + + memset(&desc, 0, sizeof(desc)); + desc.rt_format = DXGI_FORMAT_A8_UNORM; + desc.ps = &ps; + if (!init_test_context(&context, &desc)) + return; + command_list = context.list; + queue = context.queue; + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL); + + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + + check_sub_resource_uint8(context.render_target, 0, queue, command_list, 0xff, 0); + + destroy_test_context(&context); +} + START_TEST(d3d12) { bool enable_debug_layer = false; @@ -17621,4 +17719,5 @@ START_TEST(d3d12) run_test(test_face_culling); run_test(test_multithread_command_queue_exec); run_test(test_geometry_shader); + run_test(test_render_a8); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com