Mesa (master): llvmpipe: disconnect vertex texture sampling from the setup

Zack Rusin zack at kemper.freedesktop.org
Tue Jul 6 17:25:35 UTC 2010


Module: Mesa
Branch: master
Commit: 99c8d9b6dac55263b3f0ddce939173ec9a16cf80
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=99c8d9b6dac55263b3f0ddce939173ec9a16cf80

Author: Zack Rusin <zackr at vmware.com>
Date:   Tue Jul  6 13:27:31 2010 -0400

llvmpipe: disconnect vertex texture sampling from the setup

it was wrong to put this in the fs paths, but it was easier to just
stuff it along the fragment texture sampling paths. the patch
disconnects vertex texture sampling and just maps the textures
before the draw itself and unmaps them after.

---

 src/gallium/drivers/llvmpipe/lp_context.h       |    1 +
 src/gallium/drivers/llvmpipe/lp_draw_arrays.c   |    4 +
 src/gallium/drivers/llvmpipe/lp_setup.c         |   72 ---------------------
 src/gallium/drivers/llvmpipe/lp_setup.h         |    5 --
 src/gallium/drivers/llvmpipe/lp_setup_context.h |    4 -
 src/gallium/drivers/llvmpipe/lp_state.h         |    6 ++
 src/gallium/drivers/llvmpipe/lp_state_derived.c |    6 +--
 src/gallium/drivers/llvmpipe/lp_state_sampler.c |   76 ++++++++++++++++++++++-
 8 files changed, 85 insertions(+), 89 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 986e604..b2643ab 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -83,6 +83,7 @@ struct llvmpipe_context {
       int so_count[PIPE_MAX_SO_BUFFERS];
       int num_buffers;
    } so_target;
+   struct pipe_resource *mapped_vs_tex[PIPE_MAX_VERTEX_SAMPLERS];
 
    unsigned num_samplers;
    unsigned num_fragment_sampler_views;
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 98780d7..91d99db 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -84,6 +84,9 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
       draw_set_mapped_element_buffer_range(draw, 0, 0, start,
                                            start + count - 1, NULL);
    }
+   llvmpipe_prepare_vertex_sampling(lp,
+                                    lp->num_vertex_sampler_views,
+                                    lp->vertex_sampler_views);
 
    /* draw! */
    draw_arrays(draw, mode, start, count);
@@ -97,6 +100,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
    if (indexBuffer) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
+   llvmpipe_cleanup_vertex_sampling(lp);
 
    /*
     * TODO: Flush only when a user vertex/index buffer is present
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index fcb6e06..2bd6fce 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -657,75 +657,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
 
 
 /**
- * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
- */
-void
-lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
-                                  unsigned num,
-                                  struct pipe_sampler_view **views)
-{
-   unsigned i;
-   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
-   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
-   const void *data[DRAW_MAX_TEXTURE_LEVELS];
-   struct lp_scene *scene;
-   struct llvmpipe_context *lp;
-
-   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
-
-   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
-
-   scene = lp_setup_get_current_scene(setup);
-   lp = llvmpipe_context(scene->pipe);
-
-   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
-      struct pipe_sampler_view *view = i < num ? views[i] : NULL;
-
-      if (view) {
-         struct pipe_resource *tex = view->texture;
-         struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
-
-         /* We're referencing the texture's internal data, so save a
-          * reference to it.
-          */
-         pipe_resource_reference(&setup->vs.current_tex[i], tex);
-
-         if (!lp_tex->dt) {
-            /* regular texture - setup array of mipmap level pointers */
-            int j;
-            for (j = 0; j <= tex->last_level; j++) {
-               data[j] =
-                  llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
-                                                 LP_TEX_LAYOUT_LINEAR);
-               row_stride[j] = lp_tex->row_stride[j];
-               img_stride[j] = lp_tex->img_stride[j];
-            }
-         }
-         else {
-            /* display target texture/surface */
-            /*
-             * XXX: Where should this be unmapped?
-             */
-            struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
-            struct sw_winsys *winsys = screen->winsys;
-            data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
-                                                PIPE_TRANSFER_READ);
-            row_stride[0] = lp_tex->row_stride[0];
-            img_stride[0] = lp_tex->img_stride[0];
-            assert(data[0]);
-         }
-         draw_set_mapped_texture(lp->draw,
-                                 i,
-                                 tex->width0, tex->height0, tex->depth0,
-                                 tex->last_level,
-                                 row_stride, img_stride, data);
-      }
-   }
-}
-
-
-
-/**
  * Is the given texture referenced by any scene?
  * Note: we have to check all scenes including any scenes currently
  * being rendered and the current scene being built.
@@ -918,9 +849,6 @@ lp_setup_destroy( struct lp_setup_context *setup )
 
    util_unreference_framebuffer_state(&setup->fb);
 
-   for (i = 0; i < Elements(setup->vs.current_tex); i++) {
-      pipe_resource_reference(&setup->vs.current_tex[i], NULL);
-   }
    for (i = 0; i < Elements(setup->fs.current_tex); i++) {
       pipe_resource_reference(&setup->fs.current_tex[i], NULL);
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index fd2c927..6a0dc55 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -133,11 +133,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                     unsigned num,
                                     struct pipe_sampler_view **views);
 
-void
-lp_setup_set_vertex_sampler_views(struct lp_setup_context *setup,
-                                  unsigned num,
-                                  struct pipe_sampler_view **views);
-
 unsigned
 lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
                                 const struct pipe_resource *texture );
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 947d5ef..8f4e00f 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -116,10 +116,6 @@ struct lp_setup_context
       struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS];
    } fs;
 
-   struct {
-      struct pipe_resource *current_tex[PIPE_MAX_VERTEX_SAMPLERS];
-   } vs;
-
    /** fragment shader constants */
    struct {
       struct pipe_resource *current;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 05d1b93..86313e1 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -130,6 +130,12 @@ llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
 void
 llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe);
 
