Mesa (master): r300g: pick a new fragment shader when either a sampler state or view is changed

Marek Olšák mareko at kemper.freedesktop.org
Thu Apr 15 08:16:32 UTC 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Thu Apr 15 09:26:07 2010 +0200

r300g: pick a new fragment shader when either a sampler state or view is changed

---

 src/gallium/drivers/r300/r300_fs.c            |    8 ++++++--
 src/gallium/drivers/r300/r300_state.c         |   16 +++++-----------
 src/gallium/drivers/r300/r300_state_derived.c |   17 +++++++++++++----
 3 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index dab57fd..ecba8b0 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -342,8 +342,12 @@ boolean r300_pick_fragment_shader(struct r300_context* r300)
             ptr = fs->first;
             while (ptr) {
                 if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) {
-                    fs->shader = ptr;
-                    return TRUE;
+                    if (fs->shader != ptr) {
+                        fs->shader = ptr;
+                        return TRUE;
+                    }
+                    /* The currently-bound one is OK. */
+                    return FALSE;
                 }
                 ptr = ptr->next;
             }
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index a10953c..371e52d 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -36,6 +36,7 @@
 #include "r300_reg.h"
 #include "r300_screen.h"
 #include "r300_screen_buffer.h"
+#include "r300_state.h"
 #include "r300_state_inlines.h"
 #include "r300_fs.h"
 #include "r300_texture.h"
@@ -683,7 +684,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
     return (void*)fs;
 }
 
-static void r300_mark_fs_code_dirty(struct r300_context *r300)
+void r300_mark_fs_code_dirty(struct r300_context *r300)
 {
     struct r300_fragment_shader* fs = r300_fs(r300);
 
@@ -982,13 +983,6 @@ static void r300_bind_sampler_states(struct pipe_context* pipe,
     state->sampler_state_count = count;
 
     r300->textures_state.dirty = TRUE;
-
-    /* Pick a fragment shader based on the texture compare state. */
-    if (r300->fs.state && count) {
-        if (r300_pick_fragment_shader(r300)) {
-            r300_mark_fs_code_dirty(r300);
-        }
-    }
 }
 
 static void r300_lacks_vertex_textures(struct pipe_context* pipe,
@@ -1012,7 +1006,6 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
     struct r300_texture *texture;
     unsigned i;
     unsigned tex_units = r300->screen->caps.num_tex_units;
-    boolean is_r500 = r300->screen->caps.is_r500;
     boolean dirty_tex = FALSE;
 
     if (count > tex_units) {
@@ -1032,9 +1025,10 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
             /* A new sampler view (= texture)... */
             dirty_tex = TRUE;
 
-            /* R300-specific - set the texrect factor in the fragment shader */
+            /* Set the texrect factor in the fragment shader.
+             * Needed for RECT and NPOT fallback. */
             texture = r300_texture(views[i]->texture);
-            if (!is_r500 && texture->uses_pitch) {
+            if (texture->uses_pitch) {
                 r300->fs_rc_constant_state.dirty = TRUE;
             }
         }
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index ddf7285..a36cff9 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -30,6 +30,7 @@
 #include "r300_fs.h"
 #include "r300_screen.h"
 #include "r300_shader_semantics.h"
+#include "r300_state.h"
 #include "r300_state_derived.h"
 #include "r300_state_inlines.h"
 #include "r300_vs.h"
@@ -550,18 +551,26 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
     }
 
     r300->textures_state.size = size;
+
+    /* Pick a fragment shader based on either the texture compare state
+     * or the uses_pitch flag. */
+    if (r300->fs.state && count) {
+        if (r300_pick_fragment_shader(r300)) {
+            r300_mark_fs_code_dirty(r300);
+        }
+    }
 }
 
 void r300_update_derived_state(struct r300_context* r300)
 {
-    if (r300->rs_block_state.dirty) {
-        r300_update_derived_shader_state(r300);
-    }
-
     if (r300->textures_state.dirty) {
         r300_merge_textures_and_samplers(r300);
     }
 
+    if (r300->rs_block_state.dirty) {
+        r300_update_derived_shader_state(r300);
+    }
+
     if (r300->draw) {
         memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
         r300_draw_emit_all_attribs(r300);




More information about the mesa-commit mailing list