nvfx: refactor sampling code, add support for swizzles and depth tex
authorLuca Barbieri <luca@luca-barbieri.com>
Sat, 7 Aug 2010 01:47:25 +0000 (03:47 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Sat, 21 Aug 2010 18:42:14 +0000 (20:42 +0200)
This is a significant refactoring of the sampling code that:
- Moves all generic functions in nvfx_fragtex.c
- Adds a driver-specific sampler view structure and uses it to
  precompute texture setup as it should be done
- Unifies a bit more of code between nv30 and nv40
- Adds support for sampler view swizzles
- Support for specifying as sampler view format different from the
  resource one (only trivially)
- Support for sampler view specification of first and last level
- Support for depth textures on nv30, both for reading depth and
  for compare
- Support for sRGB textures
- Unifies the format table between nv30 and nv40
- Expands the format table to include essentially all supportable formats
  except mixed sign and "autonormal" formats
- Fixes the "is format supported" logic, which was quite broken, and
  makes it use the format table

Only tested on nv30 currently.

src/gallium/drivers/nouveau/nouveau_class.h
src/gallium/drivers/nvfx/nv30_fragtex.c
src/gallium/drivers/nvfx/nv40_fragtex.c
src/gallium/drivers/nvfx/nvfx_context.c
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_fragtex.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_state.c
src/gallium/drivers/nvfx/nvfx_tex.h

index adfdd37b1b64a6eaf2ea0cced614f52605079e67..685fa00b4556a04c60584e70d108a49afbfaa1da 100644 (file)
@@ -6328,6 +6328,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define    NV34TCL_TX_FORMAT_FORMAT_R8G8B8_RECT                                                0x00001e00
 #define    NV34TCL_TX_FORMAT_FORMAT_A8L8_RECT                                          0x00002000
 #define    NV34TCL_TX_FORMAT_FORMAT_DSDT8                                              0x00002800
+#define    NV34TCL_TX_FORMAT_FORMAT_Z24                                                        0x2a00
+#define    NV34TCL_TX_FORMAT_FORMAT_Z24_RECT                                           0x2b00 /* XXX: guess! */
+#define    NV34TCL_TX_FORMAT_FORMAT_Z16                                                        0x2c00
+#define    NV34TCL_TX_FORMAT_FORMAT_Z16_RECT                                           0x2d00 /* XXX: guess! */
 #define    NV34TCL_TX_FORMAT_FORMAT_HILO16                                             0x00003300
 #define    NV34TCL_TX_FORMAT_FORMAT_HILO16_RECT                                                0x00003600
 #define    NV34TCL_TX_FORMAT_FORMAT_HILO8                                              0x00004400
index fbc69cf44ace7d159959081ed1e5db6bf556023d..63c578a0ce1509b3a360a3fa32993cfe67a0ef6c 100644 (file)
@@ -10,88 +10,75 @@ nv30_sampler_state_init(struct pipe_context *pipe,
                          struct nvfx_sampler_state *ps,
                          const struct pipe_sampler_state *cso)
 {
-       if (cso->max_anisotropy >= 8) {
-               ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
-       } else
-       if (cso->max_anisotropy >= 4) {
-               ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
-       } else
-       if (cso->max_anisotropy >= 2) {
-               ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
-       }
+       float limit;
 
+       if (cso->max_anisotropy >= 2)
        {
-               float limit;
+               if (cso->max_anisotropy >= 8)
+                       ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
+               else if (cso->max_anisotropy >= 4)
+                       ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
+               else if (cso->max_anisotropy >= 2)
+                       ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
+       }
 
-               limit = CLAMP(cso->lod_bias, -16.0, 15.0);
-               ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
+       limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+       ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
 
-               limit = CLAMP(cso->max_lod, 0.0, 15.0);
-               ps->en |= (int)(limit) << 14 /*NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT*/;
+       ps->max_lod = (int)CLAMP(cso->max_lod, 0.0, 15.0);
+       ps->min_lod = (int)CLAMP(cso->min_lod, 0.0, 15.0);
 
-               limit = CLAMP(cso->min_lod, 0.0, 15.0);
-               ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/;
-       }
+       ps->en |= NV34TCL_TX_ENABLE_ENABLE;
 }
 
