radeonsi: tell LLVM not to remove s_barrier instructions
[mesa.git] / src / gallium / drivers / r600 / evergreen_state.c
index 4d86570ade8b0c9504075b7f40a5cb2e671fb2a3..19ad50409799195351d0d0df3e3e88d3c82701c1 100644 (file)
@@ -471,6 +471,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
        rs->clip_halfz = state->clip_halfz;
        rs->flatshade = state->flatshade;
        rs->sprite_coord_enable = state->sprite_coord_enable;
+       rs->rasterizer_discard = state->rasterizer_discard;
        rs->two_side = state->light_twoside;
        rs->clip_plane_enable = state->clip_plane_enable;
        rs->pa_sc_line_stipple = state->line_stipple_enable ?
@@ -700,14 +701,14 @@ static int evergreen_fill_tex_resource_words(struct r600_context *rctx,
        unsigned char array_mode = 0, non_disp_tiling = 0;
        unsigned height, depth, width;
        unsigned macro_aspect, tile_split, bankh, bankw, nbanks, fmask_bankh;
-       struct radeon_surf_level *surflevel;
+       struct legacy_surf_level *surflevel;
        unsigned base_level, first_level, last_level;
        unsigned dim, last_layer;
        uint64_t va;
        bool do_endian_swap = FALSE;
 
-       tile_split = tmp->surface.tile_split;
-       surflevel = tmp->surface.level;
+       tile_split = tmp->surface.u.legacy.tile_split;
+       surflevel = tmp->surface.u.legacy.level;
 
        /* Texturing with separate depth and stencil. */
        if (tmp->db_compatible) {
@@ -726,8 +727,8 @@ static int evergreen_fill_tex_resource_words(struct r600_context *rctx,
                case PIPE_FORMAT_S8X24_UINT:
                case PIPE_FORMAT_X32_S8X24_UINT:
                        params->pipe_format = PIPE_FORMAT_S8_UINT;
-                       tile_split = tmp->surface.stencil_tile_split;
-                       surflevel = tmp->surface.stencil_level;
+                       tile_split = tmp->surface.u.legacy.stencil_tile_split;
+                       surflevel = tmp->surface.u.legacy.stencil_level;
                        break;
                default:;
                }
@@ -777,9 +778,9 @@ static int evergreen_fill_tex_resource_words(struct r600_context *rctx,
                array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
                break;
        }
-       macro_aspect = tmp->surface.mtilea;
-       bankw = tmp->surface.bankw;
-       bankh = tmp->surface.bankh;
+       macro_aspect = tmp->surface.u.legacy.mtilea;
+       bankw = tmp->surface.u.legacy.bankw;
+       bankh = tmp->surface.u.legacy.bankh;
        tile_split = eg_tile_split(tile_split);
        macro_aspect = eg_macro_tile_aspect(macro_aspect);
        bankw = eg_bank_wh(bankw);
@@ -1011,6 +1012,71 @@ struct r600_tex_color_info {
        boolean export_16bpc;
 };
 
+static void evergreen_set_color_surface_buffer(struct r600_context *rctx,
+                                              struct r600_resource *res,
+                                              enum pipe_format pformat,
+                                              unsigned first_element,
+                                              unsigned last_element,
+                                              struct r600_tex_color_info *color)
+{
+       unsigned format, swap, ntype, endian;
+       const struct util_format_description *desc;
+       unsigned block_size = align(util_format_get_blocksize(res->b.b.format), 4);
+       unsigned pitch_alignment =
+               MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
+       unsigned pitch = align(res->b.b.width0, pitch_alignment);
+       int i;
+       unsigned width_elements;
+
+       width_elements = last_element - first_element + 1;
+
+       format = r600_translate_colorformat(rctx->b.chip_class, pformat, FALSE);
+       swap = r600_translate_colorswap(pformat, FALSE);
+
+       endian = r600_colorformat_endian_swap(format, FALSE);
+
+       desc = util_format_description(pformat);
+       for (i = 0; i < 4; i++) {
+               if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+                       break;
+               }
+       }
+       ntype = V_028C70_NUMBER_UNORM;
+               if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
+               ntype = V_028C70_NUMBER_SRGB;
+       else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+               if (desc->channel[i].normalized)
+                       ntype = V_028C70_NUMBER_SNORM;
+               else if (desc->channel[i].pure_integer)
+                       ntype = V_028C70_NUMBER_SINT;
+       } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
+               if (desc->channel[i].normalized)
+                       ntype = V_028C70_NUMBER_UNORM;
+               else if (desc->channel[i].pure_integer)
+                       ntype = V_028C70_NUMBER_UINT;
+       }
+       pitch = (pitch / 8) - 1;
+       color->pitch = S_028C64_PITCH_TILE_MAX(pitch);
+
+       color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+       color->info |= S_028C70_FORMAT(format) |
+                      S_028C70_COMP_SWAP(swap) |
+                      S_028C70_BLEND_CLAMP(0) |
+                      S_028C70_BLEND_BYPASS(1) |
+                      S_028C70_NUMBER_TYPE(ntype) |
+                      S_028C70_ENDIAN(endian);
+       color->attrib = S_028C74_NON_DISP_TILING_ORDER(1);
+       color->ntype = ntype;
+       color->export_16bpc = false;
+       color->dim = width_elements - 1;
+       color->slice = 0; /* (width_elements / 64) - 1;*/
+       color->view = 0;
+       color->offset = res->gpu_address >> 8;
+
+       color->fmask = color->offset;
+       color->fmask_slice = 0;
+}
+
 static void evergreen_set_color_surface_common(struct r600_context *rctx,
                                               struct r600_texture *rtex,
                                               unsigned level,
@@ -1027,7 +1093,7 @@ static void evergreen_set_color_surface_common(struct r600_context *rctx,
        bool blend_clamp = 0, blend_bypass = 0, do_endian_swap = FALSE;
        int i;
 
-       color->offset = rtex->surface.level[level].offset;
+       color->offset = rtex->surface.u.legacy.level[level].offset;
        color->view = S_028C6C_SLICE_START(first_layer) |
                        S_028C6C_SLICE_MAX(last_layer);
 
@@ -1035,14 +1101,14 @@ static void evergreen_set_color_surface_common(struct r600_context *rctx,
        color->offset >>= 8;
 
        color->dim = 0;
-       pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
-       slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+       pitch = (rtex->surface.u.legacy.level[level].nblk_x) / 8 - 1;
+       slice = (rtex->surface.u.legacy.level[level].nblk_x * rtex->surface.u.legacy.level[level].nblk_y) / 64;
        if (slice) {
                slice = slice - 1;
        }
 
        color->info = 0;
-       switch (rtex->surface.level[level].mode) {
+       switch (rtex->surface.u.legacy.level[level].mode) {
        default:
        case RADEON_SURF_MODE_LINEAR_ALIGNED:
                color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
@@ -1057,14 +1123,14 @@ static void evergreen_set_color_surface_common(struct r600_context *rctx,
                non_disp_tiling = rtex->non_disp_tiling;
                break;
        }
-       tile_split = rtex->surface.tile_split;
-       macro_aspect = rtex->surface.mtilea;
-       bankw = rtex->surface.bankw;
-       bankh = rtex->surface.bankh;
+       tile_split = rtex->surface.u.legacy.tile_split;
+       macro_aspect = rtex->surface.u.legacy.mtilea;
+       bankw = rtex->surface.u.legacy.bankw;
+       bankh = rtex->surface.u.legacy.bankh;
        if (rtex->fmask.size)
                fmask_bankh = rtex->fmask.bank_height;
        else
-               fmask_bankh = rtex->surface.bankh;
+               fmask_bankh = rtex->surface.u.legacy.bankh;
        tile_split = eg_tile_split(tile_split);
        macro_aspect = eg_macro_tile_aspect(macro_aspect);
        bankw = eg_bank_wh(bankw);
@@ -1190,47 +1256,27 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
                                        struct r600_surface *surf)
 {
        struct pipe_resource *pipe_buffer = surf->base.texture;
-       unsigned format = r600_translate_colorformat(rctx->b.chip_class,
-                                                    surf->base.format, FALSE);
-       unsigned endian = r600_colorformat_endian_swap(format, FALSE);
-       unsigned swap = r600_translate_colorswap(surf->base.format, FALSE);
-       unsigned block_size =
-               align(util_format_get_blocksize(pipe_buffer->format), 4);
-       unsigned pitch_alignment =
-               MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
-       unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
-
-       surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
+       struct r600_tex_color_info color;
 
-       surf->cb_color_pitch = (pitch / 8) - 1;
+       evergreen_set_color_surface_buffer(rctx, (struct r600_resource *)surf->base.texture,
+                                          surf->base.format, 0, pipe_buffer->width0,
+                                          &color);
 
-       surf->cb_color_slice = 0;
+       surf->cb_color_base = color.offset;
+       surf->cb_color_dim = color.dim;
+       surf->cb_color_info = color.info | S_028C70_RAT(1);
+       surf->cb_color_pitch = color.pitch;
+       surf->cb_color_slice = color.slice;
+       surf->cb_color_view = color.view;
+       surf->cb_color_attrib = color.attrib;
+       surf->cb_color_fmask = color.fmask;
+       surf->cb_color_fmask_slice = color.fmask_slice;
 
        surf->cb_color_view = 0;
 
-       surf->cb_color_info =
-                 S_028C70_ENDIAN(endian)
-               | S_028C70_FORMAT(format)
-               | S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
-               | S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
-               | S_028C70_COMP_SWAP(swap)
-               | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
-                                           * are using NUMBER_UINT */
-               | S_028C70_RAT(1)
-               ;
-
-       surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
-
-       /* For buffers, CB_COLOR0_DIM needs to be set to the number of
-        * elements. */
-       surf->cb_color_dim = pipe_buffer->width0;
-
        /* Set the buffer range the GPU will have access to: */
        util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
                       0, pipe_buffer->width0);
-
-       surf->cb_color_fmask = surf->cb_color_base;
-       surf->cb_color_fmask_slice = 0;
 }
 
 
@@ -1271,7 +1317,7 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
        struct r600_screen *rscreen = rctx->screen;
        struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
        unsigned level = surf->base.u.tex.level;
-       struct radeon_surf_level *levelinfo = &rtex->surface.level[level];
+       struct legacy_surf_level *levelinfo = &rtex->surface.u.legacy.level[level];
        uint64_t offset;
        unsigned format, array_mode;
        unsigned macro_aspect, tile_split, bankh, bankw, nbanks;
@@ -1281,9 +1327,9 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
        assert(format != ~0);
 
        offset = rtex->resource.gpu_address;
-       offset += rtex->surface.level[level].offset;
+       offset += rtex->surface.u.legacy.level[level].offset;
 
-       switch (rtex->surface.level[level].mode) {
+       switch (rtex->surface.u.legacy.level[level].mode) {
        case RADEON_SURF_MODE_2D:
                array_mode = V_028C70_ARRAY_2D_TILED_THIN1;
                break;
@@ -1293,10 +1339,10 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
                array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
                break;
        }
-       tile_split = rtex->surface.tile_split;
-       macro_aspect = rtex->surface.mtilea;
-       bankw = rtex->surface.bankw;
-       bankh = rtex->surface.bankh;
+       tile_split = rtex->surface.u.legacy.tile_split;
+       macro_aspect = rtex->surface.u.legacy.mtilea;
+       bankw = rtex->surface.u.legacy.bankw;
+       bankh = rtex->surface.u.legacy.bankh;
        tile_split = eg_tile_split(tile_split);
        macro_aspect = eg_macro_tile_aspect(macro_aspect);
        bankw = eg_bank_wh(bankw);
@@ -1327,11 +1373,11 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
 
        if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
                uint64_t stencil_offset;
-               unsigned stile_split = rtex->surface.stencil_tile_split;
+               unsigned stile_split = rtex->surface.u.legacy.stencil_tile_split;
 
                stile_split = eg_tile_split(stile_split);
 
-               stencil_offset = rtex->surface.stencil_level[level].offset;
+               stencil_offset = rtex->surface.u.legacy.stencil_level[level].offset;
                stencil_offset += rtex->resource.gpu_address;
 
                surf->db_stencil_base = stencil_offset >> 8;
@@ -1504,6 +1550,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
 
        r600_set_sample_locations_constant_buffer(rctx);
+       rctx->framebuffer.do_update_surf_dirtiness = true;
 }
 
 static void evergreen_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
@@ -3461,8 +3508,8 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
        unsigned sub_cmd, bank_h, bank_w, mt_aspect, nbanks, tile_split, non_disp_tiling = 0;
        uint64_t base, addr;
 
-       dst_mode = rdst->surface.level[dst_level].mode;
-       src_mode = rsrc->surface.level[src_level].mode;
+       dst_mode = rdst->surface.u.legacy.level[dst_level].mode;
+       src_mode = rsrc->surface.u.legacy.level[src_level].mode;
        assert(dst_mode != src_mode);
 
        /* non_disp_tiling bit needs to be set for depth, stencil, and fmask surfaces */
@@ -3478,7 +3525,7 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
        if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED) {
                /* T2L */
                array_mode = evergreen_array_mode(src_mode);
-               slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) / (8*8);
+               slice_tile_max = (rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.u.legacy.level[src_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -3490,20 +3537,20 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
                x = src_x;
                y = src_y;
                z = src_z;
-               base = rsrc->surface.level[src_level].offset;
-               addr = rdst->surface.level[dst_level].offset;
-               addr += rdst->surface.level[dst_level].slice_size * dst_z;
+               base = rsrc->surface.u.legacy.level[src_level].offset;
+               addr = rdst->surface.u.legacy.level[dst_level].offset;
+               addr += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
                addr += dst_y * pitch + dst_x * bpp;
-               bank_h = eg_bank_wh(rsrc->surface.bankh);
-               bank_w = eg_bank_wh(rsrc->surface.bankw);
-               mt_aspect = eg_macro_tile_aspect(rsrc->surface.mtilea);
-               tile_split = eg_tile_split(rsrc->surface.tile_split);
+               bank_h = eg_bank_wh(rsrc->surface.u.legacy.bankh);
+               bank_w = eg_bank_wh(rsrc->surface.u.legacy.bankw);
+               mt_aspect = eg_macro_tile_aspect(rsrc->surface.u.legacy.mtilea);
+               tile_split = eg_tile_split(rsrc->surface.u.legacy.tile_split);
                base += rsrc->resource.gpu_address;
                addr += rdst->resource.gpu_address;
        } else {
                /* L2T */
                array_mode = evergreen_array_mode(dst_mode);
-               slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) / (8*8);
+               slice_tile_max = (rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.u.legacy.level[dst_level].nblk_y) / (8*8);
                slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
                /* linear height must be the same as the slice tile max height, it's ok even
                 * if the linear destination/source have smaller heigh as the size of the
@@ -3515,14 +3562,14 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
                x = dst_x;
                y = dst_y;
                z = dst_z;
-               base = rdst->surface.level[dst_level].offset;
-               addr = rsrc->surface.level[src_level].offset;
-               addr += rsrc->surface.level[src_level].slice_size * src_z;
+               base = rdst->surface.u.legacy.level[dst_level].offset;
+               addr = rsrc->surface.u.legacy.level[src_level].offset;
+               addr += rsrc->surface.u.legacy.level[src_level].slice_size * src_z;
                addr += src_y * pitch + src_x * bpp;
-               bank_h = eg_bank_wh(rdst->surface.bankh);
-               bank_w = eg_bank_wh(rdst->surface.bankw);
-               mt_aspect = eg_macro_tile_aspect(rdst->surface.mtilea);
-               tile_split = eg_tile_split(rdst->surface.tile_split);
+               bank_h = eg_bank_wh(rdst->surface.u.legacy.bankh);
+               bank_w = eg_bank_wh(rdst->surface.u.legacy.bankw);
+               mt_aspect = eg_macro_tile_aspect(rdst->surface.u.legacy.mtilea);
+               tile_split = eg_tile_split(rdst->surface.u.legacy.tile_split);
                base += rdst->resource.gpu_address;
                addr += rsrc->resource.gpu_address;
        }
@@ -3595,14 +3642,14 @@ static void evergreen_dma_copy(struct pipe_context *ctx,
        dst_y = util_format_get_nblocksy(src->format, dst_y);
 
        bpp = rdst->surface.bpe;
-       dst_pitch = rdst->surface.level[dst_level].nblk_x * rdst->surface.bpe;
-       src_pitch = rsrc->surface.level[src_level].nblk_x * rsrc->surface.bpe;
+       dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.bpe;
+       src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.bpe;
        src_w = u_minify(rsrc->resource.b.b.width0, src_level);
        dst_w = u_minify(rdst->resource.b.b.width0, dst_level);
        copy_height = src_box->height / rsrc->surface.blk_h;
 
-       dst_mode = rdst->surface.level[dst_level].mode;
-       src_mode = rsrc->surface.level[src_level].mode;
+       dst_mode = rdst->surface.u.legacy.level[dst_level].mode;
+       src_mode = rsrc->surface.u.legacy.level[src_level].mode;
 
        if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) {
                /* FIXME evergreen can do partial blit */
@@ -3633,11 +3680,11 @@ static void evergreen_dma_copy(struct pipe_context *ctx,
                 *   dst_x/y == 0
                 *   dst_pitch == src_pitch
                 */
-               src_offset= rsrc->surface.level[src_level].offset;
-               src_offset += rsrc->surface.level[src_level].slice_size * src_box->z;
+               src_offset= rsrc->surface.u.legacy.level[src_level].offset;
+               src_offset += rsrc->surface.u.legacy.level[src_level].slice_size * src_box->z;
                src_offset += src_y * src_pitch + src_x * bpp;
-               dst_offset = rdst->surface.level[dst_level].offset;
-               dst_offset += rdst->surface.level[dst_level].slice_size * dst_z;
+               dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
+               dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
                dst_offset += dst_y * dst_pitch + dst_x * bpp;
                evergreen_dma_copy_buffer(rctx, dst, src, dst_offset, src_offset,
                                        src_box->height * src_pitch);