r300g: use the new vertex buffer manager
authorMarek Olšák <maraeo@gmail.com>
Mon, 7 Feb 2011 01:00:44 +0000 (02:00 +0100)
committerMarek Olšák <maraeo@gmail.com>
Mon, 7 Feb 2011 01:46:23 +0000 (02:46 +0100)
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_translate.c
src/gallium/drivers/r300/r300_screen_buffer.c
src/gallium/drivers/r300/r300_screen_buffer.h
src/gallium/drivers/r300/r300_state.c

index 69f8115c32cea1130d0553304367bace463fadac..e29990d4b956fb52f6769995e16dc39bd405b6ab 100644 (file)
@@ -55,8 +55,8 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
     util_blitter_save_viewport(r300->blitter, &r300->viewport);
     util_blitter_save_clip(r300->blitter, (struct pipe_clip_state*)r300->clip_state.state);
     util_blitter_save_vertex_elements(r300->blitter, r300->velems);
-    util_blitter_save_vertex_buffers(r300->blitter, r300->vertex_buffer_count,
-                                     r300->vertex_buffer);
+    util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers,
+                                     r300->vbuf_mgr->vertex_buffer);
 
     if (op & (R300_CLEAR_SURFACE | R300_COPY)) {
         util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
index 114fb316c0553f9348a33a8f535ce7300338b28b..b8b7afa9c27ba23581f30c0f490b43f4ee233bce 100644 (file)
@@ -83,12 +83,6 @@ static void r300_release_referenced_objects(struct r300_context *r300)
     /* The SWTCL VBO. */
     pipe_resource_reference(&r300->vbo, NULL);
 
-    /* Vertex buffers. */
-    for (i = 0; i < r300->real_vertex_buffer_count; i++) {
-        pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
-        pipe_resource_reference(&r300->real_vertex_buffer[i], NULL);
-    }
-
     /* If there are any queries pending or not destroyed, remove them now. */
     foreach_s(query, temp, &r300->query_list) {
         remove_from_list(query);
@@ -108,14 +102,11 @@ static void r300_destroy_context(struct pipe_context* context)
     if (r300->draw)
         draw_destroy(r300->draw);
 
-    if (r300->upload_vb)
-        u_upload_destroy(r300->upload_vb);
+    if (r300->vbuf_mgr)
+        u_vbuf_mgr_destroy(r300->vbuf_mgr);
     if (r300->upload_ib)
         u_upload_destroy(r300->upload_ib);
 
-    if (r300->tran.translate_cache)
-        translate_cache_destroy(r300->tran.translate_cache);
-
     /* XXX: This function assumes r300->query_list was initialized */
     r300_release_referenced_objects(r300);
 
@@ -442,6 +433,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     r300_init_state_functions(r300);
     r300_init_resource_functions(r300);
 
+    r300->vbuf_mgr = u_vbuf_mgr_create(&r300->context, 1024 * 1024, 16,
+                                      U_VERTEX_FETCH_DWORD_ALIGNED);
+    if (!r300->vbuf_mgr)
+        goto fail;
+
     r300->blitter = util_blitter_create(&r300->context);
     if (r300->blitter == NULL)
         goto fail;
@@ -463,16 +459,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     if (r300->upload_ib == NULL)
         goto fail;
 
-    r300->upload_vb = u_upload_create(&r300->context,
-                                     1024 * 1024, 16,
-                                     PIPE_BIND_VERTEX_BUFFER);
-    if (r300->upload_vb == NULL)
-        goto fail;
-
-    r300->tran.translate_cache = translate_cache_create();
-    if (r300->tran.translate_cache == NULL)
-        goto fail;
-
     r300_init_states(&r300->context);
 
     /* The KIL opcode needs the first texture unit to be enabled
index 430a0ddbb5cedd6e1b21f017da7a3ea754650aff..9d2a0b290ae62a30440ae8e5acf02f0733510675 100644 (file)
@@ -30,8 +30,7 @@
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
 #include "util/u_transfer.h"
-
-#include "translate/translate_cache.h"
+#include "util/u_vbuf_mgr.h"
 
 #include "r300_defines.h"
 #include "r300_screen.h"
@@ -421,33 +420,16 @@ struct r300_texture {
 struct r300_vertex_element_state {
     unsigned count;
     struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+    unsigned format_size[PIPE_MAX_ATTRIBS];
 
-    /* If (velem[i].src_format != hw_format[i]), the vertex buffer
-     * referenced by this vertex element cannot be used for rendering and
-     * its vertex data must be translated to hw_format[i]. */
-    enum pipe_format hw_format[PIPE_MAX_ATTRIBS];
-    unsigned hw_format_size[PIPE_MAX_ATTRIBS];
+    struct u_vbuf_mgr_elements *vmgr_elements;
 
     /* The size of the vertex, in dwords. */
     unsigned vertex_size_dwords;
 
-    /* This might mean two things:
-     * - src_format != hw_format, as discussed above.
-     * - src_offset % 4 != 0. */
-    boolean incompatible_layout;
-
     struct r300_vertex_stream_state vertex_stream;
 };
 
-struct r300_translate_context {
-    /* Translate cache for incompatible vertex offset/stride/format fallback. */
-    struct translate_cache *translate_cache;
-
-    /* Saved and new vertex element state. */
-    void *saved_velems, *new_velems;
-    unsigned vb_slot;
-};
-
 struct r300_context {
     /* Parent class */
     struct pipe_context context;
@@ -474,8 +456,6 @@ struct r300_context {
     struct blitter_context* blitter;
     /* Stencil two-sided reference value fallback. */
     struct r300_stencilref_context *stencilref_fallback;
-    /* For translating vertex buffers having incompatible vertex layout. */
-    struct r300_translate_context tran;
 
     /* The KIL opcode needs the first texture unit to be enabled
      * on r3xx-r4xx. In order to calm down the CS checker, we bind this
@@ -557,15 +537,6 @@ struct r300_context {
     /* The pointers to the first and the last atom. */
     struct r300_atom *first_dirty, *last_dirty;
 
-    /* Vertex buffers for Gallium. */
-    /* May contain user buffers. */
-    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
-    /* Contains only non-user buffers. */
-    struct pipe_resource *real_vertex_buffer[PIPE_MAX_ATTRIBS];
-    int vertex_buffer_count;
-    int real_vertex_buffer_count; /* with the translated buffer. */
-    int vertex_buffer_max_index;
-    boolean any_user_vbs;
     /* Vertex elements for Gallium. */
     struct r300_vertex_element_state *velems;
 
@@ -592,8 +563,6 @@ struct r300_context {
     int sprite_coord_enable;
     /* Whether two-sided color selection is enabled (AKA light_twoside). */
     boolean two_sided_color;
-    /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */
-    boolean incompatible_vb_layout;
 
     boolean cbzb_clear;
     /* Whether ZMASK is enabled. */
@@ -610,10 +579,11 @@ struct r300_context {
     /* two mem block managers for hiz/zmask ram space */
     struct mem_block *hiz_mm;
 
-    /* upload managers */
-    struct u_upload_mgr *upload_vb;
+    /* upload manager */
     struct u_upload_mgr *upload_ib;
 
+    struct u_vbuf_mgr *vbuf_mgr;
+
     struct util_slab_mempool pool_transfers;
 
     /* Stat counter. */
@@ -708,9 +678,6 @@ void r300_resume_query(struct r300_context *r300,
 void r300_stop_query(struct r300_context *r300);
 
 /* r300_render_translate.c */
-void r300_begin_vertex_translate(struct r300_context *r300,
-                                 int min_index, int max_index);
-void r300_end_vertex_translate(struct r300_context *r300);
 void r300_translate_index_buffer(struct r300_context *r300,
                                  struct pipe_resource **index_buffer,
                                  unsigned *index_size, unsigned index_offset,
index 34f87f74d3e77000898c777317680c08f83a5448..60234497c95fa8d3b8d55cffb468a37054ef4676 100644 (file)
@@ -812,9 +812,9 @@ void r300_emit_textures_state(struct r300_context *r300,
 
 static void r300_update_vertex_arrays_cb(struct r300_context *r300, unsigned packet_size)
 {
-    struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
+    struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vbuf_mgr->vertex_buffer;
     struct pipe_vertex_element *velem = r300->velems->velem;
-    unsigned *hw_format_size = r300->velems->hw_format_size;
+    unsigned *hw_format_size = r300->velems->format_size;
     unsigned size1, size2, vertex_array_count = r300->velems->count;
     int i;
     CB_LOCALS;
@@ -846,8 +846,8 @@ static void r300_update_vertex_arrays_cb(struct r300_context *r300, unsigned pac
 
 void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed)
 {
-    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
-    struct pipe_resource **valid_vbuf = r300->real_vertex_buffer;
+    struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer;
+    struct pipe_resource **valid_vbuf = r300->vbuf_mgr->real_vertex_buffer;
     struct pipe_vertex_element *velem = r300->velems->velem;
     struct r300_buffer *buf;
     int i;
@@ -866,7 +866,7 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde
         OUT_CS_TABLE(r300->vertex_arrays_cb, packet_size);
     } else {
         struct pipe_vertex_buffer *vb1, *vb2;
-        unsigned *hw_format_size = r300->velems->hw_format_size;
+        unsigned *hw_format_size = r300->velems->format_size;
         unsigned size1, size2;
 
         for (i = 0; i < vertex_array_count - 1; i += 2) {
@@ -892,7 +892,7 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde
 
     for (i = 0; i < vertex_array_count; i++) {
         buf = r300_buffer(valid_vbuf[velem[i].vertex_buffer_index]);
-        OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b);
+        OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b.b);
     }
     END_CS;
 }
@@ -1227,9 +1227,9 @@ validate:
                                 r300_buffer(r300->vbo)->domain, 0);
     /* ...vertex buffers for HWTCL path... */
     if (do_validate_vertex_buffers) {
-        struct pipe_resource **buf = r300->real_vertex_buffer;
-        struct pipe_resource **last = r300->real_vertex_buffer +
-                                      r300->real_vertex_buffer_count;
+        struct pipe_resource **buf = r300->vbuf_mgr->real_vertex_buffer;
+        struct pipe_resource **last = r300->vbuf_mgr->real_vertex_buffer +
+                                      r300->vbuf_mgr->nr_real_vertex_buffers;
         for (; buf != last; buf++) {
             if (!*buf)
                 continue;
index 41ddd748bbf20fca532ad04db369f744c0100174..2b4aa9f438f0755f23823c24ccfb0529f68979de 100644 (file)
@@ -136,7 +136,7 @@ void r500_emit_index_bias(struct r300_context *r300, int index_bias)
 static void r300_split_index_bias(struct r300_context *r300, int index_bias,
                                   int *buffer_offset, int *index_offset)
 {
-    struct pipe_vertex_buffer *vb, *vbufs = r300->vertex_buffer;
+    struct pipe_vertex_buffer *vb, *vbufs = r300->vbuf_mgr->vertex_buffer;
     struct pipe_vertex_element *velem = r300->velems->velem;
     unsigned i, size;
     int max_neg_bias;
@@ -225,7 +225,8 @@ static boolean r300_emit_states(struct r300_context *r300,
                                 enum r300_prepare_flags flags,
                                 struct pipe_resource *index_buffer,
                                 int buffer_offset,
-                                int index_bias)
+                                int index_bias,
+                                boolean user_buffers)
 {
     boolean first_draw     = flags & PREP_FIRST_DRAW;
     boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
@@ -246,10 +247,10 @@ static boolean r300_emit_states(struct r300_context *r300,
             /* Consider the validation done only if everything was validated. */
             if (validate_vbos) {
                 r300->validate_buffers = FALSE;
-                if (r300->any_user_vbs)
+                if (user_buffers)
                     r300->upload_vb_validated = TRUE;
                 if (r300->index_buffer.buffer &&
-                    r300_is_user_buffer(r300->index_buffer.buffer)) {
+                    r300_buffer(r300->index_buffer.buffer)->b.user_ptr) {
                     r300->upload_ib_validated = TRUE;
                 }
             }
@@ -289,12 +290,14 @@ static boolean r300_prepare_for_rendering(struct r300_context *r300,
                                           struct pipe_resource *index_buffer,
                                           unsigned cs_dwords,
                                           int buffer_offset,
-                                          int index_bias)
+                                          int index_bias,
+                                          boolean user_buffers)
 {
     if (r300_reserve_cs_dwords(r300, flags, cs_dwords))
         flags |= PREP_FIRST_DRAW;
 
-    return r300_emit_states(r300, flags, index_buffer, buffer_offset, index_bias);
+    return r300_emit_states(r300, flags, index_buffer, buffer_offset,
+                            index_bias, user_buffers);
 }
 
 static boolean immd_is_good_idea(struct r300_context *r300,
@@ -325,7 +328,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
         vbi = velem->vertex_buffer_index;
 
         if (!checked[vbi]) {
-            buf = r300->real_vertex_buffer[vbi];
+            buf = r300->vbuf_mgr->real_vertex_buffer[vbi];
 
             if (!(r300_buffer(buf)->domain & R300_DOMAIN_GTT)) {
                 return FALSE;
@@ -376,21 +379,22 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
 
     CS_LOCALS(r300);
 
-    if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0))
+    if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0,
+                                    FALSE))
         return;
 
     /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
     for (i = 0; i < vertex_element_count; i++) {
         velem = &r300->velems->velem[i];
-        size[i] = r300->velems->hw_format_size[i] / 4;
+        size[i] = r300->velems->format_size[i] / 4;
         vbi = velem->vertex_buffer_index;
-        vbuf = &r300->vertex_buffer[vbi];
+        vbuf = &r300->vbuf_mgr->vertex_buffer[vbi];
         stride[i] = vbuf->stride / 4;
 
         /* Map the buffer. */
         if (!transfer[vbi]) {
             map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context,
-                                                  r300->real_vertex_buffer[vbi],
+                                                  r300->vbuf_mgr->real_vertex_buffer[vbi],
                                                   PIPE_TRANSFER_READ,
                                                  &transfer[vbi]);
             map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start;
@@ -548,7 +552,8 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
                                      unsigned maxIndex,
                                      unsigned mode,
                                      unsigned start,
-                                     unsigned count)
+                                     unsigned count,
+                                     boolean user_buffers)
 {
     struct r300_context* r300 = r300_context(pipe);
     struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
@@ -570,7 +575,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
 
     /* Fallback for misaligned ushort indices. */
     if (indexSize == 2 && (start & 1) &&
-        !r300_is_user_buffer(indexBuffer)) {
+        !r300_buffer(indexBuffer)->b.user_ptr) {
         struct pipe_transfer *transfer;
         struct pipe_resource *userbuf;
 
@@ -592,14 +597,14 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
         }
         pipe_buffer_unmap(pipe, transfer);
     } else {
-        if (r300_is_user_buffer(indexBuffer))
+        if (r300_buffer(indexBuffer)->b.user_ptr)
             r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count);
     }
 
     /* 19 dwords for emit_draw_elements. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
             PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
-            PREP_INDEXED, indexBuffer, 19, buffer_offset, indexBias))
+            PREP_INDEXED, indexBuffer, 19, buffer_offset, indexBias, user_buffers))
         goto done;
 
     if (alt_num_verts || count <= 65535) {
@@ -619,7 +624,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
             if (count) {
                 if (!r300_prepare_for_rendering(r300,
                         PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
-                        indexBuffer, 19, buffer_offset, indexBias))
+                        indexBuffer, 19, buffer_offset, indexBias, user_buffers))
                     goto done;
             }
         } while (count);
@@ -632,7 +637,8 @@ done:
 }
 
 static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
-                             unsigned start, unsigned count)
+                             unsigned start, unsigned count,
+                             boolean user_buffers)
 {
     struct r300_context* r300 = r300_context(pipe);
     boolean alt_num_verts = r300->screen->caps.is_r500 &&
@@ -646,7 +652,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
         /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
         if (!r300_prepare_for_rendering(r300,
                 PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
-                NULL, 9, start, 0))
+                NULL, 9, start, 0, user_buffers))
             return;
 
         if (alt_num_verts || count <= 65535) {
@@ -663,7 +669,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
                 if (count) {
                     if (!r300_prepare_for_rendering(r300,
                             PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
-                            start, 0))
+                            start, 0, user_buffers))
                         return;
                 }
             } while (count);
@@ -676,10 +682,8 @@ static void r300_draw_vbo(struct pipe_context* pipe,
 {
     struct r300_context* r300 = r300_context(pipe);
     unsigned count = info->count;
-    boolean translate = FALSE;
+    boolean buffers_updated, uploader_flushed;
     boolean indexed = info->indexed && r300->index_buffer.buffer;
-    unsigned min_index = 0;
-    unsigned max_index = r300->vertex_buffer_max_index;
 
     if (r300->skip_rendering) {
         return;
@@ -689,12 +693,26 @@ static void r300_draw_vbo(struct pipe_context* pipe,
         return;
     }
 
+    u_vbuf_mgr_draw_begin(r300->vbuf_mgr, info,
+                          &buffers_updated, &uploader_flushed);
+
+    if (buffers_updated) {
+        r300->vertex_arrays_dirty = TRUE;
+
+        if (uploader_flushed || !r300->upload_vb_validated) {
+            r300->upload_vb_validated = FALSE;
+            r300->validate_buffers = TRUE;
+        }
+    } else {
+        r300->upload_vb_validated = FALSE;
+    }
+
     if (indexed) {
-        int real_min_index, real_max_index;
         /* Compute the start for draw_elements, taking the offset into account. */
         unsigned start_indexed =
             info->start +
             (r300->index_buffer.offset / r300->index_buffer.index_size);
+        int max_index = MIN2(r300->vbuf_mgr->max_index, info->max_index);
 
         assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
 
@@ -705,54 +723,21 @@ static void r300_draw_vbo(struct pipe_context* pipe,
             return;
         }
 
-        min_index = MAX2(min_index, info->min_index);
-        max_index = MIN2(max_index, info->max_index);
-        real_min_index = (int)min_index - info->index_bias;
-        real_max_index = (int)max_index - info->index_bias;
-
         if (max_index >= (1 << 24) - 1) {
             fprintf(stderr, "r300: Invalid max_index: %i. Skipping rendering...\n", max_index);
             return;
         }
 
         r300_update_derived_state(r300);
-
-        /* Set up the fallback for an incompatible vertex layout if needed. */
-        if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
-            r300_begin_vertex_translate(r300, real_min_index, real_max_index);
-            translate = TRUE;
-        }
-
-        /* Upload vertex buffers. */
-        if (r300->any_user_vbs) {
-            r300_upload_user_buffers(r300, real_min_index, real_max_index);
-        }
-
-        r300_draw_range_elements(pipe, info->index_bias, min_index, max_index,
-                                 info->mode, start_indexed, count);
+        r300_draw_range_elements(pipe, info->index_bias, info->min_index,
+                                 max_index, info->mode, start_indexed, count,
+                                 buffers_updated);
     } else {
-        min_index = MAX2(min_index, info->start);
-        max_index = MIN2(max_index, info->start + count - 1);
-
         r300_update_derived_state(r300);
-
-        /* Set up the fallback for an incompatible vertex layout if needed. */
-        if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
-            r300_begin_vertex_translate(r300, min_index, max_index);
-            translate = TRUE;
-        }
-
-        /* Upload vertex buffers. */
-        if (r300->any_user_vbs) {
-            r300_upload_user_buffers(r300, min_index, max_index);
-        }
-
-        r300_draw_arrays(pipe, info->mode, info->start, count);
+        r300_draw_arrays(pipe, info->mode, info->start, count, buffers_updated);
     }
 
-    if (translate) {
-        r300_end_vertex_translate(r300);
-    }
+    u_vbuf_mgr_draw_end(r300->vbuf_mgr);
 }
 
 /****************************************************************************
@@ -787,10 +772,10 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
             (indexed ? PREP_INDEXED : 0),
             indexed ? 256 : 6);
 
-    for (i = 0; i < r300->real_vertex_buffer_count; i++) {
-        if (r300->vertex_buffer[i].buffer) {
+    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
+        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
             void *buf = pipe_buffer_map(pipe,
-                                  r300->vertex_buffer[i].buffer,
+                                  r300->vbuf_mgr->vertex_buffer[i].buffer,
                                   PIPE_TRANSFER_READ,
                                   &vb_transfer[i]);
             draw_set_mapped_vertex_buffer(r300->draw, i, buf);
@@ -810,8 +795,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
     draw_flush(r300->draw);
     r300->draw_vbo_locked = FALSE;
 
-    for (i = 0; i < r300->real_vertex_buffer_count; i++) {
-        if (r300->vertex_buffer[i].buffer) {
+    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
+        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
             pipe_buffer_unmap(pipe, vb_transfer[i]);
             draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
         }
@@ -963,12 +948,12 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
     if (r300->draw_first_emitted) {
         if (!r300_prepare_for_rendering(r300,
                 PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
-                NULL, 6, 0, 0))
+                NULL, 6, 0, 0, FALSE))
             return;
     } else {
         if (!r300_emit_states(r300,
                 PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
-                NULL, 0, 0))
+                NULL, 0, 0, FALSE))
             return;
     }
 
@@ -1020,12 +1005,12 @@ static void r300_render_draw_elements(struct vbuf_render* render,
     if (r300->draw_first_emitted) {
         if (!r300_prepare_for_rendering(r300,
                 PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
-                NULL, 256, 0, 0))
+                NULL, 256, 0, 0, FALSE))
             return;
     } else {
         if (!r300_emit_states(r300,
                 PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
-                NULL, 0, 0))
+                NULL, 0, 0, FALSE))
             return;
     }
 
@@ -1062,7 +1047,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
         if (count) {
             if (!r300_prepare_for_rendering(r300,
                     PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
-                    NULL, 256, 0, 0))
+                    NULL, 256, 0, 0, FALSE))
                 return;
 
             end_cs_dwords = r300_get_num_cs_end_dwords(r300);
@@ -1166,7 +1151,8 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
     r300->clip_state.dirty = FALSE;
     r300->viewport_state.dirty = FALSE;
 
-    if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0))
+    if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0,
+                                    FALSE))
         goto done;
 
     DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
index ec4eaa9d62470e781b3b7166a7c53468a93f2eea..76d012d81e6875a94412bff1332bbd1e8f8fc0c2 100644 (file)
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
-/**
- * The functions below translate vertex and index buffers to the layout
- * compatible with the hardware, so that all vertex and index fetches are
- * DWORD-aligned and all used vertex and index formats are supported.
- * For indices, an optional index offset is added to each index.
- */
-
 #include "r300_context.h"
-#include "translate/translate.h"
 #include "util/u_index_modify.h"
 #include "util/u_upload_mgr.h"
 
-void r300_begin_vertex_translate(struct r300_context *r300,
-                                 int min_index, int max_index)
-{
-    struct pipe_context *pipe = &r300->context;
-    struct translate_key key = {0};
-    struct translate_element *te;
-    unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0};
-    struct translate *tr;
-    struct r300_vertex_element_state *ve = r300->velems;
-    boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
-    uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
-    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
-    struct pipe_resource *out_buffer = NULL;
-    unsigned i, num_verts, out_offset;
-    struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
-    boolean flushed;
-
-    /* Initialize the translate key, i.e. the recipe how vertices should be
-     * translated. */
-    for (i = 0; i < ve->count; i++) {
-        struct pipe_vertex_buffer *vb =
-                &r300->vertex_buffer[ve->velem[i].vertex_buffer_index];
-        enum pipe_format output_format = ve->hw_format[i];
-        unsigned output_format_size = ve->hw_format_size[i];
-
-        /* Check for support. */
-        if (ve->velem[i].src_format == ve->hw_format[i] &&
-            /* These two are r300-specific.  */
-            (vb->buffer_offset + ve->velem[i].src_offset) % 4 == 0 &&
-            vb->stride % 4 == 0) {
-            continue;
-        }
-
-        /* Workaround for translate: output floats instead of halfs. */
-        switch (output_format) {
-        case PIPE_FORMAT_R16_FLOAT:
-            output_format = PIPE_FORMAT_R32_FLOAT;
-            output_format_size = 4;
-            break;
-        case PIPE_FORMAT_R16G16_FLOAT:
-            output_format = PIPE_FORMAT_R32G32_FLOAT;
-            output_format_size = 8;
-            break;
-        case PIPE_FORMAT_R16G16B16_FLOAT:
-            output_format = PIPE_FORMAT_R32G32B32_FLOAT;
-            output_format_size = 12;
-            break;
-        case PIPE_FORMAT_R16G16B16A16_FLOAT:
-            output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-            output_format_size = 16;
-            break;
-        default:;
-        }
-
-        /* Add this vertex element. */
-        te = &key.element[key.nr_elements];
-        /*te->type;
-        te->instance_divisor;*/
-        te->input_buffer = ve->velem[i].vertex_buffer_index;
-        te->input_format = ve->velem[i].src_format;
-        te->input_offset = ve->velem[i].src_offset;
-        te->output_format = output_format;
-        te->output_offset = key.output_stride;
-
-        key.output_stride += output_format_size;
-        vb_translated[ve->velem[i].vertex_buffer_index] = TRUE;
-        tr_elem_index[i] = key.nr_elements;
-        key.nr_elements++;
-    }
-
-    /* Get a translate object. */
-    tr = translate_cache_find(r300->tran.translate_cache, &key);
-
-    /* Map buffers we want to translate. */
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        if (vb_translated[i]) {
-            struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i];
-
-            vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
-                                        PIPE_TRANSFER_READ, &vb_transfer[i]);
-
-            tr->set_buffer(tr, i,
-                           vb_map[i] + vb->buffer_offset + vb->stride * min_index,
-                           vb->stride, ~0);
-        }
-    }
-
-    /* Create and map the output buffer. */
-    num_verts = max_index + 1 - min_index;
-
-    u_upload_alloc(r300->upload_vb,
-                   key.output_stride * min_index,
-                   key.output_stride * num_verts,
-                   &out_offset, &out_buffer, &flushed,
-                   (void**)&out_map);
-
-    out_offset -= key.output_stride * min_index;
-
-    /* Translate. */
-    tr->run(tr, 0, num_verts, 0, out_map);
-
-    /* Unmap all buffers. */
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        if (vb_translated[i]) {
-            pipe_buffer_unmap(pipe, vb_transfer[i]);
-        }
-    }
-
-    /* Setup the new vertex buffer in the first free slot. */
-    r300->tran.vb_slot = ~0;
-    for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
-        if (!r300->vertex_buffer[i].buffer) {
-            r300->tran.vb_slot = i;
-
-            if (i >= r300->vertex_buffer_count) {
-                r300->real_vertex_buffer_count = i+1;
-            }
-
-            /* r300-specific: */
-            r300->validate_buffers = TRUE;
-            r300->vertex_arrays_dirty = TRUE;
-            break;
-        }
-    }
-
-    if (r300->tran.vb_slot != ~0) {
-               /* Setup the new vertex buffer. */
-               pipe_resource_reference(&r300->real_vertex_buffer[r300->tran.vb_slot], out_buffer);
-               r300->vertex_buffer[r300->tran.vb_slot].buffer_offset = out_offset;
-               r300->vertex_buffer[r300->tran.vb_slot].stride = key.output_stride;
-
-        /* Setup new vertex elements. */
-        for (i = 0; i < ve->count; i++) {
-            if (vb_translated[ve->velem[i].vertex_buffer_index]) {
-                te = &key.element[tr_elem_index[i]];
-                new_velems[i].instance_divisor = ve->velem[i].instance_divisor;
-                new_velems[i].src_format = te->output_format;
-                new_velems[i].src_offset = te->output_offset;
-                new_velems[i].vertex_buffer_index = r300->tran.vb_slot;
-            } else {
-                memcpy(&new_velems[i], &ve->velem[i],
-                       sizeof(struct pipe_vertex_element));
-            }
-        }
-
-        r300->tran.saved_velems = r300->velems;
-        r300->tran.new_velems =
-                pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
-        pipe->bind_vertex_elements_state(pipe, r300->tran.new_velems);
-    }
-
-    pipe_resource_reference(&out_buffer, NULL);
-}
-
-void r300_end_vertex_translate(struct r300_context *r300)
-{
-    struct pipe_context *pipe = &r300->context;
-
-    if (r300->tran.new_velems == NULL) {
-        return;
-    }
-
-    /* Restore vertex elements. */
-    pipe->bind_vertex_elements_state(pipe, r300->tran.saved_velems);
-    r300->tran.saved_velems = NULL;
-    pipe->delete_vertex_elements_state(pipe, r300->tran.new_velems);
-    r300->tran.new_velems = NULL;
-
-    /* Delete the now-unused VBO. */
-    pipe_resource_reference(&r300->real_vertex_buffer[r300->tran.vb_slot], NULL);
-    r300->real_vertex_buffer_count = r300->vertex_buffer_count;
-}
 
 void r300_translate_index_buffer(struct r300_context *r300,
                                  struct pipe_resource **index_buffer,
index 85057d745e2b5f5b59ee904c6e34921d0e41e601..d76524d261d0c284bb9f3b748f069c591810ff83 100644 (file)
@@ -40,7 +40,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
     struct r300_context *r300 = r300_context(context);
     struct r300_buffer *rbuf = r300_buffer(buf);
 
-    if (r300_is_user_buffer(buf))
+    if (rbuf->b.user_ptr)
        return PIPE_UNREFERENCED;
 
     if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain))
