u_vbuf: override create/bind/destroy_vertex_elements_state
authorMarek Olšák <maraeo@gmail.com>
Sat, 31 Mar 2012 04:01:39 +0000 (06:01 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 23 Apr 2012 23:39:21 +0000 (01:39 +0200)
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/auxiliary/util/u_vbuf.h
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state_common.c

index 92a7df1eda8575e0931e1078e8b8196c430aba78..f3ba89f6717ab70512f525d6f221323f0a773f54 100644 (file)
@@ -55,6 +55,8 @@ struct u_vbuf_elements {
    boolean incompatible_layout;
    /* Per-element flags. */
    boolean incompatible_layout_elem[PIPE_MAX_ATTRIBS];
+
+   void *driver_cso;
 };
 
 enum {
@@ -78,8 +80,6 @@ struct u_vbuf_priv {
    /* The index buffer. */
    struct pipe_index_buffer index_buffer;
 
-   /* Vertex element state bound by the state tracker. */
-   void *saved_ve;
    /* and its associated helper structure for this module. */
    struct u_vbuf_elements *ve;
 
@@ -91,9 +91,6 @@ struct u_vbuf_priv {
    /* The vertex buffer slot index where translated vertices have been
     * stored in. */
    unsigned fallback_vbs[VB_NUM];
-   /* When binding the fallback vertex element state, we don't want to
-    * change saved_ve and ve. This is set to TRUE in such cases. */
-   boolean ve_binding_lock;
 
    /* Whether there is any user buffer. */
    boolean any_user_vbs;
@@ -107,6 +104,11 @@ struct u_vbuf_priv {
    void (*driver_set_vertex_buffers)(struct pipe_context *,
                                     unsigned num_buffers,
                                     const struct pipe_vertex_buffer *);
+   void *(*driver_create_vertex_elements_state)(struct pipe_context *,
+                                          unsigned num_elements,
+                                          const struct pipe_vertex_element *);
+   void (*driver_bind_vertex_elements_state)(struct pipe_context *, void *);
+   void (*driver_delete_vertex_elements_state)(struct pipe_context *, void *);
 };
 
 static void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr)
@@ -168,7 +170,7 @@ u_vbuf_create(struct pipe_context *pipe,
 
 /* XXX I had to fork this off of cso_context. */
 static void *
-u_vbuf_pipe_set_vertex_elements(struct u_vbuf_priv *mgr,
+u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr,
                                 unsigned count,
                                 const struct pipe_vertex_element *states)
 {
@@ -190,10 +192,10 @@ u_vbuf_pipe_set_vertex_elements(struct u_vbuf_priv *mgr,
       struct cso_velements *cso = MALLOC_STRUCT(cso_velements);
       memcpy(&cso->state, &velems_state, key_size);
       cso->data =
-            mgr->pipe->create_vertex_elements_state(mgr->pipe, count,
-                                                    &cso->state.velems[0]);
+            mgr->driver_create_vertex_elements_state(mgr->pipe, count,
+                                                     &cso->state.velems[0]);
       cso->delete_state =
-            (cso_state_callback)mgr->pipe->delete_vertex_elements_state;
+            (cso_state_callback)mgr->driver_delete_vertex_elements_state;
       cso->context = mgr->pipe;
 
       iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso);
@@ -202,7 +204,7 @@ u_vbuf_pipe_set_vertex_elements(struct u_vbuf_priv *mgr,
       handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
    }
 
-   mgr->pipe->bind_vertex_elements_state(mgr->pipe, handle);
+   mgr->driver_bind_vertex_elements_state(mgr->pipe, handle);
    return handle;
 }
 
@@ -531,11 +533,8 @@ u_vbuf_translate_begin(struct u_vbuf_priv *mgr,
       }
    }
 
-   /* Preserve saved_ve. */
-   mgr->ve_binding_lock = TRUE;
-   mgr->fallback_ve = u_vbuf_pipe_set_vertex_elements(mgr, mgr->ve->count,
-                                                      mgr->fallback_velems);
-   mgr->ve_binding_lock = FALSE;
+   mgr->fallback_ve = u_vbuf_cache_set_vertex_elements(mgr, mgr->ve->count,
+                                                       mgr->fallback_velems);
    return TRUE;
 }
 
@@ -544,8 +543,7 @@ static void u_vbuf_translate_end(struct u_vbuf_priv *mgr)
    unsigned i;
 
    /* Restore vertex elements. */
-   /* Note that saved_ve will be overwritten in bind_vertex_elements_state. */
-   mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->saved_ve);
+   mgr->driver_bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
    mgr->fallback_ve = NULL;
 
    /* Unreference the now-unused VBOs. */
@@ -562,22 +560,18 @@ static void u_vbuf_translate_end(struct u_vbuf_priv *mgr)
 #define FORMAT_REPLACE(what, withwhat) \
     case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
 
-struct u_vbuf_elements *
-u_vbuf_create_vertex_elements(struct u_vbuf *mgrb,
+static void *
+u_vbuf_create_vertex_elements(struct pipe_context *pipe,
                               unsigned count,
-                              const struct pipe_vertex_element *attribs,
-                              struct pipe_vertex_element *native_attribs)
+                              const struct pipe_vertex_element *attribs)
 {
-   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb;
+   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
    unsigned i;
+   struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS];
    struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements);
 
    ve->count = count;
 
