gallium/radeon: boolean -> bool, TRUE -> true, FALSE -> false
[mesa.git] / src / gallium / drivers / radeon / r600_texture.c
index b0f375e4b1f67c34f5aec6eec38d8d0acd349169..81acd42a330c37add3834d455a446f4bf30ba47e 100644 (file)
@@ -366,7 +366,7 @@ static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
                rtex->cb_color_info &= ~EG_S_028C70_FAST_CLEAR(1);
 
        if (rtex->cmask_buffer != &rtex->resource)
-           pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
+           r600_resource_reference(&rtex->cmask_buffer, NULL);
 
        /* Notify all contexts about the change. */
        r600_dirty_all_framebuffer_states(rscreen);
@@ -559,9 +559,9 @@ static void r600_texture_destroy(struct pipe_screen *screen,
        if (rtex->flushed_depth_texture)
                pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
 
-       pipe_resource_reference((struct pipe_resource**)&rtex->htile_buffer, NULL);
+       r600_resource_reference(&rtex->htile_buffer, NULL);
        if (rtex->cmask_buffer != &rtex->resource) {
-           pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
+           r600_resource_reference(&rtex->cmask_buffer, NULL);
        }
        pb_reference(&resource->buf, NULL);
        FREE(rtex);
@@ -1012,6 +1012,8 @@ r600_texture_create_object(struct pipe_screen *screen,
         * This must be done after r600_setup_surface.
         * Applies to R600-Cayman. */
        rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D;
+       /* Applies to GCN. */
+       rtex->last_msaa_resolve_target_micro_mode = rtex->surface.micro_tile_mode;
 
        if (rtex->is_depth) {
                if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER |
@@ -1272,7 +1274,7 @@ bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
                return false;
        }
 
-       (*flushed_depth_texture)->is_flushing_texture = TRUE;
+       (*flushed_depth_texture)->is_flushing_texture = true;
        (*flushed_depth_texture)->non_disp_tiling = false;
        return true;
 }
@@ -1509,7 +1511,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
        }
 
        if (!(map = r600_buffer_map_sync_with_rings(rctx, buf, usage))) {
-               pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL);
+               r600_resource_reference(&trans->staging, NULL);
                FREE(trans);
                return NULL;
        }
