Mesa (master): r300g: atomize fragment shader

Marek Olšák mareko at kemper.freedesktop.org
Mon Apr 12 02:16:42 UTC 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon Apr 12 03:08:38 2010 +0200

r300g: atomize fragment shader

---

 src/gallium/drivers/r300/r300_blit.c          |    2 +-
 src/gallium/drivers/r300/r300_context.c       |    6 ++
 src/gallium/drivers/r300/r300_context.h       |    6 ++-
 src/gallium/drivers/r300/r300_defines.h       |    1 -
 src/gallium/drivers/r300/r300_emit.c          |   86 ++++++++++++++----------
 src/gallium/drivers/r300/r300_emit.h          |   10 ++-
 src/gallium/drivers/r300/r300_fs.c            |    2 +-
 src/gallium/drivers/r300/r300_state.c         |   32 +++++++---
 src/gallium/drivers/r300/r300_state_derived.c |   10 ++--
 src/gallium/drivers/r300/r300_vs.c            |    2 +-
 10 files changed, 98 insertions(+), 59 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index f26330e..322eaa8 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -32,7 +32,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
     util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state);
     util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref));
     util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state);
-    util_blitter_save_fragment_shader(r300->blitter, r300->fs);
+    util_blitter_save_fragment_shader(r300->blitter, r300->fs.state);
     util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
     util_blitter_save_viewport(r300->blitter, &r300->viewport);
     util_blitter_save_clip(r300->blitter, &r300->clip);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 38b8e35..8d8612e 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -115,6 +115,12 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(vs_state, 0);
     R300_INIT_ATOM(texture_cache_inval, 2);
     R300_INIT_ATOM(textures_state, 0);
+    R300_INIT_ATOM(fs, 0);
+
+    /* Replace emission functions for r500. */
+    if (r300->screen->caps.is_r500) {
+        r300->fs.emit = r500_emit_fs;
+    }
 
     /* Some non-CSO atoms need explicit space to store the state locally. */
     r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index e3dd6de..51beaa5 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -357,7 +357,7 @@ struct r300_context {
     /* Depth, stencil, and alpha state. */
     struct r300_atom dsa_state;
     /* Fragment shader. */
-    struct r300_fragment_shader* fs;
+    struct r300_atom fs;
     /* Framebuffer state. */
     struct r300_atom fb_state;
     /* Rasterizer state. */
@@ -432,6 +432,10 @@ static INLINE struct r300_context* r300_context(struct pipe_context* context)
     return (struct r300_context*)context;
 }
 
+static INLINE struct r300_fragment_shader *r300_fs(struct r300_context *r300)
+{
+    return (struct r300_fragment_shader*)r300->fs.state;
+}
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
                                          void *priv);
diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h
index 1cc8a86..2bcf298 100644
--- a/src/gallium/drivers/r300/r300_defines.h
+++ b/src/gallium/drivers/r300/r300_defines.h
@@ -31,7 +31,6 @@
 #define R300_RESOURCE_FLAG_TRANSFER     PIPE_RESOURCE_FLAG_DRV_PRIV
 
 /* Non-atom dirty state flags. */
-#define R300_NEW_FRAGMENT_SHADER                0x00000020
 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS      0x00000040
 #define R300_NEW_VERTEX_SHADER_CONSTANTS        0x10000000
 #define R300_NEW_QUERY                          0x40000000
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 14faef2..2fa3f6f 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -236,7 +236,7 @@ static uint32_t pack_float24(float f)
 static void r300_emit_fragment_depth_config(struct r300_context* r300)
 {
     CS_LOCALS(r300);
-    if (r300_fragment_shader_writes_depth(r300->fs)) {
+    if (r300_fragment_shader_writes_depth(r300_fs(r300))) {
         OUT_CS_REG(R300_FG_DEPTH_SRC, R300_FG_DEPTH_SRC_SHADER);
         OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W24 | R300_W_SRC_US);
     } else {
@@ -245,22 +245,31 @@ static void r300_emit_fragment_depth_config(struct r300_context* r300)
     }
 }
 
-void r300_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code)
+unsigned r300_get_fs_atom_size(struct r300_context *r300)
 {
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    unsigned imm_count = fs->shader->immediates_count;
+    struct r300_fragment_program_code *code = &fs->shader->code.code.r300;
+
+    return 19 +
+           code->alu.length * 4 +
+           (code->tex.length ? (1 + code->tex.length) : 0) +
+           (imm_count ? imm_count * 5 : 0);
+}
+
+void r300_emit_fs(struct r300_context* r300, unsigned size, void *state)
+{
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    struct rX00_fragment_program_code* generic_code = &fs->shader->code;
     struct r300_fragment_program_code * code = &generic_code->code.r300;
     unsigned i;
-    unsigned imm_count = r300->fs->shader->immediates_count;
-    unsigned imm_first = r300->fs->shader->externals_count;
+    unsigned imm_count = fs->shader->immediates_count;
+    unsigned imm_first = fs->shader->externals_count;
     unsigned imm_end = generic_code->constants.Count;
     struct rc_constant *constants = generic_code->constants.Constants;
     CS_LOCALS(r300);
 
-    BEGIN_CS(19 +
-             code->alu.length * 4 +
-             (code->tex.length ? (1 + code->tex.length) : 0) +
-             (imm_count ? imm_count * 5 : 0));
-
+    BEGIN_CS(size);
     OUT_CS_REG(R300_US_CONFIG, code->config);
     OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
     OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset);
