From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/wined3d/sampler.c | 2 +- dlls/wined3d/texture_vk.c | 56 +++++++++++++++++++++++++++++----- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d_private.h | 1 + dlls/wined3d/wined3d_vk.h | 1 + 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c index 2f269f06df5..066e92ccd89 100644 --- a/dlls/wined3d/sampler.c +++ b/dlls/wined3d/sampler.c @@ -145,7 +145,7 @@ void wined3d_sampler_gl_init(struct wined3d_sampler_gl *sampler_gl, struct wined wined3d_cs_init_object(device->cs, wined3d_sampler_gl_cs_init, sampler_gl); } -static VkFilter vk_filter_from_wined3d(enum wined3d_texture_filter_type f) +VkFilter vk_filter_from_wined3d(enum wined3d_texture_filter_type f) { switch (f) { diff --git a/dlls/wined3d/texture_vk.c b/dlls/wined3d/texture_vk.c index 88d83e3f7f4..a11606303c1 100644 --- a/dlls/wined3d/texture_vk.c +++ b/dlls/wined3d/texture_vk.c @@ -1500,6 +1500,12 @@ static bool vk_blitter_conversion_supported(enum wined3d_blit_op op, const struc if (resolve_format) return true; + if (!((src_format->attrs | dst_format->attrs) & WINED3D_FORMAT_ATTR_INTEGER)) + return true; + + if ((src_format->attrs & WINED3D_FORMAT_ATTR_UNSIGNED) == (dst_format->attrs & WINED3D_FORMAT_ATTR_UNSIGNED)) + return true; + return false; } @@ -1565,16 +1571,20 @@ static bool vk_blitter_blit_supported(enum wined3d_blit_op op, const struct wine return false; } - if ((src_rect->right - src_rect->left != dst_rect->right - dst_rect->left) - || (src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top)) - { - TRACE("Scaling not supported.\n"); - return false; - } - return true; } +static bool use_raw_blit(enum wined3d_blit_op op, const struct wined3d_format_vk *src_format_vk, + const struct wined3d_format_vk *dst_format_vk, const RECT *src_rect, const RECT *dst_rect) +{ + if (op == WINED3D_BLIT_OP_RAW_BLIT) + return true; + + return src_format_vk->vk_format == dst_format_vk->vk_format + && src_rect->right - src_rect->left == dst_rect->right - dst_rect->left + && src_rect->bottom - src_rect->top == dst_rect->bottom - dst_rect->top; +} + static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_op op, struct wined3d_context *context, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, DWORD src_location, const RECT *src_rect, struct wined3d_texture *dst_texture, @@ -1582,6 +1592,8 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ const struct wined3d_color_key *colour_key, enum wined3d_texture_filter_type filter, const struct wined3d_format *resolve_format) { + const struct wined3d_format_vk *src_format_vk = wined3d_format_vk(src_texture->resource.format); + const struct wined3d_format_vk *dst_format_vk = wined3d_format_vk(dst_texture->resource.format); struct wined3d_texture_vk *src_texture_vk = wined3d_texture_vk(src_texture); struct wined3d_texture_vk *dst_texture_vk = wined3d_texture_vk(dst_texture); struct wined3d_context_vk *context_vk = wined3d_context_vk(context); @@ -1867,7 +1879,7 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ dst_texture_vk->image.vk_image, dst_layout, 1, ©_region)); } } - else + else if (use_raw_blit(op, src_format_vk, dst_format_vk, src_rect, dst_rect)) { const struct wined3d_format *src_format = src_texture_vk->t.resource.format; VkImageCopy region; @@ -1913,6 +1925,34 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_ dst_texture_vk->image.vk_image, dst_layout, 1, ®ion)); } } + else + { + VkImageBlit region; + + region.srcSubresource.aspectMask = vk_src_range.aspectMask; + region.srcSubresource.mipLevel = vk_src_range.baseMipLevel; + region.srcSubresource.baseArrayLayer = vk_src_range.baseArrayLayer; + region.srcSubresource.layerCount = vk_src_range.layerCount; + region.srcOffsets[0].x = src_rect->left; + region.srcOffsets[0].y = src_rect->top; + region.srcOffsets[0].z = 0; + region.srcOffsets[1].x = src_rect->right; + region.srcOffsets[1].y = src_rect->bottom; + region.srcOffsets[1].z = 1; + region.dstSubresource.aspectMask = vk_dst_range.aspectMask; + region.dstSubresource.mipLevel = vk_dst_range.baseMipLevel; + region.dstSubresource.baseArrayLayer = vk_dst_range.baseArrayLayer; + region.dstSubresource.layerCount = vk_dst_range.layerCount; + region.dstOffsets[0].x = dst_rect->left; + region.dstOffsets[0].y = dst_rect->top; + region.dstOffsets[0].z = 0; + region.dstOffsets[1].x = dst_rect->right; + region.dstOffsets[1].y = dst_rect->bottom; + region.dstOffsets[1].z = 1; + + VK_CALL(vkCmdBlitImage(vk_command_buffer, src_texture_vk->image.vk_image, src_layout, + dst_texture_vk->image.vk_image, dst_layout, 1, ®ion, vk_filter_from_wined3d(filter))); + } wined3d_context_vk_image_barrier(context_vk, vk_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 6091f6bd820..0fb90ba3f18 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1928,6 +1928,8 @@ static void parse_channel_desc(struct wined3d_format *format, const char *channe attrs |= WINED3D_FORMAT_ATTR_NORMALISED; if (channel_type == WINED3D_CHANNEL_TYPE_UINT || channel_type == WINED3D_CHANNEL_TYPE_SINT) attrs |= WINED3D_FORMAT_ATTR_INTEGER; + if (channel_type == WINED3D_CHANNEL_TYPE_UINT || channel_type == WINED3D_CHANNEL_TYPE_UNORM) + attrs |= WINED3D_FORMAT_ATTR_UNSIGNED; if (channel_type == WINED3D_CHANNEL_TYPE_FLOAT) attrs |= WINED3D_FORMAT_ATTR_FLOAT; if (channel_type == WINED3D_CHANNEL_TYPE_DEPTH) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9998b29ccf1..fa758c53cc1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4541,6 +4541,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth); #define WINED3D_FORMAT_ATTR_CAST_TO_BLOCK 0x00000800 #define WINED3D_FORMAT_ATTR_PLANAR 0x00001000 #define WINED3D_FORMAT_ATTR_SHADOW 0x00002000 +#define WINED3D_FORMAT_ATTR_UNSIGNED 0x00004000 /* Pixel format capabilities */ #define WINED3D_FORMAT_CAP_POSTPIXELSHADER_BLENDING 0x00000001 diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index a0f167ea17a..aa5976bb730 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -299,6 +299,7 @@ static const VkAccessFlags WINED3D_READ_ONLY_ACCESS_FLAGS = VK_ACCESS_INDIRECT_C VkAccessFlags vk_access_mask_from_bind_flags(uint32_t bind_flags); VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op); +VkFilter vk_filter_from_wined3d(enum wined3d_texture_filter_type f); VkImageViewType vk_image_view_type_from_wined3d(enum wined3d_resource_type type, uint32_t flags); VkPipelineStageFlags vk_pipeline_stage_mask_from_bind_flags(uint32_t bind_flags); VkShaderStageFlagBits vk_shader_stage_from_wined3d(enum wined3d_shader_type shader_type); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10292