From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 102 ++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 43 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index b26b1221e7a..2c13e7fee10 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -4677,10 +4677,10 @@ const VkDescriptorImageInfo *wined3d_texture_vk_get_default_image_info(struct wi return &texture_vk->default_image_info; }
-static void wined3d_texture_vk_upload_data(struct wined3d_context *context, - const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, +static void wined3d_texture_vk_upload_plane(struct wined3d_context *context, VkImageAspectFlags vk_aspect, + const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *plane_format, const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, - struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) { struct wined3d_texture_vk *dst_texture_vk = wined3d_texture_vk(dst_texture); @@ -4695,26 +4695,16 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, VkBufferMemoryBarrier vk_barrier; VkImageSubresourceRange vk_range; struct wined3d_bo_vk staging_bo; - VkImageAspectFlags aspect_mask; struct wined3d_bo_vk *src_bo; struct wined3d_range range; VkBufferImageCopy region; size_t src_offset; void *map_ptr;
- TRACE("context %p, src_bo_addr %s, src_format %s, src_box %s, src_row_pitch %u, src_slice_pitch %u, " - "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_x %u, dst_y %u, dst_z %u.\n", - context, debug_const_bo_address(src_bo_addr), debug_d3dformat(src_format->id), debug_box(src_box), - src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, - wined3d_debug_location(dst_location), dst_x, dst_y, dst_z); - - if (src_format->id != dst_texture->resource.format->id) - { - FIXME("Unhandled format conversion (%s -> %s).\n", - debug_d3dformat(src_format->id), - debug_d3dformat(dst_texture->resource.format->id)); - return; - } + TRACE("context %p, vk_aspect %#x, src_bo_addr %s, plane_format %s, src_box %s, src_row_pitch %u, src_slice_pitch %u, " + "dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u.\n", + context, vk_aspect, debug_const_bo_address(src_bo_addr), debug_d3dformat(plane_format->id), debug_box(src_box), + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z);
dst_level = dst_sub_resource_idx % dst_texture->level_count; wined3d_texture_get_pitch(dst_texture, dst_level, &dst_row_pitch, &dst_slice_pitch); @@ -4723,25 +4713,6 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, if (dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_3D) src_slice_pitch = dst_slice_pitch = 0;
- if (dst_location != WINED3D_LOCATION_TEXTURE_RGB) - { - FIXME("Unhandled location %s.\n", wined3d_debug_location(dst_location)); - return; - } - - if (wined3d_resource_get_sample_count(&dst_texture_vk->t.resource) > 1) - { - FIXME("Not supported for multisample textures.\n"); - return; - } - - aspect_mask = vk_aspect_mask_from_format(dst_texture->resource.format); - if (wined3d_popcount(aspect_mask) > 1) - { - FIXME("Unhandled multi-aspect format %s.\n", debug_d3dformat(dst_texture->resource.format->id)); - return; - } - sub_resource = &dst_texture_vk->t.sub_resources[dst_sub_resource_idx]; vk_info = context_vk->vk_info;
@@ -4750,8 +4721,8 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, src_depth = src_box->back - src_box->front;
src_offset = src_box->front * src_slice_pitch - + (src_box->top / src_format->block_height) * src_row_pitch - + (src_box->left / src_format->block_width) * src_format->block_byte_count; + + (src_box->top / plane_format->block_height) * src_row_pitch + + (src_box->left / plane_format->block_width) * plane_format->block_byte_count;
if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) { @@ -4765,7 +4736,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, { unsigned int staging_row_pitch, staging_slice_pitch, staging_size;
- wined3d_format_calculate_pitch(src_format, context->device->surface_alignment, src_width, src_height, + wined3d_format_calculate_pitch(plane_format, context->device->surface_alignment, src_width, src_height, &staging_row_pitch, &staging_slice_pitch); staging_size = staging_slice_pitch * src_depth;
@@ -4786,7 +4757,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, return; }
- wined3d_format_copy_data(src_format, src_bo_addr->addr + src_offset, src_row_pitch, src_slice_pitch, + wined3d_format_copy_data(plane_format, src_bo_addr->addr + src_offset, src_row_pitch, src_slice_pitch, map_ptr, staging_row_pitch, staging_slice_pitch, src_width, src_height, src_depth);
range.offset = 0; @@ -4821,7 +4792,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL)); }
- vk_range.aspectMask = aspect_mask; + vk_range.aspectMask = vk_aspect; vk_range.baseMipLevel = dst_level; vk_range.levelCount = 1; vk_range.baseArrayLayer = dst_sub_resource_idx / dst_texture_vk->t.level_count; @@ -4835,9 +4806,9 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, dst_texture_vk->image.vk_image, &vk_range);
region.bufferOffset = src_bo->b.buffer_offset + src_offset; - region.bufferRowLength = (src_row_pitch / src_format->block_byte_count) * src_format->block_width; + region.bufferRowLength = (src_row_pitch / plane_format->block_byte_count) * plane_format->block_width; if (src_row_pitch) - region.bufferImageHeight = (src_slice_pitch / src_row_pitch) * src_format->block_height; + region.bufferImageHeight = (src_slice_pitch / src_row_pitch) * plane_format->block_height; else region.bufferImageHeight = 1; region.imageSubresource.aspectMask = vk_range.aspectMask; @@ -4874,6 +4845,51 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, } }
+static void wined3d_texture_vk_upload_data(struct wined3d_context *context, + const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format, + const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + VkImageAspectFlags aspect_mask; + + TRACE("context %p, src_bo_addr %s, src_format %s, src_box %s, src_row_pitch %u, src_slice_pitch %u, " + "dst_texture %p, dst_sub_resource_idx %u, dst_location %s, dst_x %u, dst_y %u, dst_z %u.\n", + context, debug_const_bo_address(src_bo_addr), debug_d3dformat(src_format->id), debug_box(src_box), + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, + wined3d_debug_location(dst_location), dst_x, dst_y, dst_z); + + if (src_format->id != dst_texture->resource.format->id) + { + FIXME("Unhandled format conversion (%s -> %s).\n", + debug_d3dformat(src_format->id), + debug_d3dformat(dst_texture->resource.format->id)); + return; + } + + if (dst_location != WINED3D_LOCATION_TEXTURE_RGB) + { + FIXME("Unhandled location %s.\n", wined3d_debug_location(dst_location)); + return; + } + + if (wined3d_resource_get_sample_count(&dst_texture->resource) > 1) + { + FIXME("Not supported for multisample textures.\n"); + return; + } + + aspect_mask = vk_aspect_mask_from_format(dst_texture->resource.format); + if (wined3d_popcount(aspect_mask) > 1) + { + FIXME("Unhandled multi-aspect format %s.\n", debug_d3dformat(dst_texture->resource.format->id)); + return; + } + + wined3d_texture_vk_upload_plane(context, aspect_mask, src_bo_addr, src_format, src_box, + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); +} + static void wined3d_texture_vk_download_data(struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 157 +++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 61 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 2c13e7fee10..1ab4db200d2 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -4890,10 +4890,10 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); }
-static void wined3d_texture_vk_download_data(struct wined3d_context *context, - struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, +static void wined3d_texture_vk_download_plane(struct wined3d_context *context, VkImageAspectFlags vk_aspect, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, - const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + const struct wined3d_format *plane_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, unsigned int dst_row_pitch, unsigned int dst_slice_pitch) { struct wined3d_texture_vk *src_texture_vk = wined3d_texture_vk(src_texture); @@ -4908,62 +4908,18 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, VkImageSubresourceRange vk_range; VkBufferMemoryBarrier vk_barrier; struct wined3d_bo_vk staging_bo; - VkImageAspectFlags aspect_mask; struct wined3d_bo_vk *dst_bo; VkBufferImageCopy region; size_t dst_offset = 0; void *map_ptr;
- TRACE("context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_box %s, dst_bo_addr %s, " - "dst_format %s, dst_x %u, dst_y %u, dst_z %u, dst_row_pitch %u, dst_slice_pitch %u.\n", - context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), - debug_box(src_box), debug_bo_address(dst_bo_addr), debug_d3dformat(dst_format->id), + TRACE("context %p, vk_aspect %#x, src_texture %p, src_sub_resource_idx %u, src_box %s, dst_bo_addr %s, " + "plane_format %s, dst_x %u, dst_y %u, dst_z %u, dst_row_pitch %u, dst_slice_pitch %u.\n", + context, vk_aspect, src_texture, src_sub_resource_idx, + debug_box(src_box), debug_bo_address(dst_bo_addr), debug_d3dformat(plane_format->id), dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch);
- if (src_location != WINED3D_LOCATION_TEXTURE_RGB) - { - FIXME("Unhandled location %s.\n", wined3d_debug_location(src_location)); - return; - } - src_level = src_sub_resource_idx % src_texture->level_count; - src_width = wined3d_texture_get_level_width(src_texture, src_level); - src_height = wined3d_texture_get_level_height(src_texture, src_level); - src_depth = wined3d_texture_get_level_depth(src_texture, src_level); - if (src_box->left || src_box->top || src_box->right != src_width || src_box->bottom != src_height - || src_box->front || src_box->back != src_depth) - { - FIXME("Unhandled source box %s.\n", debug_box(src_box)); - return; - } - - if (dst_format->id != src_texture->resource.format->id) - { - FIXME("Unhandled format conversion (%s -> %s).\n", - debug_d3dformat(src_texture->resource.format->id), - debug_d3dformat(dst_format->id)); - return; - } - - if (dst_x || dst_y || dst_z) - { - FIXME("Unhandled destination (%u, %u, %u).\n", dst_x, dst_y, dst_z); - return; - } - - if (wined3d_resource_get_sample_count(&src_texture_vk->t.resource) > 1) - { - FIXME("Not supported for multisample textures.\n"); - return; - } - - aspect_mask = vk_aspect_mask_from_format(src_texture->resource.format); - if (wined3d_popcount(aspect_mask) > 1) - { - FIXME("Unhandled multi-aspect format %s.\n", debug_d3dformat(src_texture->resource.format->id)); - return; - } - wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); if (src_texture->resource.type == WINED3D_RTYPE_TEXTURE_1D) src_row_pitch = dst_row_pitch = 0; @@ -4972,6 +4928,11 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
sub_resource = &src_texture_vk->t.sub_resources[src_sub_resource_idx]; vk_info = context_vk->vk_info; + + src_width = src_box->right - src_box->left; + src_height = src_box->bottom - src_box->top; + src_depth = src_box->back - src_box->front; + if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) { ERR("Failed to get command buffer.\n"); @@ -4992,15 +4953,15 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
dst_bo = &staging_bo;
- region.bufferRowLength = (src_row_pitch / dst_format->block_byte_count) * dst_format->block_width; + region.bufferRowLength = (src_row_pitch / plane_format->block_byte_count) * plane_format->block_width; if (src_row_pitch) - region.bufferImageHeight = (src_slice_pitch / src_row_pitch) * dst_format->block_height; + region.bufferImageHeight = (src_slice_pitch / src_row_pitch) * plane_format->block_height; else region.bufferImageHeight = 1;
- if (src_row_pitch % dst_format->byte_count) + if (src_row_pitch % plane_format->byte_count) { - FIXME("Row pitch %u is not a multiple of byte count %u.\n", src_row_pitch, dst_format->byte_count); + FIXME("Row pitch %u is not a multiple of byte count %u.\n", src_row_pitch, plane_format->byte_count); return; } if (src_row_pitch && src_slice_pitch % src_row_pitch) @@ -5013,15 +4974,15 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, { dst_bo = wined3d_bo_vk(dst_bo_addr->buffer_object);
- region.bufferRowLength = (dst_row_pitch / dst_format->block_byte_count) * dst_format->block_width; + region.bufferRowLength = (dst_row_pitch / plane_format->block_byte_count) * plane_format->block_width; if (dst_row_pitch) - region.bufferImageHeight = (dst_slice_pitch / dst_row_pitch) * dst_format->block_height; + region.bufferImageHeight = (dst_slice_pitch / dst_row_pitch) * plane_format->block_height; else region.bufferImageHeight = 1;
- if (dst_row_pitch % dst_format->byte_count) + if (dst_row_pitch % plane_format->byte_count) { - FIXME("Row pitch %u is not a multiple of byte count %u.\n", dst_row_pitch, dst_format->byte_count); + FIXME("Row pitch %u is not a multiple of byte count %u.\n", dst_row_pitch, plane_format->byte_count); return; } if (dst_row_pitch && dst_slice_pitch % dst_row_pitch) @@ -5047,7 +5008,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL)); }
- vk_range.aspectMask = aspect_mask; + vk_range.aspectMask = vk_aspect; vk_range.baseMipLevel = src_level; vk_range.levelCount = 1; vk_range.baseArrayLayer = src_sub_resource_idx / src_texture_vk->t.level_count; @@ -5100,7 +5061,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, return; }
- wined3d_format_copy_data(dst_format, map_ptr, src_row_pitch, src_slice_pitch, + wined3d_format_copy_data(plane_format, map_ptr, src_row_pitch, src_slice_pitch, dst_bo_addr->addr, dst_row_pitch, dst_slice_pitch, src_box->right - src_box->left, src_box->bottom - src_box->top, src_box->back - src_box->front);
@@ -5125,6 +5086,80 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, } }
+static void wined3d_texture_vk_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) +{ + unsigned int src_level, src_width, src_height, src_depth; + VkImageAspectFlags aspect_mask; + + TRACE("context %p, src_texture %p, src_sub_resource_idx %u, src_location %s, src_box %s, dst_bo_addr %s, " + "dst_format %s, dst_x %u, dst_y %u, dst_z %u, dst_row_pitch %u, dst_slice_pitch %u.\n", + context, src_texture, src_sub_resource_idx, wined3d_debug_location(src_location), + debug_box(src_box), debug_bo_address(dst_bo_addr), debug_d3dformat(dst_format->id), + dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); + + if (src_location != WINED3D_LOCATION_TEXTURE_RGB) + { + FIXME("Unhandled location %s.\n", wined3d_debug_location(src_location)); + return; + } + + src_level = src_sub_resource_idx % src_texture->level_count; + src_width = wined3d_texture_get_level_width(src_texture, src_level); + src_height = wined3d_texture_get_level_height(src_texture, src_level); + src_depth = wined3d_texture_get_level_depth(src_texture, src_level); + if (src_box->left || src_box->top || src_box->right != src_width || src_box->bottom != src_height + || src_box->front || src_box->back != src_depth) + { + FIXME("Unhandled source box %s.\n", debug_box(src_box)); + return; + } + + src_level = src_sub_resource_idx % src_texture->level_count; + src_width = wined3d_texture_get_level_width(src_texture, src_level); + src_height = wined3d_texture_get_level_height(src_texture, src_level); + src_depth = wined3d_texture_get_level_depth(src_texture, src_level); + if (src_box->left || src_box->top || src_box->right != src_width || src_box->bottom != src_height + || src_box->front || src_box->back != src_depth) + { + FIXME("Unhandled source box %s.\n", debug_box(src_box)); + return; + } + + if (dst_format->id != src_texture->resource.format->id) + { + FIXME("Unhandled format conversion (%s -> %s).\n", + debug_d3dformat(src_texture->resource.format->id), + debug_d3dformat(dst_format->id)); + return; + } + + if (dst_x || dst_y || dst_z) + { + FIXME("Unhandled destination (%u, %u, %u).\n", dst_x, dst_y, dst_z); + return; + } + + if (wined3d_resource_get_sample_count(&src_texture->resource) > 1) + { + FIXME("Not supported for multisample textures.\n"); + return; + } + + aspect_mask = vk_aspect_mask_from_format(src_texture->resource.format); + if (wined3d_popcount(aspect_mask) > 1) + { + FIXME("Unhandled multi-aspect format %s.\n", debug_d3dformat(src_texture->resource.format->id)); + return; + } + + wined3d_texture_vk_download_plane(context, aspect_mask, src_texture, src_sub_resource_idx, + src_box, dst_bo_addr, dst_format, dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); +} + static bool wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk, unsigned int sub_resource_idx, struct wined3d_context *context) {
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 1ab4db200d2..2f773978f9b 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -4886,8 +4886,37 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context, return; }
- wined3d_texture_vk_upload_plane(context, aspect_mask, src_bo_addr, src_format, src_box, - src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); + if (src_format->attrs & WINED3D_FORMAT_ATTR_PLANAR) + { + struct wined3d_const_bo_address uv_bo_addr; + const struct wined3d_format *plane_format; + struct wined3d_box uv_box; + + plane_format = wined3d_get_format(context->device->adapter, src_format->plane_formats[0], 0); + wined3d_texture_vk_upload_plane(context, VK_IMAGE_ASPECT_PLANE_0_BIT, src_bo_addr, plane_format, src_box, + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); + + uv_bo_addr = *src_bo_addr; + uv_bo_addr.addr += src_slice_pitch; + uv_box = *src_box; + uv_box.left /= src_format->uv_width; + uv_box.right /= src_format->uv_width; + uv_box.top /= src_format->uv_height; + uv_box.bottom /= src_format->uv_height; + dst_x /= src_format->uv_width; + dst_y /= src_format->uv_height; + src_row_pitch = src_row_pitch * 2 / src_format->uv_width; + src_slice_pitch = src_slice_pitch * 2 / src_format->uv_width / src_format->uv_height; + + plane_format = wined3d_get_format(context->device->adapter, src_format->plane_formats[1], 0); + wined3d_texture_vk_upload_plane(context, VK_IMAGE_ASPECT_PLANE_1_BIT, &uv_bo_addr, plane_format, &uv_box, + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); + } + else + { + wined3d_texture_vk_upload_plane(context, aspect_mask, src_bo_addr, src_format, src_box, + src_row_pitch, src_slice_pitch, dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z); + } }
static void wined3d_texture_vk_download_plane(struct wined3d_context *context, VkImageAspectFlags vk_aspect,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 2f773978f9b..5a98ec6cd90 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5185,8 +5185,37 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context, return; }
- wined3d_texture_vk_download_plane(context, aspect_mask, src_texture, src_sub_resource_idx, - src_box, dst_bo_addr, dst_format, dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); + if (dst_format->attrs & WINED3D_FORMAT_ATTR_PLANAR) + { + const struct wined3d_format *plane_format; + struct wined3d_bo_address uv_bo_addr; + struct wined3d_box uv_box; + + plane_format = wined3d_get_format(context->device->adapter, dst_format->plane_formats[0], 0); + wined3d_texture_vk_download_plane(context, VK_IMAGE_ASPECT_PLANE_0_BIT, src_texture, src_sub_resource_idx, + src_box, dst_bo_addr, plane_format, dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); + + uv_bo_addr = *dst_bo_addr; + uv_bo_addr.addr += dst_slice_pitch; + uv_box = *src_box; + uv_box.left /= dst_format->uv_width; + uv_box.right /= dst_format->uv_width; + uv_box.top /= dst_format->uv_height; + uv_box.bottom /= dst_format->uv_height; + dst_x /= dst_format->uv_width; + dst_y /= dst_format->uv_height; + dst_row_pitch = dst_row_pitch * 2 / dst_format->uv_width; + dst_slice_pitch = dst_slice_pitch * 2 / dst_format->uv_width / dst_format->uv_height; + + plane_format = wined3d_get_format(context->device->adapter, dst_format->plane_formats[1], 0); + wined3d_texture_vk_download_plane(context, VK_IMAGE_ASPECT_PLANE_1_BIT, src_texture, src_sub_resource_idx, + &uv_box, &uv_bo_addr, plane_format, dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); + } + else + { + wined3d_texture_vk_download_plane(context, aspect_mask, src_texture, src_sub_resource_idx, + src_box, dst_bo_addr, dst_format, dst_x, dst_y, dst_z, dst_row_pitch, dst_slice_pitch); + } }
static bool wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 5a98ec6cd90..14c3aa419a8 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -7090,6 +7090,7 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ } else { + const struct wined3d_format *src_format = src_texture_vk->t.resource.format; VkImageCopy region;
region.srcSubresource.aspectMask = vk_src_range.aspectMask; @@ -7110,8 +7111,28 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ region.extent.height = src_rect->bottom - src_rect->top; region.extent.depth = 1;
- VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->image.vk_image, src_layout, - dst_texture_vk->image.vk_image, dst_layout, 1, ®ion)); + if (src_format->attrs & WINED3D_FORMAT_ATTR_PLANAR) + { + region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT; + region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT; + VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->image.vk_image, src_layout, + dst_texture_vk->image.vk_image, dst_layout, 1, ®ion)); + region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT; + region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT; + region.srcOffset.x /= src_format->uv_width; + region.srcOffset.y /= src_format->uv_height; + region.dstOffset.x /= src_format->uv_width; + region.dstOffset.y /= src_format->uv_height; + region.extent.width /= src_format->uv_width; + region.extent.height /= src_format->uv_height; + VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->image.vk_image, src_layout, + dst_texture_vk->image.vk_image, dst_layout, 1, ®ion)); + } + else + { + VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->image.vk_image, src_layout, + dst_texture_vk->image.vk_image, dst_layout, 1, ®ion)); + } }
wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/adapter_vk.c | 2 ++ dlls/wined3d/wined3d_vk.h | 1 + 2 files changed, 3 insertions(+)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 60546d86597..cf6cf19ccb9 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2367,6 +2367,7 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk {VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, true}, {VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_API_VERSION_1_1}, {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,VK_API_VERSION_1_2}, + {VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_API_VERSION_1_1}, {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_API_VERSION_1_1}, {VK_KHR_SWAPCHAIN_EXTENSION_NAME, ~0u, true}, }; @@ -2387,6 +2388,7 @@ static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk {VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, WINED3D_VK_EXT_VERTEX_ATTRIBUTE_DIVISOR}, {VK_KHR_MAINTENANCE2_EXTENSION_NAME, WINED3D_VK_KHR_MAINTENANCE2}, {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE}, + {VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, WINED3D_VK_KHR_SAMPLER_YCBCR_CONVERSION}, {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, WINED3D_VK_KHR_SHADER_DRAW_PARAMETERS}, };
diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index a9f535fa1bd..1bc40223af6 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -246,6 +246,7 @@ enum wined3d_vk_extension WINED3D_VK_EXT_VERTEX_ATTRIBUTE_DIVISOR, WINED3D_VK_KHR_MAINTENANCE2, WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, + WINED3D_VK_KHR_SAMPLER_YCBCR_CONVERSION, WINED3D_VK_KHR_SHADER_DRAW_PARAMETERS,
WINED3D_VK_EXT_COUNT,
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 3 ++- dlls/wined3d/utils.c | 53 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 14c3aa419a8..d12cadd71fc 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5380,7 +5380,8 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, format_vk = wined3d_format_vk(resource->format);
if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain - || (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS)) + || (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS) + || (format_vk->f.attrs & WINED3D_FORMAT_ATTR_PLANAR)) { /* For UAVs, we need this in case a clear necessitates creation of a new view * with a different format. */ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index e5969daa527..ac354918940 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4242,7 +4242,7 @@ fail: return FALSE; }
-static void init_vulkan_format_info(struct wined3d_format_vk *format, +static void init_vulkan_format_info(struct wined3d_adapter *adapter, struct wined3d_format_vk *format, const struct wined3d_vk_info *vk_info, VkPhysicalDevice vk_physical_device) { static const struct @@ -4329,6 +4329,7 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, {WINED3DFMT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, }, {WINED3DFMT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, }, {WINED3DFMT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, }, + {WINED3DFMT_NV12, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,}, }; VkFormat vk_format = VK_FORMAT_UNDEFINED; VkImageFormatProperties image_properties; @@ -4356,6 +4357,10 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, return; }
+ if ((format->f.attrs & WINED3D_FORMAT_ATTR_PLANAR) && !vk_info->supported[WINED3D_VK_KHR_SAMPLER_YCBCR_CONVERSION] + && vk_info->api_version < VK_API_VERSION_1_1) + return; + format->vk_format = vk_format; if (fixup) format->f.color_fixup = create_color_fixup_desc_from_string(fixup); @@ -4375,13 +4380,45 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, } }
+ caps = 0; + texture_flags = properties.linearTilingFeatures | properties.optimalTilingFeatures; + if ((texture_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) + && (texture_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) + caps |= WINED3D_FORMAT_CAP_BLIT; + + if (format->f.attrs & WINED3D_FORMAT_ATTR_PLANAR) + { + /* Direct3D only does planar views, without YCbCr conversion. + * In order to query whether this is supported on the Vulkan side, + * we need to ignore the feature flags for the planar image, + * and instead combine the feature flags for the corresponding format + * for each plane. + * + * Somewhat oddly, Vulkan doesn't distinguish "R8_UNORM (e.g.) views of + * a planar image are supported" from "R8_UNORM views are supported in + * general", which means that we don't really know through querying if + * a given YUV format is supported. Fortunately we need blit support + * anyway, and it seems fair to assume that if blit is supported for a + * format, then we can also create planar views. */ + if (!caps) + { + TRACE("Unsupported format %s (no blit support).\n", debug_d3dformat(format->f.id)); + return; + } + + caps = ~0u; + for (unsigned int i = 0; i < 2; ++i) + caps &= get_format_internal(adapter, format->f.plane_formats[i])->caps[WINED3D_GL_RES_TYPE_TEX_2D]; + format->f.caps[WINED3D_GL_RES_TYPE_TEX_2D] |= caps; + TRACE("Caps %#08x are supported for format %s.\n", caps, debug_d3dformat(format->f.id)); + return; + } + if (properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) format->f.caps[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3D_FORMAT_CAP_VERTEX_ATTRIBUTE; if (properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) format->f.caps[WINED3D_GL_RES_TYPE_BUFFER] |= WINED3D_FORMAT_CAP_TEXTURE;
- caps = 0; - texture_flags = properties.linearTilingFeatures | properties.optimalTilingFeatures; if (texture_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { caps |= WINED3D_FORMAT_CAP_TEXTURE | WINED3D_FORMAT_CAP_VTF; @@ -4406,15 +4443,11 @@ static void init_vulkan_format_info(struct wined3d_format_vk *format, { caps |= WINED3D_FORMAT_CAP_UNORDERED_ACCESS; } - if ((texture_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) - && (texture_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) - { - caps |= WINED3D_FORMAT_CAP_BLIT; - } - if (!(~caps & (WINED3D_FORMAT_CAP_RENDERTARGET | WINED3D_FORMAT_CAP_FILTERING))) caps |= WINED3D_FORMAT_CAP_GEN_MIPMAP;
+ TRACE("Caps %#08x are supported for format %s.\n", caps, debug_d3dformat(format->f.id)); + format->f.caps[WINED3D_GL_RES_TYPE_TEX_1D] |= caps; format->f.caps[WINED3D_GL_RES_TYPE_TEX_2D] |= caps; format->f.caps[WINED3D_GL_RES_TYPE_TEX_3D] |= caps; @@ -4459,7 +4492,7 @@ BOOL wined3d_adapter_vk_init_format_info(struct wined3d_adapter_vk *adapter_vk, format = wined3d_format_vk_mutable(get_format_by_idx(adapter, i));
if (format->f.id) - init_vulkan_format_info(format, vk_info, vk_physical_device); + init_vulkan_format_info(adapter, format, vk_info, vk_physical_device); }
if (!init_typeless_formats(adapter)) goto fail;
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d11/tests/d3d11.c | 154 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 3e9ccc42e33..7e8a810323a 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -22,6 +22,7 @@ #include <limits.h> #include <math.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> #define COBJMACROS #include "initguid.h" @@ -36326,21 +36327,22 @@ static void test_nv12(void) for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx) { /* I need only two uints in the cbuffer, but the size must be a multiple of 16. */ + ID3D11Texture2D *texture, *texture2, *check_texture, *staging_texture; + unsigned int i, j, image_size, broken_warp_pitch; D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc = {0}; D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {0}; D3D11_SUBRESOURCE_DATA subresource_data = {0}; D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = {0}; - ID3D11Texture2D *texture, *check_texture; char *content, *content2, *copy_source; ID3D11UnorderedAccessView *check_uav; ID3D11RenderTargetView *rtv1, *rtv2; ID3D11ShaderResourceView *srvs[2]; + D3D11_MAPPED_SUBRESOURCE map_desc; D3D11_TEXTURE2D_DESC desc = {0}; struct resource_readback rb; uint32_t cbuffer_data[4]; ID3D11Buffer *cbuffer; HRESULT expected_hr; - unsigned int i, j; D3D11_BOX box;
const uint32_t width = tests[test_idx].width; @@ -36394,7 +36396,6 @@ static void test_nv12(void)
expected_hr = (width & 1 || height & 1) ? E_INVALIDARG : S_OK; hr = ID3D11Device_CreateTexture2D(device, &desc, &subresource_data, &texture); - todo_wine_if(SUCCEEDED(expected_hr)) ok(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
if (FAILED(hr)) @@ -36403,6 +36404,9 @@ static void test_nv12(void) continue; }
+ hr = ID3D11Device_CreateTexture2D(device, &desc, &subresource_data, &texture2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + desc.Height += height / 2; desc.Format = DXGI_FORMAT_R8_UINT; desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; @@ -36487,12 +36491,13 @@ static void test_nv12(void) } }
+ set_box(&box, copy_x, copy_y, 0, copy_x + copy_width, copy_y + copy_height, 1); + /* UpdateSubresource() copies the specified box on the luma plane and also the corresponding * box on the chroma plane. It does nothing as soon as any coordinate of the box is not a * multiple of 2. AMD seems to have a bug and copies data with the wrong pitch. */ if (!is_amd_device(device)) { - set_box(&box, copy_x, copy_y, 0, copy_x + copy_width, copy_y + copy_height, 1); ID3D11DeviceContext_UpdateSubresource(device_context, (ID3D11Resource *)texture, 0, &box, copy_source, copy_width, 0);
@@ -36555,13 +36560,154 @@ static void test_nv12(void) check_readback_data_u8_with_buffer(&rb, content, width, 0); release_resource_readback(&rb);
+ /* Staging upload, GPU blit, and staging download tests. */ + desc.Height = height; + desc.Format = DXGI_FORMAT_NV12; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.Usage = D3D11_USAGE_STAGING; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &staging_texture); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = ID3D11DeviceContext_Map(device_context, (ID3D11Resource *)staging_texture, 0, + D3D11_MAP_WRITE, 0, &map_desc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + /* Row pitch isn't consistent across drivers. Of the machines tested, + * row pitch may be aligned to a multiple of 4 (WARP), 128 (NVidia), or + * 256 (AMD). + * + * In all cases it seems to signify both the pitch of the Y plane, and + * the pitch of the U/V plane (which is 2x2 subsampled but has 2 bytes + * per sample, so has the same number of content bytes in a row). + * + * Slice pitch is either the size of the Y plane alone (WARP) or the + * size of the entire image (AMD, NVidia). + * + * Older versions of WARP (Windows 10) also calculate the size of the Y + * plane incorrectly, by taking the size of the entire image and + * multiplying by 2/3. This ends up being incorrect because said + * versions apparently add *vertical* alignment to 4 to only one plane, + * so the UV plane is not exactly half the size of the Y plane. */ + ok(map_desc.RowPitch >= width, "Got row pitch %u.\n", map_desc.RowPitch); + image_size = (map_desc.RowPitch * (height * 3 / 2)); + broken_warp_pitch = (map_desc.RowPitch * height) + (map_desc.RowPitch * ((height + 3) & ~3) / 2); + broken_warp_pitch = broken_warp_pitch / 3 * 2; + ok(map_desc.DepthPitch == image_size + || (is_warp_device(device) && map_desc.DepthPitch == (map_desc.RowPitch * height)) + || broken(is_warp_device(device) && map_desc.DepthPitch == broken_warp_pitch), + "Got row pitch %u, slice pitch %u.\n", map_desc.RowPitch, map_desc.DepthPitch); + + for (i = 0; i < height; ++i) + { + for (j = 0; j < width; ++j) + { + unsigned int idx = i * map_desc.RowPitch + j; + ((uint8_t *)map_desc.pData)[idx] = (j & 7) << 3 | (i & 7); + idx = i * width + j; + content2[idx] = (j & 7) << 3 | (i & 7); + } + } + + for (i = 0; i < height / 2; ++i) + { + for (j = 0; j < width / 2; ++j) + { + unsigned int idx = map_desc.RowPitch * (height + i) + j * 2; + ((uint8_t *)map_desc.pData)[idx] = 1u << 6 | (j & 7) << 3 | (i & 7); + ((uint8_t *)map_desc.pData)[idx + 1] = 1u << 7 | (j & 7) << 3 | (i & 7); + idx = width * (height + i) + j * 2; + content2[idx] = 1u << 6 | (j & 7) << 3 | (i & 7); + content2[idx + 1] = 1u << 7 | (j & 7) << 3 | (i & 7); + } + } + + ID3D11DeviceContext_Unmap(device_context, (ID3D11Resource *)staging_texture, 0); + + ID3D11DeviceContext_CopyResource(device_context, (ID3D11Resource *)texture2, (ID3D11Resource *)staging_texture); + ID3D11DeviceContext_CopyResource(device_context, (ID3D11Resource *)texture, (ID3D11Resource *)texture2); + + hr = ID3D11DeviceContext_Map(device_context, (ID3D11Resource *)staging_texture, 0, + D3D11_MAP_WRITE, 0, &map_desc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + memset(map_desc.pData, 0xfe, map_desc.RowPitch * height); + memset((uint8_t *)map_desc.pData + map_desc.RowPitch * height, 0xdc, map_desc.RowPitch * height / 2); + + /* Similarly CopySubresourceRegion() ignores boxes not aligned to 2. */ + if (copy_x % 2 == 0 && copy_y % 2 == 0 && copy_width % 2 == 0 && copy_height % 2 == 0) + { + for (i = copy_y; i < copy_y + copy_height; ++i) + { + memset(content2 + i * width + copy_x, 0xfe, copy_width); + if (i % 2 == 0) + memset(content2 + width * (height + i / 2) + copy_x, 0xdc, copy_width); + } + } + + ID3D11DeviceContext_Unmap(device_context, (ID3D11Resource *)staging_texture, 0); + + ID3D11DeviceContext_CopyResource(device_context, (ID3D11Resource *)texture2, (ID3D11Resource *)staging_texture); + ID3D11DeviceContext_CopySubresourceRegion(device_context, (ID3D11Resource *)texture, 0, + copy_x, copy_y, 0, (ID3D11Resource *)texture2, 0, &box); + + ID3D11DeviceContext_ClearUnorderedAccessViewUint(device_context, check_uav, clear_values); + ID3D11DeviceContext_CSSetShader(device_context, cs, NULL, 0); + ID3D11DeviceContext_CSSetShaderResources(device_context, 0, ARRAY_SIZE(srvs), srvs); + ID3D11DeviceContext_CSSetUnorderedAccessViews(device_context, 1, 1, &check_uav, NULL); + ID3D11DeviceContext_CSSetConstantBuffers(device_context, 0, 1, &cbuffer); + ID3D11DeviceContext_Dispatch(device_context, width, height, 1); + + get_texture_readback(check_texture, 0, &rb); + check_readback_data_u8_with_buffer(&rb, content2, width, 0); + release_resource_readback(&rb); + + ID3D11DeviceContext_CopyResource(device_context, (ID3D11Resource *)staging_texture, (ID3D11Resource *)texture); + + hr = ID3D11DeviceContext_Map(device_context, (ID3D11Resource *)staging_texture, 0, + D3D11_MAP_READ, 0, &map_desc); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (i = 0; i < height; ++i) + { + for (j = 0; j < width; ++j) + { + uint8_t value = ((uint8_t *)map_desc.pData)[i * map_desc.RowPitch + j]; + uint8_t expect = content2[i * width + j]; + ok(value == expect, "Got Y %02x, expected %02x at (%u, %u).\n", value, expect, i, j); + if (value != expect) + goto fail_match; + } + } + + for (i = 0; i < height / 2; ++i) + { + for (j = 0; j < width / 2; ++j) + { + uint8_t value = ((uint8_t *)map_desc.pData)[map_desc.RowPitch * (height + i) + j * 2]; + uint8_t expect = content2[width * (height + i) + j * 2]; + ok(value == expect, "Got U %02x, expected %02x at (%u, %u).\n", value, expect, i, j); + if (value != expect) + goto fail_match; + value = ((uint8_t *)map_desc.pData)[map_desc.RowPitch * (height + i) + j * 2 + 1]; + expect = content2[width * (height + i) + j * 2 + 1]; + ok(value == expect, "Got V %02x, expected %02x at (%u, %u).\n", value, expect, i, j); + if (value != expect) + goto fail_match; + } + } + +fail_match: + ID3D11DeviceContext_Unmap(device_context, (ID3D11Resource *)staging_texture, 0); + ID3D11RenderTargetView_Release(rtv2); ID3D11RenderTargetView_Release(rtv1); ID3D11Buffer_Release(cbuffer); ID3D11UnorderedAccessView_Release(check_uav); ID3D11ShaderResourceView_Release(srvs[1]); ID3D11ShaderResourceView_Release(srvs[0]); + ID3D11Texture2D_Release(staging_texture); ID3D11Texture2D_Release(check_texture); + ID3D11Texture2D_Release(texture2); ID3D11Texture2D_Release(texture); free(content);