nv30: Emit fragtex state using state objects
authorPatrice Mandin <pmandin@caramail.com>
Fri, 11 Jul 2008 20:42:42 +0000 (22:42 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Fri, 11 Jul 2008 20:42:42 +0000 (22:42 +0200)
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_fragtex.c
src/gallium/drivers/nv30/nv30_state_emit.c

index 5404685da258193b959460648f6e5cfcb449125d..72f803c80ad12c5b95b6ed8f3ed8ca788a4024bf 100644 (file)
@@ -220,6 +220,7 @@ extern struct nv30_state_entry nv30_state_blend_colour;
 extern struct nv30_state_entry nv30_state_zsa;
 extern struct nv30_state_entry nv30_state_viewport;
 extern struct nv30_state_entry nv30_state_framebuffer;
+extern struct nv30_state_entry nv30_state_fragtex;
 
 /* nv30_vbo.c */
 extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode,
index f253087c884989b82be3aaf08a830359ed4a8c7c..abe77b51df258f3fb3ff6b9848fc4cd077c09c32 100644 (file)
@@ -49,17 +49,17 @@ nv30_texture_formats[] = {
        _(A8R8G8B8_UNORM, A8R8G8B8,   S1,   S1,   S1,   S1, X, Y, Z, W),
        _(A1R5G5B5_UNORM, A1R5G5B5,   S1,   S1,   S1,   S1, X, Y, Z, W),
        _(A4R4G4B4_UNORM, A4R4G4B4,   S1,   S1,   S1,   S1, X, Y, Z, W),
-//     _(R5G6B5_UNORM  , R5G6B5  ,   S1,   S1,   S1,  ONE, X, Y, Z, W),
+       _(R5G6B5_UNORM  , R5G6B5  ,   S1,   S1,   S1,  ONE, X, Y, Z, W),
        _(L8_UNORM      , L8      ,   S1,   S1,   S1,  ONE, X, X, X, X),
        _(A8_UNORM      , L8      , ZERO, ZERO, ZERO,   S1, X, X, X, X),
        _(I8_UNORM      , L8      ,   S1,   S1,   S1,   S1, X, X, X, X),
        _(A8L8_UNORM    , A8L8    ,   S1,   S1,   S1,   S1, X, X, X, Y),
 //     _(Z16_UNORM     , Z16     ,   S1,   S1,   S1,  ONE, X, X, X, X),
 //     _(Z24S8_UNORM   , Z24     ,   S1,   S1,   S1,  ONE, X, X, X, X),
-//     _(RGB_DXT1      , 0x86,   S1,   S1,   S1,  ONE, X, Y, Z, W, 0x00, 0x00),
-//     _(RGBA_DXT1     , 0x86,   S1,   S1,   S1,   S1, X, Y, Z, W, 0x00, 0x00),
-//     _(RGBA_DXT3     , 0x87,   S1,   S1,   S1,   S1, X, Y, Z, W, 0x00, 0x00),
-//     _(RGBA_DXT5     , 0x88,   S1,   S1,   S1,   S1, X, Y, Z, W, 0x00, 0x00),
+       _(DXT1_RGB      , DXT1    ,   S1,   S1,   S1,  ONE, X, Y, Z, W),
+       _(DXT1_RGBA     , DXT1    ,   S1,   S1,   S1,   S1, X, Y, Z, W),
+       _(DXT3_RGBA     , DXT3    ,   S1,   S1,   S1,   S1, X, Y, Z, W),
+       _(DXT5_RGBA     , DXT5    ,   S1,   S1,   S1,   S1, X, Y, Z, W),
        {},
 };
 
@@ -67,6 +67,7 @@ static struct nv30_texture_format *
 nv30_fragtex_format(uint pipe_format)
 {
        struct nv30_texture_format *tf = nv30_texture_formats;
+       char fs[128];
 
        while (tf->defined) {
                if (tf->pipe == pipe_format)
@@ -74,26 +75,27 @@ nv30_fragtex_format(uint pipe_format)
                tf++;
        }
 
+       pf_sprint_name(fs, pipe_format);
+       NOUVEAU_ERR("unknown texture format %s\n", fs);
        return NULL;
 }
 
 
-static void
+static struct nouveau_stateobj *
 nv30_fragtex_build(struct nv30_context *nv30, int unit)
 {
        struct nv30_sampler_state *ps = nv30->tex_sampler[unit];
        struct nv30_miptree *nv30mt = nv30->tex_miptree[unit];
        struct pipe_texture *pt = &nv30mt->base;
        struct nv30_texture_format *tf;
-       uint32_t txf, txs, txp;
-       int swizzled = 0; /*XXX: implement in region code? */
+       struct nouveau_stateobj *so;
+       uint32_t txf, txs /*, txp*/;
+       /*int swizzled = 0;*/ /*XXX: implement in region code? */
        unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 
        tf = nv30_fragtex_format(pt->format);
-       if (!tf || !tf->defined) {
-               NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format);
-               return;
-       }
+       if (!tf)
+               assert(0);
 
        txf  = tf->format << 8;
        txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
@@ -117,35 +119,45 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
                break;
        default:
                NOUVEAU_ERR("Unknown target %d\n", pt->target);
-               return;
+               return NULL;
        }
 
        txs = tf->swizzle;
 