@@ -62,7 +62,7 @@ void r300_upload_index_buffer(struct r300_context *r300,
                              unsigned count)
 {
     unsigned index_offset;
-    uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer;
+    uint8_t *ptr = r300_buffer(*index_buffer)->b.user_ptr;
     boolean flushed;
 
     *index_buffer = NULL;
@@ -81,51 +81,6 @@ void r300_upload_index_buffer(struct r300_context *r300,
     }
 }
 
-void r300_upload_user_buffers(struct r300_context *r300,
-                              int min_index, int max_index)
-{
-    int i, nr = r300->velems->count;
-    unsigned count = max_index + 1 - min_index;
-    boolean flushed;
-    boolean uploaded[32] = {0};
-
-    for (i = 0; i < nr; i++) {
-        unsigned index = r300->velems->velem[i].vertex_buffer_index;
-        struct pipe_vertex_buffer *vb = &r300->vertex_buffer[index];
-        struct r300_buffer *userbuf = r300_buffer(vb->buffer);
-
-        if (userbuf && userbuf->user_buffer && !uploaded[index]) {
-            unsigned first, size;
-
-            if (vb->stride) {
-                first = vb->stride * min_index;
-                size = vb->stride * count;
-            } else {
-                first = 0;
-                size = r300->velems->hw_format_size[i];
-            }
-
-            u_upload_data(r300->upload_vb, first, size,
-                          userbuf->user_buffer + first,
-                          &vb->buffer_offset,
-                          &r300->real_vertex_buffer[index],
-                          &flushed);
-
-            vb->buffer_offset -= first;
-
-            r300->vertex_arrays_dirty = TRUE;
-
-            if (flushed || !r300->upload_vb_validated) {
-                r300->upload_vb_validated = FALSE;
-                r300->validate_buffers = TRUE;
-            }
-            uploaded[index] = TRUE;
-        } else {
-            assert(r300->real_vertex_buffer[index]);
-        }
-    }
-}
-
 static void r300_buffer_destroy(struct pipe_screen *screen,
                                struct pipe_resource *buf)
 {
@@ -184,8 +139,8 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
     struct r300_buffer *rbuf = r300_buffer(transfer->resource);
     uint8_t *map;
 
-    if (rbuf->user_buffer)
-        return (uint8_t *) rbuf->user_buffer + transfer->box.x;
+    if (rbuf->b.user_ptr)
+        return (uint8_t *) rbuf->b.user_ptr + transfer->box.x;
     if (rbuf->constant_buffer)
         return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
 
@@ -234,7 +189,7 @@ static void r300_buffer_transfer_inline_write(struct pipe_context *pipe,
         memcpy(rbuf->constant_buffer + box->x, data, box->width);
         return;
     }
-    assert(rbuf->user_buffer == NULL);
+    assert(rbuf->b.user_ptr == NULL);
 
     map = rws->buffer_map(rws, rbuf->buf, r300->cs,
                           PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage);
@@ -268,25 +223,25 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
-    rbuf->b.b = *templ;
-    rbuf->b.vtbl = &r300_buffer_vtbl;
-    pipe_reference_init(&rbuf->b.b.reference, 1);
-    rbuf->b.b.screen = screen;
+    rbuf->b.b.b = *templ;
+    rbuf->b.b.vtbl = &r300_buffer_vtbl;
+    pipe_reference_init(&rbuf->b.b.b.reference, 1);
+    rbuf->b.b.b.screen = screen;
+    rbuf->b.user_ptr = NULL;
     rbuf->domain = R300_DOMAIN_GTT;
     rbuf->buf = NULL;
     rbuf->constant_buffer = NULL;
-    rbuf->user_buffer = NULL;
 
     /* Alloc constant buffers in RAM. */
     if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
         rbuf->constant_buffer = MALLOC(templ->width0);
-        return &rbuf->b.b;
+        return &rbuf->b.b.b;
     }
 
     rbuf->buf =
         r300screen->rws->buffer_create(r300screen->rws,
-                                       rbuf->b.b.width0, alignment,
-                                       rbuf->b.b.bind, rbuf->b.b.usage,
+                                       rbuf->b.b.b.width0, alignment,
+                                       rbuf->b.b.b.bind, rbuf->b.b.b.usage,
                                        rbuf->domain);
     rbuf->cs_buf =
         r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf);
