r600g: consolidate set_sampler_views functions
[mesa.git] / src / gallium / drivers / r600 / r600_blit.c
index e9ed0740e659bb0c5d79b94d5e12289996f48847..072df143f1328a8472de27af60925acbf3da5260 100644 (file)
@@ -145,6 +145,16 @@ void r600_blit_decompress_depth(struct pipe_context *ctx,
        if (!staging && !texture->dirty_level_mask)
                return;
 
+       max_sample = u_max_sample(&texture->resource.b.b);
+
+       /* XXX Decompressing MSAA depth textures is broken on R6xx.
+        * There is also a hardlock if CMASK and FMASK are not present.
+        * Just skip this until we find out how to fix it. */
+       if (rctx->chip_class == R600 && max_sample > 0) {
+               texture->dirty_level_mask = 0;
+               return;
+       }
+
        if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 ||
            rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635)
                depth = 0.0f;
@@ -158,7 +168,6 @@ void r600_blit_decompress_depth(struct pipe_context *ctx,
        rctx->db_misc_state.copy_sample = first_sample;
        r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
 
-       max_sample = u_max_sample(&texture->resource.b.b);
 
        for (level = first_level; level <= last_level; level++) {
                if (!staging && !(texture->dirty_level_mask & (1 << level)))
@@ -251,6 +260,8 @@ static void r600_blit_decompress_color(struct pipe_context *ctx,
        struct r600_context *rctx = (struct r600_context *)ctx;
        unsigned layer, level, checked_last_layer, max_layer;
 
+       assert(rctx->chip_class != CAYMAN);
+
        if (!rtex->dirty_level_mask)
                return;
 
@@ -295,6 +306,13 @@ void r600_decompress_color_textures(struct r600_context *rctx,
        unsigned i;
        unsigned mask = textures->compressed_colortex_mask;
 
+       /* Cayman cannot decompress an MSAA colorbuffer,
+        * but it can read it compressed, so skip this. */
+       assert(rctx->chip_class != CAYMAN);
+       if (rctx->chip_class == CAYMAN) {
+               return;
+       }
+
        while (mask) {
                struct pipe_sampler_view *view;
                struct r600_texture *tex;
@@ -332,7 +350,7 @@ static void r600_copy_first_sample(struct pipe_context *ctx,
                                           info->src.layer, info->src.layer,
                                           0, 0);
        }
-       if (rsrc->fmask_size && rsrc->cmask_size) {
+       if (rctx->chip_class != CAYMAN && rsrc->fmask_size && rsrc->cmask_size) {
                r600_blit_decompress_color(ctx, rsrc,
                                           0, 0,
                                           info->src.layer, info->src.layer);
@@ -390,6 +408,8 @@ static void r600_color_resolve(struct pipe_context *ctx,
        struct pipe_screen *screen = ctx->screen;
        struct pipe_resource *tmp, templ;
        struct pipe_box box;
+       unsigned sample_mask =
+               rctx->chip_class == CAYMAN ? ~0 : ((1ull << MAX2(1, info->src.res->nr_samples)) - 1);
 
        assert((info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA);
 
@@ -398,7 +418,7 @@ static void r600_color_resolve(struct pipe_context *ctx,
                util_blitter_custom_resolve_color(rctx->blitter,
                                                  info->dst.res, info->dst.level, info->dst.layer,
                                                  info->src.res, info->src.layer,
-                                                 rctx->custom_blend_resolve);
+                                                 sample_mask, rctx->custom_blend_resolve);
                r600_blitter_end(ctx);
                return;
        }
@@ -423,7 +443,7 @@ static void r600_color_resolve(struct pipe_context *ctx,
        util_blitter_custom_resolve_color(rctx->blitter,
                                          tmp, 0, 0,
                                          info->src.res, info->src.layer,
-                                         rctx->custom_blend_resolve);
+                                         sample_mask, rctx->custom_blend_resolve);
        r600_blitter_end(ctx);
 
        /* this is correct for upside-down blits too */
@@ -676,7 +696,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
                                           src_box->z, src_box->z + src_box->depth - 1,
                                           0, u_max_sample(src));
        }
-       if (rsrc->fmask_size && rsrc->cmask_size) {
+       if (rctx->chip_class != CAYMAN && rsrc->fmask_size && rsrc->cmask_size) {
                r600_blit_decompress_color(ctx, rsrc, src_level, src_level,
                                           src_box->z, src_box->z + src_box->depth - 1);
        }
@@ -739,11 +759,20 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
                restore_orig[1] = TRUE;
        }
 
-       for (i = 0; i <= last_sample; i++) {
+       /* XXX Properly implement multisample textures on Cayman. In the meantime,
+        * copy only the first sample (which is the only one that doesn't return garbage). */
+       if (rctx->chip_class == CAYMAN) {
                r600_blitter_begin(ctx, R600_COPY_TEXTURE);
-               util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz,
-                                         src, src_level, i, psbox);
+               util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
+                                         src, src_level, 0, psbox);
                r600_blitter_end(ctx);
+       } else {
+               for (i = 0; i <= last_sample; i++) {
+                       r600_blitter_begin(ctx, R600_COPY_TEXTURE);
+                       util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz,
+                                                 src, src_level, i, psbox);
+                       r600_blitter_end(ctx);
+               }
        }
 
        if (restore_orig[0])