zink: use HIC for image subdata when possible
this has a lot of caveats: * extension must be supported * resource must have usage bit set * resource must not have any pending batch usage * resource must be in supported layout if all of these conditionals pass, then HIC can be used for direct image subdata Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24775>
This commit is contained in:

committed by
Marge Bot

parent
f24891269d
commit
6d5174974a
@@ -340,7 +340,7 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT,
|
||||
props2.pNext,
|
||||
};
|
||||
if (screen->info.have_EXT_host_image_copy)
|
||||
if (screen->info.have_EXT_host_image_copy && ici->usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)
|
||||
props2.pNext = &hic;
|
||||
VkPhysicalDeviceImageFormatInfo2 info;
|
||||
info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
|
||||
@@ -367,7 +367,7 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
if (vk_format_aspects(ici->format) & VK_IMAGE_ASPECT_PLANE_1_BIT)
|
||||
ret = VK_SUCCESS;
|
||||
image_props = props2.imageFormatProperties;
|
||||
if (screen->info.have_EXT_host_image_copy)
|
||||
if (screen->info.have_EXT_host_image_copy && ici->usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)
|
||||
optimalDeviceAccess = hic.optimalDeviceAccess;
|
||||
} else
|
||||
ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, ici->format, ici->imageType,
|
||||
@@ -2417,6 +2417,109 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
zink_image_subdata(struct pipe_context *pctx,
|
||||
struct pipe_resource *pres,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
const void *data,
|
||||
unsigned stride,
|
||||
uintptr_t layer_stride)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(pctx->screen);
|
||||
struct zink_context *ctx = zink_context(pctx);
|
||||
struct zink_resource *res = zink_resource(pres);
|
||||
|
||||
/* flush clears to avoid subdata conflict */
|
||||
if (res->obj->vkusage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)
|
||||
zink_fb_clears_apply_or_discard(ctx, pres, zink_rect_from_box(box), false);
|
||||
/* only use HIC if supported on image and no pending usage */
|
||||
while (res->obj->vkusage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT &&
|
||||
zink_resource_usage_check_completion(screen, res, ZINK_RESOURCE_ACCESS_RW)) {
|
||||
/* uninit images are always supported */
|
||||
bool change_layout = res->layout == VK_IMAGE_LAYOUT_UNDEFINED || res->layout == VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
if (!change_layout) {
|
||||
/* image in some other layout: test for support */
|
||||
bool can_copy_layout = false;
|
||||
for (unsigned i = 0; i < screen->info.hic_props.copyDstLayoutCount; i++) {
|
||||
if (screen->info.hic_props.pCopyDstLayouts[i] == res->layout) {
|
||||
can_copy_layout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* some layouts don't permit HIC copies */
|
||||
if (!can_copy_layout)
|
||||
break;
|
||||
}
|
||||
bool is_arrayed = false;
|
||||
switch (pres->target) {
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_CUBE_ARRAY:
|
||||
is_arrayed = true;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
/* recalc strides into texel strides because HIC spec is insane */
|
||||
unsigned vk_stride = util_format_get_stride(pres->format, 1);
|
||||
stride /= vk_stride;
|
||||
unsigned vk_layer_stride = util_format_get_2d_size(pres->format, stride, 1) * vk_stride;
|
||||
layer_stride /= vk_layer_stride;
|
||||
|
||||
VkHostImageLayoutTransitionInfoEXT t = {
|
||||
VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
|
||||
NULL,
|
||||
res->obj->image,
|
||||
res->layout,
|
||||
/* GENERAL support is guaranteed */
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
{res->aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}
|
||||
};
|
||||
/* only pre-transition uninit images to avoid thrashing */
|
||||
if (change_layout) {
|
||||
VKSCR(TransitionImageLayoutEXT)(screen->dev, 1, &t);
|
||||
res->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
VkMemoryToImageCopyEXT region = {
|
||||
VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
|
||||
NULL,
|
||||
data,
|
||||
stride,
|
||||
layer_stride,
|
||||
{res->aspect, level, is_arrayed ? box->z : 0, is_arrayed ? box->depth : 1},
|
||||
{box->x, box->y, is_arrayed ? 0 : box->z},
|
||||
{box->width, box->height, is_arrayed ? 1 : box->depth}
|
||||
};
|
||||
VkCopyMemoryToImageInfoEXT copy = {
|
||||
VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
|
||||
NULL,
|
||||
0,
|
||||
res->obj->image,
|
||||
res->layout,
|
||||
1,
|
||||
®ion
|
||||
};
|
||||
VKSCR(CopyMemoryToImageEXT)(screen->dev, ©);
|
||||
if (change_layout && screen->can_hic_shader_read && !pres->last_level && !box->x && !box->y && !box->z &&
|
||||
box->width == pres->width0 && box->height == pres->height0 &&
|
||||
((is_arrayed && box->depth == pres->array_size) || (!is_arrayed && box->depth == pres->depth0))) {
|
||||
/* assume full copy single-mip images use shader read access */
|
||||
t.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
t.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
VKSCR(TransitionImageLayoutEXT)(screen->dev, 1, &t);
|
||||
res->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
/* assume multi-mip where further subdata calls may happen */
|
||||
}
|
||||
/* make sure image is marked as having data */
|
||||
res->valid = true;
|
||||
return;
|
||||
}
|
||||
/* fallback case for per-resource unsupported or device-level unsupported */
|
||||
u_default_texture_subdata(pctx, pres, level, usage, box, data, stride, layer_stride);
|
||||
}
|
||||
|
||||
static void
|
||||
zink_transfer_flush_region(struct pipe_context *pctx,
|
||||
struct pipe_transfer *ptrans,
|
||||
@@ -2936,6 +3039,6 @@ zink_context_resource_init(struct pipe_context *pctx)
|
||||
|
||||
pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region;
|
||||
pctx->buffer_subdata = zink_buffer_subdata;
|
||||
pctx->texture_subdata = u_default_texture_subdata;
|
||||
pctx->texture_subdata = zink_image_subdata;
|
||||
pctx->invalidate_resource = zink_resource_invalidate;
|
||||
}
|
||||
|
Reference in New Issue
Block a user