Mesa (master): r600g: store samplers/ views across blit when we need to modify them

Dave Airlie airlied at kemper.freedesktop.org
Wed Oct 13 05:12:47 UTC 2010


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Oct 12 13:24:01 2010 +1000

r600g: store samplers/views across blit when we need to modify them

also fixup framebuffer state copies to avoid bad state.

---

 src/gallium/drivers/r600/evergreen_state.c |   18 +++++----
 src/gallium/drivers/r600/r600_blit.c       |   51 +++++++++++++++++++--------
 src/gallium/drivers/r600/r600_pipe.h       |   10 +++++
 src/gallium/drivers/r600/r600_state.c      |   18 +++++----
 4 files changed, 66 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index a5298e3..4e95d4c 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -39,6 +39,7 @@
 #include <util/u_pack_color.h>
 #include <util/u_memory.h>
 #include <util/u_inlines.h>
+#include <util/u_framebuffer.h>
 #include <pipebuffer/pb_buffer.h>
 #include "r600.h"
 #include "evergreend.h"
@@ -500,6 +501,9 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 	struct r600_pipe_sampler_view **resource = (struct r600_pipe_sampler_view **)views;
 
+	rctx->ps_samplers.views = resource;
+	rctx->ps_samplers.n_views = count;
+
 	for (int i = 0; i < count; i++) {
 		if (resource[i]) {
 			evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state, i);
@@ -523,6 +527,9 @@ static void evergreen_bind_ps_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;
 
+	rctx->ps_samplers.samplers = states;
+	rctx->ps_samplers.n_samplers = count;
+
 	for (int i = 0; i < count; i++) {
 		evergreen_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i);
 	}
@@ -842,14 +849,9 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 
 	/* unreference old buffer and reference new one */
 	rstate->id = R600_PIPE_STATE_FRAMEBUFFER;
-	for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
-		pipe_surface_reference(&rctx->framebuffer.cbufs[i], NULL);
-	}
-	for (int i = 0; i < state->nr_cbufs; i++) {
-		pipe_surface_reference(&rctx->framebuffer.cbufs[i], state->cbufs[i]);
-	}
-	pipe_surface_reference(&rctx->framebuffer.zsbuf, state->zsbuf);
-	rctx->framebuffer = *state;
+
+	util_copy_framebuffer_state(&rctx->framebuffer, state);
+
 	rctx->pframebuffer = &rctx->framebuffer;
 
 	/* build states */
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 4bf44a1..aecc87f 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -24,10 +24,19 @@
 #include <util/u_blitter.h>
 #include "r600_pipe.h"
 
-static void r600_blitter_save_states(struct pipe_context *ctx)
+enum r600_blitter_op /* bitmask */
+{
+    R600_CLEAR         = 1,
+    R600_CLEAR_SURFACE = 2,
+    R600_COPY          = 4
+};
+
+static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op)
 {
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 
+	r600_context_queries_suspend(&rctx->ctx);
+
 	util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]);
 	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]);
 	if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) {
@@ -47,7 +56,25 @@ static void r600_blitter_save_states(struct pipe_context *ctx)
 
 	rctx->vertex_elements = NULL;
 
-	/* TODO queries */
+	if (op & (R600_CLEAR_SURFACE | R600_COPY))
+		util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer);
+
+	if (op & R600_COPY) {
+		util_blitter_save_fragment_sampler_states(
+			rctx->blitter, rctx->ps_samplers.n_samplers,
+			(void**)rctx->ps_samplers.samplers);
+
+		util_blitter_save_fragment_sampler_views(
+			rctx->blitter, rctx->ps_samplers.n_views,
+			(struct pipe_sampler_view**)rctx->ps_samplers.views);
+	}
+
+}
+
+static void r600_blitter_end(struct pipe_context *ctx)
+{
+	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+	r600_context_queries_resume(&rctx->ctx);
 }
 
 int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture)
@@ -73,9 +100,8 @@ int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_te
 			(struct pipe_resource*)texture->flushed_depth_texture,
 			0, level, 0, PIPE_BIND_RENDER_TARGET);
 
-	r600_blitter_save_states(ctx);
+	r600_blitter_begin(ctx, R600_CLEAR);
 	util_blitter_save_framebuffer(rctx->blitter, &fb);
-
 	if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 ||
 		rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635)
 		depth = 0.0f;
@@ -99,12 +125,11 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 	struct pipe_framebuffer_state *fb = &rctx->framebuffer;
 