@@ -314,7 +323,8 @@ void r300_emit_fragment_program_code(struct r300_context* r300,
 void r300_emit_fs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants)
 {
-    unsigned i, count = r300->fs->shader->externals_count;
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    unsigned i, count = fs->shader->externals_count;
     CS_LOCALS(r300);
 
     if (count == 0)
@@ -337,9 +347,10 @@ void r300_emit_fs_constant_buffer(struct r300_context* r300,
 void r300_emit_fs_constant_rc_state(struct r300_context* r300,
                                     struct rc_constant_list* constants)
 {
+    struct r300_fragment_shader *fs = r300_fs(r300);
     unsigned i;
-    unsigned count = r300->fs->shader->rc_state_count;
-    unsigned first = r300->fs->shader->externals_count;
+    unsigned count = fs->shader->rc_state_count;
+    unsigned first = fs->shader->externals_count;
     unsigned end = constants->Count;
     CS_LOCALS(r300);
 
@@ -362,20 +373,30 @@ void r300_emit_fs_constant_rc_state(struct r300_context* r300,
     END_CS;
 }
 
-void r500_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code)
+unsigned r500_get_fs_atom_size(struct r300_context *r300)
 {
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    unsigned imm_count = fs->shader->immediates_count;
+    struct r500_fragment_program_code *code = &fs->shader->code.code.r500;
+
+    return 17 +
+           ((code->inst_end + 1) * 6) +
+           (imm_count ? imm_count * 7 : 0);
+}
+
+void r500_emit_fs(struct r300_context* r300, unsigned size, void *state)
+{
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    struct rX00_fragment_program_code* generic_code = &fs->shader->code;
     struct r500_fragment_program_code * code = &generic_code->code.r500;
     unsigned i;
-    unsigned imm_count = r300->fs->shader->immediates_count;
-    unsigned imm_first = r300->fs->shader->externals_count;
+    unsigned imm_count = fs->shader->immediates_count;
+    unsigned imm_first = fs->shader->externals_count;
     unsigned imm_end = generic_code->constants.Count;
     struct rc_constant *constants = generic_code->constants.Constants;
     CS_LOCALS(r300);
 
-    BEGIN_CS(17 +
-             ((code->inst_end + 1) * 6) +
-             (imm_count ? imm_count * 7 : 0));
+    BEGIN_CS(size);
     OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
     OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
     OUT_CS_REG(R500_US_CODE_RANGE,
@@ -421,7 +442,8 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
 void r500_emit_fs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants)
 {
-    unsigned i, count = r300->fs->shader->externals_count;
+    struct r300_fragment_shader *fs = r300_fs(r300);
+    unsigned i, count = fs->shader->externals_count;
     CS_LOCALS(r300);
 
     if (count == 0)
@@ -446,9 +468,10 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
 void r500_emit_fs_constant_rc_state(struct r300_context* r300,
                                     struct rc_constant_list* constants)
 {
+    struct r300_fragment_shader *fs = r300_fs(r300);
     unsigned i;
-    unsigned count = r300->fs->shader->rc_state_count;
-    unsigned first = r300->fs->shader->externals_count;
+    unsigned count = fs->shader->rc_state_count;
+    unsigned first = fs->shader->externals_count;
     unsigned end = constants->Count;
     CS_LOCALS(r300);
 
@@ -1188,26 +1211,17 @@ void r300_emit_dirty_state(struct r300_context* r300)
         }
     }
 
-    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
-        if (r300screen->caps.is_r500) {
-            r500_emit_fragment_program_code(r300, &r300->fs->shader->code);
-        } else {
-            r300_emit_fragment_program_code(r300, &r300->fs->shader->code);
-        }
-        r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
-    }
-
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
         if (r300screen->caps.is_r500) {
             r500_emit_fs_constant_buffer(r300,
-                                         &r300->fs->shader->code.constants);
+                                         &r300_fs(r300)->shader->code.constants);
             r500_emit_fs_constant_rc_state(r300,
-                                           &r300->fs->shader->code.constants);
+                                           &r300_fs(r300)->shader->code.constants);
         } else {
             r300_emit_fs_constant_buffer(r300,
-                                         &r300->fs->shader->code.constants);
+                                         &r300_fs(r300)->shader->code.constants);
             r300_emit_fs_constant_rc_state(r300,
-                                           &r300->fs->shader->code.constants);
+                                           &r300_fs(r300)->shader->code.constants);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
     }
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 19ab430..266538d 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -43,8 +43,9 @@ void r300_emit_clip_state(struct r300_context* r300,
 void r300_emit_dsa_state(struct r300_context* r300,
                          unsigned size, void* state);
 
-void r300_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code);
+unsigned r300_get_fs_atom_size(struct r300_context *r300);
+
+void r300_emit_fs(struct r300_context* r300, unsigned size, void *state);
 
 void r300_emit_fs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants);
