summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx
diff options
context:
space:
mode:
authorLuca Barbieri <[email protected]>2010-02-24 15:08:48 +0100
committerYounes Manton <[email protected]>2010-03-15 00:03:03 -0400
commit7d210fa05f286eb19398ac2f8c8f631f6f83c859 (patch)
tree5f070b61e5ffb7cf67d1957ef67ac11ef4c8e8e2 /src/gallium/drivers/nvfx
parent5bb68e5d174afa7a177c5e972fa80bf66e37f6ab (diff)
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.
Diffstat (limited to 'src/gallium/drivers/nvfx')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h10
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c49
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.h8
-rw-r--r--src/gallium/drivers/nvfx/nvfx_tex.h133
4 files changed, 174 insertions, 26 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index e5389042981..5eed8a560e5 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -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);
diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c
index 7e138afc717..88a9d01c509 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.c
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -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;
diff --git a/src/gallium/drivers/nvfx/nvfx_state.h b/src/gallium/drivers/nvfx/nvfx_state.h
index b243b1020fb..e585246879b 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.h
+++ b/src/gallium/drivers/nvfx/nvfx_state.h
@@ -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;
diff --git a/src/gallium/drivers/nvfx/nvfx_tex.h b/src/gallium/drivers/nvfx/nvfx_tex.h
new file mode 100644
index 00000000000..69187a79e79
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_tex.h
@@ -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_ */