Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ValveSoftware/vkd3d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Bernon <rbernon@codeweavers.com>2019-10-02 18:34:59 +0300
committerAlexandre Julliard <julliard@winehq.org>2019-10-04 23:16:12 +0300
commit5553d27085420be2c1c3447857eedbb2d8b16da8 (patch)
treea6c200033cd7db2edf434f47936ccf01b9869962
parent26a82afbc40ee317b3b4ad0be087625ed800ca17 (diff)
vkd3d: Implement ID3D12Resource::WriteToSubresource().
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
-rw-r--r--libs/vkd3d/resource.c109
-rw-r--r--tests/d3d12.c14
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);