nvfx: new 2D: optimize fragtex format lookup
[mesa.git] / src / gallium / drivers / nvfx / nv40_fragtex.c
index 05506e2809916d1335125beb038c256f6afbc818..87aa7eb1a2015c8d385d80eedff62518c8df5520 100644 (file)
@@ -1,6 +1,7 @@
 #include "util/u_format.h"
 #include "nvfx_context.h"
 #include "nvfx_tex.h"
+#include "nvfx_resource.h"
 
 void
 nv40_sampler_state_init(struct pipe_context *pipe,
@@ -48,9 +49,7 @@ nv40_sampler_state_init(struct pipe_context *pipe,
 }
 
 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw)            \
-{                                                                              \
-  TRUE,                                                                        \
-  PIPE_FORMAT_##m,                                                             \
+[PIPE_FORMAT_##m] = {                                                                              \
   NV40TCL_TEX_FORMAT_FORMAT_##tf,                                              \
   (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y |         \
    NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w |         \
@@ -61,15 +60,14 @@ nv40_sampler_state_init(struct pipe_context *pipe,
 }
 
 struct nv40_texture_format {
-       boolean defined;
-       uint    pipe;
        int     format;
        int     swizzle;
        int     sign;
 };
 
 static struct nv40_texture_format
-nv40_texture_formats[] = {
+nv40_texture_formats[PIPE_FORMAT_COUNT] = {
+       [0 ... PIPE_FORMAT_COUNT - 1] = {-1, 0, 0},
        _(B8G8R8X8_UNORM, A8R8G8B8,   S1,   S1,   S1,  ONE, X, Y, Z, W, 0, 0, 0, 0),
        _(B8G8R8A8_UNORM, A8R8G8B8,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
        _(B5G5R5A1_UNORM, A1R5G5B5,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
@@ -81,7 +79,7 @@ nv40_texture_formats[] = {
        _(I8_UNORM      , L8      ,   S1,   S1,   S1,   S1, X, X, X, X, 0, 0, 0, 0),
        _(L8A8_UNORM    , A8L8    ,   S1,   S1,   S1,   S1, X, X, X, Y, 0, 0, 0, 0),
        _(Z16_UNORM     , Z16     ,   S1,   S1,   S1,  ONE, X, X, X, X, 0, 0, 0, 0),
-       _(S8Z24_UNORM   , Z24     ,   S1,   S1,   S1,  ONE, X, X, X, X, 0, 0, 0, 0),
+       _(S8_USCALED_Z24_UNORM   , Z24     ,   S1,   S1,   S1,  ONE, X, X, X, X, 0, 0, 0, 0),
        _(DXT1_RGB      , DXT1    ,   S1,   S1,   S1,  ONE, X, Y, Z, W, 0, 0, 0, 0),
        _(DXT1_RGBA     , DXT1    ,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
        _(DXT3_RGBA     , DXT3    ,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
@@ -89,37 +87,21 @@ nv40_texture_formats[] = {
        {},
 };
 
-static struct nv40_texture_format *
-nv40_fragtex_format(uint pipe_format)
-{
-       struct nv40_texture_format *tf = nv40_texture_formats;
-
-       while (tf->defined) {
-               if (tf->pipe == pipe_format)
-                       return tf;
-               tf++;
-       }
-
-       NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format));
-       return NULL;
-}
-
-
-struct nouveau_stateobj *
-nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
+void
+nv40_fragtex_set(struct nvfx_context *nvfx, int unit)
 {
+       struct nouveau_channel* chan = nvfx->screen->base.channel;
        struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
-       struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
-       struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
-       struct pipe_texture *pt = &nv40mt->base;
+       struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
+       struct nouveau_bo *bo = mt->base.bo;
+       struct pipe_resource *pt = &mt->base.base;
        struct nv40_texture_format *tf;
-       struct nouveau_stateobj *so;
+
        uint32_t txf, txs, txp;
        unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 
-       tf = nv40_fragtex_format(pt->format);
-       if (!tf)
-               assert(0);
+       tf = &nv40_texture_formats[pt->format];
+       assert(tf->format >= 0);
 
        txf  = ps->fmt;
        txf |= tf->format | 0x8000;
@@ -133,6 +115,7 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
                txf |= NV34TCL_TX_FORMAT_CUBIC;
                /* fall-through */
        case PIPE_TEXTURE_2D:
+       case PIPE_TEXTURE_RECT:
                txf |= NV34TCL_TX_FORMAT_DIMS_2D;
                break;
        case PIPE_TEXTURE_3D:
@@ -143,32 +126,32 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
                break;
        default:
                NOUVEAU_ERR("Unknown target %d\n", pt->target);
-               return NULL;
+               return;
        }
 
-       if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
+       if (!mt->linear_pitch)
                txp = 0;
-       else {
-               txp  = nv40mt->level[0].pitch;
+       else {
+               txp  = mt->linear_pitch;
                txf |= NV40TCL_TEX_FORMAT_LINEAR;
        }
 
        txs = tf->swizzle;
 
-       so = so_new(2, 9, 2);
-       so_method(so, nvfx->screen->eng3d, NV34TCL_TX_OFFSET(unit), 8);
-       so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
-       so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
-                     NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
-       so_data  (so, ps->wrap);
-       so_data  (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
-       so_data  (so, txs);
-       so_data  (so, ps->filt | tf->sign | 0x2000 /*voodoo*/);
-       so_data  (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
-                      pt->height0);
-       so_data  (so, ps->bcol);
-       so_method(so, nvfx->screen->eng3d, NV40TCL_TEX_SIZE1(unit), 1);
-       so_data  (so, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
-
-       return so;
+       MARK_RING(chan, 11 + 2 * !unit, 2);
+       OUT_RING(chan, RING_3D(NV34TCL_TX_OFFSET(unit), 8));
+       OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
+       OUT_RELOC(chan, bo, txf, tex_flags | NOUVEAU_BO_OR,
+                       NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
+       OUT_RING(chan, ps->wrap);
+       OUT_RING(chan, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
+       OUT_RING(chan, txs);
+       OUT_RING(chan, ps->filt | tf->sign | 0x2000 /*voodoo*/);
+       OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height0);
+       OUT_RING(chan, ps->bcol);
+       OUT_RING(chan, RING_3D(NV40TCL_TEX_SIZE1(unit), 1));
+       OUT_RING(chan, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
+
+       nvfx->hw_txf[unit] = txf;
+       nvfx->hw_samplers |= (1 << unit);
 }