r600g: move SPI setup to PS setup
authorVadim Girlin <vadimgirlin@gmail.com>
Fri, 4 Nov 2011 17:24:03 +0000 (21:24 +0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 4 Nov 2011 20:23:24 +0000 (16:23 -0400)
SPI semantic indices for PS/VS are now static, so we don't
need to update spi config for every shaders combination. We can move
the functionality of r600_spi_update to r600(evergreen)_pipe_shader_ps.

Flatshade state is now controlled by the global FLAT_SHADE_ENA flag
instead of updating FLAT_SHADE for all inputs.

Sprite coord still requires the update of spi setup when
sprite_coord_enable is first changed from zero (enabled), and then
only when it's changed to other non-zero value (enabled for other input).
Change to zero (disabling) and back to the same value is handled via
global SPRITE_COORD_ENA.

New field "sprite_coord_enable" added to "struct r600_pipe_shader"
to track current state for the pixel shader. It's checked in the
r600_update_derived_state.

Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 904267da1bd714bb490e35fe83041fd03e803f64..c0b057cc334cf8abbf7433f3c83b8eafdf8a91ba 100644 (file)
@@ -908,7 +908,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
        rstate->id = R600_PIPE_STATE_RASTERIZER;
        if (state->flatshade_first)
                prov_vtx = 0;
-       tmp = S_0286D4_FLAT_SHADE_ENA(1);
+       tmp = S_0286D4_FLAT_SHADE_ENA(state->flatshade);
        if (state->sprite_coord_enable) {
                tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
                        S_0286D4_PNT_SPRITE_OVRD_X(2) |
@@ -2246,7 +2246,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
        int pos_index = -1, face_index = -1;
        int ninterp = 0;
        boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
-       unsigned spi_baryc_cntl;
+       unsigned spi_baryc_cntl, sid, tmp, idx = 0;
 
        rstate->nregs = 0;
 
@@ -2267,7 +2267,31 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
                        if (rshader->input[i].centroid)
                                have_centroid = TRUE;
                }
+
+               sid = rshader->input[i].spi_sid;
+
+               if (sid) {
+
+                       tmp = S_028644_SEMANTIC(sid);
+
+                       if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+                                       rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+                                       rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+                               tmp |= S_028644_FLAT_SHADE(1);
+                       }
+
+                       if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+                                       rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+                               tmp |= S_028644_PT_SPRITE_TEX(1);
+                       }
+
+                       r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + idx * 4,
+                                       tmp, 0xFFFFFFFF, NULL, 0);
+
+                       idx++;
+               }
        }
+
        for (i = 0; i < rshader->noutput; i++) {
                if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
                        db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
@@ -2368,6 +2392,8 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
        r600_pipe_state_add_reg(rstate,
                                R_03A200_SQ_LOOP_CONST_0, 0x01000FFF,
                                0xFFFFFFFF, NULL, 0);
+
+       shader->sprite_coord_enable = rctx->sprite_coord_enable;
 }
 
 void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader)
index 330e3202bab5fc13d39a1f096a022aceb2fc4a29..92cb34dacadbe1d9ccc3da87b4957392010b89e3 100644 (file)
@@ -68,7 +68,6 @@ enum r600_pipe_state_id {
        R600_PIPE_STATE_RESOURCE,
        R600_PIPE_STATE_POLYGON_OFFSET,
        R600_PIPE_STATE_FETCH_SHADER,
-       R600_PIPE_STATE_SPI,
        R600_PIPE_NSTATES
 };
 
@@ -133,6 +132,7 @@ struct r600_pipe_shader {
        struct r600_resource            *bo_fetch;
        struct r600_vertex_element      vertex_elements;
        struct tgsi_token               *tokens;
+       unsigned        sprite_coord_enable;
 };
 
 struct r600_pipe_sampler_state {
@@ -215,9 +215,7 @@ struct r600_pipe_context {
        /* shader information */
        boolean                         clamp_vertex_color;
        boolean                         clamp_fragment_color;
-       boolean                         spi_dirty;
        unsigned                        sprite_coord_enable;
-       boolean                         flatshade;
        boolean                         export_16bpc;
        unsigned                        alpha_ref;
        boolean                         alpha_ref_dirty;
index ce65da668df0d2aeb5909c5991e0c3d8eb822acc..863a7a4ba5a6684273746982009a6ca45df2dfcc 100644 (file)
@@ -958,7 +958,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
        rstate->id = R600_PIPE_STATE_RASTERIZER;
        if (state->flatshade_first)
                prov_vtx = 0;
-       tmp = S_0286D4_FLAT_SHADE_ENA(1);
+       tmp = S_0286D4_FLAT_SHADE_ENA(state->flatshade);
        if (state->sprite_coord_enable) {
                tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
                        S_0286D4_PNT_SPRITE_OVRD_X(2) |
@@ -2049,6 +2049,7 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad
        struct r600_shader *rshader = &shader->shader;
        unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control;
        int pos_index = -1, face_index = -1;
+       unsigned tmp, sid;
 
        rstate->nregs = 0;
 
@@ -2057,6 +2058,30 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad
                        pos_index = i;
                if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
                        face_index = i;
+
+               sid = rshader->input[i].spi_sid;
+
+               tmp = S_028644_SEMANTIC(sid);
+
+               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
+                               rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
+                               rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
+                       tmp |= S_028644_FLAT_SHADE(1);
+               }
+
+               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+                               rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
+                       tmp |= S_028644_PT_SPRITE_TEX(1);
+               }
+
+               if (rshader->input[i].centroid)
+                       tmp |= S_028644_SEL_CENTROID(1);
+
+               if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
+                       tmp |= S_028644_SEL_LINEAR(1);
+
+               r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4,
+                               tmp, 0xFFFFFFFF, NULL, 0);
        }
 
        db_shader_control = 0;
