lavapipe: allocate image and image view planes.
This allocate planes and handles disjoint. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25609>
This commit is contained in:
@@ -2074,11 +2074,22 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,
|
||||
if (!did_bind) {
|
||||
uint64_t offset_B = 0;
|
||||
VkResult result;
|
||||
|
||||
result = lvp_image_plane_bind(device, &image->planes[0],
|
||||
mem, bind_info->memoryOffset, &offset_B);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
if (image->disjoint) {
|
||||
const VkBindImagePlaneMemoryInfo *plane_info =
|
||||
vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_PLANE_MEMORY_INFO);
|
||||
uint8_t plane = lvp_image_aspects_to_plane(image, plane_info->planeAspect);
|
||||
result = lvp_image_plane_bind(device, &image->planes[plane],
|
||||
mem, bind_info->memoryOffset, &offset_B);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
} else {
|
||||
for (unsigned plane = 0; plane < image->plane_count; plane++) {
|
||||
result = lvp_image_plane_bind(device, &image->planes[plane],
|
||||
mem, bind_info->memoryOffset, &offset_B);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
|
||||
@@ -43,10 +43,20 @@ lvp_image_create(VkDevice _device,
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
image->alignment = 16;
|
||||
image->plane_count = vk_format_get_plane_count(pCreateInfo->format);
|
||||
image->disjoint = image->plane_count > 1 &&
|
||||
(pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT);
|
||||
|
||||
{
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(pCreateInfo->format);
|
||||
for (unsigned p = 0; p < image->plane_count; p++) {
|
||||
struct pipe_resource template;
|
||||
VkFormat format = pCreateInfo->format;
|
||||
VkFormat format = ycbcr_info ?
|
||||
ycbcr_info->planes[p].format : pCreateInfo->format;
|
||||
const uint8_t width_scale = ycbcr_info ?
|
||||
ycbcr_info->planes[p].denominator_scales[0] : 1;
|
||||
const uint8_t height_scale = ycbcr_info ?
|
||||
ycbcr_info->planes[p].denominator_scales[1] : 1;
|
||||
memset(&template, 0, sizeof(template));
|
||||
|
||||
template.screen = device->pscreen;
|
||||
@@ -93,20 +103,20 @@ lvp_image_create(VkDevice _device,
|
||||
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
|
||||
template.bind |= PIPE_BIND_SHADER_IMAGE;
|
||||
|
||||
template.width0 = pCreateInfo->extent.width;
|
||||
template.height0 = pCreateInfo->extent.height;
|
||||
template.width0 = pCreateInfo->extent.width / width_scale;
|
||||
template.height0 = pCreateInfo->extent.height / height_scale;
|
||||
template.depth0 = pCreateInfo->extent.depth;
|
||||
template.array_size = pCreateInfo->arrayLayers;
|
||||
template.last_level = pCreateInfo->mipLevels - 1;
|
||||
template.nr_samples = pCreateInfo->samples;
|
||||
template.nr_storage_samples = pCreateInfo->samples;
|
||||
image->planes[0].bo = device->pscreen->resource_create_unbacked(device->pscreen,
|
||||
image->planes[p].bo = device->pscreen->resource_create_unbacked(device->pscreen,
|
||||
&template,
|
||||
&image->planes[0].size);
|
||||
if (!image->planes[0].bo)
|
||||
&image->planes[p].size);
|
||||
if (!image->planes[p].bo)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
image->size += image->planes[0].size;
|
||||
image->size += image->planes[p].size;
|
||||
}
|
||||
*pImage = lvp_image_to_handle(image);
|
||||
|
||||
@@ -170,7 +180,8 @@ lvp_DestroyImage(VkDevice _device, VkImage _image,
|
||||
|
||||
if (!_image)
|
||||
return;
|
||||
pipe_resource_reference(&image->planes[0].bo, NULL);
|
||||
for (unsigned p = 0; p < image->plane_count; p++)
|
||||
pipe_resource_reference(&image->planes[p].bo, NULL);
|
||||
vk_image_destroy(&device->vk, pAllocator, &image->vk);
|
||||
}
|
||||
|
||||
@@ -191,7 +202,7 @@ static inline char conv_depth_swiz(char swiz) {
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
lvp_create_samplerview(struct pipe_context *pctx, struct lvp_image_view *iv)
|
||||
lvp_create_samplerview(struct pipe_context *pctx, struct lvp_image_view *iv, VkFormat plane_format, unsigned image_plane)
|
||||
{
|
||||
if (!iv)
|
||||
return NULL;
|
||||
@@ -199,13 +210,13 @@ lvp_create_samplerview(struct pipe_context *pctx, struct lvp_image_view *iv)
|
||||
struct pipe_sampler_view templ;
|
||||
enum pipe_format pformat;
|
||||
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
|
||||
pformat = lvp_vk_format_to_pipe_format(plane_format);
|
||||
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
|
||||
pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(plane_format));
|
||||
else
|
||||
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
|
||||
pformat = lvp_vk_format_to_pipe_format(plane_format);
|
||||
u_sampler_view_default_template(&templ,
|
||||
iv->image->planes[0].bo,
|
||||
iv->image->planes[image_plane].bo,
|
||||
pformat);
|
||||
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_1D)
|
||||
templ.target = PIPE_TEXTURE_1D;
|
||||
@@ -238,23 +249,23 @@ lvp_create_samplerview(struct pipe_context *pctx, struct lvp_image_view *iv)
|
||||
templ.swizzle_a = conv_depth_swiz(templ.swizzle_a);
|
||||
}
|
||||
|
||||
return pctx->create_sampler_view(pctx, iv->image->planes[0].bo, &templ);
|
||||
return pctx->create_sampler_view(pctx, iv->image->planes[image_plane].bo, &templ);
|
||||
}
|
||||
|
||||
static struct pipe_image_view
|
||||
lvp_create_imageview(const struct lvp_image_view *iv)
|
||||
lvp_create_imageview(const struct lvp_image_view *iv, VkFormat plane_format, unsigned image_plane)
|
||||
{
|
||||
struct pipe_image_view view = {0};
|
||||
if (!iv)
|
||||
return view;
|
||||
|
||||
view.resource = iv->image->planes[0].bo;
|
||||
view.resource = iv->image->planes[image_plane].bo;
|
||||
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
view.format = lvp_vk_format_to_pipe_format(iv->vk.format);
|
||||
view.format = lvp_vk_format_to_pipe_format(plane_format);
|
||||
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||
view.format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
|
||||
view.format = util_format_stencil_only(lvp_vk_format_to_pipe_format(plane_format));
|
||||
else
|
||||
view.format = lvp_vk_format_to_pipe_format(iv->vk.format);
|
||||
view.format = lvp_vk_format_to_pipe_format(plane_format);
|
||||
|
||||
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
||||
view.u.tex.first_layer = iv->vk.storage.z_slice_offset;
|
||||
@@ -286,16 +297,45 @@ lvp_CreateImageView(VkDevice _device,
|
||||
view->image = image;
|
||||
view->surface = NULL;
|
||||
|
||||
simple_mtx_lock(&device->queue.lock);
|
||||
|
||||
if (image->planes[0].bo->bind & PIPE_BIND_SHADER_IMAGE) {
|
||||
view->planes[0].iv = lvp_create_imageview(view);
|
||||
view->planes[0].image_handle = (void *)(uintptr_t)device->queue.ctx->create_image_handle(device->queue.ctx, &view->planes[0].iv);
|
||||
if (image->vk.aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
|
||||
VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
assert(image->plane_count == 1);
|
||||
assert(lvp_image_aspects_to_plane(image, view->vk.aspects) == 0);
|
||||
view->plane_count = 1;
|
||||
view->planes[0].image_plane = 0;
|
||||
} else {
|
||||
/* For other formats, retrieve the plane count from the aspect mask
|
||||
* and then walk through the aspect mask to map each image plane
|
||||
* to its corresponding view plane
|
||||
*/
|
||||
assert(util_bitcount(view->vk.aspects) ==
|
||||
vk_format_get_plane_count(view->vk.format));
|
||||
view->plane_count = 0;
|
||||
u_foreach_bit(aspect_bit, view->vk.aspects) {
|
||||
uint8_t image_plane = lvp_image_aspects_to_plane(image, 1u << aspect_bit);
|
||||
view->planes[view->plane_count++].image_plane = image_plane;
|
||||
}
|
||||
}
|
||||
|
||||
if (image->planes[0].bo->bind & PIPE_BIND_SAMPLER_VIEW) {
|
||||
view->planes[0].sv = lvp_create_samplerview(device->queue.ctx, view);
|
||||
view->planes[0].texture_handle = (void *)(uintptr_t)device->queue.ctx->create_texture_handle(device->queue.ctx, view->planes[0].sv, NULL);
|
||||
simple_mtx_lock(&device->queue.lock);
|
||||
|
||||
for (unsigned view_plane = 0; view_plane < view->plane_count; view_plane++) {
|
||||
const uint8_t image_plane = view->planes[view_plane].image_plane;
|
||||
const struct vk_format_ycbcr_info *ycbcr_info =
|
||||
vk_format_get_ycbcr_info(view->vk.format);
|
||||
assert(ycbcr_info || view_plane == 0);
|
||||
VkFormat plane_format = ycbcr_info ?
|
||||
ycbcr_info->planes[view_plane].format : view->vk.format;
|
||||
|
||||
if (image->planes[image_plane].bo->bind & PIPE_BIND_SHADER_IMAGE) {
|
||||
view->planes[view_plane].iv = lvp_create_imageview(view, plane_format, image_plane);
|
||||
view->planes[view_plane].image_handle = (void *)(uintptr_t)device->queue.ctx->create_image_handle(device->queue.ctx, &view->planes[view_plane].iv);
|
||||
}
|
||||
|
||||
if (image->planes[image_plane].bo->bind & PIPE_BIND_SAMPLER_VIEW) {
|
||||
view->planes[view_plane].sv = lvp_create_samplerview(device->queue.ctx, view, plane_format, image_plane);
|
||||
view->planes[view_plane].texture_handle = (void *)(uintptr_t)device->queue.ctx->create_texture_handle(device->queue.ctx, view->planes[view_plane].sv, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&device->queue.lock);
|
||||
@@ -317,11 +357,12 @@ lvp_DestroyImageView(VkDevice _device, VkImageView _iview,
|
||||
|
||||
simple_mtx_lock(&device->queue.lock);
|
||||
|
||||
device->queue.ctx->delete_image_handle(device->queue.ctx, (uint64_t)(uintptr_t)iview->planes[0].image_handle);
|
||||
|
||||
pipe_sampler_view_reference(&iview->planes[0].sv, NULL);
|
||||
device->queue.ctx->delete_texture_handle(device->queue.ctx, (uint64_t)(uintptr_t)iview->planes[0].texture_handle);
|
||||
for (uint8_t plane = 0; plane < iview->plane_count; plane++) {
|
||||
device->queue.ctx->delete_image_handle(device->queue.ctx, (uint64_t)(uintptr_t)iview->planes[plane].image_handle);
|
||||
|
||||
pipe_sampler_view_reference(&iview->planes[plane].sv, NULL);
|
||||
device->queue.ctx->delete_texture_handle(device->queue.ctx, (uint64_t)(uintptr_t)iview->planes[plane].texture_handle);
|
||||
}
|
||||
simple_mtx_unlock(&device->queue.lock);
|
||||
|
||||
pipe_surface_reference(&iview->surface, NULL);
|
||||
|
||||
@@ -263,7 +263,9 @@ struct lvp_image {
|
||||
struct vk_image vk;
|
||||
VkDeviceSize size;
|
||||
uint32_t alignment;
|
||||
struct lvp_image_plane planes[1];
|
||||
bool disjoint;
|
||||
uint8_t plane_count;
|
||||
struct lvp_image_plane planes[3];
|
||||
};
|
||||
|
||||
struct lvp_image_view {
|
||||
@@ -277,11 +279,12 @@ struct lvp_image_view {
|
||||
|
||||
uint8_t plane_count;
|
||||
struct {
|
||||
unsigned image_plane;
|
||||
struct pipe_sampler_view *sv;
|
||||
struct pipe_image_view iv;
|
||||
struct lp_texture_handle *texture_handle;
|
||||
struct lp_texture_handle *image_handle;
|
||||
} planes[1];
|
||||
} planes[3];
|
||||
};
|
||||
|
||||
struct lvp_sampler {
|
||||
@@ -690,6 +693,25 @@ lvp_vk_format_to_pipe_format(VkFormat format)
|
||||
return vk_format_to_pipe_format(format);
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
lvp_image_aspects_to_plane(ASSERTED const struct lvp_image *image,
|
||||
VkImageAspectFlags aspectMask)
|
||||
{
|
||||
/* Verify that the aspects are actually in the image */
|
||||
assert(!(aspectMask & ~image->vk.aspects));
|
||||
|
||||
/* Must only be one aspect unless it's depth/stencil */
|
||||
assert(aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |
|
||||
VK_IMAGE_ASPECT_STENCIL_BIT) ||
|
||||
util_bitcount(aspectMask) == 1);
|
||||
|
||||
switch(aspectMask) {
|
||||
case VK_IMAGE_ASPECT_PLANE_1_BIT: return 1;
|
||||
case VK_IMAGE_ASPECT_PLANE_2_BIT: return 2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lvp_pipeline_destroy(struct lvp_device *device, struct lvp_pipeline *pipeline, bool locked);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user