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

Reply via email to