gallium: simplify tgsi_full_immediate struct
[mesa.git] / src / gallium / drivers / nv30 / nv30_fragprog.c
index 6af86e4f4f9b3dd3125a8a4b1c421e9d4bbb40f2..a48ba9782b329e47e32431f5fb48379ed36ef1c3 100644 (file)
@@ -1,10 +1,11 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
 
 #include "pipe/p_shader_tokens.h"
-#include "tgsi/util/tgsi_parse.h"
-#include "tgsi/util/tgsi_util.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_util.h"
 
 #include "nv30_context.h"
 
@@ -494,10 +495,10 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
        case TGSI_OPCODE_FRC:
                arith(fpc, sat, FRC, dst, mask, src[0], none, none);
                break;
-       case TGSI_OPCODE_KIL:
+       case TGSI_OPCODE_KILP:
                arith(fpc, 0, KIL, none, 0, none, none, none);
                break;
-       case TGSI_OPCODE_KILP:
+       case TGSI_OPCODE_KIL:
                dst = nv30_sr(NV30SR_NONE, 0);
                dst.cc_update = 1;
                arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none);
@@ -526,6 +527,12 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
        case TGSI_OPCODE_MUL:
                arith(fpc, sat, MUL, dst, mask, src[0], src[1], none);
                break;
+       case TGSI_OPCODE_NOISE1:
+       case TGSI_OPCODE_NOISE2:
+       case TGSI_OPCODE_NOISE3:
+       case TGSI_OPCODE_NOISE4:
+               arith(fpc, sat, SFL, dst, mask, none, none, none);
+               break;
        case TGSI_OPCODE_POW:
                arith(fpc, sat, POW, dst, mask, src[0], src[1], none);
                break;
@@ -557,6 +564,9 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
        case TGSI_OPCODE_SGE:
                arith(fpc, sat, SGE, dst, mask, src[0], src[1], none);
                break;
+       case TGSI_OPCODE_SGT:
+               arith(fpc, sat, SGT, dst, mask, src[0], src[1], none);
+               break;
        case TGSI_OPCODE_SLT:
                arith(fpc, sat, SLT, dst, mask, src[0], src[1], none);
                break;
@@ -694,10 +704,10 @@ nv30_fragprog_prepare(struct nv30_fpc *fpc)
                        assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
                        assert(fpc->nr_imm < MAX_IMM);
 
-                       vals[0] = imm->u.ImmediateFloat32[0].Float;
-                       vals[1] = imm->u.ImmediateFloat32[1].Float;
-                       vals[2] = imm->u.ImmediateFloat32[2].Float;
-                       vals[3] = imm->u.ImmediateFloat32[3].Float;
+                       vals[0] = imm->u[0].Float;
+                       vals[1] = imm->u[1].Float;
+                       vals[2] = imm->u[2].Float;
+                       vals[3] = imm->u[3].Float;
                        fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals);
                }
                        break;
@@ -723,13 +733,15 @@ out_err:
        return FALSE;
 }
 
-void
+static void
 nv30_fragprog_translate(struct nv30_context *nv30,
                        struct nv30_fragment_program *fp)
 {
        struct tgsi_parse_context parse;
        struct nv30_fpc *fpc = NULL;
 
+       tgsi_dump(fp->pipe.tokens,0);
+
        fpc = CALLOC(1, sizeof(struct nv30_fpc));
        if (!fpc)
                return;
@@ -787,12 +799,12 @@ static void
 nv30_fragprog_upload(struct nv30_context *nv30,
                     struct nv30_fragment_program *fp)
 {
-       struct pipe_winsys *ws = nv30->pipe.winsys;
+       struct pipe_screen *pscreen = nv30->pipe.screen;
        const uint32_t le = 1;
        uint32_t *map;
        int i;
 
-       map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+       map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
 
 #if 0
        for (i = 0; i < fp->insn_len; i++) {
@@ -814,24 +826,54 @@ nv30_fragprog_upload(struct nv30_context *nv30,
                }
        }
 
-       ws->buffer_unmap(ws, fp->buffer);
+       pipe_buffer_unmap(pscreen, 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 pipe_winsys *ws = nv30->pipe.winsys;
+       struct nv30_fragment_program *fp = nv30->fragprog;
+       struct pipe_buffer *constbuf =
+               nv30->constbuf[PIPE_SHADER_FRAGMENT];
+       struct pipe_screen *pscreen = nv30->pipe.screen;
+       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 = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
+       nv30_fragprog_upload(nv30, fp);
+
+       so = so_new(8, 1);
+       so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
+       so_reloc (so, nouveau_bo(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);
+       so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1);
+       so_data  (so, fp->fp_reg_control);
+       so_method(so, nv30->screen->rankine, 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) {
-               float *map = ws->buffer_map(ws, nv30->fragprog.constant_buf,
-                                           PIPE_BUFFER_USAGE_CPU_READ);
+               float *map;
+               
+               map = pipe_buffer_map(pscreen, constbuf,
+                                     PIPE_BUFFER_USAGE_CPU_READ);
                for (i = 0; i < fp->nr_consts; i++) {
                        struct nv30_fragment_program_data *fpd = &fp->consts[i];
                        uint32_t *p = &fp->insn[fpd->offset];
@@ -840,28 +882,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, nv30->fragprog.constant_buf);
-       }
-
-       if (!fp->on_hw) {
-               const uint32_t le = 1;
-               uint32_t *map;
+               pipe_buffer_unmap(pscreen, constbuf);
 
-               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 +906,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
+       }
+};