+void
+llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *ctx,
+                                 unsigned num,
+                                 struct pipe_sampler_view **views);
+void
+llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx);
 
 
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 263b117..77bec46 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -188,14 +188,10 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
       lp_setup_set_fs_constants(llvmpipe->setup, 
                                 llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
 
-   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) {
+   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
       lp_setup_set_fragment_sampler_views(llvmpipe->setup,
                                           llvmpipe->num_fragment_sampler_views,
                                           llvmpipe->fragment_sampler_views);
-      lp_setup_set_vertex_sampler_views(llvmpipe->setup,
-                                        llvmpipe->num_vertex_sampler_views,
-                                        llvmpipe->vertex_sampler_views);
-   }
 
    llvmpipe->dirty = 0;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 0fea7f2..715ce2f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -35,10 +35,9 @@
 #include "draw/draw_context.h"
 
 #include "lp_context.h"
-#include "lp_context.h"
+#include "lp_screen.h"
 #include "lp_state.h"
-#include "draw/draw_context.h"
-
+#include "state_tracker/sw_winsys.h"
 
 
 static void *
@@ -222,6 +221,77 @@ llvmpipe_delete_sampler_state(struct pipe_context *pipe,
 }
 
 
+/**
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ */
+void
+llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
+                                 unsigned num,
+                                 struct pipe_sampler_view **views)
+{
+   unsigned i;
+   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
+   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
+   const void *data[DRAW_MAX_TEXTURE_LEVELS];
+
+   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+   if (!num)
+      return;
+
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+      if (view) {
+         struct pipe_resource *tex = view->texture;
+         struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
+
+         /* We're referencing the texture's internal data, so save a
+          * reference to it.
+          */
+         pipe_resource_reference(&lp->mapped_vs_tex[i], tex);
+
+         if (!lp_tex->dt) {
+            /* regular texture - setup array of mipmap level pointers */
+            int j;
+            for (j = 0; j <= tex->last_level; j++) {
+               data[j] =
+                  llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
+                                                 LP_TEX_LAYOUT_LINEAR);
+               row_stride[j] = lp_tex->row_stride[j];
+               img_stride[j] = lp_tex->img_stride[j];
+            }
+         }
+         else {
+            /* display target texture/surface */
+            /*
+             * XXX: Where should this be unmapped?
+             */
+            struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
+            struct sw_winsys *winsys = screen->winsys;
+            data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+                                                PIPE_TRANSFER_READ);
+            row_stride[0] = lp_tex->row_stride[0];
+            img_stride[0] = lp_tex->img_stride[0];
+            assert(data[0]);
+         }
+         draw_set_mapped_texture(lp->draw,
+                                 i,
+                                 tex->width0, tex->height0, tex->depth0,
+                                 tex->last_level,
+                                 row_stride, img_stride, data);
+      }
+   }
+}
+
+void
+llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
+{
+   unsigned i;
+   for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
+      pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
+   }
+}
+
 void
 llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
 {




More information about the mesa-commit mailing list