From: Marek Olšák <marek.ol...@amd.com> do it at bind time, so that pipe_sampler_view is immutable with regard to buffer reallocations and we don't have to remember all existing buffer views. --- src/gallium/drivers/radeonsi/si_descriptors.c | 33 ++++++++++++++++----------- src/gallium/drivers/radeonsi/si_pipe.h | 1 - src/gallium/drivers/radeonsi/si_state.c | 12 ++-------- 3 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index b60cd61..8bfeeec 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -342,20 +342,31 @@ static void si_sampler_views_begin_new_cs(struct si_context *sctx, while (mask) { int i = u_bit_scan(&mask); struct si_sampler_view *sview = (struct si_sampler_view *)views->views[i]; si_sampler_view_add_buffer(sctx, sview->base.texture, RADEON_USAGE_READ, sview->is_stencil_sampler, false); } } +/* Set buffer descriptor fields that can be changed by reallocations. */ +static void si_set_buf_desc_address(struct r600_resource *buf, + uint64_t offset, uint32_t *state) +{ + uint64_t va = buf->gpu_address + offset; + + state[0] = va; + state[1] &= C_008F04_BASE_ADDRESS_HI; + state[1] |= S_008F04_BASE_ADDRESS_HI(va >> 32); +} + /* Set texture descriptor fields that can be changed by reallocations. * * \param tex texture * \param base_level_info information of the level of BASE_ADDRESS * \param base_level the level of BASE_ADDRESS * \param first_level pipe_sampler_view.u.tex.first_level * \param block_width util_format_get_blockwidth() * \param is_stencil select between separate Z & Stencil * \param state descriptor to update */ @@ -409,20 +420,24 @@ static void si_set_sampler_view(struct si_context *sctx, if (view) { struct r600_texture *rtex = (struct r600_texture *)view->texture; uint32_t *desc = descs->list + slot * 16; assert(rtex); /* NULL views aren't supported */ pipe_sampler_view_reference(&views->views[slot], view); memcpy(desc, rview->state, 8*4); if (rtex->resource.b.b.target == PIPE_BUFFER) { rtex->resource.bind_history |= PIPE_BIND_SAMPLER_VIEW; + + si_set_buf_desc_address(&rtex->resource, + view->u.buf.offset, + desc + 4); } else { bool is_separate_stencil = rtex->db_compatible && rview->is_stencil_sampler; si_set_mutable_tex_desc_fields(rtex, rview->base_level_info, rview->base_level, rview->base.u.tex.first_level, rview->block_width, @@ -614,48 +629,50 @@ si_mark_image_range_valid(const struct pipe_image_view *view) } static void si_set_shader_image(struct si_context *ctx, unsigned shader, unsigned slot, const struct pipe_image_view *view) { struct si_screen *screen = ctx->screen; struct si_images_info *images = &ctx->images[shader]; struct si_descriptors *descs = si_image_descriptors(ctx, shader); struct r600_resource *res; + uint32_t *desc = descs->list + slot * 8; if (!view || !view->resource) { si_disable_shader_image(ctx, shader, slot); return; } res = (struct r600_resource *)view->resource; if (&images->views[slot] != view) util_copy_image_view(&images->views[slot], view); if (res->b.b.target == PIPE_BUFFER) { if (view->access & PIPE_IMAGE_ACCESS_WRITE) si_mark_image_range_valid(view); si_make_buffer_descriptor(screen, res, view->format, view->u.buf.offset, view->u.buf.size, descs->list + slot * 8); + si_set_buf_desc_address(res, view->u.buf.offset, desc + 4); + images->compressed_colortex_mask &= ~(1 << slot); res->bind_history |= PIPE_BIND_SHADER_IMAGE; } else { static const unsigned char swizzle[4] = { 0, 1, 2, 3 }; struct r600_texture *tex = (struct r600_texture *)res; unsigned level = view->u.tex.level; unsigned width, height, depth; - uint32_t *desc = descs->list + slot * 8; bool uses_dcc = tex->dcc_offset && tex->surface.level[level].dcc_enabled; assert(!tex->is_depth); assert(tex->fmask.size == 0); if (uses_dcc && (view->access & PIPE_IMAGE_ACCESS_WRITE || !vi_dcc_formats_compatible(res->b.b.format, view->format))) { /* If DCC can't be disabled, at least decompress it. @@ -1400,25 +1417,22 @@ static void si_desc_reset_buffer_offset(struct pipe_context *ctx, struct pipe_resource *new_buf) { /* Retrieve the buffer offset from the descriptor. */ uint64_t old_desc_va = desc[0] | ((uint64_t)G_008F04_BASE_ADDRESS_HI(desc[1]) << 32); assert(old_buf_va <= old_desc_va); uint64_t offset_within_buffer = old_desc_va - old_buf_va; /* Update the descriptor. */ - uint64_t va = r600_resource(new_buf)->gpu_address + offset_within_buffer; - - desc[0] = va; - desc[1] = (desc[1] & C_008F04_BASE_ADDRESS_HI) | - S_008F04_BASE_ADDRESS_HI(va >> 32); + si_set_buf_desc_address(r600_resource(new_buf), offset_within_buffer, + desc); } /* INTERNAL CONST BUFFERS */ static void si_set_polygon_stipple(struct pipe_context *ctx, const struct pipe_poly_stipple *state) { struct si_context *sctx = (struct si_context *)ctx; struct pipe_constant_buffer cb = {}; unsigned stipple[32]; @@ -1484,21 +1498,20 @@ static void si_reset_buffer_resources(struct si_context *sctx, * map_buffer flags, for example. */ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource *buf) { struct si_context *sctx = (struct si_context*)ctx; struct r600_resource *rbuffer = r600_resource(buf); unsigned i, shader; uint64_t old_va = rbuffer->gpu_address; unsigned num_elems = sctx->vertex_elements ? sctx->vertex_elements->count : 0; - struct si_sampler_view *view; /* Reallocate the buffer in the same pipe_resource. */ r600_alloc_resource(&sctx->screen->b, rbuffer); /* We changed the buffer, now we need to bind it where the old one * was bound. This consists of 2 things: * 1) Updating the resource descriptor and dirtying it. * 2) Adding a relocation to the CS, so that it's usable. */ @@ -1555,26 +1568,20 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource si_const_buffer_descriptors_idx(shader), buf, old_va); if (rbuffer->bind_history & PIPE_BIND_SHADER_BUFFER) for (shader = 0; shader < SI_NUM_SHADERS; shader++) si_reset_buffer_resources(sctx, &sctx->shader_buffers[shader], si_shader_buffer_descriptors_idx(shader), buf, old_va); if (rbuffer->bind_history & PIPE_BIND_SAMPLER_VIEW) { - /* Texture buffers - update virtual addresses in sampler view descriptors. */ - LIST_FOR_EACH_ENTRY(view, &sctx->b.texture_buffers, list) { - if (view->base.texture == buf) { - si_desc_reset_buffer_offset(ctx, &view->state[4], old_va, buf); - } - } /* Texture buffers - update bindings. */ for (shader = 0; shader < SI_NUM_SHADERS; shader++) { struct si_sampler_views *views = &sctx->samplers[shader].views; struct si_descriptors *descs = si_sampler_descriptors(sctx, shader); unsigned mask = views->enabled_mask; while (mask) { unsigned i = u_bit_scan(&mask); if (views->views[i]->texture == buf) { diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 3d9ea97..55e4ca7 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -118,21 +118,20 @@ struct si_screen { LLVMTargetMachineRef tm[4]; /* used by the queue only */ }; struct si_blend_color { struct r600_atom atom; struct pipe_blend_color state; }; struct si_sampler_view { struct pipe_sampler_view base; - struct list_head list; /* [0..7] = image descriptor * [4..7] = buffer descriptor */ uint32_t state[8]; uint32_t fmask_state[8]; const struct radeon_surf_level *base_level_info; unsigned base_level; unsigned block_width; bool is_stencil_sampler; }; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 92f8d90..e3de572 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2654,41 +2654,38 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples) * @param state 256-bit descriptor; only the high 128 bits are filled in */ void si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf, enum pipe_format format, unsigned offset, unsigned size, uint32_t *state) { const struct util_format_description *desc; int first_non_void; - uint64_t va; unsigned stride; unsigned num_records; unsigned num_format, data_format; desc = util_format_description(format); first_non_void = util_format_get_first_non_void_channel(format); stride = desc->block.bits / 8; - va = buf->gpu_address + offset; num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void); data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void); num_records = size / stride; num_records = MIN2(num_records, (buf->b.b.width0 - offset) / stride); if (screen->b.chip_class >= VI) num_records *= stride; - state[4] = va; - state[5] = S_008F04_BASE_ADDRESS_HI(va >> 32) | - S_008F04_STRIDE(stride); + state[4] = 0; + state[5] = S_008F04_STRIDE(stride); state[6] = num_records; state[7] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) | S_008F0C_DST_SEL_Y(si_map_swizzle(desc->swizzle[1])) | S_008F0C_DST_SEL_Z(si_map_swizzle(desc->swizzle[2])) | S_008F0C_DST_SEL_W(si_map_swizzle(desc->swizzle[3])) | S_008F0C_NUM_FORMAT(num_format) | S_008F0C_DATA_FORMAT(data_format); } /** @@ -2960,22 +2957,20 @@ si_create_sampler_view_custom(struct pipe_context *ctx, view->is_stencil_sampler = true; /* Buffer resource. */ if (texture->target == PIPE_BUFFER) { si_make_buffer_descriptor(sctx->screen, (struct r600_resource *)texture, state->format, state->u.buf.offset, state->u.buf.size, view->state); - - LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers); return &view->base; } state_swizzle[0] = state->swizzle_r; state_swizzle[1] = state->swizzle_g; state_swizzle[2] = state->swizzle_b; state_swizzle[3] = state->swizzle_a; base_level = 0; first_level = state->u.tex.first_level; @@ -3074,23 +3069,20 @@ si_create_sampler_view(struct pipe_context *ctx, return si_create_sampler_view_custom(ctx, texture, state, texture ? texture->width0 : 0, texture ? texture->height0 : 0, 0); } static void si_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state) { struct si_sampler_view *view = (struct si_sampler_view *)state; - if (state->texture && state->texture->target == PIPE_BUFFER) - LIST_DELINIT(&view->list); - pipe_resource_reference(&state->texture, NULL); FREE(view); } static bool wrap_mode_uses_border_color(unsigned wrap, bool linear_filter) { return wrap == PIPE_TEX_WRAP_CLAMP_TO_BORDER || wrap == PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER || (linear_filter && (wrap == PIPE_TEX_WRAP_CLAMP || -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev