diff options
-rw-r--r-- | src/gallium/drivers/nv30/nv30_context.h | 11 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_fragprog.c | 65 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_fragtex.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_state.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_state.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_state_emit.c | 14 |
6 files changed, 56 insertions, 48 deletions
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 5d7080a555d..0c900c5598f 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -125,6 +125,7 @@ struct nv30_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct nv30_vertex_program *vertprog; + struct nv30_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nv30_rasterizer_state *rasterizer; @@ -151,11 +152,6 @@ struct nv30_context { unsigned delta; } vb[16]; - struct { - struct nv30_fragment_program *active; - struct nv30_fragment_program *current; - } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; }; @@ -188,10 +184,6 @@ extern void nv30_vertprog_destroy(struct nv30_context *, struct nv30_vertex_program *); /* nv30_fragprog.c */ -extern void nv30_fragprog_translate(struct nv30_context *, - struct nv30_fragment_program *); -extern void nv30_fragprog_bind(struct nv30_context *, - struct nv30_fragment_program *); extern void nv30_fragprog_destroy(struct nv30_context *, struct nv30_fragment_program *); @@ -205,6 +197,7 @@ extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_stipple; +extern struct nv30_state_entry nv30_state_fragprog; extern struct nv30_state_entry nv30_state_vertprog; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index b560455a02f..06ed04cbfeb 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -723,7 +723,7 @@ out_err: return FALSE; } -void +static void nv30_fragprog_translate(struct nv30_context *nv30, struct nv30_fragment_program *fp) { @@ -817,23 +817,46 @@ nv30_fragprog_upload(struct nv30_context *nv30, ws->buffer_unmap(ws, fp->buffer); } -void -nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) +static boolean +nv30_fragprog_validate(struct nv30_context *nv30) { + struct nv30_fragment_program *fp = nv30->fragprog; struct pipe_buffer *constbuf = nv30->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv30->pipe.winsys; + struct nouveau_stateobj *so; + boolean new_consts = FALSE; int i; + if (fp->translated) + goto update_constants; + + /*nv30->fallback_swrast &= ~NV30_NEW_FRAGPROG;*/ + nv30_fragprog_translate(nv30, fp); if (!fp->translated) { - nv30_fragprog_translate(nv30, fp); - if (!fp->translated) - assert(0); + /*nv30->fallback_swrast |= NV30_NEW_FRAGPROG;*/ + return FALSE; } + fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); + nv30_fragprog_upload(nv30, fp); + + so = so_new(4, 1); + so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); + so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + NV34TCL_FP_ACTIVE_PROGRAM_DMA0, NV34TCL_FP_ACTIVE_PROGRAM_DMA1); + so_method(so, nv30->screen->rankine, NV34TCL_FP_CONTROL, 1); + so_data (so, fp->fp_control); + /* FIXME: Add these, and you'll have big slowdown */ + /*so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1); + so_data (so, fp->fp_control);*/ + so_ref(so, &fp->so); + +update_constants: if (fp->nr_consts) { float *map; - + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); for (i = 0; i < fp->nr_consts; i++) { struct nv30_fragment_program_data *fpd = &fp->consts[i]; @@ -843,25 +866,20 @@ nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) if (!memcmp(p, cb, 4 * sizeof(float))) continue; memcpy(p, cb, 4 * sizeof(float)); - fp->on_hw = 0; + new_consts = TRUE; } ws->buffer_unmap(ws, constbuf); - } - if (!fp->on_hw) { - if (!fp->buffer) - fp->buffer = ws->buffer_create(ws, 0x100, 0, - fp->insn_len * 4); - nv30_fragprog_upload(nv30, fp); - fp->on_hw = TRUE; + if (new_consts) + nv30_fragprog_upload(nv30, fp); } - BEGIN_RING(rankine, NV34TCL_FP_CONTROL, 1); - OUT_RING (fp->fp_control); - BEGIN_RING(rankine, NV34TCL_FP_REG_CONTROL, 1); - OUT_RING (fp->fp_reg_control); + if (new_consts || fp->so != nv30->state.hw[NV30_STATE_FRAGPROG]) { + so_ref(fp->so, &nv30->state.hw[NV30_STATE_FRAGPROG]); + return TRUE; + } - nv30->fragprog.active = fp; + return FALSE; } void @@ -872,3 +890,10 @@ nv30_fragprog_destroy(struct nv30_context *nv30, FREE(fp->insn); } +struct nv30_state_entry nv30_state_fragprog = { + .validate = nv30_fragprog_validate, + .dirty = { + .pipe = NV30_NEW_FRAGPROG, + .hw = NV30_STATE_FRAGPROG + } +}; diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index abe77b51df2..8c5e88ea1da 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -143,7 +143,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) static boolean nv30_fragtex_validate(struct nv30_context *nv30) { - struct nv30_fragment_program *fp = nv30->fragprog.current; + struct nv30_fragment_program *fp = nv30->fragprog; struct nv30_state *state = &nv30->state; struct nouveau_stateobj *so; unsigned samplers, unit; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 92695ce23c0..8dc16d361d8 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -539,6 +539,8 @@ nv30_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv30_fragment_program)); fp->pipe = *cso; + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + return (void *)fp; } @@ -546,13 +548,8 @@ static void nv30_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv30_context *nv30 = nv30_context(pipe); - struct nv30_fragment_program *fp = hwcso; - - if (!hwcso) { - return; - } - nv30->fragprog.current = fp; + nv30->fragprog = hwcso; nv30->dirty |= NV30_NEW_FRAGPROG; } diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index a897bc50687..20c51761607 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -2,6 +2,7 @@ #define __NV30_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv30_sampler_state { uint32_t fmt; @@ -50,6 +51,7 @@ struct nv30_fragment_program_data { struct nv30_fragment_program { struct pipe_shader_state pipe; + struct tgsi_shader_info info; boolean translated; boolean on_hw; @@ -65,6 +67,7 @@ struct nv30_fragment_program { uint32_t fp_control; uint32_t fp_reg_control; + struct nouveau_stateobj *so; }; struct nv30_miptree { diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 4ab62ddc016..c4ccc9422be 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -6,6 +6,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_rasterizer, &nv30_state_scissor, &nv30_state_stipple, + &nv30_state_fragprog, &nv30_state_fragtex, &nv30_state_vertprog, &nv30_state_blend, @@ -61,11 +62,6 @@ nv30_emit_hw_state(struct nv30_context *nv30) screen->cur_pctx = nv30->pctx_id; } - if (nv30->dirty & NV30_NEW_FRAGPROG) { - nv30_fragprog_bind(nv30, nv30->fragprog.current); - /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */ - } - for (i = 0, states = state->dirty; states; i++) { if (!(states & (1ULL << i))) continue; @@ -83,13 +79,7 @@ nv30_emit_hw_state(struct nv30_context *nv30) state->hw[NV30_STATE_FRAGTEX0+i]); samplers &= ~(1ULL << i); } - - /* Fragment program */ - BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); - OUT_RELOC (nv30->fragprog.active->buffer, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | - NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0, - NV34TCL_FP_ACTIVE_PROGRAM_DMA1); + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FRAGPROG]); } boolean |