radeonsi: move blender to new state handling
[mesa.git] / src / gallium / drivers / radeonsi / evergreen_state.c
index c7e4a13f583d61282d67973e8bb006e4583557ae..62f138a140438482e70a9e7c7c386725c1e15592 100644 (file)
 #include "sid.h"
 #include "r600_resource.h"
 #include "radeonsi_pipe.h"
-
-static uint32_t si_translate_blend_function(int blend_func)
-{
-       switch (blend_func) {
-       case PIPE_BLEND_ADD:
-               return V_028780_COMB_DST_PLUS_SRC;
-       case PIPE_BLEND_SUBTRACT:
-               return V_028780_COMB_SRC_MINUS_DST;
-       case PIPE_BLEND_REVERSE_SUBTRACT:
-               return V_028780_COMB_DST_MINUS_SRC;
-       case PIPE_BLEND_MIN:
-               return V_028780_COMB_MIN_DST_SRC;
-       case PIPE_BLEND_MAX:
-               return V_028780_COMB_MAX_DST_SRC;
-       default:
-               R600_ERR("Unknown blend function %d\n", blend_func);
-               assert(0);
-               break;
-       }
-       return 0;
-}
-
-static uint32_t si_translate_blend_factor(int blend_fact)
-{
-       switch (blend_fact) {
-       case PIPE_BLENDFACTOR_ONE:
-               return V_028780_BLEND_ONE;
-       case PIPE_BLENDFACTOR_SRC_COLOR:
-               return V_028780_BLEND_SRC_COLOR;
-       case PIPE_BLENDFACTOR_SRC_ALPHA:
-               return V_028780_BLEND_SRC_ALPHA;
-       case PIPE_BLENDFACTOR_DST_ALPHA:
-               return V_028780_BLEND_DST_ALPHA;
-       case PIPE_BLENDFACTOR_DST_COLOR:
-               return V_028780_BLEND_DST_COLOR;
-       case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-               return V_028780_BLEND_SRC_ALPHA_SATURATE;
-       case PIPE_BLENDFACTOR_CONST_COLOR:
-               return V_028780_BLEND_CONSTANT_COLOR;
-       case PIPE_BLENDFACTOR_CONST_ALPHA:
-               return V_028780_BLEND_CONSTANT_ALPHA;
-       case PIPE_BLENDFACTOR_ZERO:
-               return V_028780_BLEND_ZERO;
-       case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-               return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
-       case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-               return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
-       case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-               return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
-       case PIPE_BLENDFACTOR_INV_DST_COLOR:
-               return V_028780_BLEND_ONE_MINUS_DST_COLOR;
-       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-               return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR;
-       case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-               return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA;
-       case PIPE_BLENDFACTOR_SRC1_COLOR:
-               return V_028780_BLEND_SRC1_COLOR;
-       case PIPE_BLENDFACTOR_SRC1_ALPHA:
-               return V_028780_BLEND_SRC1_ALPHA;
-       case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-               return V_028780_BLEND_INV_SRC1_COLOR;
-       case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-               return V_028780_BLEND_INV_SRC1_ALPHA;
-       default:
-               R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
-               assert(0);
-               break;
-       }
-       return 0;
-}
+#include "si_state.h"
 
 #if 0
 static uint32_t r600_translate_stencil_op(int s_op)
@@ -747,8 +678,12 @@ uint32_t si_translate_vertexformat(struct pipe_screen *screen,
                                   const struct util_format_description *desc,
                                   int first_non_void)
 {
-       uint32_t result = si_translate_texformat(screen, format, desc, first_non_void);
+       uint32_t result;
 
+       if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FIXED)
+               return ~0;
+
+       result = si_translate_texformat(screen, format, desc, first_non_void);
        if (result == V_008F0C_BUF_DATA_FORMAT_INVALID ||
            result > V_008F0C_BUF_DATA_FORMAT_32_32_32_32)
                result = ~0;
@@ -848,83 +783,6 @@ static void evergreen_set_blend_color(struct pipe_context *ctx,
        r600_context_pipe_state_set(rctx, rstate);
 }
 
