radeon: don't use old bind_vertex/fragment_sampler_states() hooks
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
index ccd826e0ec6b86c1e77be127f41f1191cc0971b8..d1b8f6e3df2d659a2d956c68d31f56280e69855f 100644 (file)
@@ -36,6 +36,7 @@
 #include "radeonsi_pipe.h"
 #include "radeonsi_shader.h"
 #include "si_state.h"
+#include "../radeon/r600_cs.h"
 #include "sid.h"
 
 static uint32_t cik_num_banks(uint32_t nbanks)
@@ -255,6 +256,8 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
        if (blend == NULL)
                return NULL;
 
+       blend->alpha_to_one = state->alpha_to_one;
+
        color_control = S_028808_MODE(mode);
        if (state->logicop_enable) {
                color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
@@ -520,6 +523,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        }
 
        rs->two_side = state->light_twoside;
+       rs->multisample_enable = state->multisample;
        rs->clip_plane_enable = state->clip_plane_enable;
 
        polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
@@ -548,6 +552,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
                S_028810_PS_UCP_MODE(3) |
                S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
                S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
+               S_028810_DX_RASTERIZATION_KILL(state->rasterizer_discard) |
                S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
 
        clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
@@ -785,19 +790,20 @@ static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
 }
 
 static void *si_create_db_flush_dsa(struct r600_context *rctx, bool copy_depth,
-                                   bool copy_stencil)
+                                   bool copy_stencil, int sample)
 {
        struct pipe_depth_stencil_alpha_state dsa;
         struct si_state_dsa *state;
 
        memset(&dsa, 0, sizeof(dsa));
 
-       state = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
+       state = rctx->b.b.create_depth_stencil_alpha_state(&rctx->b.b, &dsa);
        if (copy_depth || copy_stencil) {
                si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
                               S_028000_DEPTH_COPY(copy_depth) |
                               S_028000_STENCIL_COPY(copy_stencil) |
-                              S_028000_COPY_CENTROID(1));
+                              S_028000_COPY_CENTROID(1) |
+                              S_028000_COPY_SAMPLE(sample));
        } else {
                si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
                               S_028000_DEPTH_COMPRESS_DISABLE(1) |
@@ -817,366 +823,124 @@ static void *si_create_db_flush_dsa(struct r600_context *rctx, bool copy_depth,
  */
 static uint32_t si_translate_colorformat(enum pipe_format format)
 {
-       switch (format) {
-       /* 8-bit buffers. */
-       case PIPE_FORMAT_A8_UNORM:
-       case PIPE_FORMAT_A8_SNORM:
-       case PIPE_FORMAT_A8_UINT:
-       case PIPE_FORMAT_A8_SINT:
-       case PIPE_FORMAT_I8_UNORM:
-       case PIPE_FORMAT_I8_SNORM:
-       case PIPE_FORMAT_I8_UINT:
-       case PIPE_FORMAT_I8_SINT:
-       case PIPE_FORMAT_L8_UNORM:
-       case PIPE_FORMAT_L8_SNORM:
-       case PIPE_FORMAT_L8_UINT:
-       case PIPE_FORMAT_L8_SINT:
-       case PIPE_FORMAT_L8_SRGB:
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R8_SNORM:
-       case PIPE_FORMAT_R8_UINT:
-       case PIPE_FORMAT_R8_SINT:
-               return V_028C70_COLOR_8;
-
-       /* 16-bit buffers. */
-       case PIPE_FORMAT_B5G6R5_UNORM:
-               return V_028C70_COLOR_5_6_5;
-
-       case PIPE_FORMAT_B5G5R5A1_UNORM:
-       case PIPE_FORMAT_B5G5R5X1_UNORM:
-               return V_028C70_COLOR_1_5_5_5;
-
-       case PIPE_FORMAT_B4G4R4A4_UNORM:
-       case PIPE_FORMAT_B4G4R4X4_UNORM:
-               return V_028C70_COLOR_4_4_4_4;
-
-       case PIPE_FORMAT_L8A8_UNORM:
-       case PIPE_FORMAT_L8A8_SNORM:
-       case PIPE_FORMAT_L8A8_UINT:
-       case PIPE_FORMAT_L8A8_SINT:
-       case PIPE_FORMAT_R8G8_SNORM:
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R8G8_UINT:
-       case PIPE_FORMAT_R8G8_SINT:
-               return V_028C70_COLOR_8_8;
-
-       case PIPE_FORMAT_Z16_UNORM:
-       case PIPE_FORMAT_R16_UNORM:
-       case PIPE_FORMAT_R16_SNORM:
-       case PIPE_FORMAT_R16_UINT:
-       case PIPE_FORMAT_R16_SINT:
-       case PIPE_FORMAT_R16_FLOAT:
-       case PIPE_FORMAT_L16_UNORM:
-       case PIPE_FORMAT_L16_SNORM:
-       case PIPE_FORMAT_L16_FLOAT:
-       case PIPE_FORMAT_I16_UNORM:
-       case PIPE_FORMAT_I16_SNORM:
-       case PIPE_FORMAT_I16_FLOAT:
-       case PIPE_FORMAT_A16_UNORM:
-       case PIPE_FORMAT_A16_SNORM:
-       case PIPE_FORMAT_A16_FLOAT:
-               return V_028C70_COLOR_16;
-
-       /* 32-bit buffers. */
-       case PIPE_FORMAT_A8B8G8R8_SRGB:
-       case PIPE_FORMAT_A8B8G8R8_UNORM:
-       case PIPE_FORMAT_A8R8G8B8_UNORM:
-       case PIPE_FORMAT_B8G8R8A8_SRGB:
-       case PIPE_FORMAT_B8G8R8A8_UNORM:
-       case PIPE_FORMAT_B8G8R8X8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_SNORM:
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-       case PIPE_FORMAT_R8G8B8X8_UNORM:
-       case PIPE_FORMAT_R8G8B8X8_SNORM:
-       case PIPE_FORMAT_R8G8B8X8_SRGB:
-       case PIPE_FORMAT_R8G8B8X8_UINT:
-       case PIPE_FORMAT_R8G8B8X8_SINT:
-       case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
-       case PIPE_FORMAT_X8B8G8R8_UNORM:
-       case PIPE_FORMAT_X8R8G8B8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_SSCALED:
-       case PIPE_FORMAT_R8G8B8A8_USCALED:
-       case PIPE_FORMAT_R8G8B8A8_SINT:
-       case PIPE_FORMAT_R8G8B8A8_UINT:
-               return V_028C70_COLOR_8_8_8_8;
-
-       case PIPE_FORMAT_R10G10B10A2_UNORM:
-       case PIPE_FORMAT_R10G10B10X2_SNORM:
-       case PIPE_FORMAT_B10G10R10A2_UNORM:
-       case PIPE_FORMAT_B10G10R10A2_UINT:
-       case PIPE_FORMAT_B10G10R10X2_UNORM:
-       case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
-               return V_028C70_COLOR_2_10_10_10;
-
-       case PIPE_FORMAT_Z24X8_UNORM:
-       case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-               return V_028C70_COLOR_8_24;
-
-       case PIPE_FORMAT_S8X24_UINT:
-       case PIPE_FORMAT_X8Z24_UNORM:
-       case PIPE_FORMAT_S8_UINT_Z24_UNORM:
-               return V_028C70_COLOR_24_8;
+       const struct util_format_description *desc = util_format_description(format);
 
-       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-               return V_028C70_COLOR_X24_8_32_FLOAT;
+#define HAS_SIZE(x,y,z,w) \
+       (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
+         desc->channel[2].size == (z) && desc->channel[3].size == (w))
 
-       case PIPE_FORMAT_I32_FLOAT:
-       case PIPE_FORMAT_L32_FLOAT:
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_A32_FLOAT:
-       case PIPE_FORMAT_Z32_FLOAT:
-               return V_028C70_COLOR_32;
-
-       case PIPE_FORMAT_L16A16_UNORM:
-       case PIPE_FORMAT_L16A16_SNORM:
-       case PIPE_FORMAT_L16A16_FLOAT:
-       case PIPE_FORMAT_R16G16_SSCALED:
-       case PIPE_FORMAT_R16G16_UNORM:
-       case PIPE_FORMAT_R16G16_SNORM:
-       case PIPE_FORMAT_R16G16_UINT:
-       case PIPE_FORMAT_R16G16_SINT:
-       case PIPE_FORMAT_R16G16_FLOAT:
-               return V_028C70_COLOR_16_16;
-
-       case PIPE_FORMAT_R11G11B10_FLOAT:
+       if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
                return V_028C70_COLOR_10_11_11;
 
-       /* 64-bit buffers. */
-       case PIPE_FORMAT_R16G16B16A16_UINT:
-       case PIPE_FORMAT_R16G16B16A16_SINT:
-       case PIPE_FORMAT_R16G16B16A16_USCALED:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-       case PIPE_FORMAT_R16G16B16A16_UNORM:
-       case PIPE_FORMAT_R16G16B16A16_SNORM:
-       case PIPE_FORMAT_R16G16B16A16_FLOAT:
-       case PIPE_FORMAT_R16G16B16X16_UNORM:
-       case PIPE_FORMAT_R16G16B16X16_SNORM:
-       case PIPE_FORMAT_R16G16B16X16_FLOAT:
-       case PIPE_FORMAT_R16G16B16X16_UINT:
-       case PIPE_FORMAT_R16G16B16X16_SINT:
-               return V_028C70_COLOR_16_16_16_16;
-
-       case PIPE_FORMAT_L32A32_FLOAT:
-       case PIPE_FORMAT_L32A32_UINT:
-       case PIPE_FORMAT_L32A32_SINT:
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R32G32_USCALED:
-       case PIPE_FORMAT_R32G32_SSCALED:
-       case PIPE_FORMAT_R32G32_SINT:
-       case PIPE_FORMAT_R32G32_UINT:
-               return V_028C70_COLOR_32_32;
-
-       /* 128-bit buffers. */
-       case PIPE_FORMAT_R32G32B32A32_SNORM:
-       case PIPE_FORMAT_R32G32B32A32_UNORM:
-       case PIPE_FORMAT_R32G32B32A32_SSCALED:
-       case PIPE_FORMAT_R32G32B32A32_USCALED:
-       case PIPE_FORMAT_R32G32B32A32_SINT:
-       case PIPE_FORMAT_R32G32B32A32_UINT:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R32G32B32X32_FLOAT:
-       case PIPE_FORMAT_R32G32B32X32_UINT:
-       case PIPE_FORMAT_R32G32B32X32_SINT:
-               return V_028C70_COLOR_32_32_32_32;
-
-       /* YUV buffers. */
-       case PIPE_FORMAT_UYVY:
-       case PIPE_FORMAT_YUYV:
-       /* 96-bit buffers. */
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-       /* 8-bit buffers. */
-       case PIPE_FORMAT_L4A4_UNORM:
-       case PIPE_FORMAT_R4A4_UNORM:
-       case PIPE_FORMAT_A4R4_UNORM:
-       default:
-               return V_028C70_COLOR_INVALID; /* Unsupported. */
+       if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
+               return V_028C70_COLOR_INVALID;
+
+       switch (desc->nr_channels) {
+       case 1:
+               switch (desc->channel[0].size) {
+               case 8:
+                       return V_028C70_COLOR_8;
+               case 16:
+                       return V_028C70_COLOR_16;
+               case 32:
+                       return V_028C70_COLOR_32;
+               }
+               break;
+       case 2:
+               if (desc->channel[0].size == desc->channel[1].size) {
+                       switch (desc->channel[0].size) {
+                       case 8:
+                               return V_028C70_COLOR_8_8;
+                       case 16:
+                               return V_028C70_COLOR_16_16;
+                       case 32:
+                               return V_028C70_COLOR_32_32;
+                       }
+               } else if (HAS_SIZE(8,24,0,0)) {
+                       return V_028C70_COLOR_24_8;
+               } else if (HAS_SIZE(24,8,0,0)) {
+                       return V_028C70_COLOR_8_24;
+               }
+               break;
+       case 3:
+               if (HAS_SIZE(5,6,5,0)) {
+                       return V_028C70_COLOR_5_6_5;
+               } else if (HAS_SIZE(32,8,24,0)) {
+                       return V_028C70_COLOR_X24_8_32_FLOAT;
+               }
+               break;
+       case 4:
+               if (desc->channel[0].size == desc->channel[1].size &&
+                   desc->channel[0].size == desc->channel[2].size &&
+                   desc->channel[0].size == desc->channel[3].size) {
+                       switch (desc->channel[0].size) {
+                       case 4:
+                               return V_028C70_COLOR_4_4_4_4;
+                       case 8:
+                               return V_028C70_COLOR_8_8_8_8;
+                       case 16:
+                               return V_028C70_COLOR_16_16_16_16;
+                       case 32:
+                               return V_028C70_COLOR_32_32_32_32;
+                       }
+               } else if (HAS_SIZE(5,5,5,1)) {
+                       return V_028C70_COLOR_1_5_5_5;
+               } else if (HAS_SIZE(10,10,10,2)) {
+                       return V_028C70_COLOR_2_10_10_10;
+               }
+               break;
        }
+       return V_028C70_COLOR_INVALID;
 }
 
 static uint32_t si_translate_colorswap(enum pipe_format format)
 {
-       switch (format) {
-       /* 8-bit buffers. */
-       case PIPE_FORMAT_L4A4_UNORM:
-       case PIPE_FORMAT_A4R4_UNORM:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_A8_UNORM:
-       case PIPE_FORMAT_A8_SNORM:
-       case PIPE_FORMAT_A8_UINT:
-       case PIPE_FORMAT_A8_SINT:
-       case PIPE_FORMAT_R4A4_UNORM:
-               return V_028C70_SWAP_ALT_REV;
-       case PIPE_FORMAT_I8_UNORM:
-       case PIPE_FORMAT_I8_SNORM:
-       case PIPE_FORMAT_L8_UNORM:
-       case PIPE_FORMAT_L8_SNORM:
-       case PIPE_FORMAT_I8_UINT:
-       case PIPE_FORMAT_I8_SINT:
-       case PIPE_FORMAT_L8_UINT:
-       case PIPE_FORMAT_L8_SINT:
-       case PIPE_FORMAT_L8_SRGB:
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R8_SNORM:
-       case PIPE_FORMAT_R8_UINT:
-       case PIPE_FORMAT_R8_SINT:
-               return V_028C70_SWAP_STD;
-
-       /* 16-bit buffers. */
-       case PIPE_FORMAT_B5G6R5_UNORM:
-               return V_028C70_SWAP_STD_REV;
-
-       case PIPE_FORMAT_B5G5R5A1_UNORM:
-       case PIPE_FORMAT_B5G5R5X1_UNORM:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_B4G4R4A4_UNORM:
-       case PIPE_FORMAT_B4G4R4X4_UNORM:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_Z16_UNORM:
-               return V_028C70_SWAP_STD;
-
-       case PIPE_FORMAT_L8A8_UNORM:
-       case PIPE_FORMAT_L8A8_SNORM:
-       case PIPE_FORMAT_L8A8_UINT:
-       case PIPE_FORMAT_L8A8_SINT:
-               return V_028C70_SWAP_ALT;
-       case PIPE_FORMAT_R8G8_SNORM:
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R8G8_UINT:
-       case PIPE_FORMAT_R8G8_SINT:
-               return V_028C70_SWAP_STD;
-
-       case PIPE_FORMAT_I16_UNORM:
-       case PIPE_FORMAT_I16_SNORM:
-       case PIPE_FORMAT_I16_FLOAT:
-       case PIPE_FORMAT_L16_UNORM:
-       case PIPE_FORMAT_L16_SNORM:
-       case PIPE_FORMAT_L16_FLOAT:
-       case PIPE_FORMAT_R16_UNORM:
-       case PIPE_FORMAT_R16_SNORM:
-       case PIPE_FORMAT_R16_UINT:
-       case PIPE_FORMAT_R16_SINT:
-       case PIPE_FORMAT_R16_FLOAT:
-               return V_028C70_SWAP_STD;
-
-       case PIPE_FORMAT_A16_UNORM:
-       case PIPE_FORMAT_A16_SNORM:
-       case PIPE_FORMAT_A16_FLOAT:
-               return V_028C70_SWAP_ALT_REV;
-
-       /* 32-bit buffers. */
-       case PIPE_FORMAT_A8B8G8R8_SRGB:
-               return V_028C70_SWAP_STD_REV;
-       case PIPE_FORMAT_B8G8R8A8_SRGB:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_B8G8R8A8_UNORM:
-       case PIPE_FORMAT_B8G8R8X8_UNORM:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_A8R8G8B8_UNORM:
-       case PIPE_FORMAT_X8R8G8B8_UNORM:
-               return V_028C70_SWAP_ALT_REV;
-       case PIPE_FORMAT_R8G8B8A8_SNORM:
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_SSCALED:
-       case PIPE_FORMAT_R8G8B8A8_USCALED:
-       case PIPE_FORMAT_R8G8B8A8_SINT:
-       case PIPE_FORMAT_R8G8B8A8_UINT:
-       case PIPE_FORMAT_R8G8B8X8_UNORM:
-       case PIPE_FORMAT_R8G8B8X8_SNORM:
-       case PIPE_FORMAT_R8G8B8X8_SRGB:
-       case PIPE_FORMAT_R8G8B8X8_UINT:
-       case PIPE_FORMAT_R8G8B8X8_SINT:
-               return V_028C70_SWAP_STD;
-
-       case PIPE_FORMAT_A8B8G8R8_UNORM:
-       case PIPE_FORMAT_X8B8G8R8_UNORM:
-       /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
-               return V_028C70_SWAP_STD_REV;
-
-       case PIPE_FORMAT_Z24X8_UNORM:
-       case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-               return V_028C70_SWAP_STD;
-
-       case PIPE_FORMAT_S8X24_UINT:
-       case PIPE_FORMAT_X8Z24_UNORM:
-       case PIPE_FORMAT_S8_UINT_Z24_UNORM:
-               return V_028C70_SWAP_STD_REV;
+       const struct util_format_description *desc = util_format_description(format);
 
-       case PIPE_FORMAT_R10G10B10A2_UNORM:
-       case PIPE_FORMAT_R10G10B10X2_SNORM:
-       case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
-               return V_028C70_SWAP_STD;
+#define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == UTIL_FORMAT_SWIZZLE_##swz)
 
-       case PIPE_FORMAT_B10G10R10A2_UNORM:
-       case PIPE_FORMAT_B10G10R10A2_UINT:
-       case PIPE_FORMAT_B10G10R10X2_UNORM:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_R11G11B10_FLOAT:
-       case PIPE_FORMAT_I32_FLOAT:
-       case PIPE_FORMAT_L32_FLOAT:
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R32_UINT:
-       case PIPE_FORMAT_R32_SINT:
-       case PIPE_FORMAT_Z32_FLOAT:
-       case PIPE_FORMAT_R16G16_FLOAT:
-       case PIPE_FORMAT_R16G16_UNORM:
-       case PIPE_FORMAT_R16G16_SNORM:
-       case PIPE_FORMAT_R16G16_UINT:
-       case PIPE_FORMAT_R16G16_SINT:
+       if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
                return V_028C70_SWAP_STD;
 
-       case PIPE_FORMAT_L16A16_UNORM:
-       case PIPE_FORMAT_L16A16_SNORM:
-       case PIPE_FORMAT_L16A16_FLOAT:
-               return V_028C70_SWAP_ALT;
-
-       case PIPE_FORMAT_A32_FLOAT:
-               return V_028C70_SWAP_ALT_REV;
-
-       /* 64-bit buffers. */
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R32G32_UINT:
-       case PIPE_FORMAT_R32G32_SINT:
-       case PIPE_FORMAT_R16G16B16A16_UNORM:
-       case PIPE_FORMAT_R16G16B16A16_SNORM:
-       case PIPE_FORMAT_R16G16B16A16_USCALED:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-       case PIPE_FORMAT_R16G16B16A16_UINT:
-       case PIPE_FORMAT_R16G16B16A16_SINT:
-       case PIPE_FORMAT_R16G16B16A16_FLOAT:
-       case PIPE_FORMAT_R16G16B16X16_UNORM:
-       case PIPE_FORMAT_R16G16B16X16_SNORM:
-       case PIPE_FORMAT_R16G16B16X16_FLOAT:
-       case PIPE_FORMAT_R16G16B16X16_UINT:
-       case PIPE_FORMAT_R16G16B16X16_SINT:
-       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-               return V_028C70_SWAP_STD;
+       if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
+               return ~0;
 
-       case PIPE_FORMAT_L32A32_FLOAT:
-       case PIPE_FORMAT_L32A32_UINT:
-       case PIPE_FORMAT_L32A32_SINT:
-               return V_028C70_SWAP_ALT;
-
-       /* 128-bit buffers. */
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R32G32B32A32_SNORM:
-       case PIPE_FORMAT_R32G32B32A32_UNORM:
-       case PIPE_FORMAT_R32G32B32A32_SSCALED:
-       case PIPE_FORMAT_R32G32B32A32_USCALED:
-       case PIPE_FORMAT_R32G32B32A32_SINT:
-       case PIPE_FORMAT_R32G32B32A32_UINT:
-       case PIPE_FORMAT_R32G32B32X32_FLOAT:
-       case PIPE_FORMAT_R32G32B32X32_UINT:
-       case PIPE_FORMAT_R32G32B32X32_SINT:
-               return V_028C70_SWAP_STD;
-       default:
-               R600_ERR("unsupported colorswap format %d\n", format);
-               return ~0U;
+       switch (desc->nr_channels) {
+       case 1:
+               if (HAS_SWIZZLE(0,X))
+                       return V_028C70_SWAP_STD; /* X___ */
+               else if (HAS_SWIZZLE(3,X))
+                       return V_028C70_SWAP_ALT_REV; /* ___X */
+               break;
+       case 2:
+               if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) ||
+                   (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) ||
+                   (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y)))
+                       return V_028C70_SWAP_STD; /* XY__ */
+               else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) ||
+                        (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) ||
+                        (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X)))
+                       return V_028C70_SWAP_STD_REV; /* YX__ */
+               else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y))
+                       return V_028C70_SWAP_ALT; /* X__Y */
+               break;
+       case 3:
+               if (HAS_SWIZZLE(0,X))
+                       return V_028C70_SWAP_STD; /* XYZ */
+               else if (HAS_SWIZZLE(0,Z))
+                       return V_028C70_SWAP_STD_REV; /* ZYX */
+               break;
+       case 4:
+               /* check the middle channels, the 1st and 4th channel can be NONE */
+               if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z))
+                       return V_028C70_SWAP_STD; /* XYZW */
+               else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y))
+                       return V_028C70_SWAP_STD_REV; /* WZYX */
+               else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X))
+                       return V_028C70_SWAP_ALT; /* ZYXW */
+               else if (HAS_SWIZZLE(1,X) && HAS_SWIZZLE(2,Y))
+                       return V_028C70_SWAP_ALT_REV; /* WXYZ */
+               break;
        }
        return ~0U;
 }
