zink: add docs for zink_surface

zink_surface is an abstraction that is a superset of pipe_surface,
used for all types of images

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19307>
This commit is contained in:
Mike Blumenkrantz
2022-10-25 14:19:34 -04:00
committed by Marge Bot
parent 1e63b24f88
commit b1b2dee30e
3 changed files with 38 additions and 8 deletions
+22 -3
View File
@@ -101,11 +101,13 @@ create_ivci(struct zink_screen *screen,
ivci.subresourceRange.layerCount = 1 + templ->u.tex.last_layer - templ->u.tex.first_layer;
assert(ivci.viewType != VK_IMAGE_VIEW_TYPE_3D || ivci.subresourceRange.baseArrayLayer == 0);
assert(ivci.viewType != VK_IMAGE_VIEW_TYPE_3D || ivci.subresourceRange.layerCount == 1);
/* ensure cube image types get clamped to 2D/2D_ARRAY as expected for partial views */
ivci.viewType = zink_surface_clamp_viewtype(ivci.viewType, templ->u.tex.first_layer, templ->u.tex.last_layer, res->base.b.array_size);
return ivci;
}
/* this is used for framebuffer attachments to set up imageless framebuffers */
static void
init_surface_info(struct zink_surface *surface, struct zink_resource *res, VkImageViewCreateInfo *ivci)
{
@@ -153,6 +155,7 @@ create_surface(struct pipe_context *pctx,
feats &= screen->modifier_props[templ->format].pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
}
}
/* if the format features don't support framebuffer attachment, use VkImageViewUsageCreateInfo to remove it */
if ((res->obj->vkusage & attachment) &&
!(feats & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
ivci->pNext = &surface->usage_info;
@@ -199,12 +202,14 @@ do_create_surface(struct pipe_context *pctx, struct pipe_resource *pres, const s
{
/* create a new surface */
struct zink_surface *surface = create_surface(pctx, pres, templ, ivci, actually);
/* only transient surfaces have nr_samples set */
surface->base.nr_samples = 0;
surface->hash = hash;
surface->ivci = *ivci;
return surface;
}
/* get a cached surface for a shader descriptor */
struct pipe_surface *
zink_get_surface(struct zink_context *ctx,
struct pipe_resource *pres,
@@ -219,7 +224,9 @@ zink_get_surface(struct zink_context *ctx,
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(&res->surface_cache, hash, ivci);
if (!entry) {
/* create a new surface, but don't actually create the imageview if mutable isn't set */
/* create a new surface, but don't actually create the imageview if mutable isn't set and the format is different;
* mutable will be set later and the imageview will be filled in
*/
bool actually = pres->format == templ->format || (res->obj->vkflags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
surface = do_create_surface(&ctx->base, pres, templ, ivci, hash, actually);
entry = _mesa_hash_table_insert_pre_hashed(&res->surface_cache, hash, &surface->ivci, surface);
@@ -238,6 +245,7 @@ zink_get_surface(struct zink_context *ctx,
return &surface->base;
}
/* wrap a surface for use as a framebuffer attachment */
static struct pipe_surface *
wrap_surface(struct pipe_context *pctx, struct pipe_surface *psurf)
{
@@ -250,6 +258,7 @@ wrap_surface(struct pipe_context *pctx, struct pipe_surface *psurf)
return &csurf->base;
}
/* this the context hook that returns a zink_ctx_surface */
static struct pipe_surface *
zink_create_surface(struct pipe_context *pctx,
struct pipe_resource *pres,
@@ -313,7 +322,7 @@ zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface)
if (!psurface->nr_samples && !surface->is_swapchain) {
simple_mtx_lock(&res->surface_mtx);
if (psurface->reference.count) {
/* got a cache hit during deletion */
/* a different context got a cache hit during deletion: this surface is alive again */
simple_mtx_unlock(&res->surface_mtx);
return;
}
@@ -323,7 +332,9 @@ zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface)
_mesa_hash_table_remove(&res->surface_cache, he);
simple_mtx_unlock(&res->surface_mtx);
}
/* this surface is dead now */
simple_mtx_lock(&res->obj->view_lock);
/* imageviews are never destroyed directly to ensure lifetimes for in-use surfaces */
if (surface->is_swapchain) {
for (unsigned i = 0; i < surface->swapchain_size; i++)
util_dynarray_append(&res->obj->views, VkImageView, surface->swapchain[i]);
@@ -335,6 +346,7 @@ zink_destroy_surface(struct zink_screen *screen, struct pipe_surface *psurface)
FREE(surface);
}
/* this is the context hook, so only zink_ctx_surfaces will reach it */
static void
zink_surface_destroy(struct pipe_context *pctx,
struct pipe_surface *psurface)
@@ -345,6 +357,7 @@ zink_surface_destroy(struct pipe_context *pctx,
FREE(csurf);
}
/* this is called when a surface is rebound for mutable/storage use */
bool
zink_rebind_surface(struct zink_context *ctx, struct pipe_surface **psurface)
{
@@ -393,6 +406,7 @@ zink_rebind_surface(struct zink_context *ctx, struct pipe_surface **psurface)
return true;
}
/* dummy surfaces are used for null framebuffer/descriptors */
struct pipe_surface *
zink_surface_create_null(struct zink_context *ctx, enum pipe_texture_target target, unsigned width, unsigned height, unsigned samples)
{
@@ -428,6 +442,7 @@ zink_context_surface_init(struct pipe_context *context)
context->surface_destroy = zink_surface_destroy;
}
/* must be called before a swapchain image is used to ensure correct imageview is used */
void
zink_surface_swapchain_update(struct zink_context *ctx, struct zink_surface *surface)
{
@@ -437,7 +452,9 @@ zink_surface_swapchain_update(struct zink_context *ctx, struct zink_surface *sur
if (!cdt)
return; //dead swapchain
if (res->obj->dt != surface->dt) {
/* new swapchain: clear out previous swapchain imageviews/array and setup a new one */
/* new swapchain: clear out previous swapchain imageviews/array and setup a new one;
* old views will be pruned normally in zink_batch or on object destruction
*/
simple_mtx_lock(&res->obj->view_lock);
for (unsigned i = 0; i < surface->swapchain_size; i++)
util_dynarray_append(&res->obj->views, VkImageView, surface->swapchain[i]);
@@ -450,10 +467,12 @@ zink_surface_swapchain_update(struct zink_context *ctx, struct zink_surface *sur
init_surface_info(surface, res, &surface->ivci);
}
if (!surface->swapchain[res->obj->dt_idx]) {
/* no current swapchain imageview exists: create it */
assert(res->obj->image && cdt->swapchain->images[res->obj->dt_idx].image == res->obj->image);
surface->ivci.image = res->obj->image;
assert(surface->ivci.image);
VKSCR(CreateImageView)(screen->dev, &surface->ivci, NULL, &surface->swapchain[res->obj->dt_idx]);
}
/* the current swapchain imageview is now the view for the current swapchain image */
surface->image_view = surface->swapchain[res->obj->dt_idx];
}
+1
View File
@@ -57,6 +57,7 @@ zink_get_surface(struct zink_context *ctx,
const struct pipe_surface *templ,
VkImageViewCreateInfo *ivci);
/* cube image types are clamped by gallium rules to 2D or 2D_ARRAY viewtypes if not using all layers */
static inline VkImageViewType
zink_surface_clamp_viewtype(VkImageViewType viewType, unsigned first_layer, unsigned last_layer, unsigned array_size)
{
+15 -5
View File
@@ -1296,27 +1296,37 @@ zink_screen(struct pipe_screen *pipe)
/** surface types */
/* info for validating/creating imageless framebuffers */
struct zink_surface_info {
VkImageCreateFlags flags;
VkImageUsageFlags usage;
uint32_t width;
uint32_t height;
uint32_t layerCount;
VkFormat format[2];
VkFormat format[2]; //base format, srgb format (for srgb framebuffer)
};
/* an imageview for a zink_resource:
- may be a fb attachment, samplerview, or shader image
- cached on the parent zink_resource_object
- also handles swapchains
*/
struct zink_surface {
struct pipe_surface base;
/* all the info for creating a new imageview */
VkImageViewCreateInfo ivci;
VkImageViewUsageCreateInfo usage_info;
/* for framebuffer use */
struct zink_surface_info info;
bool is_swapchain;
/* the current imageview */
VkImageView image_view;
void *dt;
/* array of imageviews for swapchains, one for each image */
VkImageView *swapchain;
unsigned swapchain_size;
void *obj; //backing resource object
uint32_t hash;
void *obj; //backing resource object; used to determine rebinds
void *dt; //current swapchain object; used to determine swapchain rebinds
uint32_t hash; //for surface caching
};
/* wrapper object that preserves the gallium expectation of having
@@ -1324,7 +1334,7 @@ struct zink_surface {
*/
struct zink_ctx_surface {
struct pipe_surface base;
struct zink_surface *surf;
struct zink_surface *surf; //the actual surface
/* TODO: use VK_EXT_multisampled_render_to_single_sampled */
struct zink_ctx_surface *transient; //for use with EXT_multisample_render_to_texture
bool transient_init; //whether the transient surface has data