@@ -296,7 +251,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
         return NULL;
     }
 
-    return &rbuf->b.b;
+    return &rbuf->b.b.b;
 }
 
 struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
@@ -310,21 +265,21 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
-    pipe_reference_init(&rbuf->b.b.reference, 1);
-    rbuf->b.vtbl = &r300_buffer_vtbl;
-    rbuf->b.b.screen = screen;
-    rbuf->b.b.target = PIPE_BUFFER;
-    rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
-    rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
-    rbuf->b.b.bind = bind;
-    rbuf->b.b.width0 = ~0;
-    rbuf->b.b.height0 = 1;
-    rbuf->b.b.depth0 = 1;
-    rbuf->b.b.array_size = 1;
-    rbuf->b.b.flags = 0;
+    pipe_reference_init(&rbuf->b.b.b.reference, 1);
+    rbuf->b.b.b.screen = screen;
+    rbuf->b.b.b.target = PIPE_BUFFER;
+    rbuf->b.b.b.format = PIPE_FORMAT_R8_UNORM;
+    rbuf->b.b.b.usage = PIPE_USAGE_IMMUTABLE;
+    rbuf->b.b.b.bind = bind;
+    rbuf->b.b.b.width0 = ~0;
+    rbuf->b.b.b.height0 = 1;
+    rbuf->b.b.b.depth0 = 1;
+    rbuf->b.b.b.array_size = 1;
+    rbuf->b.b.b.flags = 0;
+    rbuf->b.b.vtbl = &r300_buffer_vtbl;
+    rbuf->b.user_ptr = ptr;
     rbuf->domain = R300_DOMAIN_GTT;
     rbuf->buf = NULL;
     rbuf->constant_buffer = NULL;
