mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
zink: use smaller keys for surface/bufferview caching and switch to sets
this should be a bit more efficient Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35722>
This commit is contained in:
parent
9ac256645e
commit
5cfaa6cd5f
8 changed files with 165 additions and 85 deletions
|
|
@ -947,10 +947,9 @@ sampler_aspect_from_format(enum pipe_format fmt)
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
hash_bufferview(void *bvci)
|
||||
hash_bufferview_key(void *key)
|
||||
{
|
||||
size_t offset = offsetof(VkBufferViewCreateInfo, flags);
|
||||
return _mesa_hash_data((char*)bvci + offset, sizeof(VkBufferViewCreateInfo) - offset);
|
||||
return _mesa_hash_data(key, sizeof(struct zink_bufferview_key));
|
||||
}
|
||||
|
||||
static VkBufferViewCreateInfo
|
||||
|
|
@ -990,30 +989,37 @@ get_buffer_view(struct zink_context *ctx, struct zink_resource *res, enum pipe_f
|
|||
{
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
struct zink_buffer_view *buffer_view = NULL;
|
||||
struct zink_bufferview_key key = {
|
||||
format,
|
||||
offset,
|
||||
size
|
||||
};
|
||||
VkBufferViewCreateInfo bvci = create_bvci(ctx, res, format, offset, size);
|
||||
|
||||
uint32_t hash = hash_bufferview(&bvci);
|
||||
uint32_t hash = hash_bufferview_key(&key);
|
||||
simple_mtx_lock(&res->obj->surface_mtx);
|
||||
struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->obj->surface_cache, hash, &bvci);
|
||||
if (he) {
|
||||
buffer_view = he->data;
|
||||
bool found = false;
|
||||
struct set_entry *he = _mesa_set_search_or_add_pre_hashed(&res->obj->surface_cache, hash, &key, &found);
|
||||
if (found) {
|
||||
buffer_view = (void*)he->key;
|
||||
} else {
|
||||
VkBufferView view;
|
||||
VkResult result = VKSCR(CreateBufferView)(screen->dev, &bvci, NULL, &view);
|
||||
if (result != VK_SUCCESS) {
|
||||
_mesa_set_remove(&res->obj->surface_cache, he);
|
||||
mesa_loge("ZINK: vkCreateBufferView failed (%s)", vk_Result_to_str(result));
|
||||
goto out;
|
||||
}
|
||||
buffer_view = CALLOC_STRUCT(zink_buffer_view);
|
||||
if (!buffer_view) {
|
||||
_mesa_set_remove(&res->obj->surface_cache, he);
|
||||
VKSCR(DestroyBufferView)(screen->dev, view, NULL);
|
||||
goto out;
|
||||
}
|
||||
buffer_view->pres = &res->base.b;
|
||||
buffer_view->bvci = bvci;
|
||||
buffer_view->key = key;
|
||||
buffer_view->buffer_view = view;
|
||||
buffer_view->hash = hash;
|
||||
_mesa_hash_table_insert_pre_hashed(&res->obj->surface_cache, hash, &buffer_view->bvci, buffer_view);
|
||||
he->key = buffer_view;
|
||||
}
|
||||
out:
|
||||
simple_mtx_unlock(&res->obj->surface_mtx);
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ kopper_GetSwapchainImages(struct zink_screen *screen, struct kopper_swapchain *c
|
|||
if (zink_screen_handle_vkresult(screen, error)) {
|
||||
for (unsigned i = 0; i < cswap->num_images; i++) {
|
||||
cswap->images[i].image = images[i];
|
||||
_mesa_hash_table_init(&cswap->images[i].surface_cache, NULL, NULL, equals_ivci);
|
||||
_mesa_set_init(&cswap->images[i].surface_cache, NULL, NULL, equals_surface_key);
|
||||
}
|
||||
}
|
||||
cswap->max_acquires = cswap->num_images - cswap->scci.minImageCount + 1;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "kopper_interface.h"
|
||||
#include "util/u_queue.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/set.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -51,7 +51,7 @@ struct kopper_swapchain_image {
|
|||
VkSemaphore acquire;
|
||||
VkImageLayout layout;
|
||||
|
||||
struct hash_table surface_cache;
|
||||
struct set surface_cache;
|
||||
};
|
||||
|
||||
struct kopper_swapchain {
|
||||
|
|
|
|||
|
|
@ -180,12 +180,9 @@ image_hic_transition(struct zink_screen *screen, struct zink_resource *res, VkIm
|
|||
}
|
||||
|
||||
static bool
|
||||
equals_bvci(const void *a, const void *b)
|
||||
equals_bufferview_key(const void *a, const void *b)
|
||||
{
|
||||
const uint8_t *pa = a;
|
||||
const uint8_t *pb = b;
|
||||
size_t offset = offsetof(VkBufferViewCreateInfo, flags);
|
||||
return memcmp(pa + offset, pb + offset, sizeof(VkBufferViewCreateInfo) - offset) == 0;
|
||||
return memcmp(a, b, sizeof(struct zink_bufferview_key)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -200,20 +197,19 @@ debug_describe_zink_resource_object(char *buf, const struct zink_resource_object
|
|||
}
|
||||
|
||||
void
|
||||
zink_destroy_resource_surface_cache(struct zink_screen *screen, struct hash_table *ht, bool is_buffer)
|
||||
zink_destroy_resource_surface_cache(struct zink_screen *screen, struct set *ht, bool is_buffer)
|
||||
{
|
||||
if (is_buffer) {
|
||||
hash_table_foreach_remove(ht, he) {
|
||||
struct zink_buffer_view *bv = he->data;
|
||||
set_foreach_remove(ht, he) {
|
||||
struct zink_buffer_view *bv = (void*)he->key;
|
||||
VKSCR(DestroyBufferView)(screen->dev, bv->buffer_view, NULL);
|
||||
FREE(bv);
|
||||
}
|
||||
ralloc_free(ht->table);
|
||||
} else {
|
||||
hash_table_foreach_remove(ht, he) {
|
||||
struct zink_surface *surf = he->data;
|
||||
set_foreach_remove(ht, he) {
|
||||
struct zink_surface *surf = (void*)he->key;
|
||||
VKSCR(DestroyImageView)(screen->dev, surf->image_view, NULL);
|
||||
free((void*)he->key);
|
||||
FREE(surf);
|
||||
}
|
||||
ralloc_free(ht->table);
|
||||
|
|
@ -1250,7 +1246,7 @@ create_buffer(struct zink_screen *screen, struct zink_resource_object *obj,
|
|||
return roc_fail_and_cleanup_all;
|
||||
}
|
||||
}
|
||||
_mesa_hash_table_init(&obj->surface_cache, NULL, NULL, equals_bvci);
|
||||
_mesa_set_init(&obj->surface_cache, NULL, NULL, equals_bufferview_key);
|
||||
return roc_success;
|
||||
}
|
||||
|
||||
|
|
@ -1482,7 +1478,7 @@ create_image(struct zink_screen *screen, struct zink_resource_object *obj,
|
|||
return roc_fail_and_cleanup_all;
|
||||
}
|
||||
}
|
||||
_mesa_hash_table_init(&obj->surface_cache, NULL, NULL, equals_ivci);
|
||||
_mesa_set_init(&obj->surface_cache, NULL, NULL, equals_surface_key);
|
||||
return roc_success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ zink_resource_reference(struct zink_resource **d, struct zink_resource *s)
|
|||
}
|
||||
|
||||
void
|
||||
zink_destroy_resource_surface_cache(struct zink_screen *screen, struct hash_table *ht, bool is_buffer);
|
||||
zink_destroy_resource_surface_cache(struct zink_screen *screen, struct set *ht, bool is_buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,38 @@
|
|||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
static VkImageViewType
|
||||
vkviewtype_from_pipe(enum pipe_texture_target target, bool need_2D)
|
||||
{
|
||||
switch (target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
return need_2D ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D;
|
||||
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
return need_2D ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
return VK_IMAGE_VIEW_TYPE_2D;
|
||||
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
|
||||
case PIPE_TEXTURE_CUBE_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
|
||||
default:
|
||||
unreachable("unsupported target");
|
||||
}
|
||||
}
|
||||
|
||||
VkImageViewCreateInfo
|
||||
create_ivci(struct zink_screen *screen,
|
||||
struct zink_resource *res,
|
||||
|
|
@ -43,41 +75,7 @@ create_ivci(struct zink_screen *screen,
|
|||
memset(&ivci, 0, sizeof(VkImageViewCreateInfo));
|
||||
ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
ivci.image = res->obj->image;
|
||||
|
||||
switch (target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
ivci.viewType = res->need_2D ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
ivci.viewType = res->need_2D ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_CUBE_ARRAY:
|
||||
ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
break;
|
||||
|
||||
case PIPE_TEXTURE_3D:
|
||||
ivci.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("unsupported target");
|
||||
}
|
||||
|
||||
ivci.viewType = vkviewtype_from_pipe(target, res->need_2D);
|
||||
ivci.format = res->base.b.format == PIPE_FORMAT_A8_UNORM ? res->format : zink_get_format(screen, templ->format);
|
||||
assert(ivci.format != VK_FORMAT_UNDEFINED);
|
||||
|
||||
|
|
@ -136,7 +134,7 @@ apply_view_usage_for_format(struct zink_screen *screen, struct pipe_resource *pr
|
|||
static struct zink_surface *
|
||||
create_surface(struct pipe_context *pctx,
|
||||
struct pipe_resource *pres,
|
||||
const struct pipe_surface *templ,
|
||||
const struct zink_surface_key *templ,
|
||||
VkImageViewCreateInfo *ivci)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(pctx->screen);
|
||||
|
|
@ -155,17 +153,18 @@ create_surface(struct pipe_context *pctx,
|
|||
FREE(surface);
|
||||
return NULL;
|
||||
}
|
||||
surface->key = *templ;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hash_ivci(const void *key)
|
||||
hash_key(const void *key)
|
||||
{
|
||||
return _mesa_hash_data((char*)key + offsetof(VkImageViewCreateInfo, flags), sizeof(VkImageViewCreateInfo) - offsetof(VkImageViewCreateInfo, flags));
|
||||
return _mesa_hash_data(key, sizeof(struct zink_surface_key));
|
||||
}
|
||||
|
||||
static struct hash_table *
|
||||
static struct set *
|
||||
get_surface_cache(struct zink_resource *res)
|
||||
{
|
||||
struct kopper_displaytarget *cdt = res->obj->dt;
|
||||
|
|
@ -173,6 +172,59 @@ get_surface_cache(struct zink_resource *res)
|
|||
return res->obj->dt ? &cdt->swapchain->images[res->obj->dt_idx].surface_cache : &res->obj->surface_cache;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
componentmapping_to_pipe(VkComponentSwizzle c)
|
||||
{
|
||||
switch (c) {
|
||||
case VK_COMPONENT_SWIZZLE_ZERO:
|
||||
return PIPE_SWIZZLE_0;
|
||||
case VK_COMPONENT_SWIZZLE_ONE:
|
||||
return PIPE_SWIZZLE_1;
|
||||
case VK_COMPONENT_SWIZZLE_R:
|
||||
return PIPE_SWIZZLE_X;
|
||||
case VK_COMPONENT_SWIZZLE_G:
|
||||
return PIPE_SWIZZLE_Y;
|
||||
case VK_COMPONENT_SWIZZLE_B:
|
||||
return PIPE_SWIZZLE_Z;
|
||||
case VK_COMPONENT_SWIZZLE_A:
|
||||
return PIPE_SWIZZLE_W;
|
||||
default:
|
||||
unreachable("unknown swizzle");
|
||||
}
|
||||
}
|
||||
|
||||
static struct zink_surface_key
|
||||
templ_to_key(const struct pipe_surface *templ, const VkImageViewCreateInfo *ivci)
|
||||
{
|
||||
VkImageViewType baseviewtype = vkviewtype_from_pipe(templ->texture->target, zink_resource(templ->texture)->need_2D);
|
||||
enum zink_surface_type type = ZINK_SURFACE_NORMAL;
|
||||
if (baseviewtype != ivci->viewType) {
|
||||
switch (ivci->viewType) {
|
||||
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
|
||||
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
|
||||
type = ZINK_SURFACE_ARRAYED;
|
||||
break;
|
||||
default:
|
||||
type = ZINK_SURFACE_LAYERED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct zink_surface_key key = {
|
||||
.format = templ->format,
|
||||
.viewtype = type,
|
||||
.stencil = ivci->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
.swizzle_r = componentmapping_to_pipe(ivci->components.r),
|
||||
.swizzle_g = componentmapping_to_pipe(ivci->components.g),
|
||||
.swizzle_b = componentmapping_to_pipe(ivci->components.b),
|
||||
.swizzle_a = componentmapping_to_pipe(ivci->components.a),
|
||||
.first_level = ivci->subresourceRange.baseMipLevel,
|
||||
.level_count = ivci->subresourceRange.levelCount,
|
||||
.first_layer = templ->first_layer,
|
||||
.last_layer = templ->last_layer,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
/* get a cached surface for a shader descriptor */
|
||||
struct zink_surface *
|
||||
zink_get_surface(struct zink_context *ctx,
|
||||
|
|
@ -190,23 +242,24 @@ zink_get_surface(struct zink_context *ctx,
|
|||
zink_resource_object_init_mutable(ctx, res);
|
||||
/* reset for mutable obj switch */
|
||||
ivci->image = res->obj->image;
|
||||
uint32_t hash = hash_ivci(ivci);
|
||||
struct zink_surface_key key = templ_to_key(templ, ivci);
|
||||
uint32_t hash = hash_key(&key);
|
||||
|
||||
simple_mtx_lock(&res->obj->surface_mtx);
|
||||
struct hash_table *ht = get_surface_cache(res);
|
||||
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ht, hash, ivci);
|
||||
struct set *ht = get_surface_cache(res);
|
||||
bool found = false;
|
||||
struct set_entry *entry = _mesa_set_search_or_add_pre_hashed(ht, hash, &key, &found);
|
||||
|
||||
if (!entry) {
|
||||
surface = create_surface(&ctx->base, &res->base.b, templ, ivci);
|
||||
entry = _mesa_hash_table_insert_pre_hashed(ht, hash, mem_dup(ivci, sizeof(*ivci)), surface);
|
||||
if (!entry) {
|
||||
if (!found) {
|
||||
surface = create_surface(&ctx->base, &res->base.b, &key, ivci);
|
||||
if (!surface) {
|
||||
_mesa_set_remove(ht, entry);
|
||||
simple_mtx_unlock(&res->obj->surface_mtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface = entry->data;
|
||||
entry->key = surface;
|
||||
} else {
|
||||
surface = entry->data;
|
||||
surface = (void*)entry->key;
|
||||
}
|
||||
simple_mtx_unlock(&res->obj->surface_mtx);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,9 @@
|
|||
#include "zink_types.h"
|
||||
|
||||
static inline bool
|
||||
equals_ivci(const void *a, const void *b)
|
||||
equals_surface_key(const void *a, const void *b)
|
||||
{
|
||||
const uint8_t *pa = a;
|
||||
const uint8_t *pb = b;
|
||||
size_t offset = offsetof(VkImageViewCreateInfo, flags);
|
||||
return memcmp(pa + offset, pb + offset, sizeof(VkImageViewCreateInfo) - offset) == 0;
|
||||
return memcmp(a, b, sizeof(struct zink_surface_key)) == 0;
|
||||
}
|
||||
|
||||
VkImageViewCreateInfo
|
||||
|
|
|
|||
|
|
@ -1199,7 +1199,7 @@ struct zink_resource_object {
|
|||
};
|
||||
VkDeviceAddress bda;
|
||||
|
||||
struct hash_table surface_cache;
|
||||
struct set surface_cache;
|
||||
simple_mtx_t surface_mtx;
|
||||
|
||||
VkSampleLocationsInfoEXT zs_evaluate;
|
||||
|
|
@ -1519,9 +1519,32 @@ zink_screen(struct pipe_screen *pipe)
|
|||
}
|
||||
|
||||
/** surface types */
|
||||
|
||||
|
||||
enum zink_surface_type {
|
||||
ZINK_SURFACE_NORMAL,
|
||||
ZINK_SURFACE_LAYERED,
|
||||
ZINK_SURFACE_ARRAYED,
|
||||
};
|
||||
|
||||
/* compact hash table key based on pipe_surface */
|
||||
struct zink_surface_key {
|
||||
enum pipe_format format:12; /**< typed PIPE_FORMAT_x */
|
||||
unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */
|
||||
unsigned swizzle_g:3; /**< PIPE_SWIZZLE_x for green component */
|
||||
unsigned swizzle_b:3; /**< PIPE_SWIZZLE_x for blue component */
|
||||
unsigned swizzle_a:3; /**< PIPE_SWIZZLE_x for alpha component */
|
||||
unsigned first_level:4; /**< first mipmap level to use */
|
||||
unsigned level_count:4;
|
||||
enum zink_surface_type viewtype:2; /**< layered view of an array/3d iamge */
|
||||
unsigned stencil:1; /**< stencil-only view */
|
||||
unsigned pad:29;
|
||||
unsigned first_layer:16; /**< first layer to use for array textures */
|
||||
unsigned last_layer:16; /**< last layer to use for array textures */
|
||||
};
|
||||
|
||||
/* this type only exists for compat with 32bit builds because vk types are 64bit */
|
||||
struct zink_surface {
|
||||
struct zink_surface_key key;
|
||||
VkImageView image_view;
|
||||
};
|
||||
|
||||
|
|
@ -1534,11 +1557,16 @@ struct zink_sampler_state {
|
|||
bool emulate_nonseamless;
|
||||
};
|
||||
|
||||
struct zink_bufferview_key {
|
||||
enum pipe_format format:12;
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
};
|
||||
|
||||
struct zink_buffer_view {
|
||||
struct pipe_resource *pres;
|
||||
VkBufferViewCreateInfo bvci;
|
||||
struct zink_bufferview_key key;
|
||||
VkBufferView buffer_view;
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
struct zink_sampler_view {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue