diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index e16b4fb4802..90008e08fd5 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -33,7 +33,9 @@ blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info) if (src->format != zink_get_format(screen, info->src.format) || dst->format != zink_get_format(screen, info->dst.format)) return false; - + if (info->dst.resource->target == PIPE_BUFFER) + util_range_add(info->dst.resource, &dst->valid_buffer_range, + info->dst.box.x, info->dst.box.x + info->dst.box.width); struct zink_batch *batch = zink_batch_no_rp(ctx); zink_batch_reference_resource_rw(batch, src, false); @@ -119,7 +121,9 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) zink_batch_reference_resource_rw(batch, dst, true); zink_resource_setup_transfer_layouts(batch, src, dst); - + if (info->dst.resource->target == PIPE_BUFFER) + util_range_add(info->dst.resource, &dst->valid_buffer_range, + info->dst.box.x, info->dst.box.x + info->dst.box.width); VkImageBlit region = {}; region.srcSubresource.aspectMask = src->aspect; region.srcSubresource.mipLevel = info->src.level; @@ -203,6 +207,9 @@ zink_blit(struct pipe_context *pctx, return; } + if (info->dst.resource->target == PIPE_BUFFER) + util_range_add(info->dst.resource, &dst->valid_buffer_range, + info->dst.box.x, info->dst.box.x + info->dst.box.width); util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state); util_blitter_save_viewport(ctx->blitter, ctx->viewport_states); diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index daa60558e00..9f91e75b463 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -276,6 +276,8 @@ zink_clear_texture(struct pipe_context *pctx, zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS); util_clear_render_target(pctx, surf, &color, box->x, box->y, box->width, box->height); } + if (res->base.target == PIPE_BUFFER) + util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width); } else { float depth = 0.0; uint8_t stencil = 0; diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 633edbe3952..4f9f12c5a12 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -610,6 +610,8 @@ zink_set_shader_buffers(struct pipe_context *pctx, pipe_resource_reference(&ssbo->buffer, &res->base); ssbo->buffer_offset = buffers[i].buffer_offset; ssbo->buffer_size = MIN2(buffers[i].buffer_size, res->size - ssbo->buffer_offset); + util_range_add(&res->base, &res->valid_buffer_range, ssbo->buffer_offset, + ssbo->buffer_offset + ssbo->buffer_size); } else { pipe_resource_reference(&ssbo->buffer, NULL); ssbo->buffer_offset = 0; @@ -651,6 +653,8 @@ zink_set_shader_images(struct pipe_context *pctx, if (images[i].resource->target == PIPE_BUFFER) { image_view->buffer_view = create_buffer_view(zink_screen(pctx->screen), res, images[i].format, images[i].u.buf.offset, images[i].u.buf.size); assert(image_view->buffer_view); + util_range_add(&res->base, &res->valid_buffer_range, images[i].u.buf.offset, + images[i].u.buf.offset + images[i].u.buf.size); } else { struct pipe_surface tmpl = {}; tmpl.format = images[i].format; @@ -1512,10 +1516,11 @@ zink_resource_copy_region(struct pipe_context *pctx, struct zink_batch *batch = zink_batch_no_rp(ctx); zink_batch_reference_resource_rw(batch, src, false); zink_batch_reference_resource_rw(batch, dst, true); - + util_range_add(&dst->base, &dst->valid_buffer_range, dstx, dstx + src_box->width); vkCmdCopyBuffer(batch->cmdbuf, src->buffer, dst->buffer, 1, ®ion); } else debug_printf("zink: TODO resource copy\n"); + //util_range_add(dst, &dst->valid_buffer_range, dstx, dstx + src_box->width); } static struct pipe_stream_output_target * @@ -1545,6 +1550,9 @@ zink_create_stream_output_target(struct pipe_context *pctx, t->base.buffer_offset = buffer_offset; t->base.buffer_size = buffer_size; + struct zink_resource *res = zink_resource(pres); + util_range_add(pres, &res->valid_buffer_range, buffer_offset, + buffer_offset + buffer_size); return &t->base; } diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c index 5cafb544eac..8ea20df1c68 100644 --- a/src/gallium/drivers/zink/zink_query.c +++ b/src/gallium/drivers/zink/zink_query.c @@ -781,9 +781,11 @@ zink_get_query_result_resource(struct pipe_context *pctx, uint64_t *u64_map = map; u64_map[0] = u64[1]; } + util_range_add(&res->base, &res->valid_buffer_range, offset, result_size); pipe_buffer_unmap(pctx, transfer); return; } + util_range_add(&res->base, &res->valid_buffer_range, offset, result_size); unsigned fences = p_atomic_read(&query->fences); if (!is_time_query(query) && (!fences || wait)) { diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 4a0364d05b8..bf690847943 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -52,9 +52,10 @@ zink_resource_destroy(struct pipe_screen *pscreen, { struct zink_screen *screen = zink_screen(pscreen); struct zink_resource *res = zink_resource(pres); - if (pres->target == PIPE_BUFFER) + if (pres->target == PIPE_BUFFER) { vkDestroyBuffer(screen->dev, res->buffer, NULL); - else + util_range_destroy(&res->valid_buffer_range); + } else vkDestroyImage(screen->dev, res->image, NULL); vkFreeMemory(screen->dev, res->mem, NULL); @@ -344,9 +345,10 @@ resource_create(struct pipe_screen *pscreen, res->offset = 0; res->size = reqs.size; - if (templ->target == PIPE_BUFFER) + if (templ->target == PIPE_BUFFER) { vkBindBufferMemory(screen->dev, res->buffer, res->mem, res->offset); - else + util_range_init(&res->valid_buffer_range); + } else vkBindImageMemory(screen->dev, res->image, res->mem, res->offset); if (screen->winsys && (templ->bind & PIPE_BIND_DISPLAY_TARGET)) { @@ -550,7 +552,7 @@ zink_transfer_map(struct pipe_context *pctx, void *ptr; if (pres->target == PIPE_BUFFER) { - if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) { + if (!(usage & PIPE_MAP_UNSYNCHRONIZED) && util_ranges_intersect(&res->valid_buffer_range, box->x, box->x + box->width)) { if ((usage & PIPE_MAP_READ && batch_uses >= ZINK_RESOURCE_ACCESS_WRITE) || (usage & PIPE_MAP_WRITE && batch_uses)) { /* need to wait for rendering to finish @@ -591,6 +593,8 @@ zink_transfer_map(struct pipe_context *pctx, trans->base.stride = 0; trans->base.layer_stride = 0; ptr = ((uint8_t *)ptr) + box->x; + if (usage & PIPE_MAP_WRITE) + util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width); } else { if (res->optimal_tiling || !res->host_visible) { enum pipe_format format = pres->format; @@ -675,6 +679,16 @@ zink_transfer_map(struct pipe_context *pctx, return ptr; } +static void +zink_transfer_flush_region(struct pipe_context *ctx, + struct pipe_transfer *ptrans, + const struct pipe_box *box) +{ + struct zink_resource *res = zink_resource(ptrans->resource); + if (res->base.target == PIPE_BUFFER) + util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width); +} + static void zink_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) @@ -703,7 +717,9 @@ zink_transfer_unmap(struct pipe_context *pctx, vkUnmapMemory(screen->dev, res->mem); if ((trans->base.usage & PIPE_MAP_PERSISTENT) && !(trans->base.usage & PIPE_MAP_COHERENT)) res->persistent_maps--; - + if (!(trans->base.usage & (PIPE_MAP_FLUSH_EXPLICIT | PIPE_MAP_COHERENT))) { + zink_transfer_flush_region(pctx, ptrans, &ptrans->box); + } pipe_resource_reference(&trans->base.resource, NULL); slab_free(&ctx->transfer_pool, ptrans); } @@ -794,7 +810,7 @@ static const struct u_transfer_vtbl transfer_vtbl = { .resource_destroy = zink_resource_destroy, .transfer_map = zink_transfer_map, .transfer_unmap = zink_transfer_unmap, - .transfer_flush_region = u_default_transfer_flush_region, + .transfer_flush_region = zink_transfer_flush_region, .get_internal_format = zink_resource_get_internal_format, .set_stencil = zink_resource_set_separate_stencil, .get_stencil = zink_resource_get_separate_stencil, diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index d113f801b3d..92596beafc9 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -29,6 +29,7 @@ struct sw_displaytarget; struct zink_batch; #include "util/u_transfer.h" +#include "util/u_range.h" #include @@ -45,6 +46,7 @@ struct zink_resource { struct { VkAccessFlags access; VkBuffer buffer; + struct util_range valid_buffer_range; }; struct { VkFormat format;