summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_state_derived.c
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2011-04-05 17:57:02 +0200
committerMarek Olšák <maraeo@gmail.com>2011-04-05 19:25:25 +0200
commit4af3fe857dc07923af8786b434dee32d493b577e (patch)
treed1189d0cabb55b1fccceea76825983d4dd136892 /src/gallium/drivers/r300/r300_state_derived.c
parentd8361400b76dde6fb63df6c363b7dd59c5946e09 (diff)
r300g: postpone fragment shader state validation until draw_vbo
Diffstat (limited to 'src/gallium/drivers/r300/r300_state_derived.c')
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 02fc1219e95..e943f1a715f 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -961,11 +961,10 @@ 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);
- }
+ * or the uses_pitch flag or some other external state. */
+ if (count &&
+ r300->fs_status == FRAGMENT_SHADER_VALID) {
+ r300->fs_status = FRAGMENT_SHADER_MAYBE_DIRTY;
}
}
@@ -994,6 +993,34 @@ static void r300_decompress_depth_textures(struct r300_context *r300)
}
}
+static void r300_validate_fragment_shader(struct r300_context *r300)
+{
+ struct pipe_framebuffer_state *fb = r300->fb_state.state;
+
+ if (r300->fs.state && r300->fs_status != FRAGMENT_SHADER_VALID) {
+ /* Pick the fragment shader based on external states.
+ * Then mark the state dirty if the fragment shader is either dirty
+ * or the function r300_pick_fragment_shader changed the shader. */
+ if (r300_pick_fragment_shader(r300) ||
+ r300->fs_status == FRAGMENT_SHADER_DIRTY) {
+ /* Mark the state atom as dirty. */
+ r300_mark_fs_code_dirty(r300);
+
+ /* Does Multiwrite need to be changed? */
+ if (fb->nr_cbufs > 1) {
+ boolean new_multiwrite =
+ r300_fragment_shader_writes_all(r300_fs(r300));
+
+ if (r300->fb_multiwrite != new_multiwrite) {
+ r300->fb_multiwrite = new_multiwrite;
+ r300_mark_fb_state_dirty(r300, R300_CHANGED_MULTIWRITE);
+ }
+ }
+ }
+ r300->fs_status = FRAGMENT_SHADER_VALID;
+ }
+}
+
void r300_update_derived_state(struct r300_context* r300)
{
if (r300->textures_state.dirty) {
@@ -1001,6 +1028,8 @@ void r300_update_derived_state(struct r300_context* r300)
r300_merge_textures_and_samplers(r300);
}
+ r300_validate_fragment_shader(r300);
+
if (r300->rs_block_state.dirty) {
r300_update_rs_block(r300);