diff options
author | Marek Olšák <[email protected]> | 2016-12-25 18:11:59 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-01-06 21:05:48 +0100 |
commit | ece6e1f65804556de3a67a482b4ef9680f57c793 (patch) | |
tree | 955023ae52f23a32940e1e9a3e0aa7fef3f5e648 /src/gallium/drivers/radeonsi/si_state_draw.c | |
parent | a131dacb1443039b284aef3ba0a47e2ba20a13a6 (diff) |
radeonsi: add TC L2 prefetch for shaders and VBO descriptors
Reviewed-by: Edward O'Callaghan <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_state_draw.c')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_draw.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index b3f664eff2f..7b756025f81 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -937,6 +937,17 @@ void si_ce_post_draw_synchronization(struct si_context *sctx) } } +static void cik_prefetch_shader_async(struct si_context *sctx, + struct si_pm4_state *state) +{ + if (state) { + struct pipe_resource *bo = &state->bo[0]->b.b; + assert(state->nbo == 1); + + cik_prefetch_TC_L2_async(sctx, bo, 0, bo->width0); + } +} + void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { struct si_context *sctx = (struct si_context *)ctx; @@ -1114,10 +1125,34 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) if (!si_upload_vertex_buffer_descriptors(sctx)) return; - /* Flushed caches prior to emitting states. */ + /* Flushed caches prior to prefetching shaders. */ if (sctx->b.flags) si_emit_cache_flush(sctx); + /* Prefetch shaders and VBO descriptors to TC L2. */ + if (sctx->b.chip_class >= CIK) { + if (si_pm4_state_changed(sctx, ls)) + cik_prefetch_shader_async(sctx, sctx->queued.named.ls); + if (si_pm4_state_changed(sctx, hs)) + cik_prefetch_shader_async(sctx, sctx->queued.named.hs); + if (si_pm4_state_changed(sctx, es)) + cik_prefetch_shader_async(sctx, sctx->queued.named.es); + if (si_pm4_state_changed(sctx, gs)) + cik_prefetch_shader_async(sctx, sctx->queued.named.gs); + if (si_pm4_state_changed(sctx, vs)) + cik_prefetch_shader_async(sctx, sctx->queued.named.vs); + + /* Vertex buffer descriptors are uploaded uncached, so prefetch + * them right after the VS binary. */ + if (sctx->vertex_buffers.pointer_dirty) { + cik_prefetch_TC_L2_async(sctx, &sctx->vertex_buffers.buffer->b.b, + sctx->vertex_buffers.buffer_offset, + sctx->vertex_elements->count * 16); + } + if (si_pm4_state_changed(sctx, ps)) + cik_prefetch_shader_async(sctx, sctx->queued.named.ps); + } + /* Emit states. */ mask = sctx->dirty_atoms; while (mask) { |