-#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w)                        \
-[PIPE_FORMAT_##m] = {                                                                              \
-  NV34TCL_TX_FORMAT_FORMAT_##tf,                                               \
-  NV34TCL_TX_FORMAT_FORMAT_##tf##_RECT,                                               \
-  (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y |           \
-   NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w |           \
-   NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y |           \
-   NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w)            \
-}
+void
+nv30_sampler_view_init(struct pipe_context *pipe,
+                         struct nvfx_sampler_view *sv)
+{
+       struct pipe_resource* pt = sv->base.texture;
+       struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
+       unsigned txf;
+       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
+
+       assert(tf->fmt[0] >= 0);
+
+       txf = sv->u.init_fmt;
+       txf |= (level != sv->base.last_level ? NV34TCL_TX_FORMAT_MIPMAP : 0);
+       txf |= log2i(u_minify(pt->width0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
+       txf |= log2i(u_minify(pt->height0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
+       txf |= log2i(u_minify(pt->depth0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
+       txf |=  0x10000;
+
+       sv->u.nv30.fmt[0] = tf->fmt[0] | txf;
+       sv->u.nv30.fmt[1] = tf->fmt[1] | txf;
+       sv->u.nv30.fmt[2] = tf->fmt[2] | txf;
+       sv->u.nv30.fmt[3] = tf->fmt[3] | txf;
 
-struct nv30_texture_format {
-       int     format;
-       int     rect_format;
-       int     swizzle;
-};
-
-#define NV34TCL_TX_FORMAT_FORMAT_DXT1_RECT NV34TCL_TX_FORMAT_FORMAT_DXT1
-#define NV34TCL_TX_FORMAT_FORMAT_DXT3_RECT NV34TCL_TX_FORMAT_FORMAT_DXT3
-#define NV34TCL_TX_FORMAT_FORMAT_DXT5_RECT NV34TCL_TX_FORMAT_FORMAT_DXT5
-
-static struct nv30_texture_format
-nv30_texture_formats[PIPE_FORMAT_COUNT] = {
-       [0 ... PIPE_FORMAT_COUNT - 1] = {-1, 0, 0},
-       _(B8G8R8X8_UNORM, A8R8G8B8,   S1,   S1,   S1,  ONE, X, Y, Z, W),
-       _(B8G8R8A8_UNORM, A8R8G8B8,   S1,   S1,   S1,   S1, X, Y, Z, W),
-       _(B5G5R5A1_UNORM, A1R5G5B5,   S1,   S1,   S1,   S1, X, Y, Z, W),
-       _(B4G4R4A4_UNORM, A4R4G4B4,   S1,   S1,   S1,   S1, X, Y, Z, W),
-       _(B5G6R5_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),
-       _(L8A8_UNORM    , A8L8    ,   S1,   S1,   S1,   S1, X, X, X, Y),
-       _(Z16_UNORM     , R5G6B5  ,   S1,   S1,   S1,  ONE, X, X, X, X),
-       _(S8_USCALED_Z24_UNORM   , A8R8G8B8,   S1,   S1,   S1,  ONE, X, X, X, X),
-       _(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),
-       {},
-};
+       sv->swizzle  |= (nvfx_subresource_pitch(pt, 0) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT);
+
+       if(pt->height0 <= 1 || util_format_is_compressed(sv->base.format))
+               sv->u.nv30.rect = -1;
+       else
+               sv->u.nv30.rect = !!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR);
+
+       sv->lod_offset = sv->base.first_level - level;
+       sv->max_lod_limit = sv->base.last_level - level;
+}
 
 void
 nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
 {
        struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
-       struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
-       struct pipe_resource *pt = &mt->base.base;
-       struct nouveau_bo *bo = mt->base.bo;
-       struct nv30_texture_format *tf;
+       struct nvfx_sampler_view* sv = (struct nvfx_sampler_view*)nvfx->fragment_sampler_views[unit];
+       struct nouveau_bo *bo = ((struct nvfx_miptree *)sv->base.texture)->base.bo;
        struct nouveau_channel* chan = nvfx->screen->base.channel;
-       uint32_t txf, txs;
+       unsigned txf;
        unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
        unsigned use_rect;
+       unsigned max_lod = MIN2(ps->max_lod + sv->lod_offset, sv->max_lod_limit);
+       unsigned min_lod = MIN2(ps->min_lod + sv->lod_offset, max_lod) ;
 
-       tf = &nv30_texture_formats[pt->format];
-       assert(tf->format >= 0);
-
-       if(pt->height0 <= 1 || util_format_is_compressed(pt->format))
+       if(sv->u.nv30.rect < 0)
        {
                /* in the case of compressed or 1D textures, we can get away with this,
                 * since the layout is the same
@@ -100,9 +87,9 @@ nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
        }
        else
        {
-               static int warned = 0;
-               if(!warned && !ps->fmt != !(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
-                       warned = 1;
+               static boolean warned = FALSE;
+               if( !!ps->fmt != sv->u.nv30.rect && !warned) {
+                       warned = TRUE;
                        fprintf(stderr,
                                        "Unimplemented: coordinate normalization mismatch. Possible reasons:\n"
                                        "1. ARB_texture_non_power_of_two is being used despite the fact it isn't supported\n"
@@ -110,51 +97,22 @@ nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
                                        "3. The state tracker is not supported\n");
                }
 
-               use_rect  = pt->flags & NVFX_RESOURCE_FLAG_LINEAR;
-       }
-
-       txf = use_rect ? tf->rect_format : tf->format;
-       txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
-       txf |= log2i(pt->width0) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
-       txf |= log2i(pt->height0) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
-       txf |= log2i(pt->depth0) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
-       txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000;
-
-       switch (pt->target) {
-       case PIPE_TEXTURE_CUBE:
-               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:
-               txf |= NV34TCL_TX_FORMAT_DIMS_3D;
-               break;
-       case PIPE_TEXTURE_1D:
-               txf |= NV34TCL_TX_FORMAT_DIMS_1D;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown target %d\n", pt->target);
-               return;
+               use_rect  = sv->u.nv30.rect;
        }
 
-       txs = tf->swizzle;
-
-       if(use_rect)
-               txs |= nvfx_subresource_pitch(&mt->base, 0) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT;
+       txf = sv->u.nv30.fmt[ps->compare + (use_rect ? 2 : 0)];
 
        MARK_RING(chan, 9, 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, NV34TCL_TX_ENABLE_ENABLE | ps->en);
-       OUT_RING(chan, txs);
-       OUT_RING(chan, ps->filt | 0x2000 /*voodoo*/);
-       OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
-                      pt->height0);
+       OUT_RELOC(chan, bo, sv->offset, 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 & sv->wrap_mask) | sv->wrap);
+       OUT_RING(chan, ps->en | (min_lod << NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT) | (max_lod << NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT));
+       OUT_RING(chan, sv->swizzle);
+       OUT_RING(chan, ps->filt | sv->filt);
+       OUT_RING(chan, sv->npot_size);
        OUT_RING(chan, ps->bcol);
 
        nvfx->hw_txf[unit] = txf;
index 87aa7eb1a2015c8d385d80eedff62518c8df5520..5fe742f260ce52a6c396ce7a2e7c40882b585ba7 100644 (file)
@@ -8,149 +8,97 @@ nv40_sampler_state_init(struct pipe_context *pipe,
                          struct nvfx_sampler_state *ps,
                          const struct pipe_sampler_state *cso)
 {
+       float limit;
        if (cso->max_anisotropy >= 2) {
                /* no idea, binary driver sets it, works without it.. meh.. */
                ps->wrap |= (1 << 5);
 
-               if (cso->max_anisotropy >= 16) {
+               if (cso->max_anisotropy >= 16)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
-               } else
-               if (cso->max_anisotropy >= 12) {
+               else if (cso->max_anisotropy >= 12)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
-               } else
-               if (cso->max_anisotropy >= 10) {
+               else if (cso->max_anisotropy >= 10)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
-               } else
-               if (cso->max_anisotropy >= 8) {
+               else if (cso->max_anisotropy >= 8)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
-               } else
-               if (cso->max_anisotropy >= 6) {
+               else if (cso->max_anisotropy >= 6)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
-               } else
-               if (cso->max_anisotropy >= 4) {
+               else if (cso->max_anisotropy >= 4)
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
-               } else {
+               else
                        ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
-               }
        }
 
-       {
-               float limit;
+       limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+       ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
 
-               limit = CLAMP(cso->lod_bias, -16.0, 15.0);
-               ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
+       ps->max_lod = (int)(CLAMP(cso->max_lod, 0.0, 15.0) * 256.0);
+       ps->min_lod = (int)(CLAMP(cso->min_lod, 0.0, 15.0) * 256.0);
 
-               limit = CLAMP(cso->max_lod, 0.0, 15.0);
-               ps->en |= (int)(limit * 256.0) << 7;
+       ps->en |= NV40TCL_TEX_ENABLE_ENABLE;
+}
+
+void
+nv40_sampler_view_init(struct pipe_context *pipe,
+                         struct nvfx_sampler_view *sv)
+{
+       struct pipe_resource* pt = sv->base.texture;
+       struct nvfx_miptree* mt = (struct nvfx_miptree*)pt;
+       struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
+       unsigned txf;
+       unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
+       assert(tf->fmt[4] >= 0);
+
+       txf = sv->u.init_fmt;
+       txf |= 0x8000;
+       if(pt->target == PIPE_TEXTURE_CUBE)
+               txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
+       else
+               txf |= (((sv->base.last_level - sv->base.first_level) + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
 
-               limit = CLAMP(cso->min_lod, 0.0, 15.0);
-               ps->en |= (int)(limit * 256.0) << 19;
+       if (!mt->linear_pitch)
+               sv->u.nv40.npot_size2 = 0;
+       else {
+               sv->u.nv40.npot_size2  = mt->linear_pitch;
+               txf |= NV40TCL_TEX_FORMAT_LINEAR;
        }
-}
 
-#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw)            \
-[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 |         \
-   NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y |         \
-   NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w),         \
-  ((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) |       \
-   (NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw))       \
-}
+       sv->u.nv40.fmt[0] = tf->fmt[4] | txf;
+       sv->u.nv40.fmt[1] = tf->fmt[5] | txf;
 
-struct nv40_texture_format {
-       int     format;
-       int     swizzle;
-       int     sign;
-};
+       sv->u.nv40.npot_size2 |= (u_minify(pt->depth0, level) << NV40TCL_TEX_SIZE1_DEPTH_SHIFT);
 
-static struct nv40_texture_format
-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),
-       _(B4G4R4A4_UNORM, A4R4G4B4,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
-       _(B5G6R5_UNORM  , R5G6B5  ,   S1,   S1,   S1,  ONE, X, Y, Z, W, 0, 0, 0, 0),
-       _(L8_UNORM      , L8      ,   S1,   S1,   S1,  ONE, X, X, X, X, 0, 0, 0, 0),
-       _(A8_UNORM      , L8      , ZERO, ZERO, ZERO,   S1, X, X, X, X, 0, 0, 0, 0),
-       _(R16_SNORM     , A16     , ZERO, ZERO,   S1,  ONE, X, X, X, Y, 1, 1, 1, 1),
-       _(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),
-       _(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),
-       _(DXT5_RGBA     , DXT5    ,   S1,   S1,   S1,   S1, X, Y, Z, W, 0, 0, 0, 0),
-       {},
-};
+       sv->lod_offset = (sv->base.first_level - level) * 256;
+       sv->max_lod_limit = (sv->base.last_level - level) * 256;
+}
 
 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 *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;
-
-       uint32_t txf, txs, txp;
+       struct nvfx_sampler_view* sv = (struct nvfx_sampler_view*)nvfx->fragment_sampler_views[unit];
+       struct nouveau_bo *bo = ((struct nvfx_miptree *)sv->base.texture)->base.bo;
        unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+       unsigned txf;
+       unsigned max_lod = MIN2(ps->max_lod + sv->lod_offset, sv->max_lod_limit);
+       unsigned min_lod = MIN2(ps->min_lod + sv->lod_offset, max_lod);
 
-       tf = &nv40_texture_formats[pt->format];
-       assert(tf->format >= 0);
-
-       txf  = ps->fmt;
-       txf |= tf->format | 0x8000;
-       txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
-
-       if (1) /* XXX */
-               txf |= NV34TCL_TX_FORMAT_NO_BORDER;
-
-       switch (pt->target) {
-       case PIPE_TEXTURE_CUBE:
-               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:
-               txf |= NV34TCL_TX_FORMAT_DIMS_3D;
-               break;
-       case PIPE_TEXTURE_1D:
-               txf |= NV34TCL_TX_FORMAT_DIMS_1D;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown target %d\n", pt->target);
-               return;
-       }
-
-       if (!mt->linear_pitch)
-               txp = 0;
-       else {
-               txp  = mt->linear_pitch;
-               txf |= NV40TCL_TEX_FORMAT_LINEAR;
-       }
-
-       txs = tf->swizzle;
+       txf = sv->u.nv40.fmt[ps->compare] | ps->fmt;
 
-       MARK_RING(chan, 11 + 2 * !unit, 2);
+       MARK_RING(chan, 11, 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, sv->offset, 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->wrap & sv->wrap_mask) | sv->wrap);
+       OUT_RING(chan, ps->en | (min_lod << 19) | (max_lod << 7));
+       OUT_RING(chan, sv->swizzle);
+       OUT_RING(chan, ps->filt | sv->filt);
+       OUT_RING(chan, sv->npot_size);
        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);
+       OUT_RING(chan, sv->u.nv40.npot_size2);
 
        nvfx->hw_txf[unit] = txf;
        nvfx->hw_samplers |= (1 << unit);
index 7ab81de7dd5644aecafec855d8bcc5ad6731b1fe..1980176b23ec0789deb3a5c5ac04776b040e9935 100644 (file)
@@ -75,6 +75,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
        nvfx_init_query_functions(nvfx);
        nvfx_init_surface_functions(nvfx);
        nvfx_init_state_functions(nvfx);
+       nvfx_init_sampling_functions(nvfx);
        nvfx_init_resource_functions(&nvfx->pipe);
 
        /* Create, configure, and install fallback swtnl path */
index a6ea9139675731edf1802eb0b1b8e05a957aa276..bce19df044d46e331f17f79d4cfd3eeea2f66f07 100644 (file)
@@ -201,15 +201,20 @@ extern void
 nvfx_fragprog_relocate(struct nvfx_context *nvfx);
 
 /* nvfx_fragtex.c */
+extern void nvfx_init_sampling_functions(struct nvfx_context *nvfx);
 extern void nvfx_fragtex_validate(struct nvfx_context *nvfx);
-extern void
-nvfx_fragtex_relocate(struct nvfx_context *nvfx);
+extern void nvfx_fragtex_relocate(struct nvfx_context *nvfx);
+
+struct nvfx_sampler_view;
 
 /* nv30_fragtex.c */
 extern void
 nv30_sampler_state_init(struct pipe_context *pipe,
                          struct nvfx_sampler_state *ps,
                          const struct pipe_sampler_state *cso);
+extern void
+nv30_sampler_view_init(struct pipe_context *pipe,
+                         struct nvfx_sampler_view *sv);
 extern void nv30_fragtex_set(struct nvfx_context *nvfx, int unit);
 
 /* nv40_fragtex.c */
@@ -217,6 +222,9 @@ extern void
 nv40_sampler_state_init(struct pipe_context *pipe,
                          struct nvfx_sampler_state *ps,
                          const struct pipe_sampler_state *cso);
+extern void
+nv40_sampler_view_init(struct pipe_context *pipe,
+                         struct nvfx_sampler_view *sv);
 extern void nv40_fragtex_set(struct nvfx_context *nvfx, int unit);
 
 /* nvfx_state.c */
index 66057454337c4bb7ee99c675b83b25b572a73518..00c47be76ab9479e5fb24ed993b284c0e0105116 100644 (file)
@@ -1,5 +1,177 @@
 #include "nvfx_context.h"
 #include "nvfx_resource.h"
+#include "nvfx_tex.h"
+
+static void *
+nvfx_sampler_state_create(struct pipe_context *pipe,
+                         const struct pipe_sampler_state *cso)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       struct nvfx_sampler_state *ps;
+
+       ps = MALLOC(sizeof(struct nvfx_sampler_state));
+
+       /* on nv30, we use this as an internal flag */
+       ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT;
+       ps->en = 0;
+       ps->filt = nvfx_tex_filter(cso) | 0x2000; /*voodoo*/
+       ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
+                   (nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
+                   (nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT);
+       ps->compare = FALSE;
+
+       if(cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
+       {
+               ps->wrap |= nvfx_tex_wrap_compare_mode(cso->compare_func);
+               ps->compare = TRUE;
+       }
+       ps->bcol = nvfx_tex_border_color(cso->border_color);
+
+       if(nvfx->is_nv4x)
+               nv40_sampler_state_init(pipe, ps, cso);
+       else
+               nv30_sampler_state_init(pipe, ps, cso);
+
+       return (void *)ps;
+}
+
+static void
+nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+       FREE(hwcso);
+}
+
+static void
+nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       unsigned unit;
+
+       for (unit = 0; unit < nr; unit++) {
+               nvfx->tex_sampler[unit] = sampler[unit];
+               nvfx->dirty_samplers |= (1 << unit);
+       }
+
+       for (unit = nr; unit < nvfx->nr_samplers; unit++) {
+               nvfx->tex_sampler[unit] = NULL;
+               nvfx->dirty_samplers |= (1 << unit);
+       }
+
+       nvfx->nr_samplers = nr;
+       nvfx->dirty |= NVFX_NEW_SAMPLER;
+}
+
+static struct pipe_sampler_view *
+nvfx_create_sampler_view(struct pipe_context *pipe,
+                        struct pipe_resource *pt,
+                        const struct pipe_sampler_view *templ)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       struct nvfx_sampler_view *sv = CALLOC_STRUCT(nvfx_sampler_view);
+       struct nvfx_texture_format *tf = &nvfx_texture_formats[templ->format];
+       unsigned txf;
+
+       if (!sv)
+               return NULL;
+
+       sv->base = *templ;
+       sv->base.reference.count = 1;
+       sv->base.texture = NULL;
+       pipe_resource_reference(&sv->base.texture, pt);
+       sv->base.context = pipe;
+
+       txf = NV34TCL_TX_FORMAT_NO_BORDER;
+
+       switch (pt->target) {
+       case PIPE_TEXTURE_CUBE:
+               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:
+               txf |= NV34TCL_TX_FORMAT_DIMS_3D;
+               break;
+       case PIPE_TEXTURE_1D:
+               txf |= NV34TCL_TX_FORMAT_DIMS_1D;
+               break;
+       default:
+               assert(0);
+       }
+       sv->u.init_fmt = txf;
+
+       sv->swizzle = 0
+                       | (tf->src[sv->base.swizzle_r] << NV34TCL_TX_SWIZZLE_S0_Z_SHIFT)
+                       | (tf->src[sv->base.swizzle_g] << NV34TCL_TX_SWIZZLE_S0_Y_SHIFT)
+                       | (tf->src[sv->base.swizzle_b] << NV34TCL_TX_SWIZZLE_S0_X_SHIFT)
+                       | (tf->src[sv->base.swizzle_a] << NV34TCL_TX_SWIZZLE_S0_W_SHIFT)
+                       | (tf->comp[sv->base.swizzle_r] << NV34TCL_TX_SWIZZLE_S1_Z_SHIFT)
+                       | (tf->comp[sv->base.swizzle_g] << NV34TCL_TX_SWIZZLE_S1_Y_SHIFT)
+                       | (tf->comp[sv->base.swizzle_b] << NV34TCL_TX_SWIZZLE_S1_X_SHIFT)
+                       | (tf->comp[sv->base.swizzle_a] << NV34TCL_TX_SWIZZLE_S1_W_SHIFT);
+
+       sv->filt = tf->sign;
+       sv->wrap = tf->wrap;
+       sv->wrap_mask = ~0;
+
+       if (pt->target == PIPE_TEXTURE_CUBE)
+       {
+               sv->offset = 0;
+               sv->npot_size = (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height0;
+       }
+       else
+       {
+               sv->offset = nvfx_subresource_offset(pt, 0, sv->base.first_level, 0);
+               sv->npot_size = (u_minify(pt->width0, sv->base.first_level) << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | u_minify(pt->height0, sv->base.first_level);
+
+               /* apparently, we need to ignore the t coordinate for 1D textures to fix piglit tex1d-2dborder */
+               if(pt->target == PIPE_TEXTURE_1D)
+               {
+                       sv->wrap_mask &=~ NV34TCL_TX_WRAP_T_MASK;
+                       sv->wrap |= NV34TCL_TX_WRAP_T_REPEAT;
+               }
+       }
+
+       if(nvfx->is_nv4x)
+               nv40_sampler_view_init(pipe, sv);
+       else
+               nv30_sampler_view_init(pipe, sv);
+
+       return &sv->base;
+}
+
+static void
+nvfx_sampler_view_destroy(struct pipe_context *pipe,
+                         struct pipe_sampler_view *view)
+{
+       pipe_resource_reference(&view->texture, NULL);
+       FREE(view);
+}
+
+static void
+nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
+                               unsigned nr,
+                               struct pipe_sampler_view **views)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       unsigned unit;
+
+       for (unit = 0; unit < nr; unit++) {
+               pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+                                            views[unit]);
+               nvfx->dirty_samplers |= (1 << unit);
+       }
+
+       for (unit = nr; unit < nvfx->nr_textures; unit++) {
+               pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+                                            NULL);
+               nvfx->dirty_samplers |= (1 << unit);
+       }
+
+       nvfx->nr_textures = nr;
+       nvfx->dirty |= NVFX_NEW_SAMPLER;
+}
 
 void
 nvfx_fragtex_validate(struct nvfx_context *nvfx)
