summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-04-15 09:26:07 +0200
committerMarek Olšák <[email protected]>2010-04-15 10:10:28 +0200
commit6bd6f4cd4984e7afe7969e5dfe9796079c07b6bc (patch)
tree9083b27794bb0448fce6e41300e7441f1c6dd8b4
parentebf765a32460e5ec136892c1ea6f5e0166a0bd66 (diff)
r300g: pick a new fragment shader when either a sampler state or view is changed
-rw-r--r--src/gallium/drivers/r300/r300_fs.c8
-rw-r--r--src/gallium/drivers/r300/r300_state.c16
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c17
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 dab57fdcc77..ecba8b0d804 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 a10953c04ae..371e52d2089 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 ddf7285731e..a36cff98c38 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);