-static void *evergreen_create_blend_state(struct pipe_context *ctx,
-                                       const struct pipe_blend_state *state)
-{
-       struct r600_context *rctx = (struct r600_context *)ctx;
-       struct r600_pipe_blend *blend = CALLOC_STRUCT(r600_pipe_blend);
-       struct r600_pipe_state *rstate;
-       uint32_t color_control, target_mask;
-       /* FIXME there is more then 8 framebuffer */
-       unsigned blend_cntl[8];
-
-       if (blend == NULL) {
-               return NULL;
-       }
-
-       rstate = &blend->rstate;
-
-       rstate->id = R600_PIPE_STATE_BLEND;
-
-       target_mask = 0;
-       color_control = S_028808_MODE(V_028808_CB_NORMAL);
-       if (state->logicop_enable) {
-               color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
-       } else {
-               color_control |= S_028808_ROP3(0xcc);
-       }
-       /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
-       if (state->independent_blend_enable) {
-               for (int i = 0; i < 8; i++) {
-                       target_mask |= (state->rt[i].colormask << (4 * i));
-               }
-       } else {
-               for (int i = 0; i < 8; i++) {
-                       target_mask |= (state->rt[0].colormask << (4 * i));
-               }
-       }
-       blend->cb_target_mask = target_mask;
-
-       r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
-                               color_control, NULL, 0);
-
-       r600_pipe_state_add_reg(rstate, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0, NULL, 0);
-       r600_pipe_state_add_reg(rstate, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0, NULL, 0);
-
-       for (int i = 0; i < 8; i++) {
-               /* state->rt entries > 0 only written if independent blending */
-               const int j = state->independent_blend_enable ? i : 0;
-
-               unsigned eqRGB = state->rt[j].rgb_func;
-               unsigned srcRGB = state->rt[j].rgb_src_factor;
-               unsigned dstRGB = state->rt[j].rgb_dst_factor;
-               unsigned eqA = state->rt[j].alpha_func;
-               unsigned srcA = state->rt[j].alpha_src_factor;
-               unsigned dstA = state->rt[j].alpha_dst_factor;
-
-               blend_cntl[i] = 0;
-               if (!state->rt[j].blend_enable)
-                       continue;
-
-               blend_cntl[i] |= S_028780_ENABLE(1);
-               blend_cntl[i] |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
-               blend_cntl[i] |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB));
-               blend_cntl[i] |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB));
-
-               if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
-                       blend_cntl[i] |= S_028780_SEPARATE_ALPHA_BLEND(1);
-                       blend_cntl[i] |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
-                       blend_cntl[i] |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA));
-                       blend_cntl[i] |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
-               }
-       }
-       for (int i = 0; i < 8; i++) {
-               r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl[i], NULL, 0);
-       }
-
-       return rstate;
-}
-
 static void *evergreen_create_dsa_state(struct pipe_context *ctx,
                                   const struct pipe_depth_stencil_alpha_state *state)
 {
@@ -1054,7 +912,8 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
        rs->offset_scale = state->offset_scale * 12.0f;
 
        rstate->id = R600_PIPE_STATE_RASTERIZER;
-       tmp = S_0286D4_FLAT_SHADE_ENA(state->flatshade);
+       /* XXX: Flat shading hangs the GPU */
+       tmp = S_0286D4_FLAT_SHADE_ENA(0);
        if (state->sprite_coord_enable) {
                tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
                        S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
@@ -1166,24 +1025,6 @@ static void si_delete_sampler_state(struct pipe_context *ctx,
        free(state);
 }
 
-static unsigned si_map_swizzle(unsigned swizzle)
-{
-       switch (swizzle) {
-       case UTIL_FORMAT_SWIZZLE_Y:
-               return V_008F1C_SQ_SEL_Y;
-       case UTIL_FORMAT_SWIZZLE_Z:
-               return V_008F1C_SQ_SEL_Z;
-       case UTIL_FORMAT_SWIZZLE_W:
-               return V_008F1C_SQ_SEL_W;
-       case UTIL_FORMAT_SWIZZLE_0:
-               return V_008F1C_SQ_SEL_0;
-       case UTIL_FORMAT_SWIZZLE_1:
-               return V_008F1C_SQ_SEL_1;
-       default: /* UTIL_FORMAT_SWIZZLE_X */
-               return V_008F1C_SQ_SEL_X;
-       }
-}
-
 static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_context *ctx,
                                                        struct pipe_resource *texture,
                                                        const struct pipe_sampler_view *state)
@@ -1191,10 +1032,11 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        struct si_pipe_sampler_view *view = CALLOC_STRUCT(si_pipe_sampler_view);
        struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
        const struct util_format_description *desc = util_format_description(state->format);
-       unsigned format, num_format, endian;
+       unsigned blocksize = util_format_get_blocksize(tmp->real_format);
+       unsigned format, num_format, endian, tiling_index;
        uint32_t pitch = 0;
-       unsigned char state_swizzle[4], swizzle[4], array_mode = 0, tile_type = 0;
-       unsigned height, depth;
+       unsigned char state_swizzle[4], swizzle[4];
+       unsigned height, depth, width;
        int first_non_void;
        uint64_t va;
 
@@ -1220,9 +1062,6 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        case UTIL_FORMAT_TYPE_FLOAT:
                num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
                break;
-       case UTIL_FORMAT_TYPE_FIXED:
-               num_format = V_008F14_IMG_NUM_FORMAT_USCALED; /* XXX */
-               break;
        case UTIL_FORMAT_TYPE_SIGNED:
                num_format = V_008F14_IMG_NUM_FORMAT_SNORM;
                break;
@@ -1245,10 +1084,9 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 
        height = texture->height0;
        depth = texture->depth0;
-
-       pitch = tmp->pitch_in_blocks[0] * util_format_get_blockwidth(state->format);
-       array_mode = tmp->array_mode[0];
-       tile_type = tmp->tile_type;
+       width = texture->width0;
+       pitch = align(tmp->pitch_in_blocks[0] *
+                     util_format_get_blockwidth(state->format), 8);
 
        if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
                height = 1;
@@ -1257,12 +1095,57 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
                depth = texture->array_size;
        }
 
