From c8d4108fbee679735a1cc3f405d848d01bfb23f6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 12 Oct 2010 13:24:01 +1000 Subject: [PATCH] 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 a5298e3fdf9..4e95d4c4905 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #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 4bf44a171af..aecc87f7da1 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -24,10 +24,19 @@ #include #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 c46029a5617..34a59646d51 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 25310eeda4e..b2e7c282e28 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #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 */ -- 2.30.2