zink: force cached mem for streaming uploads

it was previously possible to hit a path where an idle buffer with
non-cached mem could be directly mapped for streaming data uploads,
which kills perf

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33678>
This commit is contained in:
Mike Blumenkrantz 2025-02-21 14:01:48 -05:00 committed by Marge Bot
parent 7210054db8
commit e63acdd2b7
3 changed files with 10 additions and 6 deletions

View file

@ -2340,14 +2340,17 @@ zink_buffer_map(struct pipe_context *pctx,
}
unsigned map_offset = box->x;
/* ideally never ever read or write to non-cached mem */
bool is_cached_mem = (screen->info.mem_props.memoryTypes[res->obj->bo->base.base.placement].propertyFlags & VK_STAGING_RAM) == VK_STAGING_RAM;
/* but this is only viable with a certain amount of vram since it may fully duplicate lots of large buffers */
bool host_mem_type_check = screen->always_cached_upload ? is_cached_mem : res->obj->host_visible;
if (usage & PIPE_MAP_DISCARD_RANGE &&
(!res->obj->host_visible ||
!(usage & (PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_PERSISTENT)))) {
(!host_mem_type_check || !(usage & (PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_PERSISTENT)))) {
/* Check if mapping this buffer would cause waiting for the GPU.
*/
if (!res->obj->host_visible || force_discard_range ||
if (!host_mem_type_check || force_discard_range ||
!zink_resource_usage_check_completion(screen, res, ZINK_RESOURCE_ACCESS_RW)) {
/* Do a wait-free write-only transfer using a temporary buffer. */
unsigned offset;
@ -2381,9 +2384,7 @@ zink_buffer_map(struct pipe_context *pctx,
if (!zink_resource_usage_check_completion(screen, res, ZINK_RESOURCE_ACCESS_WRITE))
goto success;
usage |= PIPE_MAP_UNSYNCHRONIZED;
} else if (((usage & PIPE_MAP_READ) && !(usage & PIPE_MAP_PERSISTENT) &&
((screen->info.mem_props.memoryTypes[res->obj->bo->base.base.placement].propertyFlags & VK_STAGING_RAM) != VK_STAGING_RAM)) ||
!res->obj->host_visible) {
} else if ((usage & PIPE_MAP_READ) && !(usage & PIPE_MAP_PERSISTENT) && !host_mem_type_check) {
/* any read, non-HV write, or unmappable that reaches this point needs staging */
if ((usage & PIPE_MAP_READ) || !res->obj->host_visible || res->base.b.flags & PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY) {
overwrite:

View file

@ -3365,6 +3365,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
/* determine if vis vram is roughly equal to total vram */
if (biggest_vis_vram > biggest_vram * 0.9)
screen->resizable_bar = true;
if (biggest_vis_vram >= 8ULL * 1024ULL * 1024ULL * 1024ULL)
screen->always_cached_upload = true;
}
setup_renderdoc(screen);

View file

@ -1456,6 +1456,7 @@ struct zink_screen {
uint8_t heap_map[ZINK_HEAP_MAX][VK_MAX_MEMORY_TYPES]; // mapping from zink heaps to memory type indices
uint8_t heap_count[ZINK_HEAP_MAX]; // number of memory types per zink heap
bool resizable_bar;
bool always_cached_upload;
uint64_t total_video_mem;
uint64_t clamp_video_mem;