From 371743157e24c59942ac680c952ab2527808e6f2 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 16 May 2019 15:01:36 -0700 Subject: [PATCH] virgl: store all info about atomic buffers We will need the full info. This also speeds up virgl_attach_res_atomic_buffers and fixes resource leaks when the context is destroyed. Signed-off-by: Chia-I Wu Reviewed-by: Alexandros Frantzis --- src/gallium/drivers/virgl/virgl_context.c | 35 ++++++++++++++++++------------- src/gallium/drivers/virgl/virgl_context.h | 4 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 0d4a886..507160a 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -195,13 +195,14 @@ static void virgl_attach_res_shader_images(struct virgl_context *vctx, static void virgl_attach_res_atomic_buffers(struct virgl_context *vctx) { struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; + uint32_t remaining_mask = vctx->atomic_buffer_enabled_mask; struct virgl_resource *res; - unsigned i; - for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) { - res = virgl_resource(vctx->atomic_buffers[i]); - if (res) { - vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); - } + + while (remaining_mask) { + int i = u_bit_scan(&remaining_mask); + res = virgl_resource(vctx->atomic_buffers[i].buffer); + assert(res); + vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); } } @@ -1007,18 +1008,19 @@ static void virgl_set_hw_atomic_buffers(struct pipe_context *ctx, { struct virgl_context *vctx = virgl_context(ctx); + vctx->atomic_buffer_enabled_mask &= ~u_bit_consecutive(start_slot, count); for (unsigned i = 0; i < count; i++) { unsigned idx = start_slot + i; - - if (buffers) { - if (buffers[i].buffer) { - pipe_resource_reference(&vctx->atomic_buffers[idx], - buffers[i].buffer); - continue; - } + if (buffers && buffers[i].buffer) { + pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, + buffers[i].buffer); + vctx->atomic_buffers[idx] = buffers[i]; + vctx->atomic_buffer_enabled_mask |= 1 << idx; + } else { + pipe_resource_reference(&vctx->atomic_buffers[idx].buffer, NULL); } - pipe_resource_reference(&vctx->atomic_buffers[idx], NULL); } + virgl_encode_set_hw_atomic_buffers(vctx, start_slot, count, buffers); } @@ -1210,6 +1212,11 @@ virgl_context_destroy( struct pipe_context *ctx ) for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) virgl_release_shader_binding(vctx, shader_type); + while (vctx->atomic_buffer_enabled_mask) { + int i = u_bit_scan(&vctx->atomic_buffer_enabled_mask); + pipe_resource_reference(&vctx->atomic_buffers[i].buffer, NULL); + } + rs->vws->cmd_buf_destroy(vctx->cbuf); if (vctx->uploader) u_upload_destroy(vctx->uploader); diff --git a/src/gallium/drivers/virgl/virgl_context.h b/src/gallium/drivers/virgl/virgl_context.h index 663a3ca..7fd0740 100644 --- a/src/gallium/drivers/virgl/virgl_context.h +++ b/src/gallium/drivers/virgl/virgl_context.h @@ -71,6 +71,8 @@ struct virgl_context { unsigned cbuf_initial_cdw; struct virgl_shader_binding_state shader_bindings[PIPE_SHADER_TYPES]; + struct pipe_shader_buffer atomic_buffers[PIPE_MAX_HW_ATOMIC_BUFFERS]; + uint32_t atomic_buffer_enabled_mask; struct virgl_vertex_elements_state *vertex_elements; @@ -91,8 +93,6 @@ struct virgl_context { uint32_t num_draws, num_compute; - struct pipe_resource *atomic_buffers[PIPE_MAX_HW_ATOMIC_BUFFERS]; - struct primconvert_context *primconvert; uint32_t hw_sub_ctx_id; }; -- 2.7.4