nvfx: so->RING_3D: fragprog
authorLuca Barbieri <luca@luca-barbieri.com>
Sun, 14 Mar 2010 19:51:42 +0000 (20:51 +0100)
committerLuca Barbieri <luca@luca-barbieri.com>
Mon, 12 Apr 2010 10:13:16 +0000 (12:13 +0200)
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_fragprog.c
src/gallium/drivers/nvfx/nvfx_state.h
src/gallium/drivers/nvfx/nvfx_state_emit.c

index 7f6e5500e54a4b7e88c531f1ef17822e140de236..46b5db0364897e9e59de89992744dcf105a8c4ad 100644 (file)
@@ -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
index c600f284446962c14ba8ad4f3c074acc67ca2015..1b831379807608e81a426b82a07ffccf2b7e4196 100644 (file)
@@ -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
        }
 };
index 8f5b33fcffb951f3ea2a400cd74d425d6589baf0..f1f9fb775b80bf1a926798045d20b651d78f27b6 100644 (file)
@@ -65,7 +65,6 @@ struct nvfx_fragment_program {
        struct pipe_resource *buffer;
 
        uint32_t fp_control;
-       struct nouveau_stateobj *so;
 };
 
 
index 8adf59d8e3da25bf68f7ff8a76c1124a63f476a8..0709c563505fbb102d8b976328231d76fcb1b5e3 100644 (file)
@@ -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);
 }