+       tiling_index = 8;
+       switch (tmp->surface.level[state->u.tex.first_level].mode) {
+       case RADEON_SURF_MODE_LINEAR_ALIGNED:
+               tiling_index = 8;
+               break;
+       case RADEON_SURF_MODE_1D:
+               tiling_index = 9;
+               break;
+       case RADEON_SURF_MODE_2D:
+               if (tmp->resource.b.b.bind & PIPE_BIND_SCANOUT) {
+                       switch (blocksize) {
+                       case 1:
+                               tiling_index = 10;
+                               break;
+                       case 2:
+                               tiling_index = 11;
+                               break;
+                       case 4:
+                               tiling_index = 12;
+                               break;
+                       }
+                       break;
+               } else switch (blocksize) {
+               case 1:
+                       tiling_index = 14;
+                       break;
+               case 2:
+                       tiling_index = 15;
+                       break;
+               case 4:
+                       tiling_index = 16;
+                       break;
+               case 8:
+                       tiling_index = 17;
+                       break;
+               default:
+                       tiling_index = 13;
+               }
+               break;
+       }
+
        va = r600_resource_va(ctx->screen, texture);
-       view->state[0] = (va + tmp->offset[0]) >> 8;
+       if (state->u.tex.last_level) {
+               view->state[0] = (va + tmp->offset[1]) >> 8;
+       } else {
+               view->state[0] = (va + tmp->offset[0]) >> 8;
+       }
        view->state[1] = (S_008F14_BASE_ADDRESS_HI((va + tmp->offset[0]) >> 40) |
                          S_008F14_DATA_FORMAT(format) |
                          S_008F14_NUM_FORMAT(num_format));
