r600g: handle NULL colorbuffers correctly on Evergreen
[mesa.git] / src / gallium / drivers / r600 / evergreen_state.c
index 754c265c8c5871402f891064cd48c393a9617c29..77e3c95636dd12f8d04637127d9bf1d92685b6df 100644 (file)
@@ -711,9 +711,14 @@ boolean evergreen_is_format_supported(struct pipe_screen *screen,
                }
        }
 
-       if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
-           r600_is_sampler_format_supported(screen, format)) {
-               retval |= PIPE_BIND_SAMPLER_VIEW;
+       if (usage & PIPE_BIND_SAMPLER_VIEW) {
+               if (target == PIPE_BUFFER) {
+                       if (r600_is_vertex_format_supported(format))
+                               retval |= PIPE_BIND_SAMPLER_VIEW;
+               } else {
+                       if (r600_is_sampler_format_supported(screen, format))
+                               retval |= PIPE_BIND_SAMPLER_VIEW;
+               }
        }
 
        if ((usage & (PIPE_BIND_RENDER_TARGET |
@@ -1195,7 +1200,7 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
                if (util_format_get_blocksize(pipe_format) >= 16)
                        non_disp_tiling = 1;
        }
-       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
+       nbanks = eg_num_banks(rscreen->b.tiling_info.num_banks);
 
        if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
                height = 1;
@@ -1348,7 +1353,7 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
        unsigned block_size =
                align(util_format_get_blocksize(pipe_buffer->format), 4);
        unsigned pitch_alignment =
-               MAX2(64, rctx->screen->tiling_info.group_bytes / block_size);
+               MAX2(64, rctx->screen->b.tiling_info.group_bytes / block_size);
        unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
 
        /* XXX: This is copied from evergreen_init_color_surface().  I don't
@@ -1456,7 +1461,7 @@ void evergreen_init_color_surface(struct r600_context *rctx,
                if (util_format_get_blocksize(surf->base.format) >= 16)
                        non_disp_tiling = 1;
        }
-       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
+       nbanks = eg_num_banks(rscreen->b.tiling_info.num_banks);
        desc = util_format_description(surf->base.format);
        for (i = 0; i < 4; i++) {
                if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
@@ -1628,7 +1633,7 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
        macro_aspect = eg_macro_tile_aspect(macro_aspect);
        bankw = eg_bank_wh(bankw);
        bankh = eg_bank_wh(bankh);
-       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
+       nbanks = eg_num_banks(rscreen->b.tiling_info.num_banks);
        offset >>= 8;
 
        surf->db_depth_info = S_028040_ARRAY_MODE(array_mode) |
@@ -1691,8 +1696,8 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
 
        surf->htile_enabled = 0;
        /* use htile only for first level */
-       if (rtex->htile && !level) {
-               uint64_t va = r600_resource_va(&rctx->screen->b.b, &rtex->htile->b.b);
+       if (rtex->htile_buffer && !level) {
+               uint64_t va = r600_resource_va(&rctx->screen->b.b, &rtex->htile_buffer->b.b);
                surf->htile_enabled = 1;
                surf->db_htile_data_base = va >> 8;
                surf->db_htile_surface = S_028ABC_HTILE_WIDTH(1) |
@@ -1716,18 +1721,15 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 
        if (rctx->framebuffer.state.nr_cbufs) {
                rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;
-               rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB;
-
-               if (rctx->framebuffer.state.cbufs[0]->texture->nr_samples > 1) {
-                       rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB_META;
-               }
+               rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB |
+                                R600_CONTEXT_FLUSH_AND_INV_CB_META;
        }
        if (rctx->framebuffer.state.zsbuf) {
                rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;
                rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_DB;
 
                rtex = (struct r600_texture*)rctx->framebuffer.state.zsbuf->texture;
-               if (rtex->htile) {
+               if (rtex->htile_buffer) {
                        rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_DB_META;
                }
        }
@@ -1736,19 +1738,16 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 
        /* Colorbuffers. */
        rctx->framebuffer.export_16bpc = state->nr_cbufs != 0;
-       rctx->framebuffer.cb0_is_integer = state->nr_cbufs &&
+       rctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] &&
                                           util_format_is_pure_integer(state->cbufs[0]->format);
        rctx->framebuffer.compressed_cb_mask = 0;
-
-       if (state->nr_cbufs)
-               rctx->framebuffer.nr_samples = state->cbufs[0]->texture->nr_samples;
-       else if (state->zsbuf)
-               rctx->framebuffer.nr_samples = state->zsbuf->texture->nr_samples;
-       else
-               rctx->framebuffer.nr_samples = 0;
+       rctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state);
 
        for (i = 0; i < state->nr_cbufs; i++) {
                surf = (struct r600_surface*)state->cbufs[i];
+               if (!surf)
+                       continue;
+
                rtex = (struct r600_texture*)surf->base.texture;
 
                r600_context_add_resource_size(ctx, state->cbufs[i]->texture);
@@ -1769,13 +1768,21 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        /* Update alpha-test state dependencies.
         * Alpha-test is done on the first colorbuffer only. */
        if (state->nr_cbufs) {
+               bool alphatest_bypass = false;
+               bool export_16bpc = true;
+
                surf = (struct r600_surface*)state->cbufs[0];
-               if (rctx->alphatest_state.bypass != surf->alphatest_bypass) {
-                       rctx->alphatest_state.bypass = surf->alphatest_bypass;
+               if (surf) {
+                       alphatest_bypass = surf->alphatest_bypass;
+                       export_16bpc = surf->export_16bpc;
+               }
+
+               if (rctx->alphatest_state.bypass != alphatest_bypass) {
+                       rctx->alphatest_state.bypass = alphatest_bypass;
                        rctx->alphatest_state.atom.dirty = true;
                }
-               if (rctx->alphatest_state.cb0_export_16bpc != surf->export_16bpc) {
-                       rctx->alphatest_state.cb0_export_16bpc = surf->export_16bpc;
+               if (rctx->alphatest_state.cb0_export_16bpc != export_16bpc) {
+                       rctx->alphatest_state.cb0_export_16bpc = export_16bpc;
                        rctx->alphatest_state.atom.dirty = true;
                }
        }
@@ -2176,12 +2183,21 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
        /* Colorbuffers. */
        for (i = 0; i < nr_cbufs; i++) {
                struct r600_surface *cb = (struct r600_surface*)state->cbufs[i];
-               struct r600_texture *tex = (struct r600_texture *)cb->base.texture;
-               unsigned reloc = r600_context_bo_reloc(&rctx->b,
-                                                      &rctx->b.rings.gfx,
-                                                      (struct r600_resource*)cb->base.texture,
-                                                      RADEON_USAGE_READWRITE);
-               unsigned cmask_reloc = 0;
+               struct r600_texture *tex;
+               unsigned reloc, cmask_reloc;
+
+               if (!cb) {
+                       r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+                                              S_028C70_FORMAT(V_028C70_COLOR_INVALID));
+                       continue;
+               }
+
+               tex = (struct r600_texture *)cb->base.texture;
+               reloc = r600_context_bo_reloc(&rctx->b,
+                                             &rctx->b.rings.gfx,
+                                             (struct r600_resource*)cb->base.texture,
+                                             RADEON_USAGE_READWRITE);
+
                if (tex->cmask_buffer && tex->cmask_buffer != &tex->resource) {
                        cmask_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx,
                                tex->cmask_buffer, RADEON_USAGE_READWRITE);
@@ -2222,7 +2238,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
                radeon_emit(cs, reloc);
        }
        /* set CB_COLOR1_INFO for possible dual-src blending */
-       if (i == 1) {
+       if (i == 1 && state->cbufs[0]) {
                r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
                                       ((struct r600_surface*)state->cbufs[0])->cb_color_info);
 
@@ -2357,11 +2373,11 @@ static void evergreen_emit_db_state(struct r600_context *rctx, struct r600_atom
                struct r600_texture *rtex = (struct r600_texture *)a->rsurf->base.texture;
                unsigned reloc_idx;
 
-               r600_write_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear));
+               r600_write_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value));
                r600_write_context_reg(cs, R_028ABC_DB_HTILE_SURFACE, a->rsurf->db_htile_surface);
                r600_write_context_reg(cs, R_028AC8_DB_PRELOAD_CONTROL, a->rsurf->db_preload_control);
                r600_write_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, a->rsurf->db_htile_data_base);
-               reloc_idx = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rtex->htile, RADEON_USAGE_READWRITE);
+               reloc_idx = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rtex->htile_buffer, RADEON_USAGE_READWRITE);
                cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
                cs->buf[cs->cdw++] = reloc_idx;
        } else {
@@ -2875,7 +2891,7 @@ static void cayman_init_atom_start_cs(struct r600_context *rctx)
        r600_store_value(cb, 0);
        r600_store_value(cb, 0);
 
-       if (rctx->screen->has_streamout) {
+       if (rctx->screen->b.has_streamout) {
                r600_store_context_reg(cb, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
        }
 
@@ -3332,7 +3348,7 @@ void evergreen_init_atom_start_cs(struct r600_context *rctx)
        r600_store_value(cb, 0); /* R_028B94_VGT_STRMOUT_CONFIG */
        r600_store_value(cb, 0); /* R_028B98_VGT_STRMOUT_BUFFER_CONFIG */
 
-       if (rctx->screen->has_streamout) {
+       if (rctx->screen->b.has_streamout) {
                r600_store_context_reg(cb, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
        }
 
@@ -3581,14 +3597,21 @@ void *evergreen_create_db_flush_dsa(struct r600_context *rctx)
 
 void evergreen_update_db_shader_control(struct r600_context * rctx)
 {
-       bool dual_export = rctx->framebuffer.export_16bpc &&
-                          !rctx->ps_shader->current->ps_depth_export;
+       bool dual_export;
+       unsigned db_shader_control;
 
-       unsigned db_shader_control = rctx->ps_shader->current->db_shader_control |
-                       S_02880C_DUAL_EXPORT_ENABLE(dual_export) |
-                       S_02880C_DB_SOURCE_FORMAT(dual_export ? V_02880C_EXPORT_DB_TWO :
-                                                               V_02880C_EXPORT_DB_FULL) |
-                       S_02880C_ALPHA_TO_MASK_DISABLE(rctx->framebuffer.cb0_is_integer);
+       if (!rctx->ps_shader) {
+               return;
+       }
+
+       dual_export = rctx->framebuffer.export_16bpc &&
+                     !rctx->ps_shader->current->ps_depth_export;
+
+       db_shader_control = rctx->ps_shader->current->db_shader_control |
+                           S_02880C_DUAL_EXPORT_ENABLE(dual_export) |
+                           S_02880C_DB_SOURCE_FORMAT(dual_export ? V_02880C_EXPORT_DB_TWO :
+                                                                   V_02880C_EXPORT_DB_FULL) |
+                           S_02880C_ALPHA_TO_MASK_DISABLE(rctx->framebuffer.cb0_is_integer);
 
        /* When alpha test is enabled we can't trust the hw to make the proper
         * decision on the order in which ztest should be run related to fragment
@@ -3655,7 +3678,7 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
        sub_cmd = 0x8;
        lbpp = util_logbase2(bpp);
        pitch_tile_max = ((pitch / bpp) >> 3) - 1;
-       nbanks = eg_num_banks(rctx->screen->tiling_info.num_banks);
+       nbanks = eg_num_banks(rctx->screen->b.tiling_info.num_banks);
 
        if (dst_mode == RADEON_SURF_MODE_LINEAR) {
                /* T2L */
@@ -3757,6 +3780,12 @@ static boolean evergreen_dma_blit(struct pipe_context *ctx,
        if (rctx->b.rings.dma.cs == NULL) {
                return FALSE;
        }
+
+       if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
+               evergreen_dma_copy(rctx, dst, src, dst_x, src_box->x, src_box->width);
+               return TRUE;
+       }
+
        if (src->format != dst->format) {
                return FALSE;
        }