nvfx: refactor sampling code, add support for swizzles and depth tex

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.
This commit is contained in:
Luca Barbieri 2010-08-07 03:47:25 +02:00
parent 4e2080a86e
commit 73b7c6fb33
9 changed files with 530 additions and 398 deletions

View 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

View 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;
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*/;
limit = CLAMP(cso->min_lod, 0.0, 15.0);
ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/;
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;
ps->max_lod = (int)CLAMP(cso->max_lod, 0.0, 15.0);
ps->min_lod = (int)CLAMP(cso->min_lod, 0.0, 15.0);
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;
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;
}
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),
{},
};
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;
use_rect = sv->u.nv30.rect;
}
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;
}
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;

View 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;
}
limit = CLAMP(cso->min_lod, 0.0, 15.0);
ps->en |= (int)(limit * 256.0) << 19;
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);
if (!mt->linear_pitch)
sv->u.nv40.npot_size2 = 0;
else {
sv->u.nv40.npot_size2 = mt->linear_pitch;
txf |= NV40TCL_TEX_FORMAT_LINEAR;
}
sv->u.nv40.fmt[0] = tf->fmt[4] | txf;
sv->u.nv40.fmt[1] = tf->fmt[5] | txf;
sv->u.nv40.npot_size2 |= (u_minify(pt->depth0, level) << NV40TCL_TEX_SIZE1_DEPTH_SHIFT);
sv->lod_offset = (sv->base.first_level - level) * 256;
sv->max_lod_limit = (sv->base.last_level - level) * 256;
}
#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)) \
}
struct nv40_texture_format {
int format;
int swizzle;
int sign;
};
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),
{},
};
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 = sv->u.nv40.fmt[ps->compare] | ps->fmt;
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;
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);

View 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 */

View 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 */

View 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)
};

View 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;
}
} 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;
}
}
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;
return FALSE;
}
}
return FALSE;
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;
}
else
{
if(tf->fmt[0] < 0)
return FALSE;
}
}
return TRUE;
}
static void

View 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;

View 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_ */