From f8d11b2e8ebaab2845080900ff4a2068f9a20b5f Mon Sep 17 00:00:00 2001
From: Jerome Glisse <jglisse@redhat.com>
Date: Thu, 2 Sep 2010 16:53:33 -0400
Subject: r600g: force unbind of previously bind sampler/sampler_view

Previously bind sampler/sampler_view can be converted and endup
overwritting the current state we want to schedule. Example :
bind texA texB to sampler_view[0] & sampler_view[1], render,
bind texB to sampler_view[0] render. Now state associated to
texB are set to configure sampler_view slot 0, but as we don't
unbind sampler_view[1] still point to texB state so we end up
with sampler_view[1] overwritting sampler_view[0], which gives
wrong rendering if next rendering bind texA to sampler_view[0],
it will endup as texB is bound to sampler_view[0]. If you are
not confuse at that point give me a call i will be buying you
beer.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
---
 src/gallium/drivers/r600/r600_state.c | 178 ++++++++++++++++++----------------
 1 file changed, 95 insertions(+), 83 deletions(-)

(limited to 'src/gallium/drivers/r600')

diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 66cab7d7a6..2071fef403 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -101,6 +101,72 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
 	return &rstate->state.sampler_view;
 }
 
+static void r600_set_ps_sampler_view(struct pipe_context *ctx,
+					unsigned count,
+					struct pipe_sampler_view **views)
+{
+	struct r600_context *rctx = r600_context(ctx);
+	struct r600_context_state *rstate;
+	unsigned i;
+
+	for (i = 0; i < rctx->ps_nsampler_view; i++) {
+		radeon_draw_unbind(&rctx->draw, rctx->ps_sampler_view[i]);
+	}
+	for (i = 0; i < count; i++) {
+		rstate = (struct r600_context_state *)views[i];
+		if (rstate) {
+			rstate->nrstate = 0;
+		}
+	}
+	for (i = 0; i < count; i++) {
+		rstate = (struct r600_context_state *)views[i];
+		if (rstate) {
+			if (rstate->nrstate >= R600_MAX_RSTATE)
+				continue;
+			if (rstate->nrstate) {
+				memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+			}
+			radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_PS);
+			rctx->ps_sampler_view[i] = &rstate->rstate[rstate->nrstate];
+			rstate->nrstate++;
+		}
+	}
+	rctx->ps_nsampler_view = count;
+}
+
+static void r600_set_vs_sampler_view(struct pipe_context *ctx,
+					unsigned count,
+					struct pipe_sampler_view **views)
+{
+	struct r600_context *rctx = r600_context(ctx);
+	struct r600_context_state *rstate;
+	unsigned i;
+
+	for (i = 0; i < rctx->vs_nsampler_view; i++) {
+		radeon_draw_unbind(&rctx->draw, rctx->vs_sampler_view[i]);
+	}
+	for (i = 0; i < count; i++) {
+		rstate = (struct r600_context_state *)views[i];
+		if (rstate) {
+			rstate->nrstate = 0;
+		}
+	}
+	for (i = 0; i < count; i++) {
+		rstate = (struct r600_context_state *)views[i];
+		if (rstate) {
+			if (rstate->nrstate >= R600_MAX_RSTATE)
+				continue;
+			if (rstate->nrstate) {
+				memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+			}
+			radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_VS);
+			rctx->vs_sampler_view[i] = &rstate->rstate[rstate->nrstate];
+			rstate->nrstate++;
+		}
+	}
+	rctx->vs_nsampler_view = count;
+}
+
 static void *r600_create_shader_state(struct pipe_context *ctx,
 					const struct pipe_shader_state *state)
 {
@@ -122,6 +188,29 @@ static void *r600_create_vertex_elements(struct pipe_context *ctx,
 	return v;
 }
 
+static void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
+{
+	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+	if (v == NULL)
+		return;
+	if (--v->refcount)
+		return;
+	free(v);
+}
+
+static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
+{
+	struct r600_context *rctx = r600_context(ctx);
+	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
+
+	r600_delete_vertex_element(ctx, rctx->vertex_elements);
+	rctx->vertex_elements = v;
+	if (v) {
+		v->refcount++;
+	}
+}
+
 static void r600_bind_state(struct pipe_context *ctx, void *state)
 {
 	struct r600_context *rctx = r600_context(ctx);
@@ -205,29 +294,6 @@ static void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
 	rctx->vs_shader = r600_context_state_incref(rstate);
 }
 
-static void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
-{
-	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
-
-	if (v == NULL)
-		return;
-	if (--v->refcount)
-		return;
-	free(v);
-}
-
-static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
-{
-	struct r600_context *rctx = r600_context(ctx);
-	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
-
-	r600_delete_vertex_element(ctx, rctx->vertex_elements);
-	rctx->vertex_elements = v;
-	if (v) {
-		v->refcount++;
-	}
-}
-
 static void r600_bind_ps_sampler(struct pipe_context *ctx,
 					unsigned count, void **states)
 {
@@ -235,6 +301,9 @@ static void r600_bind_ps_sampler(struct pipe_context *ctx,
 	struct r600_context_state *rstate;
 	unsigned i;
 
+	for (i = 0; i < rctx->ps_nsampler; i++) {
+		radeon_draw_unbind(&rctx->draw, rctx->ps_sampler[i]);
+	}
 	for (i = 0; i < count; i++) {
 		rstate = (struct r600_context_state *)states[i];
 		if (rstate) {
@@ -264,6 +333,9 @@ static void r600_bind_vs_sampler(struct pipe_context *ctx,
 	struct r600_context_state *rstate;
 	unsigned i;
 
+	for (i = 0; i < rctx->vs_nsampler; i++) {
+		radeon_draw_unbind(&rctx->draw, rctx->vs_sampler[i]);
+	}
 	for (i = 0; i < count; i++) {
 		rstate = (struct r600_context_state *)states[i];
 		if (rstate) {
@@ -359,66 +431,6 @@ static void r600_set_constant_buffer(struct pipe_context *ctx,
 	}
 }
 
-static void r600_set_ps_sampler_view(struct pipe_context *ctx,
-					unsigned count,
-					struct pipe_sampler_view **views)
-{
-	struct r600_context *rctx = r600_context(ctx);
-	struct r600_context_state *rstate;
-	unsigned i;
-
-	for (i = 0; i < count; i++) {
-		rstate = (struct r600_context_state *)views[i];
-		if (rstate) {
-			rstate->nrstate = 0;
-		}
-	}
-	for (i = 0; i < count; i++) {
-		rstate = (struct r600_context_state *)views[i];
-		if (rstate) {
-			if (rstate->nrstate >= R600_MAX_RSTATE)
-				continue;
-			if (rstate->nrstate) {
-				memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
-			}
-			radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_PS);
-			rctx->ps_sampler_view[i] = &rstate->rstate[rstate->nrstate];
-			rstate->nrstate++;
-		}
-	}
-	rctx->ps_nsampler_view = count;
-}
-
-static void r600_set_vs_sampler_view(struct pipe_context *ctx,
-					unsigned count,
-					struct pipe_sampler_view **views)
-{
-	struct r600_context *rctx = r600_context(ctx);
-	struct r600_context_state *rstate;
-	unsigned i;
-
-	for (i = 0; i < count; i++) {
-		rstate = (struct r600_context_state *)views[i];
-		if (rstate) {
-			rstate->nrstate = 0;
-		}
-	}
-	for (i = 0; i < count; i++) {
-		rstate = (struct r600_context_state *)views[i];
-		if (rstate) {
-			if (rstate->nrstate >= R600_MAX_RSTATE)
-				continue;
-			if (rstate->nrstate) {
-				memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
-			}
-			radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_VS);
-			rctx->vs_sampler_view[i] = &rstate->rstate[rstate->nrstate];
-			rstate->nrstate++;
-		}
-	}
-	rctx->vs_nsampler_view = count;
-}
-
 static void r600_set_framebuffer_state(struct pipe_context *ctx,
 					const struct pipe_framebuffer_state *state)
 {
-- 
cgit v1.2.3