summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrice Mandin <[email protected]>2008-07-12 00:48:26 +0200
committerPatrice Mandin <[email protected]>2008-07-12 00:48:26 +0200
commit58737dc87575625438d288fe2f816b6a9d2086f1 (patch)
treee4b89db836a2712be232dac764e9e4a0b1f50b0f
parent2419a5fe3601851989506a11b0bd4e3cfb071035 (diff)
nv30: Emit fragment program using state objects
-rw-r--r--src/gallium/drivers/nv30/nv30_context.h11
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c65
-rw-r--r--src/gallium/drivers/nv30/nv30_fragtex.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c9
-rw-r--r--src/gallium/drivers/nv30/nv30_state.h3
-rw-r--r--src/gallium/drivers/nv30/nv30_state_emit.c14
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