From 3eb6754e94c623c4c2393f23aeaafa933bee154e Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 26 Jun 2013 12:26:02 +0800 Subject: [PATCH] ilo: support PIPE_CAP_USER_CONSTANT_BUFFERS We need it for HUD support, and will need it for push constants in the future. --- src/gallium/drivers/ilo/ilo_context.c | 23 +++++++-- src/gallium/drivers/ilo/ilo_context.h | 7 ++- src/gallium/drivers/ilo/ilo_gpe.h | 7 +++ src/gallium/drivers/ilo/ilo_screen.c | 2 +- src/gallium/drivers/ilo/ilo_state.c | 72 +++++++++++++++++++++------ 5 files changed, 88 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c index d3e900661ee..e355a9c3089 100644 --- a/src/gallium/drivers/ilo/ilo_context.c +++ b/src/gallium/drivers/ilo/ilo_context.c @@ -25,6 +25,7 @@ * Chia-I Wu */ +#include "util/u_upload_mgr.h" #include "intel_chipset.h" #include "ilo_3d.h" @@ -96,7 +97,8 @@ ilo_context_destroy(struct pipe_context *pipe) if (ilo->last_cp_bo) intel_bo_unreference(ilo->last_cp_bo); - util_slab_destroy(&ilo->transfer_mempool); + if (ilo->uploader) + u_upload_destroy(ilo->uploader); if (ilo->blitter) ilo_blitter_destroy(ilo->blitter); @@ -107,6 +109,8 @@ ilo_context_destroy(struct pipe_context *pipe) if (ilo->cp) ilo_cp_destroy(ilo->cp); + util_slab_destroy(&ilo->transfer_mempool); + FREE(ilo); } @@ -123,6 +127,13 @@ ilo_context_create(struct pipe_screen *screen, void *priv) ilo->winsys = is->winsys; ilo->dev = &is->dev; + /* + * initialize first, otherwise it may not be safe to call + * ilo_context_destroy() on errors + */ + util_slab_create(&ilo->transfer_mempool, + sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED); + ilo->cp = ilo_cp_create(ilo->winsys, is->dev.has_llc); ilo->shader_cache = ilo_shader_cache_create(); if (ilo->cp) @@ -133,12 +144,16 @@ ilo_context_create(struct pipe_screen *screen, void *priv) return NULL; } + ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 16, + PIPE_BIND_CONSTANT_BUFFER); + if (!ilo->uploader) { + ilo_context_destroy(&ilo->base); + return NULL; + } + ilo_cp_set_flush_callback(ilo->cp, ilo_context_cp_flushed, (void *) ilo); - util_slab_create(&ilo->transfer_mempool, - sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED); - ilo->base.screen = screen; ilo->base.priv = priv; diff --git a/src/gallium/drivers/ilo/ilo_context.h b/src/gallium/drivers/ilo/ilo_context.h index a37ed001b4c..ed9bba39ab5 100644 --- a/src/gallium/drivers/ilo/ilo_context.h +++ b/src/gallium/drivers/ilo/ilo_context.h @@ -34,6 +34,7 @@ #include "ilo_gpe.h" #include "ilo_common.h" +struct u_upload_mgr; struct intel_winsys; struct intel_bo; struct ilo_3d; @@ -48,15 +49,17 @@ struct ilo_context { struct intel_winsys *winsys; struct ilo_dev_info *dev; + struct util_slab_mempool transfer_mempool; + struct ilo_cp *cp; struct intel_bo *last_cp_bo; - struct util_slab_mempool transfer_mempool; - struct ilo_shader_cache *shader_cache; struct ilo_3d *hw3d; struct ilo_blitter *blitter; + struct u_upload_mgr *uploader; + uint32_t dirty; struct ilo_vb_state vb; diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h index 5e313abd386..7825e58a40f 100644 --- a/src/gallium/drivers/ilo/ilo_gpe.h +++ b/src/gallium/drivers/ilo/ilo_gpe.h @@ -207,6 +207,13 @@ struct ilo_view_state { struct ilo_cbuf_cso { struct pipe_resource *resource; struct ilo_view_surface surface; + + /* + * this CSO is not so constant because user buffer needs to be uploaded in + * finalize_constant_buffers() + */ + const void *user_buffer; + unsigned user_buffer_size; }; struct ilo_cbuf_state { diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index d2b211366b1..aaceb7a6494 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -393,7 +393,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: return false; case PIPE_CAP_USER_CONSTANT_BUFFERS: - return false; /* TODO push constants */ + return true; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: /* imposed by OWord (Dual) Block Read */ return 16; diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 7046a69890c..71783dfaca8 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -27,6 +27,7 @@ #include "util/u_framebuffer.h" #include "util/u_helpers.h" +#include "util/u_upload_mgr.h" #include "ilo_context.h" #include "ilo_resource.h" @@ -86,18 +87,40 @@ finalize_shader_states(struct ilo_context *ilo) static void finalize_constant_buffers(struct ilo_context *ilo) { - int sh; + int sh, i; if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER)) return; + /* TODO push constants? */ for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { - int last_cbuf = Elements(ilo->cbuf[sh].cso) - 1; + int last_cbuf = -1; - /* find the last cbuf */ - while (last_cbuf >= 0 && - !ilo->cbuf[sh].cso[last_cbuf].resource) - last_cbuf--; + for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { + struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; + + /* upload user buffer */ + if (cbuf->user_buffer) { + const enum pipe_format elem_format = + PIPE_FORMAT_R32G32B32A32_FLOAT; + unsigned offset; + + u_upload_data(ilo->uploader, 0, cbuf->user_buffer_size, + cbuf->user_buffer, &offset, &cbuf->resource); + + ilo_gpe_init_view_surface_for_buffer(ilo->dev, + ilo_buffer(cbuf->resource), + offset, cbuf->user_buffer_size, + util_format_get_blocksize(elem_format), elem_format, + false, false, &cbuf->surface); + + cbuf->user_buffer = NULL; + cbuf->user_buffer_size = 0; + } + + if (cbuf->resource) + last_cbuf = i; + } ilo->cbuf[sh].count = last_cbuf + 1; } @@ -112,6 +135,8 @@ ilo_finalize_states(struct ilo_context *ilo) { finalize_shader_states(ilo); finalize_constant_buffers(ilo); + + u_upload_unmap(ilo->uploader); } static void * @@ -509,7 +534,7 @@ ilo_set_clip_state(struct pipe_context *pipe, static void ilo_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_constant_buffer *buf) + struct pipe_constant_buffer *state) { struct ilo_context *ilo = ilo_context(pipe); struct ilo_cbuf_cso *cbuf; @@ -519,22 +544,37 @@ ilo_set_constant_buffer(struct pipe_context *pipe, cbuf = &ilo->cbuf[shader].cso[index]; - if (buf) { - const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + if (state) { + pipe_resource_reference(&cbuf->resource, state->buffer); + + if (state->buffer) { + const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - /* no PIPE_CAP_USER_CONSTANT_BUFFERS */ - assert(!buf->user_buffer); + ilo_gpe_init_view_surface_for_buffer(ilo->dev, + ilo_buffer(cbuf->resource), + state->buffer_offset, state->buffer_size, + util_format_get_blocksize(elem_format), elem_format, + false, false, &cbuf->surface); - pipe_resource_reference(&cbuf->resource, buf->buffer); + cbuf->user_buffer = NULL; + cbuf->user_buffer_size = 0; + } + else { + assert(state->user_buffer); + + cbuf->surface.bo = NULL; - ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(buf->buffer), - buf->buffer_offset, buf->buffer_size, - util_format_get_blocksize(elem_format), elem_format, - false, false, &cbuf->surface); + /* state->buffer_offset does not apply for user buffer */ + cbuf->user_buffer = state->user_buffer; + cbuf->user_buffer_size = state->buffer_size; + } } else { pipe_resource_reference(&cbuf->resource, NULL); cbuf->surface.bo = NULL; + + cbuf->user_buffer = NULL; + cbuf->user_buffer_size = 0; } /* the correct value will be set in ilo_finalize_states() */ -- 2.30.2