@@ -1298,7 +1062,7 @@ static uint32_t si_translate_texformat(struct pipe_screen *screen,
                                       int first_non_void)
 {
        struct r600_screen *rscreen = (struct r600_screen*)screen;
-       bool enable_s3tc = rscreen->info.drm_minor >= 31;
+       bool enable_s3tc = rscreen->b.info.drm_minor >= 31;
        boolean uniform = TRUE;
        int i;
 
@@ -1552,7 +1316,7 @@ static unsigned si_tex_compare(unsigned compare)
        }
 }
 
-static unsigned si_tex_dim(unsigned dim)
+static unsigned si_tex_dim(unsigned dim, unsigned nr_samples)
 {
        switch (dim) {
        default:
@@ -1562,9 +1326,11 @@ static unsigned si_tex_dim(unsigned dim)
                return V_008F1C_SQ_RSRC_IMG_1D_ARRAY;
        case PIPE_TEXTURE_2D:
        case PIPE_TEXTURE_RECT:
-               return V_008F1C_SQ_RSRC_IMG_2D;
+               return nr_samples > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA :
+                                       V_008F1C_SQ_RSRC_IMG_2D;
        case PIPE_TEXTURE_2D_ARRAY:
-               return V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
+               return nr_samples > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY :
+                                       V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
        case PIPE_TEXTURE_3D:
                return V_008F1C_SQ_RSRC_IMG_3D;
        case PIPE_TEXTURE_CUBE:
@@ -1623,7 +1389,12 @@ static uint32_t si_translate_vertexformat(struct pipe_screen *screen,
                }
                break;
        case 32:
-               if (type != UTIL_FORMAT_TYPE_FLOAT)
+               /* From the Southern Islands ISA documentation about MTBUF:
+                * 'Memory reads of data in memory that is 32 or 64 bits do not
+                * undergo any format conversion.'
+                */
+               if (type != UTIL_FORMAT_TYPE_FLOAT &&
+                   !desc->channel[first_non_void].pure_integer)
                        return V_008F0C_BUF_DATA_FORMAT_INVALID;
 
                switch (desc->nr_channels) {
@@ -1683,7 +1454,7 @@ boolean si_is_format_supported(struct pipe_screen *screen,
                return FALSE;
 
        if (sample_count > 1) {
-               if (rscreen->chip_class >= CIK)
+               if (HAVE_LLVM < 0x0304 || rscreen->b.chip_class != SI)
                        return FALSE;
 
                switch (sample_count) {
@@ -1847,11 +1618,25 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
 
        if (rtex->resource.b.b.nr_samples > 1) {
                unsigned log_samples = util_logbase2(rtex->resource.b.b.nr_samples);
+
                color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
                                S_028C74_NUM_FRAGMENTS(log_samples);
+
+               if (rtex->fmask.size) {
+                       color_info |= S_028C70_COMPRESSION(1);
+                       unsigned fmask_bankh = util_logbase2(rtex->fmask.bank_height);
+
+                       /* due to a bug in the hw, FMASK_BANK_HEIGHT must be set on SI too */
+                       color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(rtex->fmask.tile_mode_index) |
+                                       S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+               }
+       }
+
+       if (rtex->cmask.size) {
+               color_info |= S_028C70_FAST_CLEAR(1);
        }
 
-       offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
+       offset += r600_resource_va(rctx->b.b.screen, state->cbufs[cb]->texture);
        offset >>= 8;
 
        /* FIXME handle enabling of CB beyond BASE8 which has different offset */
@@ -1870,6 +1655,19 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
        si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
        si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
 
+       if (rtex->cmask.size) {
+               si_pm4_set_reg(pm4, R_028C7C_CB_COLOR0_CMASK + cb * 0x3C,
+                              offset + (rtex->cmask.offset >> 8));
+               si_pm4_set_reg(pm4, R_028C80_CB_COLOR0_CMASK_SLICE + cb * 0x3C,
+                              S_028C80_TILE_MAX(rtex->cmask.slice_tile_max));
+       }
+       if (rtex->fmask.size) {
+               si_pm4_set_reg(pm4, R_028C84_CB_COLOR0_FMASK + cb * 0x3C,
+                              offset + (rtex->fmask.offset >> 8));
+               si_pm4_set_reg(pm4, R_028C88_CB_COLOR0_FMASK_SLICE + cb * 0x3C,
+                              S_028C88_TILE_MAX(rtex->fmask.slice_tile_max));
+       }
+
        /* set CB_COLOR1_INFO for possible dual-src blending */
        if (state->nr_cbufs == 1) {
                assert(cb == 0);
@@ -1910,14 +1708,14 @@ static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
        level = surf->base.u.tex.level;
        rtex = (struct r600_texture*)surf->base.texture;
 
-       format = si_translate_dbformat(rtex->real_format);
+       format = si_translate_dbformat(rtex->resource.b.b.format);
 
        if (format == V_028040_Z_INVALID) {
-               R600_ERR("Invalid DB format: %d, disabling DB.\n", rtex->real_format);
+               R600_ERR("Invalid DB format: %d, disabling DB.\n", rtex->resource.b.b.format);
        }
        assert(format != V_028040_Z_INVALID);
 
-       s_offs = z_offs = r600_resource_va(rctx->context.screen, surf->base.texture);
+       s_offs = z_offs = r600_resource_va(rctx->b.b.screen, surf->base.texture);
        z_offs += rtex->surface.level[level].offset;
        s_offs += rtex->surface.stencil_level[level].offset;
 
@@ -1942,7 +1740,7 @@ static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
        else
                s_info = S_028044_FORMAT(V_028044_STENCIL_INVALID);
 
-       if (rctx->chip_class >= CIK) {
+       if (rctx->b.chip_class >= CIK) {
                switch (rtex->surface.level[level].mode) {
                case RADEON_SURF_MODE_2D:
                        array_mode = V_02803C_ARRAY_2D_TILED_THIN1;
@@ -1964,9 +1762,9 @@ static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
                macro_aspect = cik_macro_tile_aspect(macro_aspect);
                bankw = cik_bank_wh(bankw);
                bankh = cik_bank_wh(bankh);
-               nbanks = cik_num_banks(rscreen->tiling_info.num_banks);
-               pipe_config = cik_db_pipe_config(rscreen->info.r600_num_tile_pipes,
-                                                rscreen->info.r600_num_backends);
+               nbanks = cik_num_banks(rscreen->b.tiling_info.num_banks);
+               pipe_config = cik_db_pipe_config(rscreen->b.info.r600_num_tile_pipes,
+                                                rscreen->b.info.r600_num_backends);
 
                db_depth_info |= S_02803C_ARRAY_MODE(array_mode) |
                        S_02803C_PIPE_CONFIG(pipe_config) |
@@ -2199,23 +1997,39 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
        uint32_t tl, br;
-       int tl_x, tl_y, br_x, br_y, nr_samples;
+       int tl_x, tl_y, br_x, br_y, nr_samples, i;
 
        if (pm4 == NULL)
                return;
 
-       si_pm4_inval_fb_cache(pm4, state->nr_cbufs);
-
-       if (state->zsbuf)
-               si_pm4_inval_zsbuf_cache(pm4);
+       if (rctx->framebuffer.nr_cbufs) {
+               rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB |
+                                R600_CONTEXT_FLUSH_AND_INV_CB_META;
+       }
+       if (rctx->framebuffer.zsbuf) {
+               rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_DB;
+       }
 
        util_copy_framebuffer_state(&rctx->framebuffer, state);
 
        /* build states */
        rctx->export_16bpc = 0;
-       for (int i = 0; i < state->nr_cbufs; i++) {
+       rctx->fb_compressed_cb_mask = 0;
+       for (i = 0; i < state->nr_cbufs; i++) {
+               struct r600_texture *rtex =
+                       (struct r600_texture*)state->cbufs[i]->texture;
+
                si_cb(rctx, pm4, state, i);
+
+               if (rtex->fmask.size || rtex->cmask.size) {
+                       rctx->fb_compressed_cb_mask |= 1 << i;
+               }
        }
+       for (; i < 8; i++) {
+               si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+                              S_028C70_FORMAT(V_028C70_COLOR_INVALID));
+       }
+
        assert(!(rctx->export_16bpc & ~0xff));
        si_db(rctx, pm4, state);
 
@@ -2247,6 +2061,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
        si_set_msaa_state(rctx, pm4, nr_samples);
        rctx->fb_log_samples = util_logbase2(nr_samples);
+       rctx->fb_cb0_is_integer = state->nr_cbufs &&
+                                 util_format_is_pure_integer(state->cbufs[0]->format);
 
        si_pm4_set_state(rctx, framebuffer, pm4);
        si_update_fb_rs_state(rctx);
@@ -2281,13 +2097,29 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
                if (sel->fs_write_all)
                        key->ps.nr_cbufs = rctx->framebuffer.nr_cbufs;
                key->ps.export_16bpc = rctx->export_16bpc;
+
                if (rctx->queued.named.rasterizer) {
                        key->ps.color_two_side = rctx->queued.named.rasterizer->two_side;
                        key->ps.flatshade = rctx->queued.named.rasterizer->flatshade;
+
+                       if (rctx->queued.named.blend) {
+                               key->ps.alpha_to_one = rctx->queued.named.blend->alpha_to_one &&
+                                                      rctx->queued.named.rasterizer->multisample_enable &&
+                                                      !rctx->fb_cb0_is_integer;
+                       }
                }
                if (rctx->queued.named.dsa) {
                        key->ps.alpha_func = rctx->queued.named.dsa->alpha_func;
-                       key->ps.alpha_ref = rctx->queued.named.dsa->alpha_ref;
+
+                       /* Alpha-test should be disabled if colorbuffer 0 is integer. */
+                       if (rctx->framebuffer.nr_cbufs &&
+                           rctx->framebuffer.cbufs[0] &&
+                           util_format_is_pure_integer(rctx->framebuffer.cbufs[0]->texture->format))
+                               key->ps.alpha_func = PIPE_FUNC_ALWAYS;
+
+                       if (key->ps.alpha_func != PIPE_FUNC_ALWAYS &&
+                           key->ps.alpha_func != PIPE_FUNC_NEVER)
+                               key->ps.alpha_ref = rctx->queued.named.dsa->alpha_ref;
                } else {
                        key->ps.alpha_func = PIPE_FUNC_ALWAYS;
                }
@@ -2407,10 +2239,14 @@ static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
 
        rctx->vs_shader = sel;
 
-       if (sel && sel->current)
+       if (sel && sel->current) {
                si_pm4_bind_state(rctx, vs, sel->current->pm4);
-       else
+               rctx->b.streamout.stride_in_dw = sel->so.stride;
+       } else {
                si_pm4_bind_state(rctx, vs, rctx->dummy_pixel_shader->pm4);
+       }
+
+       rctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
 static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
@@ -2427,6 +2263,8 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
                si_pm4_bind_state(rctx, ps, sel->current->pm4);
        else
                si_pm4_bind_state(rctx, ps, rctx->dummy_pixel_shader->pm4);
+
+       rctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
 static void si_delete_shader_selector(struct pipe_context *ctx,
@@ -2631,6 +2469,7 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
 
        va = r600_resource_va(ctx->screen, texture);
        va += surflevel[0].offset;
+       va += tmp->mipmap_shift * surflevel[texture->last_level].slice_size;
        view->state[0] = va >> 8;
        view->state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) |
                          S_008F14_DATA_FORMAT(format) |
@@ -2641,17 +2480,60 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
                          S_008F1C_DST_SEL_Y(si_map_swizzle(swizzle[1])) |
                          S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) |
                          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_BASE_LEVEL(texture->nr_samples > 1 ?
+                                                     0 : state->u.tex.first_level - tmp->mipmap_shift) |
+                         S_008F1C_LAST_LEVEL(texture->nr_samples > 1 ?
+                                                     util_logbase2(texture->nr_samples) :
+                                                     state->u.tex.last_level - tmp->mipmap_shift) |
                          S_008F1C_TILING_INDEX(si_tile_mode_index(tmp, 0, false)) |
                          S_008F1C_POW2_PAD(texture->last_level > 0) |
-                         S_008F1C_TYPE(si_tex_dim(texture->target)));
+                         S_008F1C_TYPE(si_tex_dim(texture->target, texture->nr_samples)));
        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) |
                          S_008F24_LAST_ARRAY(state->u.tex.last_layer));
        view->state[6] = 0;
        view->state[7] = 0;
 
+       /* Initialize the sampler view for FMASK. */
+       if (tmp->fmask.size) {
+               uint64_t va = r600_resource_va(ctx->screen, texture) + tmp->fmask.offset;
+               uint32_t fmask_format;
+
+               switch (texture->nr_samples) {
+               case 2:
+                       fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
+                       break;
+               case 4:
+                       fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
+                       break;
+               case 8:
+                       fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
+                       break;
+               default:
+                       assert(0);
+                       fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
+               }
+
+               view->fmask_state[0] = va >> 8;
+               view->fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
+                                      S_008F14_DATA_FORMAT(fmask_format) |
+                                      S_008F14_NUM_FORMAT(V_008F14_IMG_NUM_FORMAT_UINT);
+               view->fmask_state[2] = S_008F18_WIDTH(width - 1) |
+                                      S_008F18_HEIGHT(height - 1);
+               view->fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
+                                      S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
+                                      S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
+                                      S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
+                                      S_008F1C_TILING_INDEX(tmp->fmask.tile_mode_index) |
+                                      S_008F1C_TYPE(si_tex_dim(texture->target, 0));
+               view->fmask_state[4] = S_008F20_DEPTH(depth - 1) |
+                                      S_008F20_PITCH(tmp->fmask.pitch - 1);
+               view->fmask_state[5] = S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
+                                      S_008F24_LAST_ARRAY(state->u.tex.last_layer);
+               view->fmask_state[6] = 0;
+               view->fmask_state[7] = 0;
+       }
+
        return &view->base;
 }
 
@@ -2725,17 +2607,16 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
        return rstate;
 }
 
-static struct si_pm4_state *si_set_sampler_views(struct r600_context *rctx,
-                                                unsigned shader, unsigned count,
-                                                struct pipe_sampler_view **views)
+/* XXX consider moving this function to si_descriptors.c for gcc to inline
+ *     the si_set_sampler_view calls. LTO might help too. */
+static void si_set_sampler_views(struct r600_context *rctx,
+                                unsigned shader, unsigned count,
+                                struct pipe_sampler_view **views)
 {
        struct r600_textures_info *samplers = &rctx->samplers[shader];
        struct si_pipe_sampler_view **rviews = (struct si_pipe_sampler_view **)views;
-       struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
        int i;
 
-       si_pm4_inval_texture_cache(pm4);
-
        for (i = 0; i < count; i++) {
                if (views[i]) {
                        struct r600_texture *rtex =
@@ -2746,39 +2627,55 @@ static struct si_pm4_state *si_set_sampler_views(struct r600_context *rctx,
                        } else {
                                samplers->depth_texture_mask &= ~(1 << i);
                        }
+                       if (rtex->cmask.size || rtex->fmask.size) {
+                               samplers->compressed_colortex_mask |= 1 << i;
+                       } else {
+                               samplers->compressed_colortex_mask &= ~(1 << i);
+                       }
 
                        si_set_sampler_view(rctx, shader, i, views[i], rviews[i]->state);
+
+                       if (rtex->fmask.size) {
+                               si_set_sampler_view(rctx, shader, FMASK_TEX_OFFSET + i,
+                                                   views[i], rviews[i]->fmask_state);
+                       } else {
+                               si_set_sampler_view(rctx, shader, FMASK_TEX_OFFSET + i,
+                                                   NULL, NULL);
+                       }
                } else {
                        samplers->depth_texture_mask &= ~(1 << i);
+                       samplers->compressed_colortex_mask &= ~(1 << i);
                        si_set_sampler_view(rctx, shader, i, NULL, NULL);
+                       si_set_sampler_view(rctx, shader, FMASK_TEX_OFFSET + i,
+                                           NULL, NULL);
                }
        }
        for (; i < samplers->n_views; i++) {
+               samplers->depth_texture_mask &= ~(1 << i);
+               samplers->compressed_colortex_mask &= ~(1 << i);
                si_set_sampler_view(rctx, shader, i, NULL, NULL);
+               si_set_sampler_view(rctx, shader, FMASK_TEX_OFFSET + i,
+                                   NULL, NULL);
        }
 
        samplers->n_views = count;
-       return pm4;
+       rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
 }
 
 static void si_set_vs_sampler_views(struct pipe_context *ctx, unsigned count,
                                    struct pipe_sampler_view **views)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
-       struct si_pm4_state *pm4;
 
-       pm4 = si_set_sampler_views(rctx, PIPE_SHADER_VERTEX, count, views);
-       si_pm4_set_state(rctx, vs_sampler_views, pm4);
+       si_set_sampler_views(rctx, PIPE_SHADER_VERTEX, count, views);
 }
 
 static void si_set_ps_sampler_views(struct pipe_context *ctx, unsigned count,
                                    struct pipe_sampler_view **views)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
-       struct si_pm4_state *pm4;
 
-       pm4 = si_set_sampler_views(rctx, PIPE_SHADER_FRAGMENT, count, views);
-       si_pm4_set_state(rctx, ps_sampler_views, pm4);
+       si_set_sampler_views(rctx, PIPE_SHADER_FRAGMENT, count, views);
 }
 
 static struct si_pm4_state *si_bind_sampler_states(struct r600_context *rctx, unsigned count,
@@ -2794,7 +2691,7 @@ static struct si_pm4_state *si_bind_sampler_states(struct r600_context *rctx, un
        if (!count)
                goto out;
 
-       si_pm4_inval_texture_cache(pm4);
+       rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
 
        si_pm4_sh_data_begin(pm4);
        for (i = 0; i < count; i++) {
@@ -2804,19 +2701,19 @@ static struct si_pm4_state *si_bind_sampler_states(struct r600_context *rctx, un
                        if (!rctx->border_color_table ||
                            ((rctx->border_color_offset + count - i) &
                             C_008F3C_BORDER_COLOR_PTR)) {
-                               si_resource_reference(&rctx->border_color_table, NULL);
+                               r600_resource_reference(&rctx->border_color_table, NULL);
                                rctx->border_color_offset = 0;
 
                                rctx->border_color_table =
-                                       si_resource_create_custom(&rctx->screen->screen,
+                                       r600_resource_create_custom(&rctx->screen->b.b,
                                                                  PIPE_USAGE_STAGING,
                                                                  4096 * 4 * 4);
                        }
 
                        if (!border_color_table) {
                                border_color_table =
-                                       rctx->ws->buffer_map(rctx->border_color_table->cs_buf,
-                                                            rctx->cs,
+                                       rctx->b.ws->buffer_map(rctx->border_color_table->cs_buf,
+                                                            rctx->b.rings.gfx.cs,
                                                             PIPE_TRANSFER_WRITE |
                                                             PIPE_TRANSFER_UNSYNCHRONIZED);
                        }
@@ -2838,13 +2735,13 @@ static struct si_pm4_state *si_bind_sampler_states(struct r600_context *rctx, un
 
        if (border_color_table) {
                uint64_t va_offset =
-                       r600_resource_va(&rctx->screen->screen,
+                       r600_resource_va(&rctx->screen->b.b,
                                         (void*)rctx->border_color_table);
 
                si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va_offset >> 8);
-               if (rctx->chip_class >= CIK)
+               if (rctx->b.chip_class >= CIK)
                        si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, va_offset >> 40);
-               rctx->ws->buffer_unmap(rctx->border_color_table->cs_buf);
+               rctx->b.ws->buffer_unmap(rctx->border_color_table->cs_buf);
                si_pm4_add_bo(pm4, rctx->border_color_table, RADEON_USAGE_READ);
        }
 
@@ -2875,6 +2772,27 @@ static void si_bind_ps_sampler_states(struct pipe_context *ctx, unsigned count,
        si_pm4_set_state(rctx, ps_sampler, pm4);
 }
 
+
+static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader,
+                                   unsigned start, unsigned count,
+                                   void **states)
+{
+   assert(start == 0);
+
+   switch (shader) {
+   case PIPE_SHADER_VERTEX:
+      si_bind_vs_sampler_states(ctx, count, states);
+      break;
+   case PIPE_SHADER_FRAGMENT:
+      si_bind_ps_sampler_states(ctx, count, states);
+      break;
+   default:
+      ;
+   }
+}
+
+
+
 static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
@@ -2895,46 +2813,6 @@ static void si_delete_sampler_state(struct pipe_context *ctx, void *state)
        free(state);
 }
 
-/*
- * Constants
- */
-static void si_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
-                                  struct pipe_constant_buffer *input)
-{
-       struct r600_context *rctx = (struct r600_context *)ctx;
-       struct r600_constbuf_state *state = &rctx->constbuf_state[shader];
-       struct pipe_constant_buffer *cb;
-       const uint8_t *ptr;
-
-       /* Note that the state tracker can unbind constant buffers by
-        * passing NULL here.
-        */
-       if (unlikely(!input || (!input->buffer && !input->user_buffer))) {
-               state->enabled_mask &= ~(1 << index);
-               state->dirty_mask &= ~(1 << index);
-               pipe_resource_reference(&state->cb[index].buffer, NULL);
-               return;
-       }
-
-       cb = &state->cb[index];
-       cb->buffer_size = input->buffer_size;
-
-       ptr = input->user_buffer;
-
-       if (ptr) {
-               r600_upload_const_buffer(rctx,
-                               (struct si_resource**)&cb->buffer, ptr,
-                               cb->buffer_size, &cb->buffer_offset);
-       } else {
-               /* Setup the hw buffer. */
-               cb->buffer_offset = input->buffer_offset;
-               pipe_resource_reference(&cb->buffer, input->buffer);
-       }
-
-       state->enabled_mask |= 1 << index;
-       state->dirty_mask |= 1 << index;
-}
-
 /*
  * Vertex elements & buffers
  */
@@ -3047,90 +2925,134 @@ static void si_set_polygon_stipple(struct pipe_context *ctx,
 static void si_texture_barrier(struct pipe_context *ctx)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
-       struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
-
-       if (pm4 == NULL)
-               return;
 
-       si_pm4_inval_texture_cache(pm4);
-       si_pm4_inval_fb_cache(pm4, rctx->framebuffer.nr_cbufs);
-       si_pm4_set_state(rctx, texture_barrier, pm4);
+       rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE |
+                        R600_CONTEXT_FLUSH_AND_INV_CB;
 }
 
-static void *si_create_resolve_blend(struct r600_context *rctx)
+static void *si_create_blend_custom(struct r600_context *rctx, unsigned mode)
 {
        struct pipe_blend_state blend;
 
        memset(&blend, 0, sizeof(blend));
        blend.independent_blend_enable = true;
        blend.rt[0].colormask = 0xf;
-       return si_create_blend_state_mode(&rctx->context, &blend, V_028808_CB_RESOLVE);
+       return si_create_blend_state_mode(&rctx->b.b, &blend, mode);
 }
 
-void si_init_state_functions(struct r600_context *rctx)
+static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
+                                               struct pipe_resource *texture,
+                                               const struct pipe_surface *surf_tmpl)
 {
-       rctx->context.create_blend_state = si_create_blend_state;
-       rctx->context.bind_blend_state = si_bind_blend_state;
-       rctx->context.delete_blend_state = si_delete_blend_state;
-       rctx->context.set_blend_color = si_set_blend_color;
+       struct r600_texture *rtex = (struct r600_texture*)texture;
+       struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
+       unsigned level = surf_tmpl->u.tex.level;
+
+       if (surface == NULL)
+               return NULL;
 
-       rctx->context.create_rasterizer_state = si_create_rs_state;
-       rctx->context.bind_rasterizer_state = si_bind_rs_state;
-       rctx->context.delete_rasterizer_state = si_delete_rs_state;
+       assert(surf_tmpl->u.tex.first_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
+       assert(surf_tmpl->u.tex.last_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
+       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
-       rctx->context.create_depth_stencil_alpha_state = si_create_dsa_state;
-       rctx->context.bind_depth_stencil_alpha_state = si_bind_dsa_state;
-       rctx->context.delete_depth_stencil_alpha_state = si_delete_dsa_state;
+       pipe_reference_init(&surface->base.reference, 1);
+       pipe_resource_reference(&surface->base.texture, texture);
+       surface->base.context = pipe;
+       surface->base.format = surf_tmpl->format;
+       surface->base.width = rtex->surface.level[level].npix_x;
+       surface->base.height = rtex->surface.level[level].npix_y;
+       surface->base.texture = texture;
+       surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+       surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+       surface->base.u.tex.level = level;
 
-       rctx->custom_dsa_flush_depth_stencil = si_create_db_flush_dsa(rctx, true, true);
-       rctx->custom_dsa_flush_depth = si_create_db_flush_dsa(rctx, true, false);
-       rctx->custom_dsa_flush_stencil = si_create_db_flush_dsa(rctx, false, true);
-       rctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(rctx, false, false);
-       rctx->custom_blend_resolve = si_create_resolve_blend(rctx);
+       return &surface->base;
+}
 
-       rctx->context.set_clip_state = si_set_clip_state;
-       rctx->context.set_scissor_states = si_set_scissor_states;
-       rctx->context.set_viewport_states = si_set_viewport_states;
-       rctx->context.set_stencil_ref = si_set_pipe_stencil_ref;
+static void r600_surface_destroy(struct pipe_context *pipe,
+                                struct pipe_surface *surface)
+{
+       pipe_resource_reference(&surface->texture, NULL);
+       FREE(surface);
+}
 
-       rctx->context.set_framebuffer_state = si_set_framebuffer_state;
-       rctx->context.get_sample_position = si_get_sample_position;
+static boolean si_dma_copy(struct pipe_context *ctx,
+                          struct pipe_resource *dst,
+                          unsigned dst_level,
+                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
+                          struct pipe_resource *src,
+                          unsigned src_level,
+                          const struct pipe_box *src_box)
+{
+       /* XXX implement this or share evergreen_dma_blit with r600g */
+       return FALSE;
+}
+
+void si_init_state_functions(struct r600_context *rctx)
+{
+       int i;
+
+       rctx->b.b.create_blend_state = si_create_blend_state;
+       rctx->b.b.bind_blend_state = si_bind_blend_state;
+       rctx->b.b.delete_blend_state = si_delete_blend_state;
+       rctx->b.b.set_blend_color = si_set_blend_color;
+
+       rctx->b.b.create_rasterizer_state = si_create_rs_state;
+       rctx->b.b.bind_rasterizer_state = si_bind_rs_state;
+       rctx->b.b.delete_rasterizer_state = si_delete_rs_state;
+
+       rctx->b.b.create_depth_stencil_alpha_state = si_create_dsa_state;
+       rctx->b.b.bind_depth_stencil_alpha_state = si_bind_dsa_state;
+       rctx->b.b.delete_depth_stencil_alpha_state = si_delete_dsa_state;
+
+       for (i = 0; i < 8; i++) {
+               rctx->custom_dsa_flush_depth_stencil[i] = si_create_db_flush_dsa(rctx, true, true, i);
+               rctx->custom_dsa_flush_depth[i] = si_create_db_flush_dsa(rctx, true, false, i);
+               rctx->custom_dsa_flush_stencil[i] = si_create_db_flush_dsa(rctx, false, true, i);
+       }
+       rctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(rctx, false, false, 0);
+       rctx->custom_blend_resolve = si_create_blend_custom(rctx, V_028808_CB_RESOLVE);
+       rctx->custom_blend_decompress = si_create_blend_custom(rctx, V_028808_CB_FMASK_DECOMPRESS);
 
-       rctx->context.create_vs_state = si_create_vs_state;
-       rctx->context.create_fs_state = si_create_fs_state;
-       rctx->context.bind_vs_state = si_bind_vs_shader;
-       rctx->context.bind_fs_state = si_bind_ps_shader;
-       rctx->context.delete_vs_state = si_delete_vs_shader;
-       rctx->context.delete_fs_state = si_delete_ps_shader;
+       rctx->b.b.set_clip_state = si_set_clip_state;
+       rctx->b.b.set_scissor_states = si_set_scissor_states;
+       rctx->b.b.set_viewport_states = si_set_viewport_states;
+       rctx->b.b.set_stencil_ref = si_set_pipe_stencil_ref;
 
-       rctx->context.create_sampler_state = si_create_sampler_state;
-       rctx->context.bind_vertex_sampler_states = si_bind_vs_sampler_states;
-       rctx->context.bind_fragment_sampler_states = si_bind_ps_sampler_states;
-       rctx->context.delete_sampler_state = si_delete_sampler_state;
+       rctx->b.b.set_framebuffer_state = si_set_framebuffer_state;
+       rctx->b.b.get_sample_position = si_get_sample_position;
 
-       rctx->context.create_sampler_view = si_create_sampler_view;
-       rctx->context.set_vertex_sampler_views = si_set_vs_sampler_views;
-       rctx->context.set_fragment_sampler_views = si_set_ps_sampler_views;
-       rctx->context.sampler_view_destroy = si_sampler_view_destroy;
+       rctx->b.b.create_vs_state = si_create_vs_state;
+       rctx->b.b.create_fs_state = si_create_fs_state;
+       rctx->b.b.bind_vs_state = si_bind_vs_shader;
+       rctx->b.b.bind_fs_state = si_bind_ps_shader;
+       rctx->b.b.delete_vs_state = si_delete_vs_shader;
+       rctx->b.b.delete_fs_state = si_delete_ps_shader;
 
-       rctx->context.set_sample_mask = si_set_sample_mask;
+       rctx->b.b.create_sampler_state = si_create_sampler_state;
+       rctx->b.b.bind_sampler_states = si_bind_sampler_states;
+       rctx->b.b.delete_sampler_state = si_delete_sampler_state;
 
-       rctx->context.set_constant_buffer = si_set_constant_buffer;
+       rctx->b.b.create_sampler_view = si_create_sampler_view;
+       rctx->b.b.set_vertex_sampler_views = si_set_vs_sampler_views;
+       rctx->b.b.set_fragment_sampler_views = si_set_ps_sampler_views;
+       rctx->b.b.sampler_view_destroy = si_sampler_view_destroy;
 
-       rctx->context.create_vertex_elements_state = si_create_vertex_elements;
-       rctx->context.bind_vertex_elements_state = si_bind_vertex_elements;
-       rctx->context.delete_vertex_elements_state = si_delete_vertex_element;
-       rctx->context.set_vertex_buffers = si_set_vertex_buffers;
-       rctx->context.set_index_buffer = si_set_index_buffer;
+       rctx->b.b.set_sample_mask = si_set_sample_mask;
 
-       rctx->context.create_stream_output_target = si_create_so_target;
-       rctx->context.stream_output_target_destroy = si_so_target_destroy;
-       rctx->context.set_stream_output_targets = si_set_so_targets;
+       rctx->b.b.create_vertex_elements_state = si_create_vertex_elements;
+       rctx->b.b.bind_vertex_elements_state = si_bind_vertex_elements;
+       rctx->b.b.delete_vertex_elements_state = si_delete_vertex_element;
+       rctx->b.b.set_vertex_buffers = si_set_vertex_buffers;
+       rctx->b.b.set_index_buffer = si_set_index_buffer;
 
-       rctx->context.texture_barrier = si_texture_barrier;
-       rctx->context.set_polygon_stipple = si_set_polygon_stipple;
+       rctx->b.b.texture_barrier = si_texture_barrier;
+       rctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
+       rctx->b.b.create_surface = r600_create_surface;
+       rctx->b.b.surface_destroy = r600_surface_destroy;
+       rctx->b.dma_copy = si_dma_copy;
 
-       rctx->context.draw_vbo = si_draw_vbo;
+       rctx->b.b.draw_vbo = si_draw_vbo;
 }
 
 void si_init_config(struct r600_context *rctx)
@@ -3159,6 +3081,7 @@ void si_init_config(struct r600_context *rctx)
        si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, 0x0);
        si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, 0x0);
        si_pm4_set_reg(pm4, R_028A8C_VGT_PRIMITIVEID_RESET, 0x0);
+       si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
        si_pm4_set_reg(pm4, R_028B94_VGT_STRMOUT_CONFIG, 0x0);
        si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0);
        si_pm4_set_reg(pm4, R_028AA8_IA_MULTI_VGT_PARAM,
@@ -3167,7 +3090,7 @@ void si_init_config(struct r600_context *rctx)
                       S_028AA8_PRIMGROUP_SIZE(63));
        si_pm4_set_reg(pm4, R_028AB4_VGT_REUSE_OFF, 0x00000000);
        si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0);
-       if (rctx->chip_class < CIK)
+       if (rctx->b.chip_class < CIK)
                si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, S_008A14_NUM_CLIP_SEQ(3) |
                               S_008A14_CLIP_VTX_REORDER_ENA(1));
 
@@ -3177,8 +3100,8 @@ void si_init_config(struct r600_context *rctx)
 
        si_pm4_set_reg(pm4, R_02882C_PA_SU_PRIM_FILTER_CNTL, 0);
 
-       if (rctx->chip_class >= CIK) {
-               switch (rctx->screen->family) {
+       if (rctx->b.chip_class >= CIK) {
+               switch (rctx->screen->b.family) {
                case CHIP_BONAIRE:
                        si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x16000012);
                        si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, 0x00000000);
@@ -3193,7 +3116,7 @@ void si_init_config(struct r600_context *rctx)
                        break;
                }
        } else {
-               switch (rctx->screen->family) {
+               switch (rctx->screen->b.family) {
                case CHIP_TAHITI:
                case CHIP_PITCAIRN:
                        si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x2a00126a);