llvmpipe: Decouple sampler view and sampler state updates.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 29 Sep 2010 11:05:19 +0000 (12:05 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 29 Sep 2010 13:16:35 +0000 (14:16 +0100)
Fixes glean pbo crash.

It would be possible to avoid crashing without decoupling, but given
that state trackers give no guarantee that number of views is consistent,
that would likely cause too many state updates (or miss some).

src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_state_derived.c

index eade4000873c6de1bdd80113b694adf67523c6f1..5ff11a33632f0f1cea5aa438b35407b7f1e8f4cb 100644 (file)
@@ -617,8 +617,7 @@ lp_setup_set_vertex_info( struct lp_setup_context *setup,
 void
 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                     unsigned num,
-                                    struct pipe_sampler_view **views,
-                                    const struct pipe_sampler_state **samplers)
+                                    struct pipe_sampler_view **views)
 {
    unsigned i;
 
@@ -629,7 +628,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
 
-      if(view) {
+      if (view) {
          struct pipe_resource *tex = view->texture;
          struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
          struct lp_jit_texture *jit_tex;
@@ -639,12 +638,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
          jit_tex->depth = tex->depth0;
          jit_tex->last_level = tex->last_level;
 
-         /* sampler state */
-         jit_tex->min_lod = samplers[i]->min_lod;
-         jit_tex->max_lod = samplers[i]->max_lod;
-         jit_tex->lod_bias = samplers[i]->lod_bias;
-         COPY_4V(jit_tex->border_color, samplers[i]->border_color);
-
          /* We're referencing the texture's internal data, so save a
           * reference to it.
           */
@@ -693,6 +686,38 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
 }
 
 
+/**
+ * Called during state validation when LP_NEW_SAMPLER is set.
+ */
+void
+lp_setup_set_fragment_sampler_state(struct lp_setup_context *setup,
+                                    unsigned num,
+                                    const struct pipe_sampler_state **samplers)
+{
+   unsigned i;
+
+   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      const struct pipe_sampler_state *sampler = i < num ? samplers[i] : NULL;
+
+      if (sampler) {
+         struct lp_jit_texture *jit_tex;
+         jit_tex = &setup->fs.current.jit_context.textures[i];
+
+         jit_tex->min_lod = sampler->min_lod;
+         jit_tex->max_lod = sampler->max_lod;
+         jit_tex->lod_bias = sampler->lod_bias;
+         COPY_4V(jit_tex->border_color, sampler->border_color);
+      }
+   }
+
+   setup->dirty |= LP_SETUP_NEW_FS;
+}
+
+
 /**
  * Is the given texture referenced by any scene?
  * Note: we have to check all scenes including any scenes currently
index 868bd3ad2f146218a125f16f9f4f58b4a7a9e4be..25dab78f64f59293abe0037401e4371c0e3b989e 100644 (file)
@@ -143,7 +143,11 @@ lp_setup_set_scissor( struct lp_setup_context *setup,
 void
 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                     unsigned num,
-                                    struct pipe_sampler_view **views,
+                                    struct pipe_sampler_view **views);
+
+void
+lp_setup_set_fragment_sampler_state(struct lp_setup_context *setup,
+                                    unsigned num,
                                     const struct pipe_sampler_state **samplers);
 
 unsigned
index d2be22d7fc588e84fef758ec8a8551b79634dadc..bb059d04599b80351b051338f993fabee63cd89c 100644 (file)
@@ -208,11 +208,14 @@ 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 |
-                          LP_NEW_SAMPLER))
+   if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW))
       lp_setup_set_fragment_sampler_views(llvmpipe->setup,
                                           llvmpipe->num_fragment_sampler_views,
-                                          llvmpipe->fragment_sampler_views,
+                                          llvmpipe->fragment_sampler_views);
+
+   if (llvmpipe->dirty & (LP_NEW_SAMPLER))
+      lp_setup_set_fragment_sampler_state(llvmpipe->setup,
+                                          llvmpipe->num_samplers,
                                           llvmpipe->sampler);
 
    llvmpipe->dirty = 0;