From 784f49e69624cba07616fd5a22ccb80ad3b5111b Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 8 Mar 2012 15:56:11 +0100 Subject: [PATCH] nvc0: track texture dirty state individually --- src/gallium/drivers/nvc0/nvc0_context.h | 29 ++++++----- src/gallium/drivers/nvc0/nvc0_state.c | 32 ++++++++---- .../drivers/nvc0/nvc0_state_validate.c | 6 +++ src/gallium/drivers/nvc0/nvc0_surface.c | 4 ++ src/gallium/drivers/nvc0/nvc0_tex.c | 50 ++++++++++++------- 5 files changed, 81 insertions(+), 40 deletions(-) diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index f6a505587ac..fdb58898ebd 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -52,19 +52,20 @@ #define NVC0_NEW_TFB_TARGETS (1 << 21) #define NVC0_NEW_IDXBUF (1 << 22) -#define NVC0_BIND_FB 0 -#define NVC0_BIND_VTX 1 -#define NVC0_BIND_VTX_TMP 2 -#define NVC0_BIND_IDX 3 -#define NVC0_BIND_TEX 4 -#define NVC0_BIND_CB(s, i) (5 + 16 * (s) + (i)) -#define NVC0_BIND_TFB 85 -#define NVC0_BIND_SCREEN 86 -#define NVC0_BIND_TLS 87 -#define NVC0_BIND_COUNT 88 -#define NVC0_BIND_2D 0 -#define NVC0_BIND_M2MF 0 -#define NVC0_BIND_FENCE 1 +#define NVC0_BIND_FB 0 +#define NVC0_BIND_VTX 1 +#define NVC0_BIND_VTX_TMP 2 +#define NVC0_BIND_IDX 3 +#define NVC0_BIND_TEX(s, i) ( 4 + 32 * (s) + (i)) +#define NVC0_BIND_CB(s, i) (164 + 16 * (s) + (i)) +#define NVC0_BIND_TFB 244 +#define NVC0_BIND_SCREEN 245 +#define NVC0_BIND_TLS 246 +#define NVC0_BIND_COUNT 247 + +#define NVC0_BIND_2D 0 +#define NVC0_BIND_M2MF 0 +#define NVC0_BIND_FENCE 1 struct nvc0_context { struct nouveau_context base; @@ -121,8 +122,10 @@ struct nvc0_context { struct pipe_sampler_view *textures[5][PIPE_MAX_SAMPLERS]; unsigned num_textures[5]; + uint32_t textures_dirty[5]; struct nv50_tsc_entry *samplers[5][PIPE_MAX_SAMPLERS]; unsigned num_samplers[5]; + uint16_t samplers_dirty[5]; struct pipe_framebuffer_state framebuffer; struct pipe_blend_color blend_colour; diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index b2cd54af129..d493f6e7fa0 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -420,13 +420,20 @@ nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s, for (i = 0; i < nr; ++i) { struct nv50_tsc_entry *old = nvc0->samplers[s][i]; + if (hwcso[i] == old) + continue; + nvc0->samplers_dirty[s] |= 1 << i; + nvc0->samplers[s][i] = nv50_tsc_entry(hwcso[i]); if (old) nvc0_screen_tsc_unlock(nvc0->screen, old); } - for (; i < nvc0->num_samplers[s]; ++i) - if (nvc0->samplers[s][i]) + for (; i < nvc0->num_samplers[s]; ++i) { + if (nvc0->samplers[s][i]) { nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]); + nvc0->samplers[s][i] = NULL; + } + } nvc0->num_samplers[s] = nr; @@ -472,25 +479,30 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s, for (i = 0; i < nr; ++i) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); - if (old) + + if (views[i] == nvc0->textures[s][i]) + continue; + nvc0->textures_dirty[s] |= 1 << i; + + if (old) { + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); nvc0_screen_tic_unlock(nvc0->screen, old); + } pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]); } for (i = nr; i < nvc0->num_textures[s]; ++i) { struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); - if (!old) - continue; - nvc0_screen_tic_unlock(nvc0->screen, old); - - pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); + if (old) { + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); + nvc0_screen_tic_unlock(nvc0->screen, old); + pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); + } } nvc0->num_textures[s] = nr; - nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX); - nvc0->dirty |= NVC0_NEW_TEXTURES; } diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 4211fcdefd5..3533a5e1ba4 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -459,12 +459,18 @@ static void nvc0_switch_pipe_context(struct nvc0_context *ctx_to) { struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx; + unsigned s; if (ctx_from) ctx_to->state = ctx_from->state; ctx_to->dirty = ~0; + for (s = 0; s < 5; ++s) { + ctx_to->samplers_dirty[s] = ~0; + ctx_to->textures_dirty[s] = ~0; + } + if (!ctx_to->vertex) ctx_to->dirty &= ~(NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS); diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index cb5091ae376..d1a233fbcf6 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -769,6 +769,8 @@ nvc0_blitctx_pre_blit(struct nvc0_blitctx *blit, struct nvc0_context *nvc0) for (s = 0; s <= 4; ++s) { blit->saved.num_textures[s] = nvc0->num_textures[s]; blit->saved.num_samplers[s] = nvc0->num_samplers[s]; + nvc0->textures_dirty[s] = ~0; + nvc0->samplers_dirty[s] = ~0; } blit->saved.texture = nvc0->textures[4][0]; blit->saved.sampler = nvc0->samplers[4][0]; @@ -811,6 +813,8 @@ nvc0_blitctx_post_blit(struct nvc0_context *nvc0, struct nvc0_blitctx *blit) for (s = 0; s <= 4; ++s) { nvc0->num_textures[s] = blit->saved.num_textures[s]; nvc0->num_samplers[s] = blit->saved.num_samplers[s]; + nvc0->textures_dirty[s] = ~0; + nvc0->samplers_dirty[s] = ~0; } nvc0->textures[4][0] = blit->saved.texture; nvc0->samplers[4][0] = blit->saved.sampler; diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index fd58f80ab97..f6c4ab39bd9 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -206,18 +206,21 @@ nvc0_create_sampler_view(struct pipe_context *pipe, static boolean nvc0_validate_tic(struct nvc0_context *nvc0, int s) { + uint32_t commands[32]; struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nouveau_bo *txc = nvc0->screen->txc; unsigned i; + unsigned n = 0; boolean need_flush = FALSE; for (i = 0; i < nvc0->num_textures[s]; ++i) { struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]); struct nv04_resource *res; + const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i)); if (!tic) { - BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); - PUSH_DATA (push, (i << 1) | 0); + if (dirty) + commands[n++] = (i << 1) | 0; continue; } res = nv04_resource(tic->pipe.texture); @@ -248,17 +251,23 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; - BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD); + if (!dirty) + continue; + commands[n++] = (tic->id << 9) | (i << 1) | 1; - BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); - PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1); - } - for (; i < nvc0->state.num_textures[s]; ++i) { - BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1); - PUSH_DATA (push, (i << 1) | 0); + BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD); } + for (; i < nvc0->state.num_textures[s]; ++i) + commands[n++] = (i << 1) | 0; + nvc0->state.num_textures[s] = nvc0->num_textures[s]; + if (n) { + BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n); + PUSH_DATAp(push, commands, n); + } + nvc0->textures_dirty[s] = 0; + return need_flush; } @@ -279,16 +288,19 @@ void nvc0_validate_textures(struct nvc0_context *nvc0) static boolean nvc0_validate_tsc(struct nvc0_context *nvc0, int s) { + uint32_t commands[16]; struct nouveau_pushbuf *push = nvc0->base.pushbuf; unsigned i; + unsigned n = 0; boolean need_flush = FALSE; for (i = 0; i < nvc0->num_samplers[s]; ++i) { struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]); + if (!(nvc0->samplers_dirty[s] & (1 << i))) + continue; if (!tsc) { - BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); - PUSH_DATA (push, (i << 4) | 0); + commands[n++] = (i << 4) | 0; continue; } if (tsc->id < 0) { @@ -301,15 +313,19 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) } nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); - BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); - PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1); - } - for (; i < nvc0->state.num_samplers[s]; ++i) { - BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1); - PUSH_DATA (push, (i << 4) | 0); + commands[n++] = (tsc->id << 12) | (i << 4) | 1; } + for (; i < nvc0->state.num_samplers[s]; ++i) + commands[n++] = (i << 4) | 0; + nvc0->state.num_samplers[s] = nvc0->num_samplers[s]; + if (n) { + BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n); + PUSH_DATAp(push, commands, n); + } + nvc0->samplers_dirty[s] = 0; + return need_flush; } -- 2.30.2