radeonsi: fix vertex buffer and elements
authorChristian König <deathsimple@vodafone.de>
Wed, 25 Jul 2012 09:22:59 +0000 (11:22 +0200)
committerChristian König <deathsimple@vodafone.de>
Mon, 30 Jul 2012 12:45:32 +0000 (14:45 +0200)
Let's just use the T# descriptors until we get a fetch shader.

Signed-off-by: Christian König <deathsimple@vodafone.de>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/radeonsi_shader.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c

index cc4777f..66050d3 100644 (file)
@@ -182,7 +182,7 @@ static void declare_input_vs(
        struct lp_build_context * uint = &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
        struct lp_build_context * base = &si_shader_ctx->radeon_bld.soa.bld_base.base;
        struct r600_context *rctx = si_shader_ctx->rctx;
-       struct pipe_vertex_element *velem = &rctx->vertex_elements->elements[input_index];
+       //struct pipe_vertex_element *velem = &rctx->vertex_elements->elements[input_index];
        unsigned chan;
 
        /* Load the T list */
@@ -191,12 +191,12 @@ static void declare_input_vs(
         * now */
        t_list_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_V4I32, 6);
 
-       t_offset = lp_build_const_int32(base->gallivm, velem->vertex_buffer_index);
+       t_offset = lp_build_const_int32(base->gallivm, input_index);
 
        t_list = build_indexed_load(base->gallivm, t_list_ptr, t_offset);
 
        /* Build the attribute offset */
-       attribute_offset = lp_build_const_int32(base->gallivm, velem->src_offset);
+       attribute_offset = lp_build_const_int32(base->gallivm, 0);
 
        /* Load the buffer index is always, which is always stored in VGPR0
         * for Vertex Shaders */
index 297d791..c417c9c 100644 (file)
@@ -1226,10 +1226,10 @@ static bool si_is_sampler_format_supported(struct pipe_screen *screen, enum pipe
                                      util_format_get_first_non_void_channel(format)) != ~0U;
 }
 
-uint32_t si_translate_vertexformat(struct pipe_screen *screen,
-                                  enum pipe_format format,
-                                  const struct util_format_description *desc,
-                                  int first_non_void)
+static uint32_t si_translate_vertexformat(struct pipe_screen *screen,
+                                         enum pipe_format format,
+                                         const struct util_format_description *desc,
+                                         int first_non_void)
 {
        uint32_t result;
 
@@ -2078,12 +2078,45 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
                                       const struct pipe_vertex_element *elements)
 {
        struct si_vertex_element *v = CALLOC_STRUCT(si_vertex_element);
+       int i;
 
-       assert(count < 32);
+       assert(count < PIPE_MAX_ATTRIBS);
        if (!v)
                return NULL;
 
        v->count = count;
+       for (i = 0; i < count; ++i) {
+               const struct util_format_description *desc;
+               unsigned data_format, num_format;
+               int first_non_void;
+
+               desc = util_format_description(elements[i].src_format);
+               first_non_void = util_format_get_first_non_void_channel(elements[i].src_format);
+               data_format = si_translate_vertexformat(ctx->screen, elements[i].src_format,
+                                                       desc, first_non_void);
+
+               switch (desc->channel[first_non_void].type) {
+               case UTIL_FORMAT_TYPE_FIXED:
+                       num_format = V_008F0C_BUF_NUM_FORMAT_USCALED; /* XXX */
+                       break;
+               case UTIL_FORMAT_TYPE_SIGNED:
+                       num_format = V_008F0C_BUF_NUM_FORMAT_SNORM;
+                       break;
+               case UTIL_FORMAT_TYPE_UNSIGNED:
+                       num_format = V_008F0C_BUF_NUM_FORMAT_UNORM;
+                       break;
+               case UTIL_FORMAT_TYPE_FLOAT:
+               default:
+                       num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
+               }
+
+               v->rsrc_word3[i] = 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);
+       }
        memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count);
 
        return v;