-       view->state[2] = (S_008F18_WIDTH(texture->width0 - 1) |
+       view->state[2] = (S_008F18_WIDTH(width - 1) |
                          S_008F18_HEIGHT(height - 1));
        view->state[3] = (S_008F1C_DST_SEL_X(si_map_swizzle(swizzle[0])) |
                          S_008F1C_DST_SEL_Y(si_map_swizzle(swizzle[1])) |
@@ -1270,7 +1153,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
                          S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) |
                          S_008F1C_BASE_LEVEL(state->u.tex.first_level) |
                          S_008F1C_LAST_LEVEL(state->u.tex.last_level) |
-                         S_008F1C_TILING_INDEX(8) | /* XXX */
+                         S_008F1C_TILING_INDEX(tiling_index) |
                          S_008F1C_TYPE(si_tex_dim(texture->target)));
        view->state[4] = (S_008F20_DEPTH(depth - 1) | S_008F20_PITCH(pitch - 1));
        view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
@@ -1291,7 +1174,7 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pipe_sampler_view **resource = (struct si_pipe_sampler_view **)views;
-       struct r600_pipe_state *rstate = &rctx->ps_samplers.rstate;
+       struct r600_pipe_state *rstate = &rctx->ps_samplers.views_state;
        struct r600_resource *bo;
        int i;
        int has_depth = 0;
@@ -1329,6 +1212,7 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou
                        pipe_sampler_view_reference((struct pipe_sampler_view **)&rctx->ps_samplers.views[i], NULL);
        }
 
+       rstate->nregs = 0;
        va = r600_resource_va(ctx->screen, (void *)bo);
        r600_pipe_state_add_reg(rstate, R_00B040_SPI_SHADER_USER_DATA_PS_4, va, bo, RADEON_USAGE_READ);
        r600_pipe_state_add_reg(rstate, R_00B044_SPI_SHADER_USER_DATA_PS_5, va >> 32, NULL, 0);
@@ -1343,7 +1227,7 @@ static void evergreen_bind_ps_sampler(struct pipe_context *ctx, unsigned count,
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state **)states;
-       struct r600_pipe_state *rstate = &rctx->ps_samplers.rstate;
+       struct r600_pipe_state *rstate = &rctx->ps_samplers.samplers_state;
        struct r600_resource *bo;
        uint64_t va;
        char *ptr;
@@ -1365,6 +1249,9 @@ static void evergreen_bind_ps_sampler(struct pipe_context *ctx, unsigned count,
 
        rctx->ws->buffer_unmap(bo->cs_buf);
 
+       memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
+
+       rstate->nregs = 0;
        va = r600_resource_va(ctx->screen, (void *)bo);
        r600_pipe_state_add_reg(rstate, R_00B038_SPI_SHADER_USER_DATA_PS_2, va, bo, RADEON_USAGE_READ);
        r600_pipe_state_add_reg(rstate, R_00B03C_SPI_SHADER_USER_DATA_PS_3, va >> 32, NULL, 0);
@@ -1489,22 +1376,23 @@ static void evergreen_set_viewport_state(struct pipe_context *ctx,
 }
 
 static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
-                       const struct pipe_framebuffer_state *state, int cb)
+                        const struct pipe_framebuffer_state *state, int cb)
 {
        struct r600_resource_texture *rtex;
        struct r600_surface *surf;
        unsigned level = state->cbufs[cb]->u.tex.level;
        unsigned pitch, slice;
-       unsigned color_info;
+       unsigned color_info, color_attrib;
        unsigned format, swap, ntype, endian;
        uint64_t offset;
-       unsigned tile_type;
+       unsigned blocksize;
        const struct util_format_description *desc;
        int i;
        unsigned blend_clamp = 0, blend_bypass = 0;
 
        surf = (struct r600_surface *)state->cbufs[cb];
        rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
+       blocksize = util_format_get_blocksize(rtex->real_format);
 
        if (rtex->depth)
                rctx->have_depth_fb = TRUE;
@@ -1514,11 +1402,58 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
                rtex = rtex->flushed_depth_texture;
        }
 