-       BEGIN_RING(rankine, NV34TCL_TX_OFFSET(unit), 8);
-       OUT_RELOCl(nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW);
-       OUT_RELOCd(nv30mt->buffer,txf, tex_flags | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
-       OUT_RING  (ps->wrap);
-       OUT_RING  (NV34TCL_TX_ENABLE_ENABLE | ps->en);
-       OUT_RING  (txs);
-       OUT_RING  (ps->filt | 0x2000 /* magic */);
-       OUT_RING  ((pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height[0]);
-       OUT_RING  (ps->bcol);
+       so = so_new(16, 2);
+       so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8);
+       so_reloc (so, nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
+       so_reloc (so, nv30mt->buffer, txf, tex_flags | NOUVEAU_BO_OR,
+                 NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
+       so_data  (so, ps->wrap);
+       so_data  (so, NV34TCL_TX_ENABLE_ENABLE | ps->en);
+       so_data  (so, txs);
+       so_data  (so, ps->filt | 0x2000 /*voodoo*/);
+       so_data  (so, (pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
+                      pt->height[0]);
+       so_data  (so, ps->bcol);
+
+       return so;
 }
 
-void
-nv30_fragtex_bind(struct nv30_context *nv30)
+static boolean
+nv30_fragtex_validate(struct nv30_context *nv30)
 {
-       struct nv30_fragment_program *fp = nv30->fragprog.active;
+       struct nv30_fragment_program *fp = nv30->fragprog.current;
+       struct nv30_state *state = &nv30->state;
+       struct nouveau_stateobj *so;
        unsigned samplers, unit;
 
-       samplers = nv30->fp_samplers & ~fp->samplers;
+       samplers = state->fp_samplers & ~fp->samplers;
        while (samplers) {
                unit = ffs(samplers) - 1;
                samplers &= ~(1 << unit);
 
-               BEGIN_RING(rankine, NV34TCL_TX_ENABLE(unit), 1);
-               OUT_RING  (0);
+               so = so_new(2, 0);
+               so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1);
+               so_data  (so, 0);
+               so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
+               state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
        }
 
        samplers = nv30->dirty_samplers & fp->samplers;
@@ -153,9 +165,19 @@ nv30_fragtex_bind(struct nv30_context *nv30)
                unit = ffs(samplers) - 1;
                samplers &= ~(1 << unit);
 
-               nv30_fragtex_build(nv30, unit);
+               so = nv30_fragtex_build(nv30, unit);
+               so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
+               state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
        }
 
-       nv30->fp_samplers = fp->samplers;
+       nv30->state.fp_samplers = fp->samplers;
+       return FALSE;
 }
 
+struct nv30_state_entry nv30_state_fragtex = {
+       .validate = nv30_fragtex_validate,
+       .dirty = {
+               .pipe = NV30_NEW_SAMPLER | NV30_NEW_FRAGPROG,
+               .hw = 0
+       }
+};
index 0ea7857197252ab55f2479264b3c6730973ae67e..cf10ddd4b637f876dcc3ce6f19da9d012aba87a4 100644 (file)
@@ -6,6 +6,7 @@ static struct nv30_state_entry *render_states[] = {
        &nv30_state_rasterizer,
        &nv30_state_scissor,
        &nv30_state_stipple,
+       &nv30_state_fragtex,
        &nv30_state_blend,
        &nv30_state_blend_colour,
        &nv30_state_zsa,
@@ -59,6 +60,11 @@ 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;
@@ -68,28 +74,11 @@ nv30_emit_hw_state(struct nv30_context *nv30)
                states &= ~(1ULL << i);
        }
 
-       if (nv30->dirty & NV30_NEW_FRAGPROG) {
-               nv30_fragprog_bind(nv30, nv30->fragprog.current);
-               /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */
-       }
-
-       if (nv30->dirty_samplers || (nv30->dirty & NV30_NEW_FRAGPROG)) {
-               nv30_fragtex_bind(nv30);
-/*
-               BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1);
-               OUT_RING  (2);
-               BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1);
-               OUT_RING  (1);*/
-               nv30->dirty &= ~NV30_NEW_FRAGPROG;
-       }
-
        if (nv30->dirty & NV30_NEW_VERTPROG) {
                nv30_vertprog_bind(nv30, nv30->vertprog.current);
                nv30->dirty &= ~NV30_NEW_VERTPROG;
        }
 
-       nv30->dirty_samplers = 0;
-
        so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
        for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
                if (!(samplers & (1 << i)))
@@ -99,21 +88,6 @@ nv30_emit_hw_state(struct nv30_context *nv30)
                samplers &= ~(1ULL << i);
        }
 
-       /* Texture images, emitted in nv30_fragtex_build */
-#if 0
-       for (i = 0; i < 16; i++) {
-               if (!(nv30->fp_samplers & (1 << i)))
-                       continue;
-               BEGIN_RING(rankine, NV34TCL_TX_OFFSET(i), 2);
-               OUT_RELOCl(nv30->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
-                          NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-               OUT_RELOCd(nv30->tex[i].buffer, nv30->tex[i].format,
-                          NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
-                          NOUVEAU_BO_OR, NV34TCL_TX_FORMAT_DMA0,
-                          NV34TCL_TX_FORMAT_DMA1);
-       }
-#endif
-
        /* Fragment program */
        BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
        OUT_RELOC (nv30->fragprog.active->buffer, 0, NOUVEAU_BO_VRAM |