-	r600_context_queries_suspend(&rctx->ctx);
-	r600_blitter_save_states(ctx);
+	r600_blitter_begin(ctx, R600_CLEAR);
 	util_blitter_clear(rctx->blitter, fb->width, fb->height,
 				fb->nr_cbufs, buffers, rgba, depth,
 				stencil);
-	r600_context_queries_resume(&rctx->ctx);
+	r600_blitter_end(ctx);
 }
 
 static void r600_clear_render_target(struct pipe_context *ctx,
@@ -114,13 +139,11 @@ static void r600_clear_render_target(struct pipe_context *ctx,
 				     unsigned width, unsigned height)
 {
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-	struct pipe_framebuffer_state *fb = &rctx->framebuffer;
 
-	r600_context_queries_suspend(&rctx->ctx);
-	util_blitter_save_framebuffer(rctx->blitter, fb);
+	r600_blitter_begin(ctx, R600_CLEAR_SURFACE);
 	util_blitter_clear_render_target(rctx->blitter, dst, rgba,
 					 dstx, dsty, width, height);
-	r600_context_queries_resume(&rctx->ctx);
+	r600_blitter_end(ctx);
 }
 
 static void r600_clear_depth_stencil(struct pipe_context *ctx,
@@ -132,13 +155,11 @@ static void r600_clear_depth_stencil(struct pipe_context *ctx,
 				     unsigned width, unsigned height)
 {
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-	struct pipe_framebuffer_state *fb = &rctx->framebuffer;
 
-	r600_context_queries_suspend(&rctx->ctx);
-	util_blitter_save_framebuffer(rctx->blitter, fb);
+	r600_blitter_begin(ctx, R600_CLEAR_SURFACE);
 	util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil,
 					 dstx, dsty, width, height);
-	r600_context_queries_resume(&rctx->ctx);
+	r600_blitter_end(ctx);
 }
 
 
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index c46029a..34a5964 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -92,6 +92,14 @@ struct r600_pipe_shader {
 	struct r600_vertex_element	vertex_elements;
 };
 
+/* needed for blitter save */
+struct r600_textures_info {
+	struct r600_pipe_sampler_view   **views;
+	unsigned                        n_views;
+	void				**samplers;
+	unsigned                        n_samplers;
+};
+
 struct r600_pipe_context {
 	struct pipe_context		context;
 	struct blitter_context		*blitter;
@@ -130,6 +138,8 @@ struct r600_pipe_context {
 	struct u_upload_mgr		*upload_vb;
 	struct u_upload_mgr		*upload_ib;
 	unsigned			any_user_vbs;
+	struct r600_textures_info       ps_samplers;
+
 };
 
 struct r600_drawl {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 25310ee..b2e7c28 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -38,6 +38,7 @@
 #include <util/u_inlines.h>
 #include <util/u_upload_mgr.h>
 #include <util/u_index_modify.h>
+#include <util/u_framebuffer.h>
 #include <pipebuffer/pb_buffer.h>
 #include "r600.h"
 #include "r600d.h"
@@ -703,6 +704,9 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count,
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 	struct r600_pipe_sampler_view **resource = (struct r600_pipe_sampler_view **)views;
 
+	rctx->ps_samplers.views = resource;
+	rctx->ps_samplers.n_views = count;
+
 	for (int i = 0; i < count; i++) {
 		if (resource[i]) {
 			r600_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state, i);
@@ -726,6 +730,9 @@ static void r600_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
 	struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
 
+	rctx->ps_samplers.samplers = states;
+	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);
 	}
@@ -1025,14 +1032,9 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
 
 	/* unreference old buffer and reference new one */
 	rstate->id = R600_PIPE_STATE_FRAMEBUFFER;
-	for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
-		pipe_surface_reference(&rctx->framebuffer.cbufs[i], NULL);
-	}
-	for (int i = 0; i < state->nr_cbufs; i++) {
-		pipe_surface_reference(&rctx->framebuffer.cbufs[i], state->cbufs[i]);
-	}
-	pipe_surface_reference(&rctx->framebuffer.zsbuf, state->zsbuf);
-	rctx->framebuffer = *state;
+
+	util_copy_framebuffer_state(&rctx->framebuffer, state);
+	
 	rctx->pframebuffer = &rctx->framebuffer;
 
 	/* build states */




More information about the mesa-commit mailing list