@@ -52,8 +53,9 @@ void r300_emit_fs_constant_buffer(struct r300_context* r300,
 void r300_emit_fs_constant_rc_state(struct r300_context* r300,
                                     struct rc_constant_list* constants);
 
-void r500_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code);
+unsigned r500_get_fs_atom_size(struct r300_context *r300);
+
+void r500_emit_fs(struct r300_context* r300, unsigned size, void *state);
 
 void r500_emit_fs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants);
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 4969c14..762cbf2 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -278,7 +278,7 @@ static void r300_translate_fragment_shader(
 
 boolean r300_pick_fragment_shader(struct r300_context* r300)
 {
-    struct r300_fragment_shader* fs = r300->fs;
+    struct r300_fragment_shader* fs = r300_fs(r300);
     struct r300_fragment_program_external_state state;
     struct r300_fragment_shader_code* ptr;
 
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index f809355..1a00872 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -32,6 +32,7 @@
 #include "pipe/p_config.h"
 
 #include "r300_context.h"
+#include "r300_emit.h"
 #include "r300_reg.h"
 #include "r300_screen.h"
 #include "r300_screen_buffer.h"
@@ -682,6 +683,21 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
     return (void*)fs;
 }
 
+static void r300_mark_fs_code_dirty(struct r300_context *r300)
+{
+    struct r300_fragment_shader* fs = r300_fs(r300);
+
+    r300->fs.dirty = TRUE;
+
+    if (r300->screen->caps.is_r500) {
+        r300->fs.size = r500_get_fs_atom_size(r300);
+    } else {
+        r300->fs.size = r300_get_fs_atom_size(r300);
+    }
+
+    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+}
+
 /* Bind fragment shader state. */
 static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
 {
@@ -689,20 +705,19 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
     struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
 
     if (fs == NULL) {
-        r300->fs = NULL;
+        r300->fs.state = NULL;
         return;
     }
 
-    r300->fs = fs;
+    r300->fs.state = fs;
     r300_pick_fragment_shader(r300);
+    r300_mark_fs_code_dirty(r300);
 
     r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
 
     if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) {
         r300->vap_output_state.dirty = TRUE;
     }
-
-    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
 
 /* Delete fragment shader state. */
@@ -933,10 +948,9 @@ static void r300_bind_sampler_states(struct pipe_context* pipe,
     r300->textures_state.dirty = TRUE;
 
     /* Pick a fragment shader based on the texture compare state. */
-    if (r300->fs && count) {
+    if (r300->fs.state && count) {
         if (r300_pick_fragment_shader(r300)) {
-            r300->dirty_state |= R300_NEW_FRAGMENT_SHADER |
-                                 R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+            r300_mark_fs_code_dirty(r300);
         }
     }
 }
@@ -1100,7 +1114,7 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
     }
 
     r300->viewport_state.dirty = TRUE;
-    if (r300->fs && r300->fs->shader->inputs.wpos != ATTR_UNUSED) {
+    if (r300->fs.state && r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {
         r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
     }
 }
@@ -1319,7 +1333,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
     r300->vs_state.state = vs;
 
     // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
-    if (r300->fs) {
+    if (r300->fs.state) {
         r300_vertex_shader_setup_wpos(r300);
     }
     memcpy(r300->vap_output_state.state, &vs->vap_out,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 1b4c245..86c5277 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -376,7 +376,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
 {
     struct r300_vertex_shader* vs = r300->vs_state.state;
 
-    r300_update_rs_block(r300, &vs->outputs, &r300->fs->shader->inputs);
+    r300_update_rs_block(r300, &vs->outputs, &r300_fs(r300)->shader->inputs);
 }
 
 static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@@ -436,12 +436,12 @@ static void r300_update_ztop(struct r300_context* r300)
 
     /* ZS writes */
     if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
-           (r300_dsa_alpha_test_enabled(r300->dsa_state.state) ||/* (1) */
-            r300->fs->shader->info.uses_kill)) {                 /* (2) */
+           (r300_dsa_alpha_test_enabled(r300->dsa_state.state) ||  /* (1) */
+            r300_fs(r300)->shader->info.uses_kill)) {              /* (2) */
         ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300_fragment_shader_writes_depth(r300->fs)) {    /* (5) */
+    } else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */
         ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300->query_current) {                            /* (6) */
+    } else if (r300->query_current) {                              /* (6) */
         ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
     } else {
         ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index a2619b3..2f9ee76 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -348,7 +348,7 @@ boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
         return FALSE;
     }
 
-    if (r300->fs->shader->inputs.wpos != ATTR_UNUSED) {
+    if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {
         /* Enable WPOS in VAP. */
         if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) {
             vap_out->vap_vsm_vtx_assm |= tex_fmt;




More information about the mesa-commit mailing list