summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c78
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_emit.c2
4 files changed, 49 insertions, 34 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 7f6e5500e54..46b5db03648 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -221,6 +221,8 @@ extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,
/* nvfx_fragprog.c */
extern void nvfx_fragprog_destroy(struct nvfx_context *,
struct nvfx_fragment_program *);
+extern void
+nvfx_fragprog_relocate(struct nvfx_context *nvfx);
/* nvfx_fragtex.c */
extern void
diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index c600f284446..1b831379807 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -864,15 +864,14 @@ nvfx_fragprog_upload(struct nvfx_context *nvfx,
}
}
-static boolean
+boolean
nvfx_fragprog_validate(struct nvfx_context *nvfx)
{
- struct pipe_context *pipe = &nvfx->pipe;
+ struct nouveau_channel* chan = nvfx->screen->base.channel;
struct nvfx_fragment_program *fp = nvfx->fragprog;
struct pipe_resource *constbuf =
nvfx->constbuf[PIPE_SHADER_FRAGMENT];
struct pipe_screen *pscreen = nvfx->pipe.screen;
- struct nouveau_stateobj *so;
boolean new_consts = FALSE;
int i;
@@ -882,7 +881,19 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
nvfx->fallback_swrast &= ~NVFX_NEW_FRAGPROG;
nvfx_fragprog_translate(nvfx, fp);
if (!fp->translated) {
- nvfx->fallback_swrast |= NVFX_NEW_FRAGPROG;
+ static unsigned dummy[8] = {1, 0, 0, 0, 1, 0, 0, 0};
+ static int warned = 0;
+ if(!warned)
+ {
+ fprintf(stderr, "nvfx: failed to translate fragment program!\n");
+ warned = 1;
+ }
+
+ /* use a dummy program: we cannot fail here */
+ fp->translated = TRUE;
+ fp->insn = malloc(sizeof(dummy));
+ memcpy(fp->insn, dummy, sizeof(dummy));
+ fp->insn_len = sizeof(dummy) / sizeof(dummy[0]);
return FALSE;
}
@@ -893,30 +904,12 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
0, fp->insn_len * 4);
nvfx_fragprog_upload(nvfx, fp);
- so = so_new(4, 4, 1);
- so_method(so, nvfx->screen->eng3d, NV34TCL_FP_ACTIVE_PROGRAM, 1);
- so_reloc (so, nvfx_resource(fp->buffer)->bo, 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, nvfx->screen->eng3d, NV34TCL_FP_CONTROL, 1);
- so_data (so, fp->fp_control);
- if(!nvfx->is_nv4x) {
- so_method(so, nvfx->screen->eng3d, NV34TCL_FP_REG_CONTROL, 1);
- so_data (so, (1<<16)|0x4);
- so_method(so, nvfx->screen->eng3d, NV34TCL_TX_UNITS_ENABLE, 1);
- so_data (so, fp->samplers);
- }
-
- so_ref(so, &fp->so);
- so_ref(NULL, &so);
-
update_constants:
if (fp->nr_consts) {
struct pipe_transfer *transfer;
float *map;
- map = pipe_buffer_map(pipe, constbuf,
+ map = pipe_buffer_map(&nvfx->pipe, constbuf,
PIPE_TRANSFER_READ,
&transfer);
@@ -935,18 +928,42 @@ update_constants:
memcpy(p, cb, 4 * sizeof(float));
new_consts = TRUE;
}
- pipe_buffer_unmap(pipe, constbuf, transfer);
+ pipe_buffer_unmap(&nvfx->pipe, constbuf, transfer);
if (new_consts)
nvfx_fragprog_upload(nvfx, fp);
}
- if (new_consts || fp->so != nvfx->state.hw[NVFX_STATE_FRAGPROG]) {
- so_ref(fp->so, &nvfx->state.hw[NVFX_STATE_FRAGPROG]);
- return TRUE;
+ MARK_RING(chan, 8, 1);
+ OUT_RING(chan, RING_3D(NV34TCL_FP_ACTIVE_PROGRAM, 1));
+ OUT_RELOC(chan, nvfx_resource(fp->buffer)->bo, 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);
+ OUT_RING(chan, RING_3D(NV34TCL_FP_CONTROL, 1));
+ OUT_RING(chan, fp->fp_control);
+ if(!nvfx->is_nv4x) {
+ OUT_RING(chan, RING_3D(NV34TCL_FP_REG_CONTROL, 1));
+ OUT_RING(chan, (1<<16)|0x4);
+ OUT_RING(chan, RING_3D(NV34TCL_TX_UNITS_ENABLE, 1));
+ OUT_RING(chan, fp->samplers);
}
+ return TRUE;
+}
- return FALSE;
+void
+nvfx_fragprog_relocate(struct nvfx_context *nvfx)
+{
+ struct nouveau_channel* chan = nvfx->screen->base.channel;
+ struct nvfx_fragment_program *fp = nvfx->fragprog;
+ struct nouveau_bo* bo = nvfx_resource(fp->buffer)->bo;
+ unsigned fp_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; // TODO: GART?
+ fp_flags |= NOUVEAU_BO_DUMMY;
+ MARK_RING(chan, 2, 2);
+ OUT_RELOC(chan, bo, RING_3D(NV34TCL_FP_ACTIVE_PROGRAM, 1), fp_flags, 0, 0);
+ OUT_RELOC(chan, bo, 0, fp_flags | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
+ NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
}
void
@@ -956,9 +973,6 @@ nvfx_fragprog_destroy(struct nvfx_context *nvfx,
if (fp->buffer)
pipe_resource_reference(&fp->buffer, NULL);
- if (fp->so)
- so_ref(NULL, &fp->so);
-
if (fp->insn_len)
FREE(fp->insn);
}
@@ -967,6 +981,6 @@ struct nvfx_state_entry nvfx_state_fragprog = {
.validate = nvfx_fragprog_validate,
.dirty = {
.pipe = NVFX_NEW_FRAGPROG,
- .hw = NVFX_STATE_FRAGPROG
+ .hw = 0
}
};
diff --git a/src/gallium/drivers/nvfx/nvfx_state.h b/src/gallium/drivers/nvfx/nvfx_state.h
index 8f5b33fcffb..f1f9fb775b8 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.h
+++ b/src/gallium/drivers/nvfx/nvfx_state.h
@@ -65,7 +65,6 @@ struct nvfx_fragment_program {
struct pipe_resource *buffer;
uint32_t fp_control;
- struct nouveau_stateobj *so;
};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 8adf59d8e3d..0709c563505 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -102,7 +102,7 @@ nvfx_state_relocate(struct nvfx_context *nvfx)
struct nvfx_state *state = &nvfx->state;
so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FB]);
nvfx_fragtex_relocate(nvfx);
- so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FRAGPROG]);
+ nvfx_fragprog_relocate(nvfx);
if (nvfx->render_mode == HW)
nvfx_vbo_relocate(nvfx);
}