r600: Update state code to accept NIR shaders
[mesa.git] / src / gallium / drivers / r600 / r600_state.c
index 2b58d982a91027da0b863259aa80e31ef1f96b90..b20a9d2a2f00d78b8dd996d6b03f8091216d6ad3 100644 (file)
@@ -158,36 +158,37 @@ static bool r600_is_zs_format_supported(enum pipe_format format)
        return r600_translate_dbformat(format) != ~0U;
 }
 
-boolean r600_is_format_supported(struct pipe_screen *screen,
-                                enum pipe_format format,
-                                enum pipe_texture_target target,
-                                unsigned sample_count,
-                                unsigned usage)
+bool r600_is_format_supported(struct pipe_screen *screen,
+                             enum pipe_format format,
+                             enum pipe_texture_target target,
+                             unsigned sample_count,
+                             unsigned storage_sample_count,
+                             unsigned usage)
 {
        struct r600_screen *rscreen = (struct r600_screen*)screen;
        unsigned retval = 0;
 
        if (target >= PIPE_MAX_TEXTURE_TYPES) {
                R600_ERR("r600: unsupported texture type %d\n", target);
-               return FALSE;
+               return false;
        }
 
-       if (!util_format_is_supported(format, usage))
-               return FALSE;
+       if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
+               return false;
 
        if (sample_count > 1) {
                if (!rscreen->has_msaa)
-                       return FALSE;
+                       return false;
 
                /* R11G11B10 is broken on R6xx. */
                if (rscreen->b.chip_class == R600 &&
                    format == PIPE_FORMAT_R11G11B10_FLOAT)
-                       return FALSE;
+                       return false;
 
                /* MSAA integer colorbuffers hang. */
                if (util_format_is_pure_integer(format) &&
                    !util_format_is_depth_or_stencil(format))
-                       return FALSE;
+                       return false;
 
                switch (sample_count) {
                case 2:
@@ -195,7 +196,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen,
                case 8:
                        break;
                default:
-                       return FALSE;
+                       return false;
                }
        }
 
@@ -245,7 +246,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen,
 
 static void r600_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_poly_offset_state *state = (struct r600_poly_offset_state*)a;
        float offset_units = state->offset_units;
        float offset_scale = state->offset_scale;
@@ -470,6 +471,7 @@ static void *r600_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 ?
@@ -477,8 +479,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
                                S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
        rs->pa_cl_clip_cntl =
                S_028810_DX_CLIP_SPACE_DEF(state->clip_halfz) |
-               S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
-               S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
+               S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip_near) |
+               S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip_far) |
                S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
        if (rctx->b.chip_class == R700) {
                rs->pa_cl_clip_cntl |=
@@ -622,7 +624,7 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
 static struct pipe_sampler_view *
 texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
                            unsigned width0, unsigned height0)
-                           
+
 {
        struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
        int stride = util_format_get_blocksize(view->base.format);
@@ -723,7 +725,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
        width = width_first_level;
        height = height_first_level;
         depth = u_minify(texture->depth0, offset_level);
-       pitch = tmp->surface.level[offset_level].nblk_x * util_format_get_blockwidth(state->format);
+       pitch = tmp->surface.u.legacy.level[offset_level].nblk_x * util_format_get_blockwidth(state->format);
 
        if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
                height = 1;
@@ -733,7 +735,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
        } else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY)
                depth = texture->array_size / 6;
 