@@ -1539,7 +1541,7 @@ static void r600_texture_transfer_unmap(struct pipe_context *ctx,
 
        if (rtransfer->staging) {
                rctx->num_alloc_tex_transfer_bytes += rtransfer->staging->buf->size;
-               pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
+               r600_resource_reference(&rtransfer->staging, NULL);
        }
 
        /* Heuristic for {upload, draw, upload, draw, ..}:
@@ -1633,8 +1635,8 @@ static void r600_surface_destroy(struct pipe_context *pipe,
                                 struct pipe_surface *surface)
 {
        struct r600_surface *surf = (struct r600_surface*)surface;
-       pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL);
-       pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL);
+       r600_resource_reference(&surf->cb_buffer_fmask, NULL);
+       r600_resource_reference(&surf->cb_buffer_cmask, NULL);
        pipe_resource_reference(&surface->texture, NULL);
        FREE(surface);
 }
@@ -1744,7 +1746,7 @@ static void vi_get_fast_clear_parameters(enum pipe_format surface_format,
            surface_format == PIPE_FORMAT_B5G6R5_SRGB) {
                extra_channel = -1;
        } else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
-               if(r600_translate_colorswap(surface_format, FALSE) <= 1)
+               if(r600_translate_colorswap(surface_format, false) <= 1)
                        extra_channel = desc->nr_channels - 1;
                else
                        extra_channel = 0;
@@ -1793,6 +1795,98 @@ static void vi_get_fast_clear_parameters(enum pipe_format surface_format,
                *reset_value |= 0x40404040U;
 }
 
+void vi_dcc_clear_level(struct r600_common_context *rctx,
+                       struct r600_texture *rtex,
+                       unsigned level, unsigned clear_value)
+{
+       struct pipe_resource *dcc_buffer = &rtex->resource.b.b;
+       uint64_t dcc_offset = rtex->dcc_offset +
+                             rtex->surface.level[level].dcc_offset;
+
+       assert(rtex->dcc_offset && rtex->surface.level[level].dcc_enabled);
+
+       rctx->clear_buffer(&rctx->b, dcc_buffer, dcc_offset,
+                          rtex->surface.level[level].dcc_fast_clear_size,
+                          clear_value, R600_COHERENCY_CB_META);
+}
+
+/* Set the same micro tile mode as the destination of the last MSAA resolve.
+ * This allows hitting the MSAA resolve fast path, which requires that both
+ * src and dst micro tile modes match.
+ */
+static void si_set_optimal_micro_tile_mode(struct r600_common_screen *rscreen,
+                                          struct r600_texture *rtex)
+{
+       if (rtex->resource.is_shared ||
+           rtex->surface.nsamples <= 1 ||
+           rtex->surface.micro_tile_mode == rtex->last_msaa_resolve_target_micro_mode)
+               return;
+
+       assert(rtex->surface.level[0].mode == RADEON_SURF_MODE_2D);
+       assert(rtex->surface.last_level == 0);
+
+       /* These magic numbers were copied from addrlib. It doesn't use any
+        * definitions for them either. They are all 2D_TILED_THIN1 modes with
+        * different bpp and micro tile mode.
+        */
+       if (rscreen->chip_class >= CIK) {
+               switch (rtex->last_msaa_resolve_target_micro_mode) {
+               case 0: /* displayable */
+                       rtex->surface.tiling_index[0] = 10;
+                       break;
+               case 1: /* thin */
+                       rtex->surface.tiling_index[0] = 14;
+                       break;
+               case 3: /* rotated */
+                       rtex->surface.tiling_index[0] = 28;
+                       break;
+               default: /* depth, thick */
+                       assert(!"unexpected micro mode");
+                       return;
+               }
+       } else { /* SI */
+               switch (rtex->last_msaa_resolve_target_micro_mode) {
+               case 0: /* displayable */
+                       switch (rtex->surface.bpe) {
+                       case 8:
+                            rtex->surface.tiling_index[0] = 10;
+                            break;
+                       case 16:
+                            rtex->surface.tiling_index[0] = 11;
+                            break;
+                       default: /* 32, 64 */
+                            rtex->surface.tiling_index[0] = 12;
+                            break;
+                       }
+                       break;
+               case 1: /* thin */
+                       switch (rtex->surface.bpe) {
+                       case 8:
+                                rtex->surface.tiling_index[0] = 14;
+                                break;
+                       case 16:
+                                rtex->surface.tiling_index[0] = 15;
+                                break;
+                       case 32:
+                                rtex->surface.tiling_index[0] = 16;
+                                break;
+                       default: /* 64, 128 */
+                                rtex->surface.tiling_index[0] = 17;
+                                break;
+                       }
+                       break;
+               default: /* depth, thick */
+                       assert(!"unexpected micro mode");
+                       return;
+               }
+       }
+
+       rtex->surface.micro_tile_mode = rtex->last_msaa_resolve_target_micro_mode;
+
+       p_atomic_inc(&rscreen->dirty_fb_counter);
+       p_atomic_inc(&rscreen->dirty_tex_descriptor_counter);
+}
+
 void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                                   struct pipe_framebuffer_state *fb,
                                   struct r600_atom *fb_state,
@@ -1866,12 +1960,12 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                        if (rctx->screen->debug_flags & DBG_NO_DCC_CLEAR)
                                continue;
 
-                       vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
+                       /* We can change the micro tile mode before a full clear. */
+                       if (rctx->screen->chip_class >= SI)
+                               si_set_optimal_micro_tile_mode(rctx->screen, tex);
 
-                       rctx->clear_buffer(&rctx->b, &tex->resource.b.b,
-                                          tex->dcc_offset,
-                                          tex->surface.level[0].dcc_fast_clear_size,
-                                          reset_value, R600_COHERENCY_CB_META);
+                       vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
+                       vi_dcc_clear_level(rctx, tex, 0, reset_value);
 
                        if (clear_words_needed)
                                tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
@@ -1886,6 +1980,10 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                                continue;
                        }
 
+                       /* We can change the micro tile mode before a full clear. */
+                       if (rctx->screen->chip_class >= SI)
+                               si_set_optimal_micro_tile_mode(rctx->screen, tex);
+
                        /* Do the fast clear. */
                        rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
                                           tex->cmask.offset, tex->cmask.size, 0,