Mesa (master): r600g: implement seamless_cube_map on r600-r700

Marek Olšák mareko at kemper.freedesktop.org
Sun Jun 19 23:42:15 UTC 2011


Module: Mesa
Branch: master
Commit: badf0335ef70223204fbae3e8fdef718cdb3ad19
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=badf0335ef70223204fbae3e8fdef718cdb3ad19

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 23:41:02 2011 +0200

r600g: implement seamless_cube_map on r600-r700

st/mesa guarantees that all bound sampler states have the same value
in seamless_cube_map.

---

 src/gallium/drivers/r600/r600_pipe.c  |    2 +-
 src/gallium/drivers/r600/r600_pipe.h  |    6 ++++
 src/gallium/drivers/r600/r600_state.c |   45 ++++++++++++++++++++++++++++----
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 16fe6c5..a0d145d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -376,6 +376,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
 	case PIPE_CAP_SM3:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
 		return 1;
 
 	/* Supported except the original R600. */
@@ -385,7 +386,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 		return family == CHIP_R600 ? 0 : 1;
 
 	/* Supported on Evergreen. */
-	case PIPE_CAP_SEAMLESS_CUBE_MAP:
 	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
 		return family >= CHIP_CEDAR ? 1 : 0;
 
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 84a45be..9941bbf 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -50,6 +50,7 @@ enum r600_pipe_state_id {
 	R600_PIPE_STATE_BLEND = 0,
 	R600_PIPE_STATE_BLEND_COLOR,
 	R600_PIPE_STATE_CONFIG,
+	R600_PIPE_STATE_SEAMLESS_CUBEMAP,
 	R600_PIPE_STATE_CLIP,
 	R600_PIPE_STATE_SCISSOR,
 	R600_PIPE_STATE_VIEWPORT,
@@ -126,6 +127,11 @@ struct r600_pipe_shader {
 	struct r600_vertex_element	vertex_elements;
 };
 
+struct r600_pipe_sampler_state {
+	struct r600_pipe_state		rstate;
+	boolean seamless_cube_map;
+};
+
 /* needed for blitter save */
 #define NUM_TEX_UNITS 16
 
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 4ce1740..91da7c5 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -369,14 +369,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 static void *r600_create_sampler_state(struct pipe_context *ctx,
 					const struct pipe_sampler_state *state)
 {
-	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+	struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state);
+	struct r600_pipe_state *rstate;
 	union util_color uc;
 	unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0;
 
-	if (rstate == NULL) {
+	if (ss == NULL) {
 		return NULL;
 	}
 
+	ss->seamless_cube_map = state->seamless_cube_map;
+	rstate = &ss->rstate;
 	rstate->id = R600_PIPE_STATE_SAMPLER;
 	util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
 	r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -559,27 +562,57 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count,
 	rctx->ps_samplers.n_views = count;
 }
 
+static void r600_set_seamless_cubemap(struct r600_pipe_context *rctx, boolean enable)
+{
+	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+	if (rstate == NULL)
+		return;
+
+	rstate->id = R600_PIPE_STATE_SEAMLESS_CUBEMAP;
+	r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+				(enable ? 0 : S_009508_DISABLE_CUBE_WRAP(1)),
+				1, NULL);
+
+	free(rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP]);
+	rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP] = rstate;
+	r600_context_pipe_state_set(&rctx->ctx, rstate);
+}
+
 static void r600_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;
+	struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+	int seamless = -1;
 
 	memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
 	rctx->ps_samplers.n_samplers = count;
 
 	for (int i = 0; i < count; i++) {
-		r600_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i);
+		r600_context_pipe_state_set_ps_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+		if (sstates[i])
+			seamless = sstates[i]->seamless_cube_map;
 	}
+
+	if (seamless != -1)
+		r600_set_seamless_cubemap(rctx, seamless);
 }
 
 static void r600_bind_vs_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;
+	struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+	int seamless = -1;
 
 	for (int i = 0; i < count; i++) {
-		r600_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i);
+		r600_context_pipe_state_set_vs_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+		if (sstates[i])
+			seamless = sstates[i]->seamless_cube_map;
 	}
+
+	if (seamless != -1)
+		r600_set_seamless_cubemap(rctx, seamless);
 }
 
 static void r600_set_clip_state(struct pipe_context *ctx,




More information about the mesa-commit mailing list