@@ -60,3 +232,126 @@ nvfx_fragtex_relocate(struct nvfx_context *nvfx)
                                NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
        }
 }
+
+void
+nvfx_init_sampling_functions(struct nvfx_context *nvfx)
+{
+       nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
+       nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
+       nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
+       nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
+       nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
+       nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
+}
+
+#define NV34TCL_TX_FORMAT_FORMAT_DXT1_RECT NV34TCL_TX_FORMAT_FORMAT_DXT1
+#define NV34TCL_TX_FORMAT_FORMAT_DXT3_RECT NV34TCL_TX_FORMAT_FORMAT_DXT3
+#define NV34TCL_TX_FORMAT_FORMAT_DXT5_RECT NV34TCL_TX_FORMAT_FORMAT_DXT5
+
+#define NV40TCL_TEX_FORMAT_FORMAT_HILO16 NV40TCL_TEX_FORMAT_FORMAT_A16L16
+
+#define NV34TCL_TX_FORMAT_FORMAT_RGBA16F 0x00004a00
+#define NV34TCL_TX_FORMAT_FORMAT_RGBA16F_RECT NV34TCL_TX_FORMAT_FORMAT_RGBA16F
+#define NV34TCL_TX_FORMAT_FORMAT_RGBA32F 0x00004b00
+#define NV34TCL_TX_FORMAT_FORMAT_RGBA32F_RECT NV34TCL_TX_FORMAT_FORMAT_RGBA32F
+#define NV34TCL_TX_FORMAT_FORMAT_R32F 0x00004c00
+#define NV34TCL_TX_FORMAT_FORMAT_R32F_RECT NV34TCL_TX_FORMAT_FORMAT_R32F
+
+// TODO: guess!
+#define NV40TCL_TEX_FORMAT_FORMAT_R32F 0x00001c00
+
+#define SRGB 0x00700000
+
+#define __(m,tf,tfc,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign,wrap) \
+[PIPE_FORMAT_##m] = { \
+  {NV34TCL_TX_FORMAT_FORMAT_##tf, \
+  NV34TCL_TX_FORMAT_FORMAT_##tfc, \
+  NV34TCL_TX_FORMAT_FORMAT_##tf##_RECT, \
+  NV34TCL_TX_FORMAT_FORMAT_##tfc##_RECT, \
+  NV40TCL_TEX_FORMAT_FORMAT_##tf, \
+  NV40TCL_TEX_FORMAT_FORMAT_##tfc}, \
+  sign, wrap, \
+  {ts0z, ts0y, ts0x, ts0w, 0, 1}, {ts1z, ts1y, ts1x, ts1w, 0, 0} \
+}
+
+#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap) \
+       __(m,tf,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap)
+
+/* Depth formats works by reading the depth value most significant 8/16 bits.
+ * We are losing precision, but nVidia loses even more by using A8R8G8B8 instead of HILO16
+ * There is no 32-bit integer texture support, so other things are infeasible.
+ *
+ * TODO: is it possible to read 16 bits for Z16? A16 doesn't seem to work, either due to normalization or endianness issues
+ */
+
+#define T 2
+
+#define X 3
+#define Y 2
+#define Z 1
+#define W 0
+
+#define SNORM ((NV34TCL_TX_FILTER_SIGNED_RED) | (NV34TCL_TX_FILTER_SIGNED_GREEN) | (NV34TCL_TX_FILTER_SIGNED_BLUE) | (NV34TCL_TX_FILTER_SIGNED_ALPHA))
+#define UNORM 0
+
+struct nvfx_texture_format
+nvfx_texture_formats[PIPE_FORMAT_COUNT] = {
+       [0 ... PIPE_FORMAT_COUNT - 1] = {{-1, -1, -1, -1, -1, -1}},
+       _(B8G8R8X8_UNORM,       A8R8G8B8,       T, T, T, 1, X, Y, Z, W, UNORM, 0),
+       _(B8G8R8X8_SRGB,        A8R8G8B8,       T, T, T, 1, X, Y, Z, W, UNORM, SRGB),
+       _(B8G8R8A8_UNORM,       A8R8G8B8,       T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(B8G8R8A8_SRGB,        A8R8G8B8,       T, T, T, T, X, Y, Z, W, UNORM, SRGB),
+
+       _(R8G8B8A8_UNORM,       A8R8G8B8,       T, T, T, T, Z, Y, X, W, UNORM, 0),
+       _(R8G8B8A8_SRGB,        A8R8G8B8,       T, T, T, T, Z, Y, X, W, UNORM, SRGB),
+       _(R8G8B8X8_UNORM,       A8R8G8B8,       T, T, T, 1, Z, Y, X, W, UNORM, 0),
+
+       _(A8R8G8B8_UNORM,       A8R8G8B8,       T, T, T, T, W, Z, Y, X, UNORM, 0),
+       _(A8R8G8B8_SRGB,        A8R8G8B8,       T, T, T, T, W, Z, Y, X, UNORM, SRGB),
+       _(A8B8G8R8_UNORM,       A8R8G8B8,       T, T, T, T, W, X, Y, Z, UNORM, 0),
+       _(A8B8G8R8_SRGB,        A8R8G8B8,       T, T, T, T, W, X, Y, Z, UNORM, SRGB),
+       _(X8R8G8B8_UNORM,       A8R8G8B8,       T, T, T, 1, W, Z, Y, X, UNORM, 0),
+       _(X8R8G8B8_SRGB,        A8R8G8B8,       T, T, T, 1, W, Z, Y, X, UNORM, SRGB),
+
+       _(B5G5R5A1_UNORM,       A1R5G5B5,       T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(B5G5R5X1_UNORM,       A1R5G5B5,       T, T, T, 1, X, Y, Z, W, UNORM, 0),
+
+       _(B4G4R4A4_UNORM,       A4R4G4B4,       T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(B4G4R4X4_UNORM,       A4R4G4B4,       T, T, T, 1, X, Y, Z, W, UNORM, 0),
+
+       _(B5G6R5_UNORM,         R5G6B5,         T, T, T, 1, X, Y, Z, W, UNORM, 0),
+
+       _(R8_UNORM,             L8,             T, 0, 0, 1, X, X, X, X, UNORM, 0),
+       _(R8_SNORM,             L8,             T, 0, 0, 1, X, X, X, X, SNORM, 0),
+       _(L8_UNORM,             L8,             T, T, T, 1, X, X, X, X, UNORM, 0),
+       _(L8_SRGB,              L8,             T, T, T, 1, X, X, X, X, UNORM, SRGB),
+       _(A8_UNORM,             L8,             0, 0, 0, T, X, X, X, X, UNORM, 0),
+       _(I8_UNORM,             L8,             T, T, T, T, X, X, X, X, UNORM, 0),
+
+       _(R8G8_UNORM,           A8L8,           T, T, T, T, X, X, X, W, UNORM, 0),
+       _(R8G8_SNORM,           A8L8,           T, T, T, T, X, X, X, W, SNORM, 0),
+       _(L8A8_UNORM,           A8L8,           T, T, T, T, X, X, X, W, UNORM, 0),
+       _(L8A8_SRGB,            A8L8,           T, T, T, T, X, X, X, W, UNORM, SRGB),
+
+       _(DXT1_RGB,             DXT1,           T, T, T, 1, X, Y, Z, W, UNORM, 0),
+       _(DXT1_SRGB,            DXT1,           T, T, T, 1, X, Y, Z, W, UNORM, SRGB),
+       _(DXT1_RGBA,            DXT1,           T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(DXT1_SRGBA,           DXT1,           T, T, T, T, X, Y, Z, W, UNORM, SRGB),
+       _(DXT3_RGBA,            DXT3,           T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(DXT3_SRGBA,           DXT3,           T, T, T, T, X, Y, Z, W, UNORM, SRGB),
+       _(DXT5_RGBA,            DXT5,           T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(DXT5_SRGBA,           DXT5,           T, T, T, T, X, Y, Z, W, UNORM, SRGB),
+
+       __(Z16_UNORM,           A8L8, Z16,      T, T, T, 1, W, W, W, W, UNORM, 0),
+       __(S8_USCALED_Z24_UNORM,HILO16,Z24,     T, T, T, 1, W, W, W, W, UNORM, 0),
+       __(X8Z24_UNORM,         HILO16,Z24,     T, T, T, 1, W, W, W, W, UNORM, 0),
+
+       _(R16_UNORM,            A16,            T, 0, 0, 1, X, X, X, X, UNORM, 0),
+       _(R16_SNORM,            A16,            T, 0, 0, 1, X, X, X, X, SNORM, 0),
+       _(R16G16_UNORM,         HILO16,         T, T, 0, 1, X, Y, X, X, UNORM, 0),
+       _(R16G16_SNORM,         HILO16,         T, T, 0, 1, X, Y, X, X, SNORM, 0),
+
+       _(R16G16B16A16_FLOAT,           RGBA16F,        T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(R32G32B32A32_FLOAT,           RGBA32F,        T, T, T, T, X, Y, Z, W, UNORM, 0),
+       _(R32_FLOAT,            R32F,   T, 0, 0, 1, X, X, X, X, UNORM, 0)
+};
index a1b7c218f117bbe134ce7e0f250e2f8e3a489557..a1b8361a9a47595f35e6d44d22b022cb3e76a6d9 100644 (file)
@@ -8,6 +8,7 @@
 #include "nvfx_context.h"
 #include "nvfx_screen.h"
 #include "nvfx_resource.h"
+#include "nvfx_tex.h"
 
 #define NV30TCL_CHIPSET_3X_MASK 0x00000003
 #define NV34TCL_CHIPSET_3X_MASK 0x00000010
@@ -179,58 +180,45 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
                case PIPE_FORMAT_B8G8R8A8_UNORM:
                case PIPE_FORMAT_B8G8R8X8_UNORM:
                case PIPE_FORMAT_B5G6R5_UNORM:
-                       return TRUE;
-               default:
                        break;
+               default:
+                       return FALSE;
                }
-       } else
+       }
+
        if (tex_usage & PIPE_BIND_DEPTH_STENCIL) {
                switch (format) {
                case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
                case PIPE_FORMAT_X8Z24_UNORM:
-                       return TRUE;
+                       break;
                case PIPE_FORMAT_Z16_UNORM:
                        /* TODO: this nv30 limitation probably does not exist */
-                       if (!screen->is_nv4x && front)
-                               return (front->format == PIPE_FORMAT_B5G6R5_UNORM);
-                       return TRUE;
-               default:
+                       if (!screen->is_nv4x && front && front->format != PIPE_FORMAT_B5G6R5_UNORM)
+                               return FALSE;
                        break;
+               default:
+                       return FALSE;
                }
-       } else {
-               if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
-                       switch (format) {
-                       case PIPE_FORMAT_DXT1_RGB:
-                       case PIPE_FORMAT_DXT1_RGBA:
-                       case PIPE_FORMAT_DXT3_RGBA:
-                       case PIPE_FORMAT_DXT5_RGBA:
-                               return util_format_s3tc_enabled;
-                       default:
-                               break;
-                       }
+       }
+
+       if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
+               struct nvfx_texture_format* tf = &nvfx_texture_formats[format];
+               if(util_format_is_s3tc(format) && !util_format_s3tc_enabled)
+                       return FALSE;
+
+               if(screen->is_nv4x)
+               {
+                       if(tf->fmt[4] < 0)
+                               return FALSE;
                }
-               switch (format) {
-               case PIPE_FORMAT_B8G8R8A8_UNORM:
-               case PIPE_FORMAT_B8G8R8X8_UNORM:
-               case PIPE_FORMAT_B5G5R5A1_UNORM:
-               case PIPE_FORMAT_B4G4R4A4_UNORM:
-               case PIPE_FORMAT_B5G6R5_UNORM:
-               case PIPE_FORMAT_L8_UNORM:
-               case PIPE_FORMAT_A8_UNORM:
-               case PIPE_FORMAT_I8_UNORM:
-               case PIPE_FORMAT_L8A8_UNORM:
-               case PIPE_FORMAT_Z16_UNORM:
-               case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-                       return TRUE;
-               /* TODO: does nv30 support this? */
-               case PIPE_FORMAT_R16_SNORM:
-                       return !!screen->is_nv4x;
-               default:
-                       break;
+               else
+               {
+                       if(tf->fmt[0] < 0)
+                               return FALSE;
                }
        }
 
-       return FALSE;
+       return TRUE;
 }
 
 static void
index ab7bed0f938e3fd50ff80bf1ff6fbc145d94cf6e..d459f9a88013ccabc43404275abe71e4951f71cb 100644 (file)
@@ -81,111 +81,6 @@ nvfx_blend_state_delete(struct pipe_context *pipe, void *hwcso)
        FREE(bso);
 }
 
-static void *
-nvfx_sampler_state_create(struct pipe_context *pipe,
-                         const struct pipe_sampler_state *cso)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct nvfx_sampler_state *ps;
-
-       ps = MALLOC(sizeof(struct nvfx_sampler_state));
-
-       /* on nv30, we use this as an internal flag */
-       ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT;
-       ps->en = 0;
-       ps->filt = nvfx_tex_filter(cso);
-       ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
-                   (nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
-                   (nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT) |
-                   nvfx_tex_wrap_compare_mode(cso);
-       ps->bcol = nvfx_tex_border_color(cso->border_color);
-
-       if(nvfx->is_nv4x)
-               nv40_sampler_state_init(pipe, ps, cso);
-       else
-               nv30_sampler_state_init(pipe, ps, cso);
-
-       return (void *)ps;
-}
-
-static void
-nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       unsigned unit;
-
-       for (unit = 0; unit < nr; unit++) {
-               nvfx->tex_sampler[unit] = sampler[unit];
-               nvfx->dirty_samplers |= (1 << unit);
-       }
-
-       for (unit = nr; unit < nvfx->nr_samplers; unit++) {
-               nvfx->tex_sampler[unit] = NULL;
-               nvfx->dirty_samplers |= (1 << unit);
-       }
-
-       nvfx->nr_samplers = nr;
-       nvfx->dirty |= NVFX_NEW_SAMPLER;
-}
-
-static void
-nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
-{
-       FREE(hwcso);
-}
-
-static void
-nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
-                               unsigned nr,
-                               struct pipe_sampler_view **views)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       unsigned unit;
-
-       for (unit = 0; unit < nr; unit++) {
-               pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
-                                            views[unit]);
-               nvfx->dirty_samplers |= (1 << unit);
-       }
-
-       for (unit = nr; unit < nvfx->nr_textures; unit++) {
-               pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
-                                            NULL);
-               nvfx->dirty_samplers |= (1 << unit);
-       }
-
-       nvfx->nr_textures = nr;
-       nvfx->dirty |= NVFX_NEW_SAMPLER;
-}
-
-
-static struct pipe_sampler_view *
-nvfx_create_sampler_view(struct pipe_context *pipe,
-                        struct pipe_resource *texture,
-                        const struct pipe_sampler_view *templ)
-{
-       struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
-
-       if (view) {
-               *view = *templ;
-               view->reference.count = 1;
-               view->texture = NULL;
-               pipe_resource_reference(&view->texture, texture);
-               view->context = pipe;
-       }
-
-       return view;
-}
-
-
-static void
-nvfx_sampler_view_destroy(struct pipe_context *pipe,
-                         struct pipe_sampler_view *view)
-{
-       pipe_resource_reference(&view->texture, NULL);
-       FREE(view);
-}
-
 static void *
 nvfx_rasterizer_state_create(struct pipe_context *pipe,
                             const struct pipe_rasterizer_state *cso)