index 0eecf2f..fa1a871 100644 (file)
@@ -63,8 +63,9 @@ struct si_state_dsa {
 
 struct si_vertex_element
 {
-        unsigned                        count;
-        struct pipe_vertex_element      elements[PIPE_MAX_ATTRIBS];
+       unsigned                        count;
+       uint32_t                        rsrc_word3[PIPE_MAX_ATTRIBS];
+       struct pipe_vertex_element      elements[PIPE_MAX_ATTRIBS];
 };
 
 struct si_shader_io {
@@ -157,10 +158,6 @@ union si_state {
        } while(0);
 
 /* si_state.c */
-uint32_t si_translate_vertexformat(struct pipe_screen *screen,
-                                  enum pipe_format format,
-                                  const struct util_format_description *desc,
-                                  int first_non_void);
 bool si_is_format_supported(struct pipe_screen *screen,
                            enum pipe_format format,
                            enum pipe_texture_target target,
index c49091d..0d9f009 100644 (file)
@@ -383,17 +383,17 @@ static void si_update_derived_state(struct r600_context *rctx)
 static void si_vertex_buffer_update(struct r600_context *rctx)
 {
        struct pipe_context *ctx = &rctx->context;
-       struct si_resource *rbuffer, *t_list_buffer;
-       struct pipe_vertex_buffer *vertex_buffer;
        struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
-       unsigned i, count, offset;
+       bool bound[PIPE_MAX_ATTRIBS] = {};
+       struct si_resource *t_list_buffer;
+       unsigned i, count;
        uint32_t *ptr;
        uint64_t va;
 
        si_pm4_inval_vertex_cache(pm4);
 
        /* bind vertex buffer once */
-       count = rctx->nr_vertex_buffers;
+       count = rctx->vertex_elements->count;
        assert(count <= 256 / 4);
 
        t_list_buffer = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE,
@@ -402,70 +402,50 @@ static void si_vertex_buffer_update(struct r600_context *rctx)
                FREE(pm4);
                return;
        }
+       si_pm4_add_bo(pm4, t_list_buffer, RADEON_USAGE_READ);
 
        ptr = (uint32_t*)rctx->ws->buffer_map(t_list_buffer->cs_buf,
                                              rctx->cs,
                                              PIPE_TRANSFER_WRITE);
 
        for (i = 0 ; i < count; i++, ptr += 4) {
-               struct pipe_vertex_element *velem = &rctx->vertex_elements->elements[i];
-               const struct util_format_description *desc;
-               unsigned data_format, num_format;
-               int first_non_void;
-
-               /* bind vertex buffer once */
-               vertex_buffer = &rctx->vertex_buffer[i];
-               rbuffer = (struct si_resource*)vertex_buffer->buffer;
-               offset = 0;
-               if (vertex_buffer == NULL || rbuffer == NULL)
+               struct pipe_vertex_element *ve = &rctx->vertex_elements->elements[i];
+               struct pipe_vertex_buffer *vb;
+               struct si_resource *rbuffer;
+               unsigned offset;
+
+               if (ve->vertex_buffer_index >= rctx->nr_vertex_buffers)
                        continue;
-               offset += vertex_buffer->buffer_offset;
+
+               vb = &rctx->vertex_buffer[ve->vertex_buffer_index];
+               rbuffer = (struct si_resource*)vb->buffer;
+               if (rbuffer == NULL)
+                       continue;
+
+               offset = 0;
+               offset += vb->buffer_offset;
+               offset += ve->src_offset;
 
                va = r600_resource_va(ctx->screen, (void*)rbuffer);
                va += offset;
 
-               desc = util_format_description(velem->src_format);
-               first_non_void = util_format_get_first_non_void_channel(velem->src_format);
-               data_format = si_translate_vertexformat(ctx->screen,
-                                                       velem->src_format,
-                                                       desc, first_non_void);
-
-               switch (desc->channel[first_non_void].type) {
-               case UTIL_FORMAT_TYPE_FIXED:
-                       num_format = V_008F0C_BUF_NUM_FORMAT_USCALED; /* XXX */
-                       break;
-               case UTIL_FORMAT_TYPE_SIGNED:
-                       num_format = V_008F0C_BUF_NUM_FORMAT_SNORM;
-                       break;
-               case UTIL_FORMAT_TYPE_UNSIGNED:
-                       num_format = V_008F0C_BUF_NUM_FORMAT_UNORM;
-                       break;
-               case UTIL_FORMAT_TYPE_FLOAT:
-               default:
-                       num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
-               }
-
                /* Fill in T# buffer resource description */
                ptr[0] = va & 0xFFFFFFFF;
                ptr[1] = (S_008F04_BASE_ADDRESS_HI(va >> 32) |
-                         S_008F04_STRIDE(vertex_buffer->stride));
-               if (vertex_buffer->stride > 0)
-                       ptr[2] = ((vertex_buffer->buffer->width0 - offset) /
-                                 vertex_buffer->stride);
+                         S_008F04_STRIDE(vb->stride));
+               if (vb->stride > 0)
+                       ptr[2] = (vb->buffer->width0 - offset) / vb->stride;
                else
-                       ptr[2] = vertex_buffer->buffer->width0 - offset;
-               ptr[3] = (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));
-
-               si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ);
+                       ptr[2] = vb->buffer->width0 - offset;
+               ptr[3] = rctx->vertex_elements->rsrc_word3[i];
+
+               if (!bound[ve->vertex_buffer_index]) {
+                       si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ);
+                       bound[ve->vertex_buffer_index] = true;
+               }
        }
 
        va = r600_resource_va(ctx->screen, (void*)t_list_buffer);
-       si_pm4_add_bo(pm4, t_list_buffer, RADEON_USAGE_READ);
        si_pm4_set_reg(pm4, R_00B148_SPI_SHADER_USER_DATA_VS_6, va);
        si_pm4_set_reg(pm4, R_00B14C_SPI_SHADER_USER_DATA_VS_7, va >> 32);
        si_pm4_set_state(rctx, vertex_buffers, pm4);