@@ -2134,6 +2159,8 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad
        r600_pipe_state_add_reg(rstate,
                                R_03E200_SQ_LOOP_CONST_0, 0x01000FFF,
                                0xFFFFFFFF, NULL, 0);
+
+       shader->sprite_coord_enable = rctx->sprite_coord_enable;
 }
 
 void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader)
index 3d0345addce1f6d2e69b3adc7bf32b19ee2bc2f5..b81fba104674f2deb8711f429890e9ec9d5bd7ae 100644 (file)
@@ -34,8 +34,6 @@
 #include "r600_pipe.h"
 #include "r600d.h"
 
-static void r600_spi_update(struct r600_pipe_context *rctx);
-
 static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
 {
        static const int prim_conv[] = {
@@ -103,8 +101,9 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
 
        rctx->clamp_vertex_color = rs->clamp_vertex_color;
        rctx->clamp_fragment_color = rs->clamp_fragment_color;
-       rctx->flatshade = rs->flatshade;
+
        rctx->sprite_coord_enable = rs->sprite_coord_enable;
+
        rctx->rasterizer = rs;
 
        rctx->states[rs->rstate.id] = &rs->rstate;
@@ -115,8 +114,6 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
        } else {
                r600_polygon_offset_update(rctx);
        }
-       if (rctx->ps_shader && rctx->vs_shader)
-               rctx->spi_dirty = true;
 }
 
 void r600_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -280,7 +277,6 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
                r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
        }
        if (rctx->ps_shader && rctx->vs_shader) {
-               rctx->spi_dirty = true;
                r600_adjust_gprs(rctx);
        }
 }
@@ -295,7 +291,6 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
                r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
        }
        if (rctx->ps_shader && rctx->vs_shader) {
-               rctx->spi_dirty = true;
                r600_adjust_gprs(rctx);
        }
 }
@@ -343,63 +338,6 @@ static void r600_update_alpha_ref(struct r600_pipe_context *rctx)
        rctx->alpha_ref_dirty = false;
 }
 
-/* FIXME optimize away spi update when it's not needed */
-static void r600_spi_block_init(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate)
-{
-       int i;
-       rstate->nregs = 0;
-       rstate->id = R600_PIPE_STATE_SPI;
-       for (i = 0; i < 32; i++) {
-               r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL, 0);
-       }
-}
-
-static void r600_spi_update(struct r600_pipe_context *rctx)
-{
-       struct r600_pipe_shader *shader = rctx->ps_shader;
-       struct r600_pipe_state *rstate = &rctx->spi;
-       struct r600_shader *rshader = &shader->shader;
-       unsigned i, tmp, sid;
-
-       if (rctx->spi.id == 0)
-               r600_spi_block_init(rctx, &rctx->spi);
-
-       rstate->nregs = 0;
-       for (i = 0; i < rshader->ninput; i++) {
-
-               sid = rshader->input[i].spi_sid;
-
-               if (!sid && (rctx->chip_class >= EVERGREEN))
-                       continue;
-
-               tmp = S_028644_SEMANTIC(sid);
-
-               if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
-                   rshader->input[i].name == TGSI_SEMANTIC_POSITION) {
-                       tmp |= S_028644_FLAT_SHADE(rctx->flatshade);
-               }
-
-               if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-                   rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) {
-                       tmp |= S_028644_PT_SPRITE_TEX(1);
-               }
-
-               if (rctx->chip_class < EVERGREEN) {
-                       if (rshader->input[i].centroid)
-                               tmp |= S_028644_SEL_CENTROID(1);
-
-                       if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
-                               tmp |= S_028644_SEL_LINEAR(1);
-               }
-
-               r600_pipe_state_mod_reg(rstate, tmp);
-       }
-
-       rctx->spi_dirty = false;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
-}
-
 void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
                              struct pipe_resource *buffer)
 {
@@ -552,6 +490,8 @@ static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shade
 
 static void r600_update_derived_state(struct r600_pipe_context *rctx)
 {
+       struct pipe_context * ctx = (struct pipe_context*)rctx;
+
        if (!rctx->blitter->running) {
                if (rctx->have_depth_fb || rctx->have_depth_texture)
                        r600_flush_depth_textures(rctx);
@@ -571,13 +511,21 @@ static void r600_update_derived_state(struct r600_pipe_context *rctx)
                r600_shader_rebuild(&rctx->context, rctx->ps_shader);
        }
 
-       if (rctx->spi_dirty) {
-               r600_spi_update(rctx);
-       }
-
        if (rctx->alpha_ref_dirty) {
                r600_update_alpha_ref(rctx);
        }
+
+       if (rctx->ps_shader && rctx->sprite_coord_enable &&
+               (rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) {
+
+               if (rctx->chip_class >= EVERGREEN)
+                       evergreen_pipe_shader_ps(ctx, rctx->ps_shader);
+               else
+                       r600_pipe_shader_ps(ctx, rctx->ps_shader);
+
+               r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
+       }
+
 }
 
 void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)