[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