-   if (!count) {
-      return ve;
-   }
-
    memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count);
    memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count);
 
@@ -665,28 +659,29 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgrb,
       }
    }
 
+   ve->driver_cso =
+      mgr->driver_create_vertex_elements_state(pipe, count, native_attribs);
    return ve;
 }
 
-void u_vbuf_bind_vertex_elements(struct u_vbuf *mgrb,
-                                 void *cso,
-                                 struct u_vbuf_elements *ve)
+static void u_vbuf_bind_vertex_elements(struct pipe_context *pipe,
+                                        void *cso)
 {
-   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb;
-
-   if (!cso) {
-      return;
-   }
+   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
+   struct u_vbuf_elements *ve = cso;
 
-   if (!mgr->ve_binding_lock) {
-      mgr->saved_ve = cso;
-      mgr->ve = ve;
-   }
+   mgr->ve = ve;
+   mgr->b.vertex_elements = ve;
+   mgr->driver_bind_vertex_elements_state(pipe, ve ? ve->driver_cso : NULL);
 }
 
-void u_vbuf_destroy_vertex_elements(struct u_vbuf *mgr,
-                                    struct u_vbuf_elements *ve)
+static void u_vbuf_delete_vertex_elements(struct pipe_context *pipe,
+                                          void *cso)
 {
+   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
+   struct u_vbuf_elements *ve = cso;
+
+   mgr->driver_delete_vertex_elements_state(pipe, ve->driver_cso);
    FREE(ve);
 }
 
@@ -1198,6 +1193,14 @@ static void u_vbuf_install(struct u_vbuf_priv *mgr)
    pipe->draw = mgr;
    mgr->driver_set_index_buffer = pipe->set_index_buffer;
    mgr->driver_set_vertex_buffers = pipe->set_vertex_buffers;
+   mgr->driver_create_vertex_elements_state =
+      pipe->create_vertex_elements_state;
+   mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state;
+   mgr->driver_delete_vertex_elements_state =
+      pipe->delete_vertex_elements_state;
    pipe->set_index_buffer = u_vbuf_set_index_buffer;
    pipe->set_vertex_buffers = u_vbuf_set_vertex_buffers;
+   pipe->create_vertex_elements_state = u_vbuf_create_vertex_elements;
+   pipe->bind_vertex_elements_state = u_vbuf_bind_vertex_elements;
+   pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements;
 }
