Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- libs/vkd3d/resource.c | 109 ++++++++++++++++++++++++++++++++++++++++-- tests/d3d12.c | 14 +++--- 2 files changed, 111 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index f9738f36..ccd1230c 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1289,12 +1289,111 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc UINT dst_sub_resource, const D3D12_BOX *dst_box, const void *src_data, UINT src_row_pitch, UINT src_slice_pitch) { - FIXME("iface %p, dst_sub_resource %u, dst_box %p, src_data %p, " - "src_row_pitch %u, src_slice_pitch %u stub!\n", - iface, dst_sub_resource, dst_box, - src_data, src_row_pitch, src_slice_pitch); + 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; + BYTE *dst_data, *dst; + BYTE const *src; + unsigned int y, z; + D3D12_BOX box; + size_t size; + HRESULT hr; + + TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, " + "dst_sub_resource %u, dst_box %s.\n", + iface, src_data, src_row_pitch, src_slice_pitch, dst_sub_resource, debug_d3d12_box(dst_box));
- return E_NOTIMPL; + if (d3d12_resource_is_buffer(resource)) + { + WARN("Buffers are not supported.\n"); + return E_INVALIDARG; + } + + device = resource->device; + vk_procs = &device->vk_procs; + + if (!(format = vkd3d_format_from_d3d12_resource_desc(device, &resource->desc, 0))) + { + ERR("Invalid DXGI format %#x.\n", resource->desc.Format); + return E_INVALIDARG; + } + if (format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) + { + FIXME("Not supported for format %#x.\n", format->dxgi_format); + return E_NOTIMPL; + } + + vk_sub_resource.arrayLayer = dst_sub_resource / resource->desc.MipLevels; + vk_sub_resource.mipLevel = dst_sub_resource % resource->desc.MipLevels; + vk_sub_resource.aspectMask = format->vk_aspect_mask; + + if (dst_box) + { + if (!d3d12_resource_validate_box(resource, dst_sub_resource, dst_box)) + { + WARN("Invalid box %s.\n", debug_d3d12_box(dst_box)); + return E_INVALIDARG; + } + + box = *dst_box; + } + else + { + box.left = 0; + box.top = 0; + box.front = 0; + box.right = d3d12_resource_desc_get_width(&resource->desc, vk_sub_resource.mipLevel); + box.bottom = d3d12_resource_desc_get_height(&resource->desc, vk_sub_resource.mipLevel); + box.back = d3d12_resource_desc_get_depth(&resource->desc, vk_sub_resource.mipLevel); + } + if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front) + { + WARN("Empty box %s.\n", debug_d3d12_box(dst_box)); + return S_OK; + } + + if (!d3d12_resource_is_cpu_accessible(resource)) + { + FIXME_ONCE("Not implemented for this resource type.\n"); + return E_NOTIMPL; + } + if (!(resource->flags & VKD3D_RESOURCE_LINEAR_TILING)) + { + FIXME_ONCE("Not implemented for image tiling other than VK_IMAGE_TILING_LINEAR.\n"); + return E_NOTIMPL; + } + + VK_CALL(vkGetImageSubresourceLayout(device->vk_device, resource->u.vk_image, &vk_sub_resource, &vk_layout)); + TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n", + vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch); + + if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, (void **)&dst_data))) + { + WARN("Failed to map resource %p, hr %#x.\n", resource, hr); + return hr; + } + + dst_data += vk_layout.offset; + dst_data += box.left / format->block_width * format->byte_count * format->block_byte_count; + size = (box.right - box.left) / format->block_width * format->byte_count * format->block_byte_count; + for (z = box.front; z < box.back; ++z) + { + src = (uint8_t *)src_data + (z - box.front) * src_slice_pitch; + dst = dst_data + z * vk_layout.depthPitch + box.top / format->block_height * vk_layout.rowPitch; + for (y = box.top; y < box.bottom; y += format->block_height) + { + memcpy(dst, src, size); + src += src_row_pitch; + dst += vk_layout.rowPitch; + } + } + + d3d12_heap_unmap(resource->heap, resource); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resource *iface, diff --git a/tests/d3d12.c b/tests/d3d12.c index ffefbac1..9fe47c6c 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -30507,7 +30507,7 @@ static void test_read_write_subresource(void)
set_box(&box, 0, 0, 0, 1, 1, 1); hr = ID3D12Resource_WriteToSubresource(rb_buffer, 0, &box, dst_buffer, row_pitch, slice_pitch); - todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(rb_buffer, dst_buffer, row_pitch, slice_pitch, 0, &box); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); @@ -30554,7 +30554,7 @@ static void test_read_write_subresource(void)
/* NULL box */ hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, dst_buffer, row_pitch, slice_pitch); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, NULL); todo_if(is_nvidia_device(device)) @@ -30567,7 +30567,7 @@ static void test_read_write_subresource(void)
set_box(&box, 0, 0, 0, 0, 0, 0); hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); @@ -30596,18 +30596,18 @@ static void test_read_write_subresource(void) if (i) { hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, zero_buffer, row_pitch, slice_pitch); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Write region 1 */ set_box(&box, 0, 0, 0, 2, 2, 2); hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
/* Write region 2 */ set_box(&box, 2, 2, 2, 11, 13, 17); hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2], row_pitch, slice_pitch); - todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); } else { @@ -30711,7 +30711,7 @@ static void test_read_write_subresource(void) if (got != expected) break; } - todo ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected); + ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected); release_resource_readback(&rb);
ID3D12Resource_Release(src_texture);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- libs/vkd3d/resource.c | 89 ++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 48 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index ccd1230c..dd66f175 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1072,6 +1072,43 @@ static bool d3d12_resource_validate_box(const struct d3d12_resource *resource, && !(box->bottom & height_mask); }
+static HRESULT d3d12_resource_validate_box_or_default(const struct d3d12_resource *resource, + unsigned int sub_resource_idx, const D3D12_BOX *box_in, D3D12_BOX *box_out) +{ + unsigned int mip_level = sub_resource_idx % resource->desc.MipLevels; + D3D12_BOX box; + + if (box_in) + { + if (!d3d12_resource_validate_box(resource, sub_resource_idx, box_in)) + { + WARN("Invalid box %s.\n", debug_d3d12_box(box_in)); + return E_INVALIDARG; + } + + box = *box_in; + } + else + { + box.left = 0; + box.top = 0; + box.front = 0; + box.right = d3d12_resource_desc_get_width(&resource->desc, mip_level); + box.bottom = d3d12_resource_desc_get_height(&resource->desc, mip_level); + box.back = d3d12_resource_desc_get_depth(&resource->desc, mip_level); + } + + if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front) + { + WARN("Empty box %s.\n", debug_d3d12_box(box_in)); + return S_FALSE; + } + + assert(box_out); + *box_out = box; + return S_OK; +} + /* ID3D12Resource */ static inline struct d3d12_resource *impl_from_ID3D12Resource(ID3D12Resource *iface) { @@ -1330,30 +1367,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc vk_sub_resource.mipLevel = dst_sub_resource % resource->desc.MipLevels; vk_sub_resource.aspectMask = format->vk_aspect_mask;
- if (dst_box) - { - if (!d3d12_resource_validate_box(resource, dst_sub_resource, dst_box)) - { - WARN("Invalid box %s.\n", debug_d3d12_box(dst_box)); - return E_INVALIDARG; - } - - box = *dst_box; - } - else - { - box.left = 0; - box.top = 0; - box.front = 0; - box.right = d3d12_resource_desc_get_width(&resource->desc, vk_sub_resource.mipLevel); - box.bottom = d3d12_resource_desc_get_height(&resource->desc, vk_sub_resource.mipLevel); - box.back = d3d12_resource_desc_get_depth(&resource->desc, vk_sub_resource.mipLevel); - } - if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front) - { - WARN("Empty box %s.\n", debug_d3d12_box(dst_box)); - return S_OK; - } + if ((hr = d3d12_resource_validate_box_or_default(resource, dst_sub_resource, dst_box, &box))) + return SUCCEEDED(hr) ? S_OK : hr;
if (!d3d12_resource_is_cpu_accessible(resource)) { @@ -1440,30 +1455,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour vk_sub_resource.mipLevel = src_sub_resource % resource->desc.MipLevels; vk_sub_resource.aspectMask = format->vk_aspect_mask;
- if (src_box) - { - if (!d3d12_resource_validate_box(resource, src_sub_resource, src_box)) - { - WARN("Invalid box %s.\n", debug_d3d12_box(src_box)); - return E_INVALIDARG; - } - - box = *src_box; - } - else - { - box.left = 0; - box.top = 0; - box.front = 0; - box.right = d3d12_resource_desc_get_width(&resource->desc, vk_sub_resource.mipLevel); - box.bottom = d3d12_resource_desc_get_height(&resource->desc, vk_sub_resource.mipLevel); - box.back = d3d12_resource_desc_get_depth(&resource->desc, vk_sub_resource.mipLevel); - } - if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front) - { - WARN("Empty box %s.\n", debug_d3d12_box(src_box)); - return S_OK; - } + if ((hr = d3d12_resource_validate_box_or_default(resource, src_sub_resource, src_box, &box))) + return SUCCEEDED(hr) ? S_OK : hr;
if (!d3d12_resource_is_cpu_accessible(resource)) {
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- libs/vkd3d/resource.c | 70 ++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index dd66f175..14fbf775 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1322,6 +1322,31 @@ static D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE d3d12_resource_GetGPUVirtualA return resource->gpu_address; }
+static void d3d12_resource_copy_subresource_data(void *dst_data, const void *src_data, + UINT dst_slice_pitch, UINT dst_row_pitch, UINT src_slice_pitch, UINT src_row_pitch, + const D3D12_BOX *box, const struct vkd3d_format *format) +{ + unsigned int y, z; + size_t size; + BYTE *dst; + const BYTE *src; + + assert(box); + assert(format); + size = (box->right - box->left) / format->block_width * format->byte_count * format->block_byte_count; + for (z = box->front; z < box->back; ++z) + { + dst = (uint8_t *)dst_data + (z - box->front) * dst_slice_pitch; + src = (uint8_t *)src_data + (z - box->front) * src_slice_pitch; + for (y = box->top; y < box->bottom; y += format->block_height) + { + memcpy(dst, src, size); + dst += dst_row_pitch; + src += src_row_pitch; + } + } +} + static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource *iface, UINT dst_sub_resource, const D3D12_BOX *dst_box, const void *src_data, UINT src_row_pitch, UINT src_slice_pitch) @@ -1332,11 +1357,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc const struct vkd3d_format *format; VkSubresourceLayout vk_layout; struct d3d12_device *device; - BYTE *dst_data, *dst; - BYTE const *src; - unsigned int y, z; + BYTE *dst_data; D3D12_BOX box; - size_t size; HRESULT hr;
TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, " @@ -1393,18 +1415,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc
dst_data += vk_layout.offset; dst_data += box.left / format->block_width * format->byte_count * format->block_byte_count; - size = (box.right - box.left) / format->block_width * format->byte_count * format->block_byte_count; - for (z = box.front; z < box.back; ++z) - { - src = (uint8_t *)src_data + (z - box.front) * src_slice_pitch; - dst = dst_data + z * vk_layout.depthPitch + box.top / format->block_height * vk_layout.rowPitch; - for (y = box.top; y < box.bottom; y += format->block_height) - { - memcpy(dst, src, size); - src += src_row_pitch; - dst += vk_layout.rowPitch; - } - } + dst_data += box.top / format->block_height * vk_layout.rowPitch; + dst_data += box.front * vk_layout.depthPitch; + + d3d12_resource_copy_subresource_data(dst_data, src_data, + vk_layout.depthPitch, vk_layout.rowPitch, src_slice_pitch, src_row_pitch, + &box, format);
d3d12_heap_unmap(resource->heap, resource);
@@ -1421,10 +1437,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour const struct vkd3d_format *format; VkSubresourceLayout vk_layout; struct d3d12_device *device; - BYTE *src_data, *src, *dst; - unsigned int y, z; + BYTE *src_data; D3D12_BOX box; - size_t size; HRESULT hr;
TRACE("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, " @@ -1481,18 +1495,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
src_data += vk_layout.offset; src_data += box.left / format->block_width * format->byte_count * format->block_byte_count; - size = (box.right - box.left) / format->block_width * format->byte_count * format->block_byte_count; - for (z = box.front; z < box.back; ++z) - { - dst = (uint8_t *)dst_data + (z - box.front) * dst_slice_pitch; - src = src_data + z * vk_layout.depthPitch + box.top / format->block_height * vk_layout.rowPitch; - for (y = box.top; y < box.bottom; y += format->block_height) - { - memcpy(dst, src, size); - dst += dst_row_pitch; - src += vk_layout.rowPitch; - } - } + src_data += box.top / format->block_height * vk_layout.rowPitch; + src_data += box.front * vk_layout.depthPitch; + + d3d12_resource_copy_subresource_data(dst_data, src_data, + dst_slice_pitch, dst_row_pitch, vk_layout.depthPitch, vk_layout.rowPitch, + &box, format);
d3d12_heap_unmap(resource->heap, resource);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- libs/vkd3d/resource.c | 111 +++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 67 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 14fbf775..764adff3 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1347,24 +1347,15 @@ static void d3d12_resource_copy_subresource_data(void *dst_data, const void *src } }
-static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource *iface, - UINT dst_sub_resource, const D3D12_BOX *dst_box, const void *src_data, - UINT src_row_pitch, UINT src_slice_pitch) +static HRESULT d3d12_resource_map_subresource_data(struct d3d12_resource *resource, + unsigned int sub_resource_idx, const struct vkd3d_format *format, + VkSubresourceLayout *vk_layout, void **data) { - struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); + struct d3d12_device *device; const struct vkd3d_vk_device_procs *vk_procs; VkImageSubresource vk_sub_resource; - const struct vkd3d_format *format; - VkSubresourceLayout vk_layout; - struct d3d12_device *device; - BYTE *dst_data; - D3D12_BOX box; HRESULT hr;
- TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, " - "dst_sub_resource %u, dst_box %s.\n", - iface, src_data, src_row_pitch, src_slice_pitch, dst_sub_resource, debug_d3d12_box(dst_box)); - if (d3d12_resource_is_buffer(resource)) { WARN("Buffers are not supported.\n"); @@ -1374,24 +1365,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc device = resource->device; vk_procs = &device->vk_procs;
- if (!(format = vkd3d_format_from_d3d12_resource_desc(device, &resource->desc, 0))) - { - ERR("Invalid DXGI format %#x.\n", resource->desc.Format); - return E_INVALIDARG; - } + assert(format); if (format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) { FIXME("Not supported for format %#x.\n", format->dxgi_format); return E_NOTIMPL; }
- vk_sub_resource.arrayLayer = dst_sub_resource / resource->desc.MipLevels; - vk_sub_resource.mipLevel = dst_sub_resource % resource->desc.MipLevels; + vk_sub_resource.arrayLayer = sub_resource_idx / resource->desc.MipLevels; + vk_sub_resource.mipLevel = sub_resource_idx % resource->desc.MipLevels; vk_sub_resource.aspectMask = format->vk_aspect_mask;
- if ((hr = d3d12_resource_validate_box_or_default(resource, dst_sub_resource, dst_box, &box))) - return SUCCEEDED(hr) ? S_OK : hr; - if (!d3d12_resource_is_cpu_accessible(resource)) { FIXME_ONCE("Not implemented for this resource type.\n"); @@ -1403,16 +1387,48 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc return E_NOTIMPL; }
- VK_CALL(vkGetImageSubresourceLayout(device->vk_device, resource->u.vk_image, &vk_sub_resource, &vk_layout)); + assert(vk_layout); + VK_CALL(vkGetImageSubresourceLayout(device->vk_device, resource->u.vk_image, &vk_sub_resource, vk_layout)); TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n", - vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch); + vk_layout->offset, vk_layout->size, vk_layout->rowPitch, vk_layout->depthPitch);
- if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, (void **)&dst_data))) + assert(data); + if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, data))) { WARN("Failed to map resource %p, hr %#x.\n", resource, hr); return hr; }
+ return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource *iface, + UINT dst_sub_resource, const D3D12_BOX *dst_box, const void *src_data, + UINT src_row_pitch, UINT src_slice_pitch) +{ + struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); + const struct vkd3d_format *format; + VkSubresourceLayout vk_layout; + BYTE *dst_data; + D3D12_BOX box; + HRESULT hr; + + TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, " + "dst_sub_resource %u, dst_box %s.\n", + iface, src_data, src_row_pitch, src_slice_pitch, dst_sub_resource, debug_d3d12_box(dst_box)); + + if (!(format = vkd3d_format_from_d3d12_resource_desc(resource->device, &resource->desc, 0))) + { + ERR("Invalid DXGI format %#x.\n", resource->desc.Format); + return E_INVALIDARG; + } + + if ((hr = d3d12_resource_validate_box_or_default(resource, dst_sub_resource, dst_box, &box))) + return SUCCEEDED(hr) ? S_OK : hr; + + if (FAILED(hr = d3d12_resource_map_subresource_data(resource, dst_sub_resource, format, &vk_layout, (void**)&dst_data))) + return hr; + dst_data += vk_layout.offset; dst_data += box.left / format->block_width * format->byte_count * format->block_byte_count; dst_data += box.top / format->block_height * vk_layout.rowPitch; @@ -1432,11 +1448,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour UINT src_sub_resource, const D3D12_BOX *src_box) { 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; BYTE *src_data; D3D12_BOX box; HRESULT hr; @@ -1445,53 +1458,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour "src_sub_resource %u, src_box %s.\n", iface, dst_data, dst_row_pitch, dst_slice_pitch, src_sub_resource, debug_d3d12_box(src_box));
- if (d3d12_resource_is_buffer(resource)) - { - WARN("Buffers are not supported.\n"); - return E_INVALIDARG; - } - - device = resource->device; - vk_procs = &device->vk_procs; - - if (!(format = vkd3d_format_from_d3d12_resource_desc(device, &resource->desc, 0))) + if (!(format = vkd3d_format_from_d3d12_resource_desc(resource->device, &resource->desc, 0))) { ERR("Invalid DXGI format %#x.\n", resource->desc.Format); return E_INVALIDARG; } - if (format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) - { - FIXME("Not supported for format %#x.\n", format->dxgi_format); - return E_NOTIMPL; - } - - 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;
if ((hr = d3d12_resource_validate_box_or_default(resource, src_sub_resource, src_box, &box))) return SUCCEEDED(hr) ? S_OK : hr;
- if (!d3d12_resource_is_cpu_accessible(resource)) - { - FIXME_ONCE("Not implemented for this resource type.\n"); - return E_NOTIMPL; - } - if (!(resource->flags & VKD3D_RESOURCE_LINEAR_TILING)) - { - FIXME_ONCE("Not implemented for image tiling other than VK_IMAGE_TILING_LINEAR.\n"); - return E_NOTIMPL; - } - - VK_CALL(vkGetImageSubresourceLayout(device->vk_device, resource->u.vk_image, &vk_sub_resource, &vk_layout)); - TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n", - vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch); - - if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, (void **)&src_data))) - { - WARN("Failed to map resource %p, hr %#x.\n", resource, hr); + if (FAILED(hr = d3d12_resource_map_subresource_data(resource, src_sub_resource, format, &vk_layout, (void**)&src_data))) return hr; - }
src_data += vk_layout.offset; src_data += box.left / format->block_width * format->byte_count * format->block_byte_count;