@@ -630,13 +525,6 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
        nvfx->pipe.bind_blend_state = nvfx_blend_state_bind;
        nvfx->pipe.delete_blend_state = nvfx_blend_state_delete;
 
-       nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
-       nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
-       nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
-       nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
-        nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
-        nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
-
        nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
        nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;
        nvfx->pipe.delete_rasterizer_state = nvfx_rasterizer_state_delete;
index 69187a79e792d9221adcfb4e9344ff6289e90114..34be936a891d93b3c76e32e10a7a3d48103a80a0 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef NVFX_TEX_H_
 #define NVFX_TEX_H_
 
+#include "util/u_math.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include <nouveau/nouveau_class.h>
+
 static inline unsigned
 nvfx_tex_wrap_mode(unsigned wrap) {
        unsigned ret;
@@ -31,7 +36,7 @@ nvfx_tex_wrap_mode(unsigned wrap) {
                ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
                break;
        default:
-               NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
+               assert(0);
                ret = NV34TCL_TX_WRAP_S_REPEAT;
                break;
        }
@@ -40,31 +45,29 @@ nvfx_tex_wrap_mode(unsigned wrap) {
 }
 
 static inline unsigned
-nvfx_tex_wrap_compare_mode(const struct pipe_sampler_state* cso)
+nvfx_tex_wrap_compare_mode(unsigned func)
 {
-       if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               switch (cso->compare_func) {
-               case PIPE_FUNC_NEVER:
-                       return NV34TCL_TX_WRAP_RCOMP_NEVER;
-               case PIPE_FUNC_GREATER:
-                       return NV34TCL_TX_WRAP_RCOMP_GREATER;
-               case PIPE_FUNC_EQUAL:
-                       return NV34TCL_TX_WRAP_RCOMP_EQUAL;
-               case PIPE_FUNC_GEQUAL:
-                       return NV34TCL_TX_WRAP_RCOMP_GEQUAL;
-               case PIPE_FUNC_LESS:
-                       return NV34TCL_TX_WRAP_RCOMP_LESS;
-               case PIPE_FUNC_NOTEQUAL:
-                       return NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
-               case PIPE_FUNC_LEQUAL:
-                       return NV34TCL_TX_WRAP_RCOMP_LEQUAL;
-               case PIPE_FUNC_ALWAYS:
-                       return NV34TCL_TX_WRAP_RCOMP_ALWAYS;
-               default:
-                       break;
-               }
+       switch (func) {
+       case PIPE_FUNC_NEVER:
+               return NV34TCL_TX_WRAP_RCOMP_NEVER;
+       case PIPE_FUNC_GREATER:
+               return NV34TCL_TX_WRAP_RCOMP_GREATER;
+       case PIPE_FUNC_EQUAL:
+               return NV34TCL_TX_WRAP_RCOMP_EQUAL;
+       case PIPE_FUNC_GEQUAL:
+               return NV34TCL_TX_WRAP_RCOMP_GEQUAL;
+       case PIPE_FUNC_LESS:
+               return NV34TCL_TX_WRAP_RCOMP_LESS;
+       case PIPE_FUNC_NOTEQUAL:
+               return NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
+       case PIPE_FUNC_LEQUAL:
+               return NV34TCL_TX_WRAP_RCOMP_LEQUAL;
+       case PIPE_FUNC_ALWAYS:
+               return NV34TCL_TX_WRAP_RCOMP_ALWAYS;
+       default:
+               assert(0);
+               return 0;
        }
-       return 0;
 }
 
 static inline unsigned nvfx_tex_filter(const struct pipe_sampler_state* cso)
@@ -128,6 +131,45 @@ struct nvfx_sampler_state {
        uint32_t en;
        uint32_t filt;
        uint32_t bcol;
+       uint32_t min_lod;
+       uint32_t max_lod;
+       boolean compare;
+};
+
+struct nvfx_sampler_view {
+       struct pipe_sampler_view base;
+       int offset;
+       uint32_t swizzle;
+       uint32_t npot_size;
+       uint32_t filt;
+       uint32_t wrap_mask;
+       uint32_t wrap;
+       uint32_t lod_offset;
+       uint32_t max_lod_limit;
+       union
+       {
+               struct
+               {
+                       uint32_t fmt[4]; /* nv30 has 4 entries, nv40 one */
+                       int rect;
+               } nv30;
+               struct
+               {
+                       uint32_t fmt[2]; /* nv30 has 4 entries, nv40 one */
+                       uint32_t npot_size2; /* nv40 only */
+               } nv40;
+               uint32_t init_fmt;
+       } u;
 };
 
+struct nvfx_texture_format {
+       int fmt[6];
+       unsigned sign;
+       unsigned wrap;
+       unsigned char src[6];
+       unsigned char comp[6];
+};
+
+extern struct nvfx_texture_format nvfx_texture_formats[PIPE_FORMAT_COUNT];
+
 #endif /* NVFX_TEX_H_ */