summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nvfx/nv30_fragtex.c
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-09-02 18:31:49 +0200
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-09-02 18:31:49 +0200
commit222d2f2ac2c7d93cbc0643082c78278ad2c8cfce (patch)
treeb79152c238022b2a901201c22e5809ac520732bf /src/gallium/drivers/nvfx/nv30_fragtex.c
parent443abc80db9e1a288ce770e76cccd43664348098 (diff)
parente73c5501b2fe20290d1b691c85a5d82ac3a0431c (diff)
Merge remote branch 'origin/master' into nv50-compiler
Conflicts: src/gallium/drivers/nv50/nv50_program.c
Diffstat (limited to 'src/gallium/drivers/nvfx/nv30_fragtex.c')
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c192
1 files changed, 81 insertions, 111 deletions
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index dec073ac90..0c3d43fd57 100644
--- a/src/gallium/drivers/nvfx/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -1,7 +1,6 @@
#include "util/u_format.h"
#include "nvfx_context.h"
-#include "nouveau/nouveau_util.h"
#include "nvfx_tex.h"
#include "nvfx_resource.h"
@@ -10,138 +9,109 @@ 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 + (255.0 / 256.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) \
-{ \
- TRUE, \
- PIPE_FORMAT_##m, \
- NV34TCL_TX_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) \
-}
-
-struct nv30_texture_format {
- boolean defined;
- uint pipe;
- int format;
- int swizzle;
-};
-
-static struct nv30_texture_format
-nv30_texture_formats[] = {
- _(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),
- {},
-};
-
-static struct nv30_texture_format *
-nv30_fragtex_format(uint pipe_format)
+void
+nv30_sampler_view_init(struct pipe_context *pipe,
+ struct nvfx_sampler_view *sv)
{
- struct nv30_texture_format *tf = nv30_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 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 |= util_logbase2(u_minify(pt->width0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
+ txf |= util_logbase2(u_minify(pt->height0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
+ txf |= util_logbase2(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;
+
+ 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 *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
- struct pipe_resource *pt = &nv30mt->base.base;
- struct nouveau_bo *bo = nv30mt->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_fragtex_format(pt->format);
- if (!tf)
- return;
-
- txf = 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:
- 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(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
+ */
+ use_rect = ps->fmt;
+ }
+ else
+ {
+ 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"
+ "2. The state tracker is not using the appropriate coordinate normalization\n"
+ "3. The state tracker is not supported\n");
+ }
+
+ use_rect = sv->u.nv30.rect;
}
- txs = tf->swizzle;
+ 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;