-    rbuf->user_buffer = ptr;
-    return &rbuf->b.b;
+    return &rbuf->b.b.b;
 }
index 58dec8539b668e390ca58518edbf75019fc3ce49..1dfbc1399ba63b234c355e40df40d3f02624b92d 100644 (file)
@@ -46,7 +46,7 @@ struct r300_buffer_range {
 /* Vertex buffer. */
 struct r300_buffer
 {
-    struct u_resource b;
+    struct u_vbuf_resource b;
 
     uint32_t magic;
 
@@ -55,15 +55,11 @@ struct r300_buffer
 
     enum r300_buffer_domain domain;
 
-    uint8_t *user_buffer;
     uint8_t *constant_buffer;
 };
 
 /* Functions. */
 
-void r300_upload_user_buffers(struct r300_context *r300,
-                             int min_index, int max_index);
-
 void r300_upload_index_buffer(struct r300_context *r300,
                              struct pipe_resource **index_buffer,
                              unsigned index_size, unsigned *start,
@@ -87,9 +83,4 @@ static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer)
     return (struct r300_buffer *)buffer;
 }
 
-static INLINE boolean r300_is_user_buffer(struct pipe_resource *buffer)
-{
-    return r300_buffer(buffer)->user_buffer ? true : false;
-}
-
 #endif
