From 778c64da97272e7508dbcdf0bffdb699d1b04ce0 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Sun, 21 Feb 2010 11:33:15 +0100 Subject: [PATCH] nv30, nv40: non-trivially unify nv[34]0_state_emit.c The files are the same except for swtnl support on nv40 and for texture cache flushing on nv40. Unify them, and use a macro to define 4 versions of render_states, for all combinations of nvfx and hwtnl/swtnl. --- src/gallium/drivers/nv30/Makefile | 1 - src/gallium/drivers/nv30/nv30_context.c | 2 +- src/gallium/drivers/nv30/nv30_context.h | 3 - src/gallium/drivers/nv30/nv30_state_emit.c | 121 ------------------ src/gallium/drivers/nv30/nv30_vbo.c | 14 +- src/gallium/drivers/nv40/Makefile | 1 - src/gallium/drivers/nv40/nv40_context.c | 2 +- src/gallium/drivers/nv40/nv40_context.h | 4 - src/gallium/drivers/nv40/nv40_draw.c | 6 +- src/gallium/drivers/nv40/nv40_vbo.c | 14 +- src/gallium/drivers/nvfx/Makefile | 1 + src/gallium/drivers/nvfx/nvfx_context.h | 6 + .../nvfx_state_emit.c} | 99 +++++++------- 13 files changed, 75 insertions(+), 199 deletions(-) delete mode 100644 src/gallium/drivers/nv30/nv30_state_emit.c rename src/gallium/drivers/{nv40/nv40_state_emit.c => nvfx/nvfx_state_emit.c} (67%) diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index f18295cefc2..3067e450628 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -13,7 +13,6 @@ C_SOURCES = \ nv30_screen.c \ nv30_state.c \ nv30_state_blend.c \ - nv30_state_emit.c \ nv30_state_fb.c \ nv30_state_rasterizer.c \ nv30_state_scissor.c \ diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index ee2c465bc6d..6fe8cb3e324 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -69,7 +69,7 @@ nv30_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; screen->base.channel->user_private = nvfx; - screen->base.channel->flush_notify = nv30_state_flush_notify; + screen->base.channel->flush_notify = nvfx_state_flush_notify; nvfx->is_nv4x = screen->is_nv4x; diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 9f28d49706f..a6767da4dc1 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -24,9 +24,6 @@ extern void nv30_fragprog_destroy(struct nvfx_context *, extern void nv30_fragtex_bind(struct nvfx_context *); /* nv30_state.c and friends */ -extern boolean nv30_state_validate(struct nvfx_context *nvfx); -extern void nv30_state_emit(struct nvfx_context *nvfx); -extern void nv30_state_flush_notify(struct nouveau_channel *chan); extern struct nvfx_state_entry nv30_state_rasterizer; extern struct nvfx_state_entry nv30_state_scissor; extern struct nvfx_state_entry nv30_state_stipple; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c deleted file mode 100644 index 6df93618da8..00000000000 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "nv30_context.h" -#include "nvfx_state.h" - -static struct nvfx_state_entry *render_states[] = { - &nv30_state_framebuffer, - &nv30_state_rasterizer, - &nv30_state_scissor, - &nv30_state_stipple, - &nv30_state_fragprog, - &nv30_state_fragtex, - &nv30_state_vertprog, - &nv30_state_blend, - &nv30_state_blend_colour, - &nv30_state_zsa, - &nv30_state_sr, - &nv30_state_viewport, - &nv30_state_vbo, - NULL -}; - -static void -nv30_state_do_validate(struct nvfx_context *nvfx, - struct nvfx_state_entry **states) -{ - while (*states) { - struct nvfx_state_entry *e = *states; - - if (nvfx->dirty & e->dirty.pipe) { - if (e->validate(nvfx)) - nvfx->state.dirty |= (1ULL << e->dirty.hw); - } - - states++; - } - nvfx->dirty = 0; -} - -void -nv30_state_emit(struct nvfx_context *nvfx) -{ - struct nouveau_channel *chan = nvfx->screen->base.channel; - struct nvfx_state *state = &nvfx->state; - struct nvfx_screen *screen = nvfx->screen; - unsigned i; - uint64_t states; - - /* XXX: racy! - */ - if (nvfx != screen->cur_ctx) { - for (i = 0; i < NVFX_STATE_MAX; i++) { - if (state->hw[i] && screen->state[i] != state->hw[i]) - state->dirty |= (1ULL << i); - } - - screen->cur_ctx = nvfx; - } - - for (i = 0, states = state->dirty; states; i++) { - if (!(states & (1ULL << i))) - continue; - so_ref (state->hw[i], &nvfx->screen->state[i]); - if (state->hw[i]) - so_emit(chan, nvfx->screen->state[i]); - states &= ~(1ULL << i); - } - - state->dirty = 0; -} - -void -nv30_state_flush_notify(struct nouveau_channel *chan) -{ - struct nvfx_context *nvfx = chan->user_private; - struct nvfx_state *state = &nvfx->state; - unsigned i, samplers; - - so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FB]); - for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { - if (!(samplers & (1 << i))) - continue; - so_emit_reloc_markers(chan, - state->hw[NVFX_STATE_FRAGTEX0+i]); - samplers &= ~(1ULL << i); - } - so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FRAGPROG]); - if (state->hw[NVFX_STATE_VTXBUF] /*&& nvfx->render_mode == HW*/) - so_emit_reloc_markers(chan, state->hw[NVFX_STATE_VTXBUF]); -} - -boolean -nv30_state_validate(struct nvfx_context *nvfx) -{ -#if 0 - boolean was_sw = nvfx->fallback_swtnl ? TRUE : FALSE; - - if (nvfx->render_mode != HW) { - /* Don't even bother trying to go back to hw if none - * of the states that caused swtnl previously have changed. - */ - if ((nvfx->fallback_swtnl & nvfx->dirty) - != nvfx->fallback_swtnl) - return FALSE; - - /* Attempt to go to hwtnl again */ - nvfx->pipe.flush(&nvfx->pipe, 0, NULL); - nvfx->dirty |= (NVFX_NEW_VIEWPORT | - NVFX_NEW_VERTPROG | - NVFX_NEW_ARRAYS); - nvfx->render_mode = HW; - } -#endif - nv30_state_do_validate(nvfx, render_states); -#if 0 - if (nvfx->fallback_swtnl || nvfx->fallback_swrast) - return FALSE; - - if (was_sw) - NOUVEAU_ERR("swtnl->hw\n"); -#endif - return TRUE; -} diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 119fa59890e..2b4401e5330 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -175,7 +175,7 @@ nv30_draw_arrays(struct pipe_context *pipe, unsigned restart = 0; nv30_vbo_set_idxbuf(nvfx, NULL, 0); - if (FORCE_SWTNL || !nv30_state_validate(nvfx)) { + if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) { /*return nv30_draw_elements_swtnl(pipe, NULL, 0, mode, start, count);*/ return; @@ -184,7 +184,7 @@ nv30_draw_arrays(struct pipe_context *pipe, while (count) { unsigned vc, nr; - nv30_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); @@ -238,7 +238,7 @@ nv30_draw_elements_u08(struct nvfx_context *nvfx, void *ib, uint8_t *elts = (uint8_t *)ib + start; unsigned vc, push, restart = 0; - nv30_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); @@ -289,7 +289,7 @@ nv30_draw_elements_u16(struct nvfx_context *nvfx, void *ib, uint16_t *elts = (uint16_t *)ib + start; unsigned vc, push, restart = 0; - nv30_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); @@ -340,7 +340,7 @@ nv30_draw_elements_u32(struct nvfx_context *nvfx, void *ib, uint32_t *elts = (uint32_t *)ib + start; unsigned vc, push, restart = 0; - nv30_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1, mode, start, count, &restart); @@ -416,7 +416,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, while (count) { unsigned nr, vc; - nv30_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); @@ -465,7 +465,7 @@ nv30_draw_elements(struct pipe_context *pipe, boolean idxbuf; idxbuf = nv30_vbo_set_idxbuf(nvfx, indexBuffer, indexSize); - if (FORCE_SWTNL || !nv30_state_validate(nvfx)) { + if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) { /*return nv30_draw_elements_swtnl(pipe, NULL, 0, mode, start, count);*/ return; diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 8d09ef807f8..b0c0c09d517 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -13,7 +13,6 @@ C_SOURCES = \ nv40_screen.c \ nv40_state.c \ nv40_state_blend.c \ - nv40_state_emit.c \ nv40_state_fb.c \ nv40_state_rasterizer.c \ nv40_state_scissor.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 9934b582eef..12f57377cde 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -69,7 +69,7 @@ nv40_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; screen->base.channel->user_private = nvfx; - screen->base.channel->flush_notify = nv40_state_flush_notify; + screen->base.channel->flush_notify = nvfx_state_flush_notify; nvfx->is_nv4x = screen->is_nv4x; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e7c6d5ad86d..0b875bcb065 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -28,10 +28,6 @@ extern void nv40_fragprog_destroy(struct nvfx_context *, extern void nv40_fragtex_bind(struct nvfx_context *); /* nv40_state.c and friends */ -extern boolean nv40_state_validate(struct nvfx_context *nvfx); -extern boolean nv40_state_validate_swtnl(struct nvfx_context *nvfx); -extern void nv40_state_emit(struct nvfx_context *nvfx); -extern void nv40_state_flush_notify(struct nouveau_channel *chan); extern struct nvfx_state_entry nv40_state_rasterizer; extern struct nvfx_state_entry nv40_state_scissor; extern struct nvfx_state_entry nv40_state_stipple; diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index cce1c64621d..87d2689d54b 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -98,7 +98,7 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, assert(0); } FIRE_RING(chan); - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); } /* Switch primitive modes if necessary */ @@ -245,10 +245,10 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, unsigned i; void *map; - if (!nv40_state_validate_swtnl(nvfx)) + if (!nvfx_state_validate_swtnl(nvfx)) return; nvfx->state.dirty &= ~(1ULL << NVFX_STATE_VTXBUF); - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); for (i = 0; i < nvfx->vtxbuf_nr; i++) { map = pipe_buffer_map(pscreen, nvfx->vtxbuf[i].buffer, diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 0738d5c93b4..456b508d438 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -176,7 +176,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned restart; nv40_vbo_set_idxbuf(nvfx, NULL, 0); - if (FORCE_SWTNL || !nv40_state_validate(nvfx)) { + if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) { nv40_draw_elements_swtnl(pipe, NULL, 0, mode, start, count); return; @@ -185,7 +185,7 @@ nv40_draw_arrays(struct pipe_context *pipe, while (count) { unsigned vc, nr; - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); @@ -239,7 +239,7 @@ nv40_draw_elements_u08(struct nvfx_context *nvfx, void *ib, uint8_t *elts = (uint8_t *)ib + start; unsigned vc, push, restart; - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); @@ -290,7 +290,7 @@ nv40_draw_elements_u16(struct nvfx_context *nvfx, void *ib, uint16_t *elts = (uint16_t *)ib + start; unsigned vc, push, restart; - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); @@ -341,7 +341,7 @@ nv40_draw_elements_u32(struct nvfx_context *nvfx, void *ib, uint32_t *elts = (uint32_t *)ib + start; unsigned vc, push, restart; - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1, mode, start, count, &restart); @@ -417,7 +417,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, while (count) { unsigned nr, vc; - nv40_state_emit(nvfx); + nvfx_state_emit(nvfx); vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); @@ -466,7 +466,7 @@ nv40_draw_elements(struct pipe_context *pipe, boolean idxbuf; idxbuf = nv40_vbo_set_idxbuf(nvfx, indexBuffer, indexSize); - if (FORCE_SWTNL || !nv40_state_validate(nvfx)) { + if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) { nv40_draw_elements_swtnl(pipe, NULL, 0, mode, start, count); return; diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile index 699cbedbc84..0eb1bebeb30 100644 --- a/src/gallium/drivers/nvfx/Makefile +++ b/src/gallium/drivers/nvfx/Makefile @@ -5,6 +5,7 @@ LIBNAME = nvfx C_SOURCES = \ nvfx_clear.c \ + nvfx_state_emit.c \ nvfx_transfer.c include ../../Makefile.template diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 38d1142ff97..3d4bc6bbc93 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -185,6 +185,12 @@ struct nvfx_state_entry { extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil); +/* nvfx_state_emit.c */ +extern void nvfx_state_flush_notify(struct nouveau_channel *chan); +extern boolean nvfx_state_validate(struct nvfx_context *nvfx); +extern boolean nvfx_state_validate_swtnl(struct nvfx_context *nvfx); +extern void nvfx_state_emit(struct nvfx_context *nvfx); + /* nvfx_transfer.c */ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c similarity index 67% rename from src/gallium/drivers/nv40/nv40_state_emit.c rename to src/gallium/drivers/nvfx/nvfx_state_emit.c index 5c437f9969b..9582ba9648c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c @@ -1,43 +1,33 @@ -#include "nv40_context.h" +#include "nv30/nv30_context.h" +#include "nv40/nv40_context.h" #include "nvfx_state.h" #include "draw/draw_context.h" -static struct nvfx_state_entry *render_states[] = { - &nv40_state_framebuffer, - &nv40_state_rasterizer, - &nv40_state_scissor, - &nv40_state_stipple, - &nv40_state_fragprog, - &nv40_state_fragtex, - &nv40_state_vertprog, - &nv40_state_blend, - &nv40_state_blend_colour, - &nv40_state_zsa, - &nv40_state_sr, - &nv40_state_viewport, - &nv40_state_vbo, - NULL -}; - -static struct nvfx_state_entry *swtnl_states[] = { - &nv40_state_framebuffer, - &nv40_state_rasterizer, - &nv40_state_scissor, - &nv40_state_stipple, - &nv40_state_fragprog, - &nv40_state_fragtex, - &nv40_state_vertprog, - &nv40_state_blend, - &nv40_state_blend_colour, - &nv40_state_zsa, - &nv40_state_sr, - &nv40_state_viewport, - &nv40_state_vtxfmt, - NULL -}; +#define RENDER_STATES(name, nvxx, vbo) \ +static struct nvfx_state_entry *name##_render_states[] = { \ + &nvxx##_state_framebuffer, \ + &nvxx##_state_rasterizer, \ + &nvxx##_state_scissor, \ + &nvxx##_state_stipple, \ + &nvxx##_state_fragprog, \ + &nvxx##_state_fragtex, \ + &nvxx##_state_vertprog, \ + &nvxx##_state_blend, \ + &nvxx##_state_blend_colour, \ + &nvxx##_state_zsa, \ + &nvxx##_state_sr, \ + &nvxx##_state_viewport, \ + &nvxx##_state_##vbo, \ + NULL \ +} + +RENDER_STATES(nv30, nv30, vbo); +RENDER_STATES(nv30_swtnl, nv30, vbo); /* TODO: replace with vtxfmt once draw is unified */ +RENDER_STATES(nv40, nv40, vbo); +RENDER_STATES(nv40_swtnl, nv40, vtxfmt); static void -nv40_state_do_validate(struct nvfx_context *nvfx, +nvfx_state_do_validate(struct nvfx_context *nvfx, struct nvfx_state_entry **states) { while (*states) { @@ -54,7 +44,7 @@ nv40_state_do_validate(struct nvfx_context *nvfx, } void -nv40_state_emit(struct nvfx_context *nvfx) +nvfx_state_emit(struct nvfx_context *nvfx) { struct nvfx_state *state = &nvfx->state; struct nvfx_screen *screen = nvfx->screen; @@ -83,19 +73,21 @@ nv40_state_emit(struct nvfx_context *nvfx) states &= ~(1ULL << i); } - if (state->dirty & ((1ULL << NVFX_STATE_FRAGPROG) | - (1ULL << NVFX_STATE_FRAGTEX0))) { - BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (chan, 2); - BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (chan, 1); + /* TODO: could nv30 need this or something similar too? */ + if(nvfx->is_nv4x) { + if (state->dirty & ((1ULL << NVFX_STATE_FRAGPROG) | + (1ULL << NVFX_STATE_FRAGTEX0))) { + BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (chan, 2); + BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (chan, 1); + } } - state->dirty = 0; } void -nv40_state_flush_notify(struct nouveau_channel *chan) +nvfx_state_flush_notify(struct nouveau_channel *chan) { struct nvfx_context *nvfx = chan->user_private; struct nvfx_state *state = &nvfx->state; @@ -115,7 +107,7 @@ nv40_state_flush_notify(struct nouveau_channel *chan) } boolean -nv40_state_validate(struct nvfx_context *nvfx) +nvfx_state_validate(struct nvfx_context *nvfx) { boolean was_sw = nvfx->fallback_swtnl ? TRUE : FALSE; @@ -135,10 +127,14 @@ nv40_state_validate(struct nvfx_context *nvfx) nvfx->render_mode = HW; } - nv40_state_do_validate(nvfx, render_states); + if(!nvfx->is_nv4x) + nvfx_state_do_validate(nvfx, nv30_render_states); + else + nvfx_state_do_validate(nvfx, nv40_render_states); + if (nvfx->fallback_swtnl || nvfx->fallback_swrast) return FALSE; - + if (was_sw) NOUVEAU_ERR("swtnl->hw\n"); @@ -146,7 +142,7 @@ nv40_state_validate(struct nvfx_context *nvfx) } boolean -nv40_state_validate_swtnl(struct nvfx_context *nvfx) +nvfx_state_validate_swtnl(struct nvfx_context *nvfx) { struct draw_context *draw = nvfx->draw; @@ -177,7 +173,11 @@ nv40_state_validate_swtnl(struct nvfx_context *nvfx) draw_set_vertex_elements(draw, nvfx->vtxelt->num_elements, nvfx->vtxelt->pipe); } - nv40_state_do_validate(nvfx, swtnl_states); + if(!nvfx->is_nv4x) + nvfx_state_do_validate(nvfx, nv30_swtnl_render_states); + else + nvfx_state_do_validate(nvfx, nv40_swtnl_render_states); + if (nvfx->fallback_swrast) { NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nvfx->fallback_swrast); return FALSE; @@ -186,4 +186,3 @@ nv40_state_validate_swtnl(struct nvfx_context *nvfx) nvfx->draw_dirty = 0; return TRUE; } - -- 2.30.2