nv30, nv40: partially non-trivially unify sampler state in nv[34]0_state.c

Many things, like texture wrap modes and min/mag filters are common.

Some others, like annisotropy and lod settings, are not.
This commit is contained in:
Luca Barbieri
2010-02-24 15:08:48 +01:00
committed by Younes Manton
parent 5bb68e5d17
commit 7d210fa05f
10 changed files with 252 additions and 399 deletions
+1 -2
View File
@@ -4,8 +4,7 @@ include $(TOP)/configs/current
LIBNAME = nv30
C_SOURCES = \
nv30_fragtex.c \
nv30_state.c
nv30_fragtex.c
LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/nvfx
+30
View File
@@ -2,6 +2,36 @@
#include "nvfx_context.h"
#include "nouveau/nouveau_util.h"
#include "nvfx_tex.h"
void
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;
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*/;
}
}
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
{ \
-179
View File
@@ -1,179 +0,0 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "tgsi/tgsi_parse.h"
#include "nv30_context.h"
#include "nvfx_state.h"
static INLINE unsigned
wrap_mode(unsigned wrap) {
unsigned ret;
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV34TCL_TX_WRAP_S_CLAMP;
break;
/* case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP;
break;*/
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
}
return ret >> NV34TCL_TX_WRAP_S_SHIFT;
}
void *
nv30_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
struct nvfx_sampler_state *ps;
uint32_t filter = 0;
ps = MALLOC(sizeof(struct nvfx_sampler_state));
ps->fmt = 0;
/* TODO: Not all RECTs formats have this bit set, bits 15-8 of format
are the tx format to use. We should store normalized coord flag
in sampler state structure, and set appropriate format in
nvxx_fragtex_build()
*/
/*NV34TCL_TX_FORMAT_RECT*/
/*if (!cso->normalized_coords) {
ps->fmt |= (1<<14) ;
}*/
ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
(wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
(wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT));
ps->en = 0;
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;
}
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}
switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}
ps->filt = filter;
{
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->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
switch (cso->compare_func) {
case PIPE_FUNC_NEVER:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NEVER;
break;
case PIPE_FUNC_GREATER:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GREATER;
break;
case PIPE_FUNC_EQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_EQUAL;
break;
case PIPE_FUNC_GEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GEQUAL;
break;
case PIPE_FUNC_LESS:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LESS;
break;
case PIPE_FUNC_NOTEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
break;
case PIPE_FUNC_LEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LEQUAL;
break;
case PIPE_FUNC_ALWAYS:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_ALWAYS;
break;
default:
break;
}
}
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
(float_to_ubyte(cso->border_color[0]) << 16) |
(float_to_ubyte(cso->border_color[1]) << 8) |
(float_to_ubyte(cso->border_color[2]) << 0));
return (void *)ps;
}
+1 -2
View File
@@ -4,8 +4,7 @@ include $(TOP)/configs/current
LIBNAME = nv40
C_SOURCES = \
nv40_fragtex.c \
nv40_state.c
nv40_fragtex.c
LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/nvfx
+46
View File
@@ -1,5 +1,51 @@
#include "util/u_format.h"
#include "nvfx_context.h"
#include "nvfx_tex.h"
void
nv40_sampler_state_init(struct pipe_context *pipe,
struct nvfx_sampler_state *ps,
const struct pipe_sampler_state *cso)
{
if (cso->max_anisotropy >= 2) {
/* no idea, binary driver sets it, works without it.. meh.. */
ps->wrap |= (1 << 5);
if (cso->max_anisotropy >= 16) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
} else
if (cso->max_anisotropy >= 12) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
} else
if (cso->max_anisotropy >= 10) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
} else
if (cso->max_anisotropy >= 8) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
} else
if (cso->max_anisotropy >= 6) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
} else
if (cso->max_anisotropy >= 4) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
} 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->max_lod, 0.0, 15.0);
ps->en |= (int)(limit * 256.0) << 7;
limit = CLAMP(cso->min_lod, 0.0, 15.0);
ps->en |= (int)(limit * 256.0) << 19;
}
}
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
{ \
-190
View File
@@ -1,190 +0,0 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_parse.h"
#include "nv40_context.h"
#include "nvfx_state.h"
static INLINE unsigned
wrap_mode(unsigned wrap) {
unsigned ret;
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV34TCL_TX_WRAP_S_CLAMP;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
break;
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
}
return ret >> NV34TCL_TX_WRAP_S_SHIFT;
}
void *
nv40_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
struct nvfx_sampler_state *ps;
uint32_t filter = 0;
ps = MALLOC(sizeof(struct nvfx_sampler_state));
ps->fmt = 0;
if (!cso->normalized_coords)
ps->fmt |= NV40TCL_TEX_FORMAT_RECT;
ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
(wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
(wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT));
ps->en = 0;
if (cso->max_anisotropy >= 2) {
/* no idea, binary driver sets it, works without it.. meh.. */
ps->wrap |= (1 << 5);
if (cso->max_anisotropy >= 16) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
} else
if (cso->max_anisotropy >= 12) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
} else
if (cso->max_anisotropy >= 10) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
} else
if (cso->max_anisotropy >= 8) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
} else
if (cso->max_anisotropy >= 6) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
} else
if (cso->max_anisotropy >= 4) {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
} else {
ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
}
}
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}
switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}
ps->filt = filter;
{
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 * 256.0) << 7;
limit = CLAMP(cso->min_lod, 0.0, 15.0);
ps->en |= (int)(limit * 256.0) << 19;
}
if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
switch (cso->compare_func) {
case PIPE_FUNC_NEVER:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NEVER;
break;
case PIPE_FUNC_GREATER:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GREATER;
break;
case PIPE_FUNC_EQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_EQUAL;
break;
case PIPE_FUNC_GEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GEQUAL;
break;
case PIPE_FUNC_LESS:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LESS;
break;
case PIPE_FUNC_NOTEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
break;
case PIPE_FUNC_LEQUAL:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LEQUAL;
break;
case PIPE_FUNC_ALWAYS:
ps->wrap |= NV34TCL_TX_WRAP_RCOMP_ALWAYS;
break;
default:
break;
}
}
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
(float_to_ubyte(cso->border_color[0]) << 16) |
(float_to_ubyte(cso->border_color[1]) << 8) |
(float_to_ubyte(cso->border_color[2]) << 0));
return (void *)ps;
}
+8 -2
View File
@@ -219,13 +219,19 @@ extern void nvfx_fragprog_destroy(struct nvfx_context *,
struct nvfx_fragment_program *);
/* nv30_fragtex.c */
extern void nv30_init_sampler_functions(struct nvfx_context *nvfx);
extern void
nv30_sampler_state_init(struct pipe_context *pipe,
struct nvfx_sampler_state *ps,
const struct pipe_sampler_state *cso);
extern void nv30_fragtex_bind(struct nvfx_context *);
extern struct nouveau_stateobj *
nv30_fragtex_build(struct nvfx_context *nvfx, int unit);
/* nv40_fragtex.c */
extern void nv40_init_sampler_functions(struct nvfx_context *nvfx);
extern void
nv40_sampler_state_init(struct pipe_context *pipe,
struct nvfx_sampler_state *ps,
const struct pipe_sampler_state *cso);
extern void nv40_fragtex_bind(struct nvfx_context *);
extern struct nouveau_stateobj *
nv40_fragtex_build(struct nvfx_context *nvfx, int unit);
+33 -16
View File
@@ -8,6 +8,7 @@
#include "nvfx_context.h"
#include "nvfx_state.h"
#include "nvfx_tex.h"
static void *
nvfx_blend_state_create(struct pipe_context *pipe,
@@ -82,8 +83,35 @@ 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
nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
unsigned unit;
@@ -103,7 +131,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
}
static void
nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
{
FREE(hwcso);
}
@@ -543,14 +571,6 @@ nvfx_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
/*nvfx->draw_dirty |= NVFX_NEW_ARRAYS;*/
}
void *
nv30_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso);
void *
nv40_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso);
void
nvfx_init_state_functions(struct nvfx_context *nvfx)
{
@@ -558,12 +578,9 @@ 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;
if(nvfx->is_nv4x)
nvfx->pipe.create_sampler_state = nv40_sampler_state_create;
else
nvfx->pipe.create_sampler_state = nv30_sampler_state_create;
nvfx->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind;
nvfx->pipe.delete_sampler_state = nv40_sampler_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_textures = nvfx_set_sampler_texture;
nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
-8
View File
@@ -4,14 +4,6 @@
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
struct nvfx_sampler_state {
uint32_t fmt;
uint32_t wrap;
uint32_t en;
uint32_t filt;
uint32_t bcol;
};
struct nvfx_vertex_program_exec {
uint32_t data[4];
boolean has_branch_offset;
+133
View File
@@ -0,0 +1,133 @@
#ifndef NVFX_TEX_H_
#define NVFX_TEX_H_
static inline unsigned
nvfx_tex_wrap_mode(unsigned wrap) {
unsigned ret;
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV34TCL_TX_WRAP_S_CLAMP;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
break;
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV34TCL_TX_WRAP_S_REPEAT;
break;
}
return ret >> NV34TCL_TX_WRAP_S_SHIFT;
}
static inline unsigned
nvfx_tex_wrap_compare_mode(const struct pipe_sampler_state* cso)
{
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;
}
}
return 0;
}
static inline unsigned nvfx_tex_filter(const struct pipe_sampler_state* cso)
{
unsigned filter = 0;
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}
switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}
return filter;
}
static inline unsigned nvfx_tex_border_color(const float* border_color)
{
return ((float_to_ubyte(border_color[3]) << 24) |
(float_to_ubyte(border_color[0]) << 16) |
(float_to_ubyte(border_color[1]) << 8) |
(float_to_ubyte(border_color[2]) << 0));
}
struct nvfx_sampler_state {
uint32_t fmt;
uint32_t wrap;
uint32_t en;
uint32_t filt;
uint32_t bcol;
};
#endif /* NVFX_TEX_H_ */