-       switch (tmp->surface.level[offset_level].mode) {
+       switch (tmp->surface.u.legacy.level[offset_level].mode) {
        default:
        case RADEON_SURF_MODE_LINEAR_ALIGNED:
                array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
@@ -755,11 +757,11 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
        view->tex_resource_words[1] = (S_038004_TEX_HEIGHT(height - 1) |
                                       S_038004_TEX_DEPTH(depth - 1) |
                                       S_038004_DATA_FORMAT(format));
-       view->tex_resource_words[2] = tmp->surface.level[offset_level].offset >> 8;
-       if (offset_level >= tmp->surface.last_level) {
-               view->tex_resource_words[3] = tmp->surface.level[offset_level].offset >> 8;
+       view->tex_resource_words[2] = tmp->surface.u.legacy.level[offset_level].offset >> 8;
+       if (offset_level >= tmp->resource.b.b.last_level) {
+               view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level].offset >> 8;
        } else {
-               view->tex_resource_words[3] = tmp->surface.level[offset_level + 1].offset >> 8;
+               view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level + 1].offset >> 8;
        }
        view->tex_resource_words[4] = (word4 |
                                       S_038010_REQUEST_SIZE(1) |
@@ -790,7 +792,7 @@ r600_create_sampler_view(struct pipe_context *ctx,
 
 static void r600_emit_clip_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct pipe_clip_state *state = &rctx->clip_state.state;
 
        radeon_set_context_reg_seq(cs, R_028E20_PA_CL_UCP0_X, 6*4);
@@ -802,26 +804,6 @@ static void r600_set_polygon_stipple(struct pipe_context *ctx,
 {
 }
 
-static struct r600_resource *r600_buffer_create_helper(struct r600_screen *rscreen,
-                                                      unsigned size, unsigned alignment)
-{
-       struct pipe_resource buffer;
-
-       memset(&buffer, 0, sizeof buffer);
-       buffer.target = PIPE_BUFFER;
-       buffer.format = PIPE_FORMAT_R8_UNORM;
-       buffer.bind = PIPE_BIND_CUSTOM;
-       buffer.usage = PIPE_USAGE_DEFAULT;
-       buffer.flags = 0;
-       buffer.width0 = size;
-       buffer.height0 = 1;
-       buffer.depth0 = 1;
-       buffer.array_size = 1;
-
-       return (struct r600_resource*)
-               r600_buffer_create(&rscreen->b.b, &buffer, alignment);
-}
-
 static void r600_init_color_surface(struct r600_context *rctx,
                                    struct r600_surface *surf,
                                    bool force_cmask_fmask)
@@ -836,7 +818,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
        unsigned offset;
        const struct util_format_description *desc;
        int i;
-       bool blend_bypass = 0, blend_clamp = 1, do_endian_swap = FALSE;
+       bool blend_bypass = 0, blend_clamp = 0, do_endian_swap = FALSE;
 
        if (rtex->db_compatible && !r600_can_sample_zs(rtex, false)) {
                r600_init_flushed_depth_texture(&rctx->b.b, surf->base.texture, NULL);
@@ -844,17 +826,17 @@ static void r600_init_color_surface(struct r600_context *rctx,
                assert(rtex);
        }
 
-       offset = rtex->surface.level[level].offset;
+       offset = rtex->surface.u.legacy.level[level].offset;
        color_view = S_028080_SLICE_START(surf->base.u.tex.first_layer) |
                     S_028080_SLICE_MAX(surf->base.u.tex.last_layer);
 
-       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_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_ALIGNED);
@@ -888,6 +870,8 @@ static void r600_init_color_surface(struct r600_context *rctx,
                        ntype = V_0280A0_NUMBER_UNORM;
                else if (desc->channel[i].pure_integer)
                        ntype = V_0280A0_NUMBER_UINT;
+       } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
+               ntype = V_0280A0_NUMBER_FLOAT;
        }
 
        if (R600_BIG_ENDIAN)
@@ -902,6 +886,11 @@ static void r600_init_color_surface(struct r600_context *rctx,
 
        endian = r600_colorformat_endian_swap(format, do_endian_swap);
 
+       /* blend clamp should be set for all NORM/SRGB types */
+       if (ntype == V_0280A0_NUMBER_UNORM || ntype == V_0280A0_NUMBER_SNORM ||
+           ntype == V_0280A0_NUMBER_SRGB)
+               blend_clamp = 1;
+
        /* set blend bypass according to docs if SINT/UINT or
           8/24 COLOR variants */
        if (ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT ||
@@ -917,6 +906,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
                S_0280A0_COMP_SWAP(swap) |
                S_0280A0_BLEND_BYPASS(blend_bypass) |
                S_0280A0_BLEND_CLAMP(blend_clamp) |
+               S_0280A0_SIMPLE_FLOAT(1) |
                S_0280A0_NUMBER_TYPE(ntype) |
                S_0280A0_ENDIAN(endian);
 
@@ -935,6 +925,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
                     ntype != V_0280A0_NUMBER_UINT &&
                     ntype != V_0280A0_NUMBER_SINT) &&
                    G_0280A0_BLEND_CLAMP(color_info) &&
+                   /* XXX this condition is always true since BLEND_FLOAT32 is never set (bug?). */
                    !G_0280A0_BLEND_FLOAT32(color_info)) {
                        color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
                        surf->export_16bpc = true;
@@ -998,7 +989,15 @@ static void r600_init_color_surface(struct r600_context *rctx,
                        void *ptr;
 
                        r600_resource_reference(&rctx->dummy_cmask, NULL);
-                       rctx->dummy_cmask = r600_buffer_create_helper(rscreen, cmask.size, cmask.alignment);
+                       rctx->dummy_cmask = (struct r600_resource*)
+                               r600_aligned_buffer_create(&rscreen->b.b, 0,
+                                                          PIPE_USAGE_DEFAULT,
+                                                          cmask.size, cmask.alignment);
+
+                       if (unlikely(!rctx->dummy_cmask)) {
+                               surf->color_initialized = false;
+                               return;
+                       }
 
                        /* Set the contents to 0xCC. */
                        ptr = pipe_buffer_map(&rctx->b.b, &rctx->dummy_cmask->b.b, PIPE_TRANSFER_WRITE, &transfer);
@@ -1012,8 +1011,15 @@ static void r600_init_color_surface(struct r600_context *rctx,
                    rctx->dummy_fmask->b.b.width0 < fmask.size ||
                    rctx->dummy_fmask->buf->alignment % fmask.alignment != 0) {
                        r600_resource_reference(&rctx->dummy_fmask, NULL);
-                       rctx->dummy_fmask = r600_buffer_create_helper(rscreen, fmask.size, fmask.alignment);
+                       rctx->dummy_fmask = (struct r600_resource*)
+                               r600_aligned_buffer_create(&rscreen->b.b, 0,
+                                                          PIPE_USAGE_DEFAULT,
+                                                          fmask.size, fmask.alignment);
 
+                       if (unlikely(!rctx->dummy_fmask)) {
+                               surf->color_initialized = false;
+                               return;
+                       }
                }
                r600_resource_reference(&surf->cb_buffer_fmask, rctx->dummy_fmask);
 
@@ -1037,13 +1043,13 @@ static void r600_init_depth_surface(struct r600_context *rctx,
        unsigned level, pitch, slice, format, offset, array_mode;
 
        level = surf->base.u.tex.level;
-       offset = rtex->surface.level[level].offset;
-       pitch = rtex->surface.level[level].nblk_x / 8 - 1;
-       slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+       offset = rtex->surface.u.legacy.level[level].offset;
+       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;
        }
-       switch (rtex->surface.level[level].mode) {
+       switch (rtex->surface.u.legacy.level[level].mode) {
        case RADEON_SURF_MODE_2D:
                array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
                break;
@@ -1062,11 +1068,10 @@ static void r600_init_depth_surface(struct r600_context *rctx,
        surf->db_depth_view = S_028004_SLICE_START(surf->base.u.tex.first_layer) |
                              S_028004_SLICE_MAX(surf->base.u.tex.last_layer);
        surf->db_depth_size = S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice);
-       surf->db_prefetch_limit = (rtex->surface.level[level].nblk_y / 8) - 1;
+       surf->db_prefetch_limit = (rtex->surface.u.legacy.level[level].nblk_y / 8) - 1;
 
-       /* use htile only for first level */
-       if (rtex->htile_buffer && !level) {
-               surf->db_htile_data_base = 0;
+       if (r600_htile_enabled(rtex, level)) {
+               surf->db_htile_data_base = rtex->htile_offset >> 8;
                surf->db_htile_surface = S_028D24_HTILE_WIDTH(1) |
                                         S_028D24_HTILE_HEIGHT(1) |
                                         S_028D24_FULL_CACHE(1);
@@ -1084,6 +1089,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_surface *surf;
        struct r600_texture *rtex;
        unsigned i;
+       uint32_t target_mask = 0;
 
        /* Flush TC when changing the framebuffer state, because the only
         * client not using TC that can change textures is the framebuffer.
@@ -1124,6 +1130,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
                rtex = (struct r600_texture*)surf->base.texture;
                r600_context_add_resource_size(ctx, state->cbufs[i]->texture);
 
+               target_mask |= (0xf << (i * 4));
+
                if (!surf->color_initialized || force_cmask_fmask) {
                        r600_init_color_surface(rctx, surf, force_cmask_fmask);
                        if (force_cmask_fmask) {
@@ -1136,7 +1144,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
                        rctx->framebuffer.export_16bpc = false;
                }
 
-               if (rtex->fmask.size && rtex->cmask.size) {
+               if (rtex->fmask.size) {
                        rctx->framebuffer.compressed_cb_mask |= 1 << i;
                }
        }
@@ -1183,7 +1191,9 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
                r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
        }
 
-       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) {
+       if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs ||
+           rctx->cb_misc_state.bound_cbufs_target_mask != target_mask) {
+               rctx->cb_misc_state.bound_cbufs_target_mask = target_mask;
                rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
                r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
        }
@@ -1213,24 +1223,25 @@ static void r600_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 uint32_t sample_locs_2x[] = {
+static const uint32_t sample_locs_2x[] = {
        FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
        FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
 };
-static unsigned max_dist_2x = 4;
+static const unsigned max_dist_2x = 4;
 
-static uint32_t sample_locs_4x[] = {
+static const uint32_t sample_locs_4x[] = {
        FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
        FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
 };
-static unsigned max_dist_4x = 6;
-static uint32_t sample_locs_8x[] = {
+static const unsigned max_dist_4x = 6;
+static const uint32_t sample_locs_8x[] = {
        FILL_SREG(-1,  1,  1,  5,  3, -5,  5,  3),
        FILL_SREG(-7, -1, -3, -7,  7, -3, -5,  7),
 };
-static unsigned max_dist_8x = 7;
+static const unsigned max_dist_8x = 7;
 
 static void r600_get_sample_position(struct pipe_context *ctx,
                                     unsigned sample_count,
@@ -1273,7 +1284,7 @@ static void r600_get_sample_position(struct pipe_context *ctx,
 
 static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        unsigned max_dist = 0;
 
        if (rctx->b.family == CHIP_R600) {
@@ -1340,7 +1351,7 @@ static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples)
 
 static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct pipe_framebuffer_state *state = &rctx->framebuffer.state;
        unsigned nr_cbufs = state->nr_cbufs;
        struct r600_surface **cb = (struct r600_surface**)&state->cbufs[0];
@@ -1352,7 +1363,7 @@ static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_a
                radeon_emit(cs, cb[i] ? cb[i]->cb_color_info : 0);
        }
        /* set CB_COLOR1_INFO for possible dual-src blending */
-       if (i == 1 && cb[0]) {
+       if (rctx->framebuffer.dual_src_blend && i == 1 && cb[0]) {
                radeon_emit(cs, cb[0]->cb_color_info);
                i++;
        }
@@ -1506,7 +1517,7 @@ static void r600_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
 
 static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom;
 
        if (G_028808_SPECIAL_OP(a->cb_color_control) == V_028808_SPECIAL_RESOLVE_BOX) {
@@ -1520,8 +1531,8 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom
                }
                radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, a->cb_color_control);
        } else {
-               unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1;
-               unsigned ps_colormask = (1ULL << ((unsigned)a->nr_ps_color_outputs * 4)) - 1;
+               unsigned fb_colormask = a->bound_cbufs_target_mask;
+               unsigned ps_colormask = a->ps_color_export_mask;
                unsigned multiwrite = a->multiwrite && a->nr_cbufs > 1;
 
                radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2);
@@ -1536,7 +1547,7 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_db_state *a = (struct r600_db_state*)atom;
 
        if (a->rsurf && a->rsurf->db_htile_surface) {
@@ -1546,8 +1557,8 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom
                radeon_set_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value));
                radeon_set_context_reg(cs, R_028D24_DB_HTILE_SURFACE, a->rsurf->db_htile_surface);
                radeon_set_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, a->rsurf->db_htile_data_base);
-               reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rtex->htile_buffer,
-                                                 RADEON_USAGE_READWRITE, RADEON_PRIO_HTILE);
+               reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, &rtex->resource,
+                                                 RADEON_USAGE_READWRITE, RADEON_PRIO_SEPARATE_META);
                radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
                radeon_emit(cs, reloc_idx);
        } else {
@@ -1557,7 +1568,7 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom
 
 static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_db_misc_state *a = (struct r600_db_misc_state*)atom;
        unsigned db_render_control = 0;
        unsigned db_render_override =
@@ -1642,7 +1653,7 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_config_state *a = (struct r600_config_state*)atom;
 
        radeon_set_config_reg(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, a->sq_gpr_resource_mgmt_1);
@@ -1651,7 +1662,7 @@ static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *
 
 static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask;
 
        while (dirty_mask) {
@@ -1661,7 +1672,7 @@ static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom
                unsigned buffer_index = u_bit_scan(&dirty_mask);
 
                vb = &rctx->vertex_buffer_state.vb[buffer_index];
-               rbuffer = (struct r600_resource*)vb->buffer;
+               rbuffer = (struct r600_resource*)vb->buffer.resource;
                assert(rbuffer);
 
                offset = vb->buffer_offset;
@@ -1691,7 +1702,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
                                       unsigned reg_alu_constbuf_size,
                                       unsigned reg_alu_const_cache)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = state->dirty_mask;
 
        while (dirty_mask) {
@@ -1707,19 +1718,19 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
                offset = cb->buffer_offset;
 
                if (!gs_ring_buffer) {
+                       assert(buffer_index < R600_MAX_HW_CONST_BUFFERS);
                        radeon_set_context_reg(cs, reg_alu_constbuf_size + buffer_index * 4,
                                               DIV_ROUND_UP(cb->buffer_size, 256));
                        radeon_set_context_reg(cs, reg_alu_const_cache + buffer_index * 4, offset >> 8);
+                       radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+                       radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
+                                                                 RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
                }
 
-               radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
-               radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
-                                                     RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
-
                radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
                radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
                radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
-               radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */
+               radeon_emit(cs, cb->buffer_size - 1); /* RESOURCEi_WORD1 */
                radeon_emit(cs, /* RESOURCEi_WORD2 */
                            S_038008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
                            S_038008_STRIDE(gs_ring_buffer ? 4 : 16));
@@ -1765,7 +1776,7 @@ static void r600_emit_sampler_views(struct r600_context *rctx,
                                    struct r600_samplerview_state *state,
                                    unsigned resource_id_base)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = state->dirty_mask;
 
        while (dirty_mask) {
@@ -1812,7 +1823,7 @@ static void r600_emit_sampler_states(struct r600_context *rctx,
                                unsigned resource_id_base,
                                unsigned border_color_reg)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        uint32_t dirty_mask = texinfo->states.dirty_mask;
 
        while (dirty_mask) {
@@ -1826,18 +1837,17 @@ static void r600_emit_sampler_states(struct r600_context *rctx,
 
                /* TEX_ARRAY_OVERRIDE must be set for array textures to disable
                 * filtering between layers.
-                * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view.
                 */
-               if (rview) {
-                       enum pipe_texture_target target = rview->base.texture->target;
-                       if (target == PIPE_TEXTURE_1D_ARRAY ||
-                           target == PIPE_TEXTURE_2D_ARRAY) {
-                               rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
-                               texinfo->is_array_sampler[i] = true;
-                       } else {
-                               rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
-                               texinfo->is_array_sampler[i] = false;
-                       }
+               enum pipe_texture_target target = PIPE_BUFFER;
+               if (rview)
+                       target = rview->base.texture->target;
+               if (target == PIPE_TEXTURE_1D_ARRAY ||
+                   target == PIPE_TEXTURE_2D_ARRAY) {
+                       rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
+                       texinfo->is_array_sampler[i] = true;
+               } else {
+                       rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
+                       texinfo->is_array_sampler[i] = false;
                }
 
                radeon_emit(cs, PKT3(PKT3_SET_SAMPLER, 3, 0));
@@ -1873,7 +1883,7 @@ static void r600_emit_ps_sampler_states(struct r600_context *rctx, struct r600_a
 
 static void r600_emit_seamless_cube_map(struct r600_context *rctx, struct r600_atom *atom)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        unsigned tmp;
 
        tmp = S_009508_DISABLE_CUBE_ANISO(1) |
@@ -1897,10 +1907,13 @@ static void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a
 
 static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_cso_state *state = (struct r600_cso_state*)a;
        struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state->cso;
 
+       if (!shader)
+               return;
+
        radeon_set_context_reg(cs, R_028894_SQ_PGM_START_FS, shader->offset >> 8);
        radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
        radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, shader->buffer,
@@ -1910,7 +1923,7 @@ static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600
 
 static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a;
 
        uint32_t v2 = 0, primid = 0;
@@ -1945,7 +1958,7 @@ static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom
 
 static void r600_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
 {
-       struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+       struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
        struct r600_gs_rings_state *state = (struct r600_gs_rings_state*)a;
        struct r600_resource *rbuffer;
 
@@ -2512,6 +2525,7 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
        }
 
        shader->nr_ps_color_outputs = num_cout;
+       shader->ps_color_export_mask = rshader->ps_color_export_mask;
 
        spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) |
                                S_0286CC_PERSP_GRADIENT_ENA(1)|
@@ -2549,6 +2563,12 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
        r600_store_context_reg_seq(cb, R_028850_SQ_PGM_RESOURCES_PS, 2);
        r600_store_value(cb, /* R_028850_SQ_PGM_RESOURCES_PS*/
                         S_028850_NUM_GPRS(rshader->bc.ngpr) |
+       /*
+        * docs are misleading about the dx10_clamp bit. This only affects
+        * instructions using CLAMP dst modifier, in which case they will
+        * return 0 with this set for a NaN (otherwise NaN).
+        */
+                        S_028850_DX10_CLAMP(1) |
                         S_028850_STACK_SIZE(rshader->bc.nstack) |
                         S_028850_UNCACHED_FIRST_INST(ufi));
        r600_store_value(cb, exports_ps); /* R_028854_SQ_PGM_EXPORTS_PS */
@@ -2598,6 +2618,7 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
                               S_0286C4_VS_EXPORT_COUNT(nparams - 1));
        r600_store_context_reg(cb, R_028868_SQ_PGM_RESOURCES_VS,
                               S_028868_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028868_DX10_CLAMP(1) |
                               S_028868_STACK_SIZE(rshader->bc.nstack));
        if (rshader->vs_position_window_space) {
                r600_store_context_reg(cb, R_028818_PA_CL_VTE_CNTL,
@@ -2682,6 +2703,7 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
 
        r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_GS,
                               S_02887C_NUM_GPRS(rshader->bc.ngpr) |
+                              S_02887C_DX10_CLAMP(1) |
                               S_02887C_STACK_SIZE(rshader->bc.nstack));
        r600_store_context_reg(cb, R_02886C_SQ_PGM_START_GS, 0);
        /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
@@ -2696,6 +2718,7 @@ void r600_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
 
        r600_store_context_reg(cb, R_028890_SQ_PGM_RESOURCES_ES,
                               S_028890_NUM_GPRS(rshader->bc.ngpr) |
+                              S_028890_DX10_CLAMP(1) |
                               S_028890_STACK_SIZE(rshader->bc.nstack));
        r600_store_context_reg(cb, R_028880_SQ_PGM_START_ES, 0);
        /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
@@ -2832,15 +2855,15 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                                unsigned pitch,
                                unsigned bpp)
 {
-       struct radeon_winsys_cs *cs = rctx->b.dma.cs;
+       struct radeon_cmdbuf *cs = rctx->b.dma.cs;
        struct r600_texture *rsrc = (struct r600_texture*)src;
        struct r600_texture *rdst = (struct r600_texture*)dst;
        unsigned array_mode, lbpp, pitch_tile_max, slice_tile_max, size;
        unsigned ncopy, height, cheight, detile, i, x, y, z, src_mode, dst_mode;
        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);
 
        y = 0;
@@ -2850,40 +2873,40 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
        if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED) {
                /* T2L */
                array_mode = r600_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
                 * dma packet will be using the copy_height which is always smaller or equal
                 * to the linear height
                 */
-               height = rsrc->surface.level[src_level].npix_y;
+               height = u_minify(rsrc->resource.b.b.height0, src_level);
                detile = 1;
                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 += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
                addr += dst_y * pitch + dst_x * bpp;
        } else {
                /* L2T */
                array_mode = r600_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
                 * dma packet will be using the copy_height which is always smaller or equal
                 * to the linear height
                 */
-               height = rdst->surface.level[dst_level].npix_y;
+               height = u_minify(rdst->resource.b.b.height0, dst_level);
                detile = 0;
                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 += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z;
                addr += src_y * pitch + src_x * bpp;
        }
        /* check that we are in dw/base alignment constraint */
@@ -2902,10 +2925,8 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                cheight = cheight > copy_height ? copy_height : cheight;
                size = (cheight * pitch) / 4;
                /* emit reloc before writing cs so that cs is always in consistent state */
-               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ,
-                                     RADEON_PRIO_SDMA_TEXTURE);
-               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE,
-                                     RADEON_PRIO_SDMA_TEXTURE);
+               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ, 0);
+               radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE, 0);
                radeon_emit(cs, DMA_PACKET(DMA_PACKET_COPY, 1, 0, size));
                radeon_emit(cs, base >> 8);
                radeon_emit(cs, (detile << 31) | (array_mode << 27) |
@@ -2919,7 +2940,6 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
                addr += cheight * pitch;
                y += cheight;
        }
-       r600_dma_emit_wait_idle(&rctx->b);
        return TRUE;
 }
 
@@ -2962,14 +2982,14 @@ static void r600_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].pitch_bytes;
-       src_pitch = rsrc->surface.level[src_level].pitch_bytes;
-       src_w = rsrc->surface.level[src_level].npix_x;
-       dst_w = rdst->surface.level[dst_level].npix_x;
+       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) {
                /* strict requirement on r6xx/r7xx */
@@ -2988,11 +3008,11 @@ static void r600_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 += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * 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 += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
                dst_offset += dst_y * dst_pitch + dst_x * bpp;
                size = src_box->height * src_pitch;
                /* must be dw aligned */