index 06665b522acd43872811d65c486ddaee6bd3ed1d..99b97a2b09c6065fc067cd364dde2a02bfadca7d 100644 (file)
@@ -71,6 +71,11 @@ struct u_vbuf {
    struct u_upload_mgr *uploader;
 
    struct u_vbuf_caps caps;
+
+   /* Vertex elements state as created by u_vbuf.
+    * This is used when saving the state into u_blitter, there's no other
+    * usage. */
+   void *vertex_elements;
 };
 
 struct u_vbuf_resource {
@@ -78,9 +83,6 @@ struct u_vbuf_resource {
    uint8_t *user_ptr;
 };
 
-/* Opaque type containing information about vertex elements for the manager. */
-struct u_vbuf_elements;
-
 enum u_fetch_alignment {
    U_VERTEX_FETCH_BYTE_ALIGNED,
    U_VERTEX_FETCH_DWORD_ALIGNED
@@ -96,19 +98,6 @@ u_vbuf_create(struct pipe_context *pipe,
 
 void u_vbuf_destroy(struct u_vbuf *mgr);
 
-struct u_vbuf_elements *
-u_vbuf_create_vertex_elements(struct u_vbuf *mgr,
-                              unsigned count,
-                              const struct pipe_vertex_element *attrs,
-                              struct pipe_vertex_element *native_attrs);
-
-void u_vbuf_bind_vertex_elements(struct u_vbuf *mgr,
-                                 void *cso,
-                                 struct u_vbuf_elements *ve);
-
-void u_vbuf_destroy_vertex_elements(struct u_vbuf *mgr,
-                                    struct u_vbuf_elements *ve);
-
 void u_vbuf_draw_begin(struct u_vbuf *mgr,
                        struct pipe_draw_info *info);
 
index 103780ffe63c3be4439d029b1d57f8be411da109..5b76c4b16e19e7f5d57423b2dd7ac640f38f56cd 100644 (file)
@@ -62,13 +62,14 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
     util_blitter_save_fragment_shader(r300->blitter, r300->fs.state);
     util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
     util_blitter_save_viewport(r300->blitter, &r300->viewport);
-    util_blitter_save_vertex_elements(r300->blitter, r300->velems);
     if (r300->vbuf_mgr) {
         util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers,
                                          r300->vbuf_mgr->vertex_buffer);
+        util_blitter_save_vertex_elements(r300->blitter, r300->vbuf_mgr->vertex_elements);
     } else {
         util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers,
                                          r300->vertex_buffer);
+        util_blitter_save_vertex_elements(r300->blitter, r300->velems);
     }
 
     if (op & R300_SAVE_FRAMEBUFFER) {
index 086799dbaddd431fc5312552adcfb054901708b2..9367fc05ca27b7b3f745669171d8738bbe2a8c94 100644 (file)
@@ -406,8 +406,6 @@ struct r300_vertex_element_state {
     struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
     unsigned format_size[PIPE_MAX_ATTRIBS];
 
-    struct u_vbuf_elements *vmgr_elements;
-
     /* The size of the vertex, in dwords. */
     unsigned vertex_size_dwords;
 
index 3345bae0990466ccf1b4d6324ce8fbc25dcacef6..a5bc662f5fdb7fdd75e87f8e01ed754052b7aac5 100644 (file)
@@ -1676,7 +1676,6 @@ 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;
     struct pipe_vertex_element dummy_attrib = {0};
@@ -1697,11 +1696,9 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
         return NULL;
 
     velems->count = count;
+    memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
 
     if (r300_screen(pipe->screen)->caps.has_tcl) {
-        velems->vmgr_elements =
-            u_vbuf_create_vertex_elements(r300->vbuf_mgr, count, attribs,
-                                          velems->velem);
         /* Setup PSC.
          * The unused components will be replaced by (..., 0, 1). */
         r300_vertex_psc(velems);
@@ -1711,8 +1708,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
                 align(util_format_get_blocksize(velems->velem[i].src_format), 4);
             velems->vertex_size_dwords += velems->format_size[i] / 4;
         }
-    } else {
-        memcpy(velems->velem, attribs, count * sizeof(struct pipe_vertex_element));
     }
 
     return velems;
@@ -1730,9 +1725,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
 
     r300->velems = velems;
 
-    if (r300->screen->caps.has_tcl) {
-        u_vbuf_bind_vertex_elements(r300->vbuf_mgr, state, velems->vmgr_elements);
-    } else {
+    if (r300->draw) {
         draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
         return;
     }
@@ -1744,12 +1737,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
 
 static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
 {
-    struct r300_context *r300 = r300_context(pipe);
-    struct r300_vertex_element_state *velems = state;
-
-    if (r300->screen->caps.has_tcl) {
-        u_vbuf_destroy_vertex_elements(r300->vbuf_mgr, velems->vmgr_elements);
-    }
     FREE(state);
 }
 
index c748fca60c90a8ddd3794ad179147436cc9dd969..480bef1baab4d7ec55cb8e9b99afcabfc954c364 100644 (file)
@@ -55,7 +55,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
        util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]);
        util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
        util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
-       util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
+       util_blitter_save_vertex_elements(rctx->blitter, rctx->vbuf_mgr->vertex_elements);
        if (rctx->states[R600_PIPE_STATE_VIEWPORT]) {
                util_blitter_save_viewport(rctx->blitter, &rctx->viewport);
        }
index dfc93d1ff700fa819c9131878df0714249a83bc1..c3f603c3255fc2a69f067bfb890b13cc46585864 100644 (file)
@@ -167,7 +167,6 @@ struct r600_vertex_element
 {
        unsigned                        count;
        struct pipe_vertex_element      elements[PIPE_MAX_ATTRIBS];
-       struct u_vbuf_elements          *vmgr_elements;
        struct r600_resource            *fetch_shader;
        unsigned                        fs_size;
        struct r600_pipe_state          rstate;
index 864996d006f5621af6f77bc355b3a792422b716b..a6fb6b81d833172f144286458430e5d6f5487373 100644 (file)
@@ -358,8 +358,6 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
        rctx->vertex_elements = v;
        if (v) {
                r600_inval_shader_cache(rctx);
-               u_vbuf_bind_vertex_elements(rctx->vbuf_mgr, state,
-                                               v->vmgr_elements);
 
                rctx->states[v->rstate.id] = &v->rstate;
                r600_context_pipe_state_set(rctx, &v->rstate);
@@ -378,7 +376,6 @@ void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
                rctx->vertex_elements = NULL;
 
        pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL);
-       u_vbuf_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements);
        FREE(state);
 }
 
@@ -416,9 +413,7 @@ void *r600_create_vertex_elements(struct pipe_context *ctx,
                return NULL;
 
        v->count = count;
-       v->vmgr_elements =
-               u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count,
-                                                 elements, v->elements);
+       memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count);
 
        if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
                FREE(v);