[Mesa-dev] [PATCH 4/6] r600g: implement ARB_seamless_cube_map for evergreen
Marek Olšák
maraeo at gmail.com
Mon May 2 06:03:04 PDT 2011
The Gallium state bit is part of pipe_rasterizer_state, but the hardware
state is per-sampler. The idea here is to change the state bit in sampler
state registers based on the currently-bound rasterizer state.
---
src/gallium/drivers/r600/evergreen_state.c | 45 +++++++++++++++++++++++++-
src/gallium/drivers/r600/evergreend.h | 9 +++++
src/gallium/drivers/r600/r600_pipe.c | 1 +
src/gallium/drivers/r600/r600_pipe.h | 5 ++-
src/gallium/drivers/r600/r600_state_common.c | 1 +
5 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index e325361..3e7f64d 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -239,6 +239,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
rstate = &rs->rstate;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
+ rs->seamless_cube_map = state->seamless_cube_map;
clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
@@ -478,15 +479,35 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
rctx->ps_samplers.n_views = count;
}
+static void evergreen_update_seamless_cube_map_state(struct r600_textures_info *tex,
+ boolean enable)
+{
+ unsigned i;
+
+ for (i = 0; i < tex->n_samplers; i++) {
+ if (tex->samplers[i]) {
+ struct r600_pipe_state *state = tex->samplers[i];
+
+ /* SQ_TEX_SAMPLER_WORD2_0 is at index 2. */
+ if (enable) {
+ state->regs[2].value &= C_03C008_DISABLE_CUBE_WRAP;
+ } else {
+ state->regs[2].value |= S_03C008_DISABLE_CUBE_WRAP(1);
+ }
+ }
+ }
+}
+
static void evergreen_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
-
memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
rctx->ps_samplers.n_samplers = count;
+ evergreen_update_seamless_cube_map_state(&rctx->ps_samplers, rctx->seamless_cube_map);
+
for (int i = 0; i < count; i++) {
evergreen_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i);
}
@@ -497,11 +518,33 @@ static void evergreen_bind_vs_sampler(struct pipe_context *ctx, unsigned count,
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
+ memcpy(rctx->vs_samplers.samplers, states, sizeof(void*) * count);
+ rctx->vs_samplers.n_samplers = count;
+
+ evergreen_update_seamless_cube_map_state(&rctx->vs_samplers, rctx->seamless_cube_map);
+
for (int i = 0; i < count; i++) {
evergreen_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i);
}
}
+void evergreen_set_seamless_cube_map(struct r600_pipe_context *rctx, boolean enable)
+{
+ if (rctx->seamless_cube_map != enable) {
+ rctx->seamless_cube_map = enable;
+
+ evergreen_update_seamless_cube_map_state(&rctx->ps_samplers, enable);
+ evergreen_update_seamless_cube_map_state(&rctx->vs_samplers, enable);
+
+ evergreen_bind_ps_sampler(&rctx->context,
+ rctx->ps_samplers.n_samplers,
+ rctx->ps_samplers.samplers);
+ evergreen_bind_vs_sampler(&rctx->context,
+ rctx->vs_samplers.n_samplers,
+ rctx->vs_samplers.samplers);
+ }
+}
+
static void evergreen_set_clip_state(struct pipe_context *ctx,
const struct pipe_clip_state *state)
{
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index de445b8..670606d 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -1194,6 +1194,15 @@
#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21)
#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1)
#define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF
+#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22)
+#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f)
+#define C_03C008_ANISO_BIAS (~(0x3f << 22))
+#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28)
+#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1)
+#define C_03C008_TRUNCATE_COORD (~(1 << 28))
+#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29)
+#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1)
+#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29))
#define S_03C008_TYPE(x) (((x) & 0x1) << 31)
#define G_03C008_TYPE(x) (((x) >> 31) & 0x1)
#define C_03C008_TYPE 0x7FFFFFFF
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index e28d834..677d42b 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -373,6 +373,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+ case PIPE_CAP_SEAMLESS_CUBE_MAP:
return 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_INDEP_BLEND_FUNC:
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index ae2a57e..55b836e 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -87,6 +87,7 @@ struct r600_pipe_sampler_view {
struct r600_pipe_rasterizer {
struct r600_pipe_state rstate;
bool flatshade;
+ boolean seamless_cube_map;
unsigned sprite_coord_enable;
float offset_units;
float offset_scale;
@@ -186,7 +187,8 @@ struct r600_pipe_context {
/* shader information */
unsigned sprite_coord_enable;
bool flatshade;
- struct r600_textures_info ps_samplers;
+ boolean seamless_cube_map;
+ struct r600_textures_info ps_samplers, vs_samplers;
struct r600_pipe_fences fences;
@@ -216,6 +218,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
struct r600_pipe_state *rstate,
struct r600_resource *rbuffer,
unsigned offset, unsigned stride);
+void evergreen_set_seamless_cube_map(struct r600_pipe_context *rctx, boolean enable);
/* r600_blit.c */
void r600_init_blit_functions(struct r600_pipe_context *rctx);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index cf605e1..591b2ef 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -103,6 +103,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
if (rctx->family >= CHIP_CEDAR) {
evergreen_polygon_offset_update(rctx);
+ evergreen_set_seamless_cube_map(rctx, rs->seamless_cube_map);
} else {
r600_polygon_offset_update(rctx);
}
--
1.7.4.1
More information about the mesa-dev
mailing list