radeonsi: skip unnecessary si_update_shaders calls
authorMarek Olšák <marek.olsak@amd.com>
Tue, 2 Aug 2016 09:51:21 +0000 (11:51 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 Aug 2016 15:46:46 +0000 (17:46 +0200)
Small decrease in draw call overhead.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_draw.c
src/gallium/drivers/radeonsi/si_state_shaders.c

index 326b8191475e47aa97e5a0bfc34e066c56149fd4..41e94487c8ae262abc8abb561c940a4f1f819793 100644 (file)
@@ -260,6 +260,7 @@ struct si_context {
        struct si_vertex_element        *vertex_elements;
        unsigned                        sprite_coord_enable;
        bool                            flatshade;
+       bool                            do_update_shaders;
 
        /* shader descriptors */
        struct si_descriptors           vertex_buffers;
index c5b61e9411414af2021c6d054fbd20ce18c76ef1..47fc7a0b14b697b55741514b1b39b1d17377b527 100644 (file)
@@ -572,6 +572,7 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state)
        struct si_context *sctx = (struct si_context *)ctx;
        si_pm4_bind_state(sctx, blend, (struct si_state_blend *)state);
        si_mark_atom_dirty(sctx, &sctx->cb_render_state);
+       sctx->do_update_shaders = true;
 }
 
 static void si_delete_blend_state(struct pipe_context *ctx, void *state)
@@ -869,6 +870,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
        si_update_poly_offset_state(sctx);
 
        si_mark_atom_dirty(sctx, &sctx->clip_regs);
+       sctx->do_update_shaders = true;
 }
 
 static void si_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -1018,6 +1020,7 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
                sctx->stencil_ref.dsa_part = dsa->stencil_ref;
                si_mark_atom_dirty(sctx, &sctx->stencil_ref.atom);
        }
+       sctx->do_update_shaders = true;
 }
 
 static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
@@ -2388,6 +2391,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
        }
 
        sctx->need_check_render_feedback = true;
+       sctx->do_update_shaders = true;
 }
 
 static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom *atom)
@@ -2628,6 +2632,7 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
                return;
 
        sctx->ps_iter_samples = min_samples;
+       sctx->do_update_shaders = true;
 
        if (sctx->framebuffer.nr_samples > 1)
                si_mark_atom_dirty(sctx, &sctx->msaa_config);
@@ -3267,6 +3272,7 @@ static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
 
        sctx->vertex_elements = v;
        sctx->vertex_buffers_dirty = true;
+       sctx->do_update_shaders = true;
 }
 
 static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
index 24fa682926c64e54b9029618175ff51bdad96f3c..30b644ee42b5fbb9c72ec1b2363ef64b8a7f29cb 100644 (file)
@@ -867,7 +867,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
        struct si_context *sctx = (struct si_context *)ctx;
        struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
        struct pipe_index_buffer ib = {};
-       unsigned mask, dirty_fb_counter, dirty_tex_counter;
+       unsigned mask, dirty_fb_counter, dirty_tex_counter, rast_prim;
 
        if (!info->count && !info->indirect &&
            (info->indexed || !info->count_from_stream_output))
@@ -911,15 +911,21 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
         * draw_vbo recursively, and before si_update_shaders, which uses
         * current_rast_prim for this draw_vbo call. */
        if (sctx->gs_shader.cso)
-               sctx->current_rast_prim = sctx->gs_shader.cso->gs_output_prim;
+               rast_prim = sctx->gs_shader.cso->gs_output_prim;
        else if (sctx->tes_shader.cso)
-               sctx->current_rast_prim =
-                       sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
+               rast_prim = sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
        else
-               sctx->current_rast_prim = info->mode;
+               rast_prim = info->mode;
 
-       if (!si_update_shaders(sctx) ||
-           !si_upload_graphics_shader_descriptors(sctx))
+       if (rast_prim != sctx->current_rast_prim) {
+               sctx->current_rast_prim = rast_prim;
+               sctx->do_update_shaders = true;
+       }
+
+       if (sctx->do_update_shaders && !si_update_shaders(sctx))
+               return;
+
+       if (!si_upload_graphics_shader_descriptors(sctx))
                return;
 
        if (info->indexed) {
index 47cf496ae41d6dfdb230a789542bee64dd19f5a8..87d0b7d9022e2e1d54b69eb2b74f2919b9162929 100644 (file)
@@ -1360,6 +1360,7 @@ static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
 
        sctx->vs_shader.cso = sel;
        sctx->vs_shader.current = sel ? sel->first_variant : NULL;
+       sctx->do_update_shaders = true;
        si_mark_atom_dirty(sctx, &sctx->clip_regs);
        r600_update_vs_writes_viewport_index(&sctx->b, si_get_vs_info(sctx));
 }
@@ -1375,6 +1376,7 @@ static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
 
        sctx->gs_shader.cso = sel;
        sctx->gs_shader.current = sel ? sel->first_variant : NULL;
+       sctx->do_update_shaders = true;
        si_mark_atom_dirty(sctx, &sctx->clip_regs);
        sctx->last_rast_prim = -1; /* reset this so that it gets updated */
 
@@ -1394,6 +1396,7 @@ static void si_bind_tcs_shader(struct pipe_context *ctx, void *state)
 
        sctx->tcs_shader.cso = sel;
        sctx->tcs_shader.current = sel ? sel->first_variant : NULL;
+       sctx->do_update_shaders = true;
 
        if (enable_changed)
                sctx->last_tcs = NULL; /* invalidate derived tess state */
@@ -1410,6 +1413,7 @@ static void si_bind_tes_shader(struct pipe_context *ctx, void *state)
 
        sctx->tes_shader.cso = sel;
        sctx->tes_shader.current = sel ? sel->first_variant : NULL;
+       sctx->do_update_shaders = true;
        si_mark_atom_dirty(sctx, &sctx->clip_regs);
        sctx->last_rast_prim = -1; /* reset this so that it gets updated */
 
@@ -1431,6 +1435,7 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
 
        sctx->ps_shader.cso = sel;
        sctx->ps_shader.current = sel ? sel->first_variant : NULL;
+       sctx->do_update_shaders = true;
        si_mark_atom_dirty(sctx, &sctx->cb_render_state);
 }
 
@@ -2199,6 +2204,8 @@ bool si_update_shaders(struct si_context *sctx)
                if (!si_update_spi_tmpring_size(sctx))
                        return false;
        }
+
+       sctx->do_update_shaders = false;
        return true;
 }