From 1cea195a9520a548d1a19db208f956177d3fc12f Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 28 Jun 2018 00:57:49 -0700 Subject: [PATCH] iris: state ref tuple --- src/gallium/drivers/iris/iris_context.h | 20 +-- src/gallium/drivers/iris/iris_program_cache.c | 23 +-- src/gallium/drivers/iris/iris_resource.h | 12 +- src/gallium/drivers/iris/iris_state.c | 155 +++++++++--------- 4 files changed, 103 insertions(+), 107 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 5e6b9e02280..597dfc28065 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -30,6 +30,7 @@ #include "intel/common/gen_debug.h" #include "intel/compiler/brw_compiler.h" #include "iris_batch.h" +#include "iris_resource.h" #include "iris_screen.h" struct iris_bo; @@ -157,8 +158,8 @@ enum pipe_control_flags /** @} */ struct iris_compiled_shader { - /** Buffer containing the uploaded assembly. */ - struct pipe_resource *buffer; + /** Reference to the uploaded assembly. */ + struct iris_state_ref assembly; /** Pointer to the assembly in the BO's map. */ void *map; @@ -166,9 +167,6 @@ struct iris_compiled_shader { /** The program data (owned by the program cache hash table) */ struct brw_stage_prog_data *prog_data; - /** Offset where the assembly lives in the BO. */ - unsigned offset; - /** * Shader packets and other data derived from prog_data. These must be * completely determined from prog_data. @@ -178,12 +176,10 @@ struct iris_compiled_shader { struct iris_const_buffer { /** The resource and offset for the actual constant data */ - struct pipe_resource *resource; - unsigned offset; + struct iris_state_ref data; /** The resource and offset for the SURFACE_STATE for pull access. */ - struct pipe_resource *surface_state_resource; - unsigned surface_state_offset; + struct iris_state_ref surface_state; }; struct iris_shader_state { @@ -262,15 +258,13 @@ struct iris_context { struct pipe_framebuffer_state framebuffer; struct iris_depth_buffer_state *cso_depthbuffer; - struct pipe_resource *sampler_table_resource[MESA_SHADER_STAGES]; - uint32_t sampler_table_offset[MESA_SHADER_STAGES]; + struct iris_state_ref sampler_table[MESA_SHADER_STAGES]; struct iris_sampler_state *samplers[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS]; struct iris_sampler_view *textures[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS]; unsigned num_samplers[MESA_SHADER_STAGES]; unsigned num_textures[MESA_SHADER_STAGES]; - struct pipe_resource *unbound_tex_surface_state_resource; - unsigned unbound_tex_surface_state_offset; + struct iris_state_ref unbound_tex; struct u_upload_mgr *surface_uploader; // XXX: may want a separate uploader for "hey I made a CSO!" vs diff --git a/src/gallium/drivers/iris/iris_program_cache.c b/src/gallium/drivers/iris/iris_program_cache.c index 700648f0d4e..17e92566392 100644 --- a/src/gallium/drivers/iris/iris_program_cache.c +++ b/src/gallium/drivers/iris/iris_program_cache.c @@ -229,13 +229,14 @@ iris_upload_shader(struct iris_context *ice, * backend. */ if (existing) { - pipe_resource_reference(&shader->buffer, existing->buffer); - shader->offset = existing->offset; + pipe_resource_reference(&shader->assembly.res, existing->assembly.res); + shader->assembly.offset = existing->assembly.offset; shader->map = existing->map; } else { - shader->buffer = NULL; - u_upload_alloc(ice->shaders.uploader, 0, prog_data->program_size, - 64, &shader->offset, &shader->buffer, &shader->map); + shader->assembly.res = NULL; + u_upload_alloc(ice->shaders.uploader, 0, prog_data->program_size, 64, + &shader->assembly.offset, &shader->assembly.res, + &shader->map); memcpy(shader->map, assembly, prog_data->program_size); } @@ -290,8 +291,9 @@ iris_blorp_lookup_shader(struct blorp_batch *blorp_batch, if (!shader) return false; - struct iris_bo *bo = iris_resource_bo(shader->buffer); - *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset; + struct iris_bo *bo = iris_resource_bo(shader->assembly.res); + *kernel_out = + iris_bo_offset_from_base_address(bo) + shader->assembly.offset; *((void **) prog_data_out) = shader->prog_data; iris_use_pinned_bo(batch, bo, false); @@ -318,8 +320,9 @@ iris_blorp_upload_shader(struct blorp_batch *blorp_batch, iris_upload_shader(ice, IRIS_CACHE_BLORP, key_size, key, kernel, prog_data); - struct iris_bo *bo = iris_resource_bo(shader->buffer); - *kernel_out = iris_bo_offset_from_base_address(bo) + shader->offset; + struct iris_bo *bo = iris_resource_bo(shader->assembly.res); + *kernel_out = + iris_bo_offset_from_base_address(bo) + shader->assembly.offset; *((void **) prog_data_out) = shader->prog_data; iris_use_pinned_bo(batch, bo, false); @@ -347,7 +350,7 @@ iris_destroy_program_cache(struct iris_context *ice) hash_table_foreach(ice->shaders.cache, entry) { struct iris_compiled_shader *shader = entry->data; - pipe_resource_reference(&shader->buffer, NULL); + pipe_resource_reference(&shader->assembly.res, NULL); } u_upload_destroy(ice->shaders.uploader); diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 45b8cf6a6c7..3280dc1c49c 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -33,6 +33,15 @@ struct iris_resource { struct iris_bo *bo; }; +/** + * A simple tuple for storing a reference to a + * piece of state stored in a GPU buffer object. + */ +struct iris_state_ref { + struct pipe_resource *res; + uint32_t offset; +}; + enum isl_format iris_isl_format_for_pipe_format(enum pipe_format pf); void iris_init_screen_resource_functions(struct pipe_screen *pscreen); @@ -49,8 +58,7 @@ struct iris_surface { struct isl_view view; /** The resource (BO) holding our SURFACE_STATE. */ - struct pipe_resource *surface_state_resource; - unsigned surface_state_offset; + struct iris_state_ref surface_state; }; #endif diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 4efef936ac4..5bfab87a0ce 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -276,6 +276,17 @@ ro_bo(struct iris_bo *bo, uint64_t offset) return (struct iris_address) { .bo = bo, .offset = offset }; } +static void * +upload_state(struct u_upload_mgr *uploader, + struct iris_state_ref *ref, + unsigned size, + unsigned alignment) +{ + void *p = NULL; + u_upload_alloc(uploader, 0, size, alignment, &ref->offset, &ref->res, &p); + return p; +} + static uint32_t * stream_state(struct iris_batch *batch, struct u_upload_mgr *uploader, @@ -861,17 +872,14 @@ iris_bind_sampler_states(struct pipe_context *ctx, /* 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); + void *map = upload_state(ice->state.dynamic_uploader, + &ice->state.sampler_table[stage], + count * 4 * GENX(SAMPLER_STATE_length), 32); if (unlikely(!map)) return; - struct pipe_resource *res = ice->state.sampler_table_resource[stage]; - ice->state.sampler_table_offset[stage] += + struct pipe_resource *res = ice->state.sampler_table[stage].res; + ice->state.sampler_table[stage].offset += iris_bo_offset_from_base_address(iris_resource_bo(res)); for (int i = 0; i < count; i++) { @@ -898,8 +906,7 @@ struct iris_sampler_view { struct isl_view view; /** The resource (BO) holding our SURFACE_STATE. */ - struct pipe_resource *surface_state_resource; - unsigned surface_state_offset; + struct iris_state_ref surface_state; }; /** @@ -958,17 +965,13 @@ iris_create_sampler_view(struct pipe_context *ctx, .usage = ISL_SURF_USAGE_TEXTURE_BIT, }; - void *map = NULL; - u_upload_alloc(ice->state.surface_uploader, 0, - 4 * GENX(RENDER_SURFACE_STATE_length), 64, - &isv->surface_state_offset, - &isv->surface_state_resource, - &map); + void *map = upload_state(ice->state.surface_uploader, &isv->surface_state, + 4 * GENX(RENDER_SURFACE_STATE_length), 64); if (!unlikely(map)) return NULL; - struct iris_bo *state_bo = iris_resource_bo(isv->surface_state_resource); - isv->surface_state_offset += iris_bo_offset_from_base_address(state_bo); + struct iris_bo *state_bo = iris_resource_bo(isv->surface_state.res); + isv->surface_state.offset += iris_bo_offset_from_base_address(state_bo); isl_surf_fill_state(&screen->isl_dev, map, .surf = &itex->surf, .view = &isv->view, @@ -1028,17 +1031,14 @@ iris_create_surface(struct pipe_context *ctx, ISL_SURF_USAGE_STENCIL_BIT)) return psurf; - void *map = NULL; - u_upload_alloc(ice->state.surface_uploader, 0, - 4 * GENX(RENDER_SURFACE_STATE_length), 64, - &surf->surface_state_offset, - &surf->surface_state_resource, - &map); + + void *map = upload_state(ice->state.surface_uploader, &surf->surface_state, + 4 * GENX(RENDER_SURFACE_STATE_length), 64); if (!unlikely(map)) return NULL; - struct iris_bo *state_bo = iris_resource_bo(surf->surface_state_resource); - surf->surface_state_offset += iris_bo_offset_from_base_address(state_bo); + struct iris_bo *state_bo = iris_resource_bo(surf->surface_state.res); + surf->surface_state.offset += iris_bo_offset_from_base_address(state_bo); isl_surf_fill_state(&screen->isl_dev, map, .surf = &res->surf, .view = &surf->view, @@ -1361,36 +1361,34 @@ iris_set_constant_buffer(struct pipe_context *ctx, if (input && (input->buffer || input->user_buffer)) { if (input->user_buffer) { u_upload_data(ctx->const_uploader, 0, input->buffer_size, 32, - input->user_buffer, &cbuf->offset, &cbuf->resource); + input->user_buffer, &cbuf->data.offset, + &cbuf->data.res); } else { - pipe_resource_reference(&cbuf->resource, input->buffer); + pipe_resource_reference(&cbuf->data.res, input->buffer); } - void *map = NULL; // XXX: these are not retained forever, use a separate uploader? - u_upload_alloc(ice->state.surface_uploader, 0, - 4 * GENX(RENDER_SURFACE_STATE_length), 64, - &cbuf->surface_state_offset, - &cbuf->surface_state_resource, - &map); + void *map = + upload_state(ice->state.surface_uploader, &cbuf->surface_state, + 4 * GENX(RENDER_SURFACE_STATE_length), 64); if (!unlikely(map)) { - pipe_resource_reference(&cbuf->resource, NULL); + pipe_resource_reference(&cbuf->data.res, NULL); return; } - struct iris_resource *res = (void *) cbuf->resource; - struct iris_bo *surf_bo = iris_resource_bo(cbuf->surface_state_resource); - cbuf->surface_state_offset += iris_bo_offset_from_base_address(surf_bo); + struct iris_resource *res = (void *) cbuf->data.res; + struct iris_bo *surf_bo = iris_resource_bo(cbuf->surface_state.res); + cbuf->surface_state.offset += iris_bo_offset_from_base_address(surf_bo); isl_buffer_fill_state(&screen->isl_dev, map, - .address = res->bo->gtt_offset + cbuf->offset, + .address = res->bo->gtt_offset + cbuf->data.offset, .size_B = input->buffer_size, .format = ISL_FORMAT_R32G32B32A32_FLOAT, .stride_B = 1, .mocs = MOCS_WB) } else { - pipe_resource_reference(&cbuf->resource, NULL); - pipe_resource_reference(&cbuf->surface_state_resource, NULL); + pipe_resource_reference(&cbuf->data.res, NULL); + pipe_resource_reference(&cbuf->surface_state.res, NULL); } ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS << stage; @@ -1404,7 +1402,7 @@ iris_sampler_view_destroy(struct pipe_context *ctx, { struct iris_sampler_view *isv = (void *) state; pipe_resource_reference(&state->texture, NULL); - pipe_resource_reference(&isv->surface_state_resource, NULL); + pipe_resource_reference(&isv->surface_state.res, NULL); free(isv); } @@ -1414,7 +1412,7 @@ iris_surface_destroy(struct pipe_context *ctx, struct pipe_surface *p_surf) { struct iris_surface *surf = (void *) p_surf; pipe_resource_reference(&p_surf->texture, NULL); - pipe_resource_reference(&surf->surface_state_resource, NULL); + pipe_resource_reference(&surf->surface_state.res, NULL); free(surf); } @@ -1916,8 +1914,8 @@ iris_populate_fs_key(const struct iris_context *ice, static uint64_t KSP(const struct iris_compiled_shader *shader) { - struct iris_resource *res = (void *) shader->buffer; - return res->bo->gtt_offset + shader->offset; + struct iris_resource *res = (void *) shader->assembly.res; + return iris_bo_offset_from_base_address(res->bo) + shader->assembly.offset; } #define INIT_THREAD_DISPATCH_FIELDS(pkt, prefix) \ @@ -2230,45 +2228,39 @@ use_surface(struct iris_batch *batch, bool writeable) { struct iris_surface *surf = (void *) p_surf; - struct iris_resource *res = (void *) p_surf->texture; - struct iris_resource *state_res = (void *) surf->surface_state_resource; - iris_use_pinned_bo(batch, res->bo, writeable); - iris_use_pinned_bo(batch, state_res->bo, false); - return surf->surface_state_offset; + iris_use_pinned_bo(batch, iris_resource_bo(p_surf->texture), writeable); + iris_use_pinned_bo(batch, iris_resource_bo(surf->surface_state.res), false); + + return surf->surface_state.offset; } static uint32_t use_sampler_view(struct iris_batch *batch, struct iris_sampler_view *isv) { - struct iris_resource *res = (void *) isv->pipe.texture; - struct iris_resource *state_res = (void *) isv->surface_state_resource; - iris_use_pinned_bo(batch, res->bo, false); - iris_use_pinned_bo(batch, state_res->bo, false); + iris_use_pinned_bo(batch, iris_resource_bo(isv->pipe.texture), false); + iris_use_pinned_bo(batch, iris_resource_bo(isv->surface_state.res), false); - return isv->surface_state_offset; + return isv->surface_state.offset; } static uint32_t use_const_buffer(struct iris_batch *batch, struct iris_const_buffer *cbuf) { - struct iris_resource *res = (void *) cbuf->resource; - struct iris_resource *state_res = (void *) cbuf->surface_state_resource; - iris_use_pinned_bo(batch, res->bo, false); - iris_use_pinned_bo(batch, state_res->bo, false); + iris_use_pinned_bo(batch, iris_resource_bo(cbuf->data.res), false); + iris_use_pinned_bo(batch, iris_resource_bo(cbuf->surface_state.res), false); - return cbuf->surface_state_offset; + return cbuf->surface_state.offset; } static uint32_t use_null_surface(struct iris_batch *batch, struct iris_context *ice) { - struct iris_resource *state_res = - (void *) ice->state.unbound_tex_surface_state_resource; + struct iris_bo *state_bo = iris_resource_bo(ice->state.unbound_tex.res); - iris_use_pinned_bo(batch, state_res->bo, false); + iris_use_pinned_bo(batch, state_bo, false); - return ice->state.unbound_tex_surface_state_offset; + return ice->state.unbound_tex.offset; } static void @@ -2312,7 +2304,7 @@ iris_populate_binding_table(struct iris_context *ice, struct iris_shader_state *shs = &ice->shaders.state[stage]; for (int i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { struct iris_const_buffer *cbuf = &shs->constbuf[i]; - if (!cbuf->surface_state_resource) + if (!cbuf->surface_state.res) break; bt_map[s++] = use_const_buffer(batch, cbuf); @@ -2402,7 +2394,7 @@ iris_restore_context_saved_bos(struct iris_context *ice, continue; struct iris_const_buffer *cbuf = &shs->constbuf[range->block]; - struct iris_resource *res = (void *) cbuf->resource; + struct iris_resource *res = (void *) cbuf->data.res; if (res) iris_use_pinned_bo(batch, res->bo, false); @@ -2412,7 +2404,7 @@ iris_restore_context_saved_bos(struct iris_context *ice, } for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { - struct pipe_resource *res = ice->state.sampler_table_resource[stage]; + struct pipe_resource *res = ice->state.sampler_table[stage].res; if (res) iris_use_pinned_bo(batch, iris_resource_bo(res), false); } @@ -2420,8 +2412,10 @@ iris_restore_context_saved_bos(struct iris_context *ice, for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) { if (clean & (IRIS_DIRTY_VS << stage)) { struct iris_compiled_shader *shader = ice->shaders.prog[stage]; - if (shader) - iris_use_pinned_bo(batch, iris_resource_bo(shader->buffer), false); + if (shader) { + struct iris_bo *bo = iris_resource_bo(shader->assembly.res); + iris_use_pinned_bo(batch, bo, false); + } // XXX: scratch buffer } @@ -2577,13 +2571,13 @@ iris_upload_render_state(struct iris_context *ice, // XXX: is range->block a constbuf index? it would be nice struct iris_const_buffer *cbuf = &shs->constbuf[range->block]; - struct iris_resource *res = (void *) cbuf->resource; + struct iris_resource *res = (void *) cbuf->data.res; - assert(cbuf->offset % 32 == 0); + assert(cbuf->data.offset % 32 == 0); pkt.ConstantBody.ReadLength[n] = range->length; pkt.ConstantBody.Buffer[n] = - res ? ro_bo(res->bo, range->start * 32 + cbuf->offset) + res ? ro_bo(res->bo, range->start * 32 + cbuf->data.offset) : ro_bo(batch->screen->workaround_bo, 0); n--; } @@ -2613,13 +2607,13 @@ iris_upload_render_state(struct iris_context *ice, !ice->shaders.prog[stage]) continue; - struct pipe_resource *res = ice->state.sampler_table_resource[stage]; + struct pipe_resource *res = ice->state.sampler_table[stage].res; if (res) iris_use_pinned_bo(batch, iris_resource_bo(res), false); iris_emit_cmd(batch, GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ptr) { ptr._3DCommandSubOpcode = 43 + stage; - ptr.PointertoVSSamplerState = ice->state.sampler_table_offset[stage]; + ptr.PointertoVSSamplerState = ice->state.sampler_table[stage].offset; } } @@ -2645,7 +2639,7 @@ iris_upload_render_state(struct iris_context *ice, struct iris_compiled_shader *shader = ice->shaders.prog[stage]; if (shader) { - struct iris_resource *cache = (void *) shader->buffer; + struct iris_resource *cache = (void *) shader->assembly.res; iris_use_pinned_bo(batch, cache->bo, false); iris_batch_emit(batch, shader->derived_data, iris_derived_program_state_size(stage)); @@ -2884,7 +2878,7 @@ iris_destroy_state(struct iris_context *ice) pipe_surface_reference(&ice->state.framebuffer.zsbuf, NULL); for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) { - pipe_resource_reference(&ice->state.sampler_table_resource[stage], NULL); + pipe_resource_reference(&ice->state.sampler_table[stage].res, NULL); } free(ice->state.cso_vp); free(ice->state.cso_depthbuffer); @@ -3371,11 +3365,8 @@ genX(init_state)(struct iris_context *ice) calloc(1, sizeof(struct iris_vertex_buffer_state)); /* Make a 1x1x1 null surface for unbound textures */ - void *null_surf_map = NULL; - u_upload_alloc(ice->state.surface_uploader, 0, - 4 * GENX(RENDER_SURFACE_STATE_length), 64, - &ice->state.unbound_tex_surface_state_offset, - &ice->state.unbound_tex_surface_state_resource, - &null_surf_map); + void *null_surf_map = + upload_state(ice->state.surface_uploader, &ice->state.unbound_tex, + 4 * GENX(RENDER_SURFACE_STATE_length), 64); isl_null_fill_state(&screen->isl_dev, null_surf_map, isl_extent3d(1, 1, 1)); } -- 2.30.2