[PATCH 2/3] vkd3d: Implement ID3D12Resource::ReadFromSubresource().
Conor McCarthy
cmccarthy at codeweavers.com
Tue Aug 6 08:16:57 CDT 2019
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
libs/vkd3d/resource.c | 92 +++++++++++++++++++++++++++++++++++++++++--
tests/d3d12.c | 10 ++---
2 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 22deaef..f34de9d 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1244,12 +1244,98 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
void *dst_data, UINT dst_row_pitch, UINT dst_slice_pitch,
UINT src_sub_resource, const D3D12_BOX *src_box)
{
- FIXME("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, "
- "src_sub_resource %u, src_box %p stub!\n",
+ struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
+ const struct vkd3d_vk_device_procs *vk_procs;
+ VkImageSubresource vk_sub_resource;
+ const struct vkd3d_format *format;
+ VkSubresourceLayout vk_layout;
+ struct d3d12_device *device;
+ void *src_map_ptr;
+ unsigned int y, z;
+ D3D12_BOX box;
+ HRESULT hr;
+ BYTE *dst;
+
+ TRACE("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, "
+ "src_sub_resource %u, src_box %p.\n",
iface, dst_data, dst_row_pitch, dst_slice_pitch,
src_sub_resource, src_box);
- return E_NOTIMPL;
+ if (src_box)
+ {
+ box = *src_box;
+ }
+ else
+ {
+ box.left = 0;
+ box.top = 0;
+ box.front = 0;
+ box.right = resource->desc.Width;
+ box.bottom = resource->desc.Height;
+ box.back = d3d12_resource_desc_get_depth(&resource->desc, src_sub_resource % resource->desc.MipLevels);
+ }
+ if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front)
+ return S_OK;
+
+ if (d3d12_resource_is_buffer(resource))
+ {
+ WARN("Buffers are not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ if (!d3d12_resource_is_cpu_accessible(resource))
+ {
+ FIXME("Not implemented for this resource type.\n");
+ return E_NOTIMPL;
+ }
+
+ device = resource->device;
+ vk_procs = &device->vk_procs;
+
+ if (!(format = vkd3d_format_from_d3d12_resource_desc(device, &resource->desc, 0)))
+ {
+ WARN("Invalid DXGI format %#x.\n", resource->desc.Format);
+ return E_INVALIDARG;
+ }
+
+ if (!resource->is_linear_texture)
+ {
+ FIXME("Not implemented for layouts other than D3D12_TEXTURE_LAYOUT_ROW_MAJOR.\n");
+ return E_NOTIMPL;
+ }
+
+ if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, &src_map_ptr)))
+ {
+ WARN("Failed to map resource %p, hr %#x.\n", resource, hr);
+ return hr;
+ }
+
+ vk_sub_resource.arrayLayer = src_sub_resource / resource->desc.MipLevels;
+ vk_sub_resource.mipLevel = src_sub_resource % resource->desc.MipLevels;
+ vk_sub_resource.aspectMask = format->vk_aspect_mask;
+ VK_CALL(vkGetImageSubresourceLayout(device->vk_device, resource->u.vk_image, &vk_sub_resource, &vk_layout));
+ TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", array pitch %#"PRIx64", depth pitch %#"PRIx64".\n",
+ vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.arrayPitch, vk_layout.depthPitch);
+
+ src_map_ptr = (BYTE*)src_map_ptr + vk_layout.offset;
+ for (z = box.front; z < box.back; ++z)
+ {
+ dst = dst_data + (z - box.front) * dst_slice_pitch;
+ for (y = box.top; y < box.bottom; y += format->block_height)
+ {
+ size_t size = (box.right - box.left) / format->block_width
+ * format->byte_count * format->block_byte_count;
+ const BYTE *src = (BYTE*)src_map_ptr + z * vk_layout.depthPitch
+ + y / format->block_height * vk_layout.rowPitch
+ + box.left / format->block_width * format->byte_count * format->block_byte_count;
+ memcpy(dst, src, size);
+ dst += dst_row_pitch;
+ }
+ }
+
+ d3d12_heap_unmap(resource->heap, resource);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource *iface,
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 80f3f2d..a7647e0 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -30227,7 +30227,7 @@ static void test_read_write_subresource(void)
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(rb_buffer, dst_buffer, row_pitch, slice_pitch, 0, &box);
- todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
ID3D12Resource_Release(rb_buffer);
@@ -30261,7 +30261,7 @@ static void test_read_write_subresource(void)
todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, NULL);
- todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Empty box */
set_box(&box, 0, 0, 0, 0, 0, 0);
@@ -30269,7 +30269,7 @@ static void test_read_write_subresource(void)
todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
- todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
for (z = 0; z < 64; ++z)
{
@@ -30304,13 +30304,13 @@ static void test_read_write_subresource(void)
/* Read region 1 */
set_box(&box, 0, 0, 0, 2, 2, 2);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
- todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Read region 2 */
set_box(&box, 2, 2, 2, 11, 13, 17);
hr = ID3D12Resource_ReadFromSubresource(src_texture, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2], row_pitch,
slice_pitch, 0, &box);
- todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
for (z = 0; z < 64; ++z)
{
--
2.22.0
More information about the wine-devel
mailing list