index dad41ab91ed2939aa787d24e13564a54157f467e..aa4e05d4be5ceead23c5fa0c06f65590d0b2a0e7 100644 (file)
@@ -1478,10 +1478,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
                                     const struct pipe_vertex_buffer* buffers)
 {
     struct r300_context* r300 = r300_context(pipe);
-    const struct pipe_vertex_buffer *vbo;
-    unsigned i, max_index = (1 << 24) - 1;
-    boolean any_user_buffer = FALSE;
-    boolean any_nonuser_buffer = FALSE;
+    unsigned i;
     struct pipe_vertex_buffer dummy_vb = {0};
 
     /* There must be at least one vertex buffer set, otherwise it locks up. */
@@ -1491,91 +1488,21 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
         count = 1;
     }
 
-    if (count == r300->vertex_buffer_count &&
-        memcmp(r300->vertex_buffer, buffers,
-            sizeof(struct pipe_vertex_buffer) * count) == 0) {
-        return;
-    }
+    u_vbuf_mgr_set_vertex_buffers(r300->vbuf_mgr, count, buffers);
 
     if (r300->screen->caps.has_tcl) {
         /* HW TCL. */
-        r300->incompatible_vb_layout = FALSE;
-
-        /* Check if the strides and offsets are aligned to the size of DWORD. */
         for (i = 0; i < count; i++) {
-            if (buffers[i].buffer) {
-                if (buffers[i].stride % 4 != 0 ||
-                    buffers[i].buffer_offset % 4 != 0) {
-                    r300->incompatible_vb_layout = TRUE;
-                    break;
-                }
+            if (buffers[i].buffer &&
+               !r300_buffer(buffers[i].buffer)->b.user_ptr) {
+                r300->validate_buffers = TRUE;
             }
         }
-
-        for (i = 0; i < count; i++) {
-            vbo = &buffers[i];
-
-            /* Skip NULL buffers */
-            if (!vbo->buffer) {
-                continue;
-            }
-
-            /* User buffers have no info about maximum index,
-             * we will have to compute it in draw_vbo. */
-            if (r300_is_user_buffer(vbo->buffer)) {
-                any_user_buffer = TRUE;
-                continue;
-            }
-            any_nonuser_buffer = TRUE;
-
-            /* The stride of zero means we will be fetching only the first
-             * vertex, so don't care about max_index. */
-            if (!vbo->stride)
-                continue;
-
-            /* Update the maximum index. */
-            {
-                unsigned vbo_max_index =
-                      (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
-                max_index = MIN2(max_index, vbo_max_index);
-            }
-        }
-
-        r300->any_user_vbs = any_user_buffer;
-        r300->vertex_buffer_max_index = max_index;
         r300->vertex_arrays_dirty = TRUE;
-        if (any_nonuser_buffer)
-            r300->validate_buffers = TRUE;
-        if (!any_user_buffer)
-            r300->upload_vb_validated = FALSE;
     } else {
         /* SW TCL. */
         draw_set_vertex_buffers(r300->draw, count, buffers);
     }
-
-    /* Common code. */
-    for (i = 0; i < count; i++) {
-        vbo = &buffers[i];
-
-        /* Reference our buffer. */
-        pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
-        if (vbo->buffer && r300_is_user_buffer(vbo->buffer)) {
-            pipe_resource_reference(&r300->real_vertex_buffer[i], NULL);
-        } else {
-            pipe_resource_reference(&r300->real_vertex_buffer[i], vbo->buffer);
-        }
-    }
-    for (; i < r300->real_vertex_buffer_count; i++) {
-        /* Dereference any old buffers. */
-        pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
-        pipe_resource_reference(&r300->real_vertex_buffer[i], NULL);
-    }
-
-    memcpy(r300->vertex_buffer, buffers,
-           sizeof(struct pipe_vertex_buffer) * count);
-
-    r300->vertex_buffer_count = count;
-    r300->real_vertex_buffer_count = count;
 }
 
 static void r300_set_index_buffer(struct pipe_context* pipe,
@@ -1588,7 +1515,7 @@ static void r300_set_index_buffer(struct pipe_context* pipe,
         memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer));
 
         if (r300->screen->caps.has_tcl &&
-            !r300_is_user_buffer(ib->buffer)) {
+            !r300_buffer(ib->buffer)->b.user_ptr) {
             r300->validate_buffers = TRUE;
             r300->upload_ib_validated = FALSE;
         }
@@ -1621,7 +1548,7 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
      * so PSC should just route stuff based on the vertex elements,
      * and not on attrib information. */
     for (i = 0; i < velems->count; i++) {
-        format = velems->hw_format[i];
+        format = velems->velem[i].src_format;
 
         type = r300_translate_vertex_data_type(format);
         if (type == R300_INVALID_FORMAT) {
@@ -1653,16 +1580,13 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
     vstream->count = (i >> 1) + 1;
 }
 
-#define FORMAT_REPLACE(what, withwhat) \
-    case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
-
 static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
                                                unsigned count,
                                                const struct pipe_vertex_element* attribs)
 {
+    struct r300_context *r300 = r300_context(pipe);
     struct r300_vertex_element_state *velems;
     unsigned i;
-    enum pipe_format *format;
     struct pipe_vertex_element dummy_attrib = {0};
 
     /* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */
@@ -1674,77 +1598,26 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
 
     assert(count <= PIPE_MAX_ATTRIBS);
     velems = CALLOC_STRUCT(r300_vertex_element_state);
-    if (velems != NULL) {
-        velems->count = count;
-        memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
-
-        if (r300_screen(pipe->screen)->caps.has_tcl) {
-            /* Set the best hw format in case the original format is not
-             * supported by hw. */
-            for (i = 0; i < count; i++) {
-                velems->hw_format[i] = velems->velem[i].src_format;
-                format = &velems->hw_format[i];
-
-                /* This is basically the list of unsupported formats.
-                 * For now we don't care about the alignment, that's going to
-                 * be sorted out after the PSC setup. */
-                switch (*format) {
-                    FORMAT_REPLACE(R64_FLOAT,           R32_FLOAT);
-                    FORMAT_REPLACE(R64G64_FLOAT,        R32G32_FLOAT);
-                    FORMAT_REPLACE(R64G64B64_FLOAT,     R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R64G64B64A64_FLOAT,  R32G32B32A32_FLOAT);
-
-                    FORMAT_REPLACE(R32_UNORM,           R32_FLOAT);
-                    FORMAT_REPLACE(R32G32_UNORM,        R32G32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32_UNORM,     R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32A32_UNORM,  R32G32B32A32_FLOAT);
-
-                    FORMAT_REPLACE(R32_USCALED,         R32_FLOAT);
-                    FORMAT_REPLACE(R32G32_USCALED,      R32G32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32_USCALED,   R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
-
-                    FORMAT_REPLACE(R32_SNORM,           R32_FLOAT);
-                    FORMAT_REPLACE(R32G32_SNORM,        R32G32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32_SNORM,     R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32A32_SNORM,  R32G32B32A32_FLOAT);
-
-                    FORMAT_REPLACE(R32_SSCALED,         R32_FLOAT);
-                    FORMAT_REPLACE(R32G32_SSCALED,      R32G32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32_SSCALED,   R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
-
-                    FORMAT_REPLACE(R32_FIXED,           R32_FLOAT);
-                    FORMAT_REPLACE(R32G32_FIXED,        R32G32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32_FIXED,     R32G32B32_FLOAT);
-                    FORMAT_REPLACE(R32G32B32A32_FIXED,  R32G32B32A32_FLOAT);
-
-                    default:;
-                }
+    if (!velems)
+        return NULL;
 
-                velems->incompatible_layout =
-                        velems->incompatible_layout ||
-                        velems->velem[i].src_format != velems->hw_format[i] ||
-                        velems->velem[i].src_offset % 4 != 0;
-            }
+    velems->count = count;
+    velems->vmgr_elements =
+        u_vbuf_mgr_create_vertex_elements(r300->vbuf_mgr, count, attribs,
+                                          velems->velem);
 
-            /* Now setup PSC.
-             * The unused components will be replaced by (..., 0, 1). */
-            r300_vertex_psc(velems);
-
-            /* Align the formats to the size of DWORD.
-             * We only care about the blocksizes of the formats since
-             * swizzles are already set up.
-             * Also compute the vertex size. */
-            for (i = 0; i < count; i++) {
-                /* This is OK because we check for aligned strides too
-                 * elsewhere. */
-                velems->hw_format_size[i] =
-                    align(util_format_get_blocksize(velems->hw_format[i]), 4);
-                velems->vertex_size_dwords += velems->hw_format_size[i] / 4;
-            }
+    if (r300_screen(pipe->screen)->caps.has_tcl) {
+        /* Setup PSC.
+         * The unused components will be replaced by (..., 0, 1). */
+        r300_vertex_psc(velems);
+
+        for (i = 0; i < count; i++) {
+            velems->format_size[i] =
+                align(util_format_get_blocksize(velems->velem[i].src_format), 4);
+            velems->vertex_size_dwords += velems->format_size[i] / 4;
         }
     }
+
     return velems;
 }
 
@@ -1760,6 +1633,8 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
 
     r300->velems = velems;
 
+    u_vbuf_mgr_bind_vertex_elements(r300->vbuf_mgr, state, velems->vmgr_elements);
+
     if (r300->draw) {
         draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
         return;
@@ -1772,7 +1647,11 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
 
 static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
 {
-   FREE(state);
+    struct r300_context *r300 = r300_context(pipe);
+    struct r300_vertex_element_state *velems = state;
+
+    u_vbuf_mgr_destroy_vertex_elements(r300->vbuf_mgr, velems->vmgr_elements);
+    FREE(state);
 }
 
 static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1876,8 +1755,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     if (buf == NULL || buf->width0 == 0)
         return;
 
-    if (rbuf->user_buffer)
-        mapped = (uint32_t*)rbuf->user_buffer;
+    if (rbuf->b.user_ptr)
+        mapped = (uint32_t*)rbuf->b.user_ptr;
     else if (rbuf->constant_buffer)
         mapped = (uint32_t*)rbuf->constant_buffer;
     else