From d6dc68e7b5b6f76a55037f6995dad101cc089d02 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 13 Mar 2019 22:58:22 +0000 Subject: [PATCH] virgl: use uint16_t mask instead of separate booleans This should save some space. Suggested-by: Erik Faye-Lund Reviewed-by: Emil Velikov --- src/gallium/drivers/virgl/virgl_buffer.c | 15 ++- src/gallium/drivers/virgl/virgl_context.c | 6 +- src/gallium/drivers/virgl/virgl_query.c | 2 +- src/gallium/drivers/virgl/virgl_resource.c | 15 ++- src/gallium/drivers/virgl/virgl_resource.h | 6 +- src/gallium/drivers/virgl/virgl_texture.c | 10 +- .../winsys/virgl/drm/virgl_drm_winsys.c | 101 +++++++++--------- .../winsys/virgl/vtest/virgl_vtest_winsys.c | 62 +++++------ 8 files changed, 106 insertions(+), 111 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c index ae4e74c7936..3baccc010be 100644 --- a/src/gallium/drivers/virgl/virgl_buffer.c +++ b/src/gallium/drivers/virgl/virgl_buffer.c @@ -40,28 +40,25 @@ static void *virgl_buffer_transfer_map(struct pipe_context *ctx, struct virgl_transfer *trans; void *ptr; bool readback; - bool doflushwait = false; + bool flush = false; trans = virgl_resource_create_transfer(&vctx->transfer_pool, resource, &vbuf->metadata, level, usage, box); if (usage & PIPE_TRANSFER_READ) - doflushwait = true; + flush = true; else - doflushwait = virgl_res_needs_flush_wait(vctx, trans); + flush = virgl_res_needs_flush(vctx, trans); - if (doflushwait) + if (flush) ctx->flush(ctx, NULL, 0); readback = virgl_res_needs_readback(vctx, vbuf, usage, 0); - if (readback) + if (readback) { vs->vws->transfer_get(vs->vws, vbuf->hw_res, box, trans->base.stride, trans->l_stride, trans->offset, level); - if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) - doflushwait = true; - - if (doflushwait || readback) vs->vws->resource_wait(vs->vws, vbuf->hw_res); + } ptr = vs->vws->resource_map(vs->vws, vbuf->hw_res); if (!ptr) { diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 1fa89f61149..fd4001daf25 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -522,7 +522,6 @@ void virgl_transfer_inline_write(struct pipe_context *ctx, unsigned layer_stride) { struct virgl_context *vctx = virgl_context(ctx); - struct virgl_screen *vs = virgl_screen(ctx->screen); struct virgl_resource *grres = virgl_resource(res); struct virgl_transfer trans = { 0 }; @@ -536,12 +535,9 @@ void virgl_transfer_inline_write(struct pipe_context *ctx, virgl_resource_dirty(grres, 0); - if (virgl_res_needs_flush_wait(vctx, &trans)) { + if (virgl_res_needs_flush(vctx, &trans)) ctx->flush(ctx, NULL, 0); - vs->vws->resource_wait(vs->vws, grres->hw_res); - } - virgl_encoder_inline_write(vctx, grres, level, usage, box, data, stride, layer_stride); } diff --git a/src/gallium/drivers/virgl/virgl_query.c b/src/gallium/drivers/virgl/virgl_query.c index 4fc5dd8a8c2..0373eb8a828 100644 --- a/src/gallium/drivers/virgl/virgl_query.c +++ b/src/gallium/drivers/virgl/virgl_query.c @@ -113,7 +113,7 @@ static struct pipe_query *virgl_create_query(struct pipe_context *ctx, query->type = pipe_to_virgl_query(query_type); query->index = index; query->handle = handle; - query->buf->clean[0] = FALSE; + query->buf->clean_mask &= ~1; virgl_encoder_create_query(vctx, handle, query->type, index, query->buf, 0); return (struct pipe_query *)query; diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index 2a1e0c18b8b..7aef1dfdd23 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -27,8 +27,8 @@ #include "virgl_resource.h" #include "virgl_screen.h" -bool virgl_res_needs_flush_wait(struct virgl_context *vctx, - struct virgl_transfer *trans) +bool virgl_res_needs_flush(struct virgl_context *vctx, + struct virgl_transfer *trans) { struct virgl_screen *vs = virgl_screen(vctx->base.screen); struct virgl_resource *res = virgl_resource(trans->base.resource); @@ -37,7 +37,7 @@ bool virgl_res_needs_flush_wait(struct virgl_context *vctx, return false; if (!vs->vws->res_is_referenced(vs->vws, vctx->cbuf, res->hw_res)) return false; - if (res->clean[trans->base.level]) { + if (res->clean_mask & (1 << trans->base.level)) { if (vctx->num_draws == 0 && vctx->num_compute == 0) return false; if (!virgl_transfer_queue_is_queued(&vctx->queue, trans)) @@ -52,7 +52,7 @@ bool virgl_res_needs_readback(struct virgl_context *vctx, unsigned usage, unsigned level) { bool readback = true; - if (res->clean[level]) + if (res->clean_mask & (1 << level)) readback = false; else if (usage & PIPE_TRANSFER_DISCARD_RANGE) readback = false; @@ -88,8 +88,7 @@ static struct pipe_resource *virgl_resource_create(struct pipe_screen *screen, return NULL; } - for (uint32_t i = 0; i < VR_MAX_TEXTURE_2D_LEVELS; i++) - res->clean[i] = TRUE; + res->clean_mask = (1 << VR_MAX_TEXTURE_2D_LEVELS) - 1; if (templ->target == PIPE_BUFFER) virgl_buffer_init(res); @@ -290,8 +289,8 @@ void virgl_resource_dirty(struct virgl_resource *res, uint32_t level) { if (res) { if (res->u.b.target == PIPE_BUFFER) - res->clean[0] = FALSE; + res->clean_mask &= ~1; else - res->clean[level] = FALSE; + res->clean_mask &= ~(1 << level); } } diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h index 01f6bd7ce7d..a60987c5b86 100644 --- a/src/gallium/drivers/virgl/virgl_resource.h +++ b/src/gallium/drivers/virgl/virgl_resource.h @@ -46,7 +46,7 @@ struct virgl_resource_metadata struct virgl_resource { struct u_resource u; - boolean clean[VR_MAX_TEXTURE_2D_LEVELS]; + uint16_t clean_mask; struct virgl_hw_res *hw_res; struct virgl_resource_metadata metadata; }; @@ -112,8 +112,8 @@ static inline unsigned pipe_to_virgl_bind(unsigned pbind) return outbind; } -bool virgl_res_needs_flush_wait(struct virgl_context *vctx, - struct virgl_transfer *transfer); +bool virgl_res_needs_flush(struct virgl_context *vctx, + struct virgl_transfer *transfer); bool virgl_res_needs_readback(struct virgl_context *vctx, struct virgl_resource *res, unsigned usage, unsigned level); diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c index c661ca91752..231319899e0 100644 --- a/src/gallium/drivers/virgl/virgl_texture.c +++ b/src/gallium/drivers/virgl/virgl_texture.c @@ -108,13 +108,13 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx, void *ptr; boolean readback = TRUE; struct virgl_hw_res *hw_res; - bool doflushwait; + bool flush; trans = virgl_resource_create_transfer(&vctx->transfer_pool, resource, &vtex->metadata, level, usage, box); - doflushwait = virgl_res_needs_flush_wait(vctx, trans); - if (doflushwait) + flush = virgl_res_needs_flush(vctx, trans); + if (flush) ctx->flush(ctx, NULL, 0); if (resource->nr_samples > 1) { @@ -138,12 +138,12 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx, } readback = virgl_res_needs_readback(vctx, vtex, usage, level); - if (readback) + if (readback) { vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride, trans->l_stride, trans->offset, level); - if (doflushwait || readback) vs->vws->resource_wait(vs->vws, vtex->hw_res); + } ptr = vs->vws->resource_map(vs->vws, hw_res); if (!ptr) { diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index 7759c87f9cf..120e8eda2cd 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -230,7 +230,7 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws, res->size = size; res->stride = stride; pipe_reference_init(&res->reference, 1); - res->num_cs_references = 0; + p_atomic_set(&res->num_cs_references, 0); res->fence_fd = -1; return res; } @@ -564,54 +564,6 @@ static void virgl_drm_resource_wait(struct virgl_winsys *qws, goto again; } -static struct virgl_cmd_buf *virgl_drm_cmd_buf_create(struct virgl_winsys *qws, - uint32_t size) -{ - struct virgl_drm_cmd_buf *cbuf; - - cbuf = CALLOC_STRUCT(virgl_drm_cmd_buf); - if (!cbuf) - return NULL; - - cbuf->ws = qws; - - cbuf->nres = 512; - cbuf->res_bo = CALLOC(cbuf->nres, sizeof(struct virgl_hw_buf*)); - if (!cbuf->res_bo) { - FREE(cbuf); - return NULL; - } - cbuf->res_hlist = MALLOC(cbuf->nres * sizeof(uint32_t)); - if (!cbuf->res_hlist) { - FREE(cbuf->res_bo); - FREE(cbuf); - return NULL; - } - - cbuf->buf = CALLOC(size, sizeof(uint32_t)); - if (!cbuf->buf) { - FREE(cbuf->res_hlist); - FREE(cbuf->res_bo); - FREE(cbuf); - return NULL; - } - - cbuf->base.buf = cbuf->buf; - cbuf->base.in_fence_fd = -1; - return &cbuf->base; -} - -static void virgl_drm_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf) -{ - struct virgl_drm_cmd_buf *cbuf = virgl_drm_cmd_buf(_cbuf); - - FREE(cbuf->res_hlist); - FREE(cbuf->res_bo); - FREE(cbuf->buf); - FREE(cbuf); - -} - static boolean virgl_drm_lookup_res(struct virgl_drm_cmd_buf *cbuf, struct virgl_hw_res *res) { @@ -702,12 +654,61 @@ static boolean virgl_drm_res_is_ref(struct virgl_winsys *qws, struct virgl_cmd_buf *_cbuf, struct virgl_hw_res *res) { - if (!res->num_cs_references) + if (!p_atomic_read(&res->num_cs_references)) return FALSE; return TRUE; } +static struct virgl_cmd_buf *virgl_drm_cmd_buf_create(struct virgl_winsys *qws, + uint32_t size) +{ + struct virgl_drm_cmd_buf *cbuf; + + cbuf = CALLOC_STRUCT(virgl_drm_cmd_buf); + if (!cbuf) + return NULL; + + cbuf->ws = qws; + + cbuf->nres = 512; + cbuf->res_bo = CALLOC(cbuf->nres, sizeof(struct virgl_hw_buf*)); + if (!cbuf->res_bo) { + FREE(cbuf); + return NULL; + } + cbuf->res_hlist = MALLOC(cbuf->nres * sizeof(uint32_t)); + if (!cbuf->res_hlist) { + FREE(cbuf->res_bo); + FREE(cbuf); + return NULL; + } + + cbuf->buf = CALLOC(size, sizeof(uint32_t)); + if (!cbuf->buf) { + FREE(cbuf->res_hlist); + FREE(cbuf->res_bo); + FREE(cbuf); + return NULL; + } + + cbuf->base.buf = cbuf->buf; + cbuf->base.in_fence_fd = -1; + return &cbuf->base; +} + +static void virgl_drm_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf) +{ + struct virgl_drm_cmd_buf *cbuf = virgl_drm_cmd_buf(_cbuf); + + virgl_drm_release_all_res(virgl_drm_winsys(cbuf->ws), cbuf); + FREE(cbuf->res_hlist); + FREE(cbuf->res_bo); + FREE(cbuf->buf); + FREE(cbuf); + +} + static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws, struct virgl_cmd_buf *_cbuf, int in_fence_fd, int *out_fence_fd) diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index bc65ef3d22a..3ca15e6aed7 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -247,6 +247,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws, res->res_handle = handle++; pipe_reference_init(&res->reference, 1); + p_atomic_set(&res->num_cs_references, 0); return res; } @@ -394,35 +395,6 @@ alloc: return res; } -static struct virgl_cmd_buf *virgl_vtest_cmd_buf_create(struct virgl_winsys *vws, - uint32_t size) -{ - struct virgl_vtest_cmd_buf *cbuf; - - cbuf = CALLOC_STRUCT(virgl_vtest_cmd_buf); - if (!cbuf) - return NULL; - - cbuf->nres = 512; - cbuf->res_bo = CALLOC(cbuf->nres, sizeof(struct virgl_hw_buf*)); - if (!cbuf->res_bo) { - FREE(cbuf); - return NULL; - } - cbuf->ws = vws; - cbuf->base.buf = cbuf->buf; - cbuf->base.in_fence_fd = -1; - return &cbuf->base; -} - -static void virgl_vtest_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf) -{ - struct virgl_vtest_cmd_buf *cbuf = virgl_vtest_cmd_buf(_cbuf); - - FREE(cbuf->res_bo); - FREE(cbuf); -} - static boolean virgl_vtest_lookup_res(struct virgl_vtest_cmd_buf *cbuf, struct virgl_hw_res *res) { @@ -485,6 +457,36 @@ static void virgl_vtest_add_res(struct virgl_vtest_winsys *vtws, cbuf->cres++; } +static struct virgl_cmd_buf *virgl_vtest_cmd_buf_create(struct virgl_winsys *vws, + uint32_t size) +{ + struct virgl_vtest_cmd_buf *cbuf; + + cbuf = CALLOC_STRUCT(virgl_vtest_cmd_buf); + if (!cbuf) + return NULL; + + cbuf->nres = 512; + cbuf->res_bo = CALLOC(cbuf->nres, sizeof(struct virgl_hw_buf*)); + if (!cbuf->res_bo) { + FREE(cbuf); + return NULL; + } + cbuf->ws = vws; + cbuf->base.buf = cbuf->buf; + cbuf->base.in_fence_fd = -1; + return &cbuf->base; +} + +static void virgl_vtest_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf) +{ + struct virgl_vtest_cmd_buf *cbuf = virgl_vtest_cmd_buf(_cbuf); + + virgl_vtest_release_all_res(virgl_vtest_winsys(cbuf->ws), cbuf); + FREE(cbuf->res_bo); + FREE(cbuf); +} + static int virgl_vtest_winsys_submit_cmd(struct virgl_winsys *vws, struct virgl_cmd_buf *_cbuf, int in_fence_fd, int *out_fence_fd) @@ -525,7 +527,7 @@ static boolean virgl_vtest_res_is_ref(struct virgl_winsys *vws, struct virgl_cmd_buf *_cbuf, struct virgl_hw_res *res) { - if (!res->num_cs_references) + if (!p_atomic_read(&res->num_cs_references)) return FALSE; return TRUE; -- 2.30.2