winsys/radeon: fold cs_set_flush_callback into cs_create
[mesa.git] / src / gallium / drivers / radeonsi / si_blit.c
index ba2ebe7d7f02b0dbdd4e2a1ec9494a363fa9f78a..6bc89ab76d17575712e3bea5c8de485802211fea 100644 (file)
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "util/u_surface.h"
+
+#include "si_pipe.h"
 #include "util/u_blitter.h"
 #include "util/u_format.h"
-#include "si_pipe.h"
-#include "si_state.h"
 
 enum si_blitter_op /* bitmask */
 {
@@ -51,13 +50,14 @@ static void si_blitter_begin(struct pipe_context *ctx, enum si_blitter_op op)
 {
        struct si_context *sctx = (struct si_context *)ctx;
 
-       si_context_queries_suspend(sctx);
+       r600_suspend_nontimer_queries(&sctx->b);
 
        util_blitter_save_blend(sctx->blitter, sctx->queued.named.blend);
        util_blitter_save_depth_stencil_alpha(sctx->blitter, sctx->queued.named.dsa);
        util_blitter_save_stencil_ref(sctx->blitter, &sctx->stencil_ref);
        util_blitter_save_rasterizer(sctx->blitter, sctx->queued.named.rasterizer);
        util_blitter_save_fragment_shader(sctx->blitter, sctx->ps_shader);
+       util_blitter_save_geometry_shader(sctx->blitter, sctx->gs_shader);
        util_blitter_save_vertex_shader(sctx->blitter, sctx->vs_shader);
        util_blitter_save_vertex_elements(sctx->blitter, sctx->vertex_elements);
        if (sctx->queued.named.viewport) {
@@ -68,7 +68,7 @@ static void si_blitter_begin(struct pipe_context *ctx, enum si_blitter_op op)
                                     (struct pipe_stream_output_target**)sctx->b.streamout.targets);
 
        if (op & SI_SAVE_FRAMEBUFFER)
-               util_blitter_save_framebuffer(sctx->blitter, &sctx->framebuffer);
+               util_blitter_save_framebuffer(sctx->blitter, &sctx->framebuffer.state);
 
        if (op & SI_SAVE_TEXTURES) {
                util_blitter_save_fragment_sampler_states(
@@ -81,26 +81,18 @@ static void si_blitter_begin(struct pipe_context *ctx, enum si_blitter_op op)
                        sctx->samplers[PIPE_SHADER_FRAGMENT].views.views);
        }
 
-       if ((op & SI_DISABLE_RENDER_COND) && sctx->current_render_cond) {
-               sctx->saved_render_cond = sctx->current_render_cond;
-               sctx->saved_render_cond_cond = sctx->current_render_cond_cond;
-               sctx->saved_render_cond_mode = sctx->current_render_cond_mode;
-               sctx->b.b.render_condition(&sctx->b.b, NULL, FALSE, 0);
+       if ((op & SI_DISABLE_RENDER_COND) && sctx->b.current_render_cond) {
+               util_blitter_save_render_condition(sctx->blitter,
+                                                   sctx->b.current_render_cond,
+                                                   sctx->b.current_render_cond_cond,
+                                                   sctx->b.current_render_cond_mode);
        }
-
 }
 
 static void si_blitter_end(struct pipe_context *ctx)
 {
        struct si_context *sctx = (struct si_context *)ctx;
-       if (sctx->saved_render_cond) {
-               sctx->b.b.render_condition(&sctx->b.b,
-                                              sctx->saved_render_cond,
-                                              sctx->saved_render_cond_cond,
-                                              sctx->saved_render_cond_mode);
-               sctx->saved_render_cond = NULL;
-       }
-       si_context_queries_resume(sctx);
+       r600_resume_nontimer_queries(&sctx->b);
 }
 
 static unsigned u_max_sample(struct pipe_resource *r)
@@ -285,7 +277,8 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
 
                        si_blitter_begin(ctx, SI_DECOMPRESS);
                        util_blitter_custom_color(sctx->blitter, cbsurf,
-                                                 sctx->custom_blend_decompress);
+                               rtex->fmask.size ? sctx->custom_blend_decompress :
+                                                  sctx->custom_blend_fastclear);
                        si_blitter_end(ctx);
 
                        pipe_surface_reference(&cbsurf, NULL);
@@ -328,7 +321,32 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
                     double depth, unsigned stencil)
 {
        struct si_context *sctx = (struct si_context *)ctx;
-       struct pipe_framebuffer_state *fb = &sctx->framebuffer;
+       struct pipe_framebuffer_state *fb = &sctx->framebuffer.state;
+
+       if (buffers & PIPE_CLEAR_COLOR) {
+               evergreen_do_fast_color_clear(&sctx->b, fb, &sctx->framebuffer.atom,
+                                             &buffers, color);
+       }
+
+       if (buffers & PIPE_CLEAR_COLOR) {
+               int i;
+
+               /* These buffers cannot use fast clear, make sure to disable expansion. */
+               for (i = 0; i < fb->nr_cbufs; i++) {
+                       struct r600_texture *tex;
+
+                       /* If not clearing this buffer, skip. */
+                       if (!(buffers & (PIPE_CLEAR_COLOR0 << i)))
+                               continue;
+
+                       if (!fb->cbufs[i])
+                               continue;
+
+                       tex = (struct r600_texture *)fb->cbufs[i]->texture;
+                       if (tex->fmask.size == 0)
+                               tex->dirty_level_mask &= ~(1 << fb->cbufs[i]->u.tex.level);
+               }
+       }
 
        si_blitter_begin(ctx, SI_CLEAR);
        util_blitter_clear(sctx->blitter, fb->width, fb->height,
@@ -491,9 +509,11 @@ static void si_resource_copy_region(struct pipe_context *ctx,
                                    const struct pipe_box *src_box)
 {
        struct si_context *sctx = (struct si_context *)ctx;
+       struct r600_texture *rdst = (struct r600_texture*)dst;
+       struct pipe_surface *dst_view, dst_templ;
+       struct pipe_sampler_view src_templ, *src_view;
        struct texture_orig_info orig_info[2];
-       struct pipe_box sbox;
-       const struct pipe_box *psbox = src_box;
+       struct pipe_box sbox, dstbox;
        boolean restore_orig[2];
 
        /* Fallback for buffers. */
@@ -521,7 +541,7 @@ static void si_resource_copy_region(struct pipe_context *ctx,
                sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width);
                sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
                sbox.depth = src_box->depth;
-               psbox=&sbox;
+               src_box = &sbox;
 
                si_compressed_to_blittable(dst, dst_level, &orig_info[1]);
                restore_orig[1] = TRUE;
@@ -571,11 +591,29 @@ static void si_resource_copy_region(struct pipe_context *ctx,
                restore_orig[1] = TRUE;
        }
 
+       /* Initialize the surface. */
+       util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
+       dst_view = r600_create_surface_custom(ctx, dst, &dst_templ,
+                                             rdst->surface.level[dst_level].npix_x,
+                                             rdst->surface.level[dst_level].npix_y);
+
+       /* Initialize the sampler view. */
+       util_blitter_default_src_texture(&src_templ, src, src_level);
+       src_view = ctx->create_sampler_view(ctx, src, &src_templ);
+
+       u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height),
+                abs(src_box->depth), &dstbox);
+
+       /* Copy. */
        si_blitter_begin(ctx, SI_COPY);
-       util_blitter_copy_texture(sctx->blitter, dst, dst_level, dstx, dsty, dstz,
-                                 src, src_level, psbox);
+       util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox,
+                                 src_view, src_box, src->width0, src->height0,
+                                 PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL);
        si_blitter_end(ctx);
 
+       pipe_surface_reference(&dst_view, NULL);
+       pipe_sampler_view_reference(&src_view, NULL);
+
        if (restore_orig[0])
                si_reset_blittable_to_orig(src, src_level, &orig_info[0]);
 
@@ -688,8 +726,16 @@ static void si_blit(struct pipe_context *ctx,
 }
 
 static void si_flush_resource(struct pipe_context *ctx,
-                             struct pipe_resource *resource)
+                             struct pipe_resource *res)
 {
+       struct r600_texture *rtex = (struct r600_texture*)res;
+
+       assert(res->target != PIPE_BUFFER);
+
+       if (!rtex->is_depth && rtex->cmask.size) {
+               si_blit_decompress_color(ctx, rtex, 0, res->last_level,
+                                        0, res->array_size - 1);
+       }
 }
 
 void si_init_blit_functions(struct si_context *sctx)