r600g: store samplers/views across blit when we need to modify them
authorDave Airlie <airlied@redhat.com>
Tue, 12 Oct 2010 03:24:01 +0000 (13:24 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 13 Oct 2010 05:11:30 +0000 (15:11 +1000)
also fixup framebuffer state copies to avoid bad state.

src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c

index a5298e3fdf9e41d0014282682397d4cc4292b27c..4e95d4c490588774c19e045e9ed179031e1abc56 100644 (file)
@@ -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 */
index 4bf44a171af3916f438e8567af8f11e78411143f..aecc87f7da10f9d831a461a21ace23888901e006 100644 (file)
 #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);
 }
 
 
index c46029a5617196fa885a4ed5ec736f6e1cc9e09d..34a59646d5136cf9e4c1c5aaebae2a73030a84a2 100644 (file)
@@ -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 {
index 25310eeda4e2977c6e13f962f3811f4b91cf2936..b2e7c282e28861c6a989630cdea36364b2d97bb7 100644 (file)
@@ -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 */