-       /* XXX quite sure for dx10+ hw don't need any offset hacks */
-       offset = r600_texture_get_offset(rtex,
-                                        level, state->cbufs[cb]->u.tex.first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+       offset = rtex->surface.level[level].offset;
+       if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+               offset += rtex->surface.level[level].slice_size *
+                         state->cbufs[cb]->u.tex.first_layer;
+       }
+       pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
+       slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+       if (slice) {
+               slice = slice - 1;
+       }
+
+       color_attrib = S_028C74_TILE_MODE_INDEX(8);
+       switch (rtex->surface.level[level].mode) {
+       case RADEON_SURF_MODE_LINEAR_ALIGNED:
+               color_attrib = S_028C74_TILE_MODE_INDEX(8);
+               break;
+       case RADEON_SURF_MODE_1D:
+               color_attrib = S_028C74_TILE_MODE_INDEX(9);
+               break;
+       case RADEON_SURF_MODE_2D:
+               if (rtex->resource.b.b.bind & PIPE_BIND_SCANOUT) {
+                       switch (blocksize) {
+                       case 1:
+                               color_attrib = S_028C74_TILE_MODE_INDEX(10);
+                               break;
+                       case 2:
+                               color_attrib = S_028C74_TILE_MODE_INDEX(11);
+                               break;
+                       case 4:
+                               color_attrib = S_028C74_TILE_MODE_INDEX(12);
+                               break;
+                       }
+                       break;
+               } else switch (blocksize) {
+               case 1:
+                       color_attrib = S_028C74_TILE_MODE_INDEX(14);
+                       break;
+               case 2:
+                       color_attrib = S_028C74_TILE_MODE_INDEX(15);
+                       break;
+               case 4:
+                       color_attrib = S_028C74_TILE_MODE_INDEX(16);
+                       break;
+               case 8:
+                       color_attrib = S_028C74_TILE_MODE_INDEX(17);
+                       break;
+               default:
+                       color_attrib = S_028C74_TILE_MODE_INDEX(13);
+               }
+               break;
+       }
+
        desc = util_format_description(surf->base.format);
        for (i = 0; i < 4; i++) {
                if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
@@ -1569,14 +1504,11 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
 
        color_info = S_028C70_FORMAT(format) |
                S_028C70_COMP_SWAP(swap) |
-               //S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
                S_028C70_BLEND_CLAMP(blend_clamp) |
                S_028C70_BLEND_BYPASS(blend_bypass) |
                S_028C70_NUMBER_TYPE(ntype) |
                S_028C70_ENDIAN(endian);
 
-       color_info |= S_028C70_LINEAR_GENERAL(1);
-
        rctx->alpha_ref_dirty = true;
 
        offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
@@ -1594,15 +1526,23 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
                                R_028C68_CB_COLOR0_SLICE + cb * 0x3C,
                                S_028C68_TILE_MAX(slice),
                                NULL, 0);
-       r600_pipe_state_add_reg(rstate,
-                               R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
-                               0x00000000, NULL, 0);
+       if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+               r600_pipe_state_add_reg(rstate,
+                                       R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
+                                       0x00000000, NULL, 0);
+       } else {
+               r600_pipe_state_add_reg(rstate,
+                                       R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
+                                       S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
+                                       S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer),
+                                       NULL, 0);
+       }
        r600_pipe_state_add_reg(rstate,
                                R_028C70_CB_COLOR0_INFO + cb * 0x3C,
                                color_info, &rtex->resource, RADEON_USAGE_READWRITE);
        r600_pipe_state_add_reg(rstate,
                                R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-                               0,
+                               color_attrib,
                                &rtex->resource, RADEON_USAGE_READWRITE);
 }
 
@@ -1626,19 +1566,25 @@ static void si_db(struct r600_context *rctx, struct r600_pipe_state *rstate,
        rtex = (struct r600_resource_texture*)surf->base.texture;
 
        first_layer = surf->base.u.tex.first_layer;
-       offset = r600_texture_get_offset(rtex, level, first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
        format = si_translate_dbformat(rtex->real_format);
 
-       offset += r600_resource_va(rctx->context.screen, surf->base.texture);
+       offset = r600_resource_va(rctx->context.screen, surf->base.texture);
+       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;
+       if (slice) {
+               slice = slice - 1;
+       }
        offset >>= 8;
 
        r600_pipe_state_add_reg(rstate, R_028048_DB_Z_READ_BASE,
                                offset, &rtex->resource, RADEON_USAGE_READWRITE);
        r600_pipe_state_add_reg(rstate, R_028050_DB_Z_WRITE_BASE,
                                offset, &rtex->resource, RADEON_USAGE_READWRITE);
-       r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW, 0x00000000, NULL, 0);
+       r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW,
+                               S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
+                               S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer),
+                               NULL, 0);
 
        db_z_info = S_028040_FORMAT(format);
        stencil_info = S_028044_FORMAT(rtex->stencil != 0);
