From 0707ff3f2f31d9b72aebd169e9464c5fbfaa00ca Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 7 Apr 2018 00:49:12 -0700 Subject: [PATCH] iris: assemble SAMPLER_STATE table at bind time It's useless to allocate SAMPLER_STATEs in GPU memory on creation like we do for SURFACE_STATES, because they need to be organized into a contiguous block of memory. But we can do that at bind time, rather than draw time. --- src/gallium/drivers/iris/iris_context.h | 5 +++ src/gallium/drivers/iris/iris_state.c | 54 ++++++++++++++----------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 51eabf91e4b..21e81d37477 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -183,10 +183,15 @@ struct iris_context { struct pipe_stencil_ref stencil_ref; struct pipe_framebuffer_state framebuffer; + struct pipe_resource *sampler_table_resource[MESA_SHADER_STAGES]; + uint32_t sampler_table_offset[MESA_SHADER_STAGES]; struct iris_sampler_state *samplers[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS]; + unsigned num_samplers; struct iris_binder binder; struct u_upload_mgr *surface_uploader; + // XXX: may want a separate uploader for "hey I made a CSO!" vs + // "I'm streaming this out at draw time and never want it again!" struct u_upload_mgr *dynamic_uploader; void (*destroy_state)(struct iris_context *ice); diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 20b2c29abbc..a0f6a685b43 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -872,10 +872,37 @@ iris_bind_sampler_states(struct pipe_context *ctx, assert(start + count <= IRIS_MAX_TEXTURE_SAMPLERS); + /* Assemble the SAMPLER_STATEs into a contiguous chunk of memory + * relative to Dynamic State Base Address. + */ + void *map = NULL; + u_upload_alloc(ice->state.dynamic_uploader, 0, + count * 4 * GENX(SAMPLER_STATE_length), 32, + &ice->state.sampler_table_offset[stage], + &ice->state.sampler_table_resource[stage], + &map); + if (!unlikely(map)) + return NULL; + + ice->state.sampler_table_offset[stage] += + bo_offset_from_base_address(ice->state.sampler_table_resource[stage]); + for (int i = 0; i < count; i++) { - ice->state.samplers[stage][start + i] = states[i]; + struct iris_sampler_state *state = states[i]; + + /* Save a pointer to the iris_sampler_state, a few fields need + * to inform draw-time decisions. + */ + ice->state.samplers[stage][start + i] = state; + + if (state) + memcpy(map, state->sampler_state, 4 * GENX(SAMPLER_STATE_length)); + + map += GENX(SAMPLER_STATE_length); } + ice->state.num_samplers = count; + ice->state.dirty |= IRIS_DIRTY_SAMPLER_STATES_VS << stage; } @@ -2068,12 +2095,10 @@ iris_upload_render_state(struct iris_context *ice, } #if 0 - for (int i = 0; i < TEXTURES; i++) { + for (int i = 0; i < ice->state.num_samplers; i++) { struct iris_sampler_view *view = SOMEWHERE; struct iris_resource *res = (void *) view->pipe.texture; - // XXX: these are per-context??????????? pipe_sampler_view::context - *bt_map++ = - emit_patched_surface_state(batch, view->surface_state, res, 0); + *bt_map++ = use_surface(batch, isv, true); } // XXX: not implemented yet @@ -2092,26 +2117,9 @@ iris_upload_render_state(struct iris_context *ice, !ice->shaders.prog[stage]) continue; - // XXX: get sampler count from shader; don't emit them all... - const int count = IRIS_MAX_TEXTURE_SAMPLERS; - - uint32_t offset; - uint32_t *map = stream_state(batch, ice->state.dynamic_uploader, - count * 4 * GENX(SAMPLER_STATE_length), - 32, &offset); - - for (int i = 0; i < count; i++) { - // XXX: when we have a correct count, these better be bound - if (!ice->state.samplers[stage][i]) - continue; - memcpy(map, ice->state.samplers[stage][i]->sampler_state, - 4 * GENX(SAMPLER_STATE_length)); - map += GENX(SAMPLER_STATE_length); - } - iris_emit_cmd(batch, GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ptr) { ptr._3DCommandSubOpcode = 43 + stage; - ptr.PointertoVSSamplerState = offset; + ptr.PointertoVSSamplerState = ice->state.sampler_table_offset[stage]; } } -- 2.30.2