@@ -1788,7 +1734,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
 
 void cayman_init_state_functions(struct r600_context *rctx)
 {
-       rctx->context.create_blend_state = evergreen_create_blend_state;
+       si_init_state_functions(rctx);
        rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state;
        rctx->context.create_fs_state = si_create_shader_state;
        rctx->context.create_rasterizer_state = evergreen_create_rs_state;
@@ -1796,7 +1742,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
        rctx->context.create_sampler_view = evergreen_create_sampler_view;
        rctx->context.create_vertex_elements_state = si_create_vertex_elements;
        rctx->context.create_vs_state = si_create_shader_state;
-       rctx->context.bind_blend_state = r600_bind_blend_state;
        rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
        rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler;
        rctx->context.bind_fs_state = r600_bind_ps_shader;
@@ -1804,7 +1749,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
        rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements;
        rctx->context.bind_vertex_sampler_states = evergreen_bind_vs_sampler;
        rctx->context.bind_vs_state = r600_bind_vs_shader;
-       rctx->context.delete_blend_state = r600_delete_state;
        rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
        rctx->context.delete_fs_state = r600_delete_ps_shader;
        rctx->context.delete_rasterizer_state = r600_delete_rs_state;
@@ -1825,7 +1769,6 @@ void cayman_init_state_functions(struct r600_context *rctx)
        rctx->context.set_vertex_sampler_views = evergreen_set_vs_sampler_view;
        rctx->context.set_viewport_state = evergreen_set_viewport_state;
        rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
-       rctx->context.redefine_user_buffer = u_default_redefine_user_buffer;
        rctx->context.texture_barrier = r600_texture_barrier;
        rctx->context.create_stream_output_target = r600_create_so_target;
        rctx->context.stream_output_target_destroy = r600_so_target_destroy;
@@ -1942,6 +1885,11 @@ void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *shader)
        db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
        for (i = 0; i < rshader->ninput; i++) {
                ninterp++;
+               /* XXX: Flat shading hangs the GPU */
+               if (rshader->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
+                   (rshader->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
+                    rctx->rasterizer->flatshade))
+                       have_linear = TRUE;
                if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
                        have_linear = TRUE;
                if (rshader->input[i].interpolate == TGSI_INTERPOLATE_PERSPECTIVE)
@@ -2134,11 +2082,15 @@ void si_update_spi_map(struct r600_context *rctx)
        for (i = 0; i < ps->ninput; i++) {
                tmp = 0;
 
-               if (ps->input[i].name == TGSI_SEMANTIC_COLOR ||
-                   ps->input[i].name == TGSI_SEMANTIC_BCOLOR ||
-                   ps->input[i].name == TGSI_SEMANTIC_POSITION) {
+#if 0
+               /* XXX: Flat shading hangs the GPU */
+               if (ps->input[i].name == TGSI_SEMANTIC_POSITION ||
+                   ps->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
+                   (ps->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
+                    rctx->rasterizer && rctx->rasterizer->flatshade)) {
                        tmp |= S_028644_FLAT_SHADE(1);
                }
+#endif
 
                if (ps->input[i].name == TGSI_SEMANTIC_GENERIC &&
                    rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
@@ -2148,7 +2100,7 @@ void si_update_spi_map(struct r600_context *rctx)
                for (j = 0; j < vs->noutput; j++) {
                        if (ps->input[i].name == vs->output[j].name &&
                            ps->input[i].sid == vs->output[j].sid) {
-                               tmp |= S_028644_OFFSET(ps->input[i].sid);
+                               tmp |= S_028644_OFFSET(vs->output[j].param_offset);
                                break;
                        }
                }