This contains the evergreen support.

Support is possible on rv670 upwards and the code in here
should work, but it doesn't and I haven't debugged it to
figure out why.

Beyond just adding support for the cube map array sampling,
r600 resinfo isn't conformant with the GL specification,
which states the number of layers should be returned for
the textureSize, so we have to track in an external
constant buffer the layers for each sampler if we need
them in the shader.

v2: only update the sampler constants if the sampler views have changed,
as suggested by Marek.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 src/gallium/drivers/r600/evergreen_state.c   |   4 +-
 src/gallium/drivers/r600/r600_blit.c         |   1 +
 src/gallium/drivers/r600/r600_pipe.c         |   1 +
 src/gallium/drivers/r600/r600_pipe.h         |   7 +-
 src/gallium/drivers/r600/r600_shader.c       | 198 +++++++++++++++++++++++++--
 src/gallium/drivers/r600/r600_shader.h       |   1 +
 src/gallium/drivers/r600/r600_state.c        |   4 +-
 src/gallium/drivers/r600/r600_state_common.c |  36 ++++-
 src/gallium/drivers/r600/r600_texture.c      |   1 +
 9 files changed, 238 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index c105e55..9b898cb 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -174,6 +174,7 @@ static unsigned r600_tex_dim(unsigned dim, unsigned 
nr_samples)
        case PIPE_TEXTURE_3D:
                return V_030000_SQ_TEX_DIM_3D;
        case PIPE_TEXTURE_CUBE:
+       case PIPE_TEXTURE_CUBE_ARRAY:
                return V_030000_SQ_TEX_DIM_CUBEMAP;
        }
 }
@@ -1073,7 +1074,8 @@ evergreen_create_sampler_view_custom(struct pipe_context 
*ctx,
                depth = texture->array_size;
        } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
                depth = texture->array_size;
-       }
+       } else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY)
+               depth = texture->array_size / 6;
 
        view->tex_resource = &tmp->resource;
        view->tex_resource_words[0] = 
(S_030000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) |
diff --git a/src/gallium/drivers/r600/r600_blit.c 
b/src/gallium/drivers/r600/r600_blit.c
index a2ed177..e39f4bd 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -107,6 +107,7 @@ static unsigned u_max_layer(struct pipe_resource *r, 
unsigned level)
                return u_minify(r->depth0, level) - 1;
        case PIPE_TEXTURE_1D_ARRAY:
        case PIPE_TEXTURE_2D_ARRAY:
+       case PIPE_TEXTURE_CUBE_ARRAY:
                return r->array_size - 1;
        default:
                return 0;
diff --git a/src/gallium/drivers/r600/r600_pipe.c 
b/src/gallium/drivers/r600/r600_pipe.c
index 3a69eb2..296f812 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -420,6 +420,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum 
pipe_cap param)
 
        /* Supported on Evergreen. */
        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+       case PIPE_CAP_CUBE_MAP_ARRAY:
                return family >= CHIP_CEDAR ? 1 : 0;
 
        /* Unsupported features. */
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index 2287d63..33ccefa 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -37,11 +37,12 @@
 #define R600_NUM_ATOMS 36
 
 #define R600_MAX_USER_CONST_BUFFERS 1
-#define R600_MAX_DRIVER_CONST_BUFFERS 1
+#define R600_MAX_DRIVER_CONST_BUFFERS 2
 #define R600_MAX_CONST_BUFFERS (R600_MAX_USER_CONST_BUFFERS + 
R600_MAX_DRIVER_CONST_BUFFERS)
 
 /* start driver buffers after user buffers */
 #define R600_UCP_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS)
+#define R600_TXQ_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 1)
 
 #define R600_MAX_CONST_BUFFER_SIZE 4096
 
@@ -311,6 +312,7 @@ struct r600_samplerview_state {
        uint32_t                        dirty_mask;
        uint32_t                        compressed_depthtex_mask; /* which 
textures are depth */
        uint32_t                        compressed_colortex_mask;
+       boolean                         dirty_txq_constants;
 };
 
 struct r600_sampler_states {
@@ -325,6 +327,9 @@ struct r600_textures_info {
        struct r600_samplerview_state   views;
        struct r600_sampler_states      states;
        bool                            is_array_sampler[NUM_TEX_UNITS];
+
+       /* cube array txq workaround */
+       uint32_t                        *txq_constants;
 };
 
 struct r600_fence {
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 8d0a9b4..84821ac 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -3842,6 +3842,20 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
        boolean src_loaded = FALSE;
        unsigned sampler_src_reg = inst->Instruction.Opcode == 
TGSI_OPCODE_TXQ_LZ ? 0 : 1;
        uint8_t offset_x = 0, offset_y = 0, offset_z = 0;
+       boolean has_txq_cube_array_z = false;
+
+       if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ &&
+           ((inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY ||
+             inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)))
+               if (inst->Dst[0].Register.WriteMask & 4) {
+                       ctx->shader->has_txq_cube_array_z_comp = true;
+                       has_txq_cube_array_z = true;
+               }
+
+       if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 ||
+           inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
+           inst->Instruction.Opcode == TGSI_OPCODE_TXL2)
+               sampler_src_reg = 2;
 
        src_gpr = tgsi_tex_get_src_gpr(ctx, 0);
 
@@ -3972,7 +3986,9 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
        }
 
        if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
-            inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
+            inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY ||
+            inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
+            inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) &&
            inst->Instruction.Opcode != TGSI_OPCODE_TXQ &&
            inst->Instruction.Opcode != TGSI_OPCODE_TXQ_LZ) {
 
@@ -4074,11 +4090,17 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                r = r600_bytecode_add_alu(ctx->bc, &alu);
                if (r)
                        return r;
-               /* write initial W value into Z component */
-               if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) {
+               /* write initial compare value into Z component 
+                 - W src 0 for shadow cube
+                 - X src 1 for shadow cube array */
+               if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
+                   inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
                        memset(&alu, 0, sizeof(struct r600_bytecode_alu));
                        alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
-                       r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+                       if (inst->Texture.Texture == 
TGSI_TEXTURE_SHADOWCUBE_ARRAY)
+                               r600_bytecode_src(&alu.src[0], &ctx->src[1], 0);
+                       else
+                               r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
                        alu.dst.sel = ctx->temp_reg;
                        alu.dst.chan = 2;
                        alu.dst.write = 1;
@@ -4088,13 +4110,85 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                                return r;
                }
 
-               /* for cube forms of lod and bias we need to route the lod
-                  value into Z */
+               if (inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY ||
+                   inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
+                       if (ctx->bc->chip_class >= EVERGREEN) {
+                               int mytmp = r600_get_temp(ctx);
+                               static const float eight = 8.0f;
+                               memset(&alu, 0, sizeof(struct 
r600_bytecode_alu));
+                               alu.inst = 
CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+                               alu.src[0].sel = ctx->temp_reg;
+                               alu.src[0].chan = 3;
+                               alu.dst.sel = mytmp;
+                               alu.dst.chan = 0;
+                               alu.dst.write = 1;
+                               alu.last = 1;
+                               r = r600_bytecode_add_alu(ctx->bc, &alu);
+                               if (r)
+                                       return r;
+
+                               /* have to multiply original layer by 8 and add 
to face id (temp.w) in Z */
+                               memset(&alu, 0, sizeof(struct 
r600_bytecode_alu));
+                               alu.inst = 
CTX_INST(V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD);
+                               alu.is_op3 = 1;
+                               r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+                               alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+                               alu.src[1].chan = 0;
+                               alu.src[1].value = *(uint32_t *)&eight;
+                               alu.src[2].sel = mytmp;
+                               alu.src[2].chan = 0;
+                               alu.dst.sel = ctx->temp_reg;
+                               alu.dst.chan = 3;
+                               alu.dst.write = 1;
+                               alu.last = 1;
+                               r = r600_bytecode_add_alu(ctx->bc, &alu);
+                               if (r)
+                                       return r;
+                       } else if (ctx->bc->chip_class < EVERGREEN) {
+                               memset(&tex, 0, sizeof(struct 
r600_bytecode_tex));
+                               tex.inst = SQ_TEX_INST_SET_CUBEMAP_INDEX;
+                               tex.sampler_id = tgsi_tex_get_src_gpr(ctx, 
sampler_src_reg);
+                               tex.resource_id = tex.sampler_id + 
R600_MAX_CONST_BUFFERS;
+                               tex.src_gpr = r600_get_temp(ctx);
+                               tex.src_sel_x = 0;
+                               tex.src_sel_y = 0;
+                               tex.src_sel_z = 0;
+                               tex.src_sel_w = 0;
+                               tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = 
tex.dst_sel_w = 7;
+                               tex.coord_type_x = 1;
+                               tex.coord_type_y = 1;
+                               tex.coord_type_z = 1;
+                               tex.coord_type_w = 1;
+                               memset(&alu, 0, sizeof(struct 
r600_bytecode_alu));
+                               alu.inst = 
CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+                               r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+                               alu.dst.sel = tex.src_gpr;
+                               alu.dst.chan = 0;
+                               alu.last = 1;
+                               alu.dst.write = 1;
+                               r = r600_bytecode_add_alu(ctx->bc, &alu);
+                               if (r)
+                                       return r;
+                                       
+                               r = r600_bytecode_add_tex(ctx->bc, &tex);
+                               if (r)
+                                       return r;
+                       }
+
+               }
+
+               /* for cube forms of lod and bias we need to route things */
                if (inst->Instruction.Opcode == TGSI_OPCODE_TXB ||
-                   inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
+                   inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
+                   inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
+                   inst->Instruction.Opcode == TGSI_OPCODE_TXL2) {
                        memset(&alu, 0, sizeof(struct r600_bytecode_alu));
                        alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
-                       r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+                       if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
+                           inst->Instruction.Opcode == TGSI_OPCODE_TXL2)
+                               r600_bytecode_src(&alu.src[0], &ctx->src[1], 0);
+                       else
+                               r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
                        alu.dst.sel = ctx->temp_reg;
                        alu.dst.chan = 2;
                        alu.last = 1;
@@ -4247,13 +4341,33 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 #endif
        }
 
+       /* does this shader want a num layers from TXQ for a cube array? */
+       if (has_txq_cube_array_z) {
+               int id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg);
+               
+               memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+               alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+
+               alu.src[0].sel = 512 + (id / 4);
+               alu.src[0].kc_bank = R600_TXQ_CONST_BUFFER;
+               alu.src[0].chan = id % 4;
+               tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+               alu.last = 1;
+               r = r600_bytecode_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+               /* disable writemask from texture instruction */
+               inst->Dst[0].Register.WriteMask &= ~4;
+       }
+
        opcode = ctx->inst_info->r600_opcode;
        if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D ||
            inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D ||
            inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT ||
            inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
            inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY ||
-           inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY) {
+           inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
+           inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
                switch (opcode) {
                case SQ_TEX_INST_SAMPLE:
                        opcode = SQ_TEX_INST_SAMPLE_C;
@@ -4301,7 +4415,9 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
        }
 
        if (inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
-           inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) {
+           inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
+           inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY ||
+           inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
                tex.src_sel_x = 1;
                tex.src_sel_y = 0;
                tex.src_sel_z = 3;
@@ -4344,7 +4460,10 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                        tex.src_sel_z = tex.src_sel_y;
                }
        } else if (inst->Texture.Texture == TGSI_TEXTURE_2D_ARRAY ||
-                  inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY)
+                  inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
+                  ((inst->Texture.Texture == TGSI_TEXTURE_CUBE_ARRAY ||
+                   inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) &&
+                   (ctx->bc->chip_class >= EVERGREEN)))
                /* the array index is read from Z */
                tex.coord_type_z = 0;
 
@@ -5601,6 +5720,25 @@ static struct r600_shader_tgsi_instruction 
r600_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_UCMP,      0, 0, tgsi_unsupported},
        {TGSI_OPCODE_IABS,      0, 0, tgsi_iabs},
        {TGSI_OPCODE_ISSG,      0, 0, tgsi_issg},
+       {TGSI_OPCODE_LOAD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_STORE,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_MFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_LFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_SFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_BARRIER,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUADD,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXCHG,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMCAS,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMAND,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMOR,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXOR,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_TEX2,      0, SQ_TEX_INST_SAMPLE, tgsi_tex},
+       {TGSI_OPCODE_TXB2,      0, SQ_TEX_INST_SAMPLE_LB, tgsi_tex},
+       {TGSI_OPCODE_TXL2,      0, SQ_TEX_INST_SAMPLE_L, tgsi_tex},
        {TGSI_OPCODE_LAST,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
 };
 
@@ -5775,6 +5913,25 @@ static struct r600_shader_tgsi_instruction 
eg_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_UCMP,      0, 0, tgsi_unsupported},
        {TGSI_OPCODE_IABS,      0, 0, tgsi_iabs},
        {TGSI_OPCODE_ISSG,      0, 0, tgsi_issg},
+       {TGSI_OPCODE_LOAD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_STORE,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_MFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_LFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_SFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_BARRIER,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUADD,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXCHG,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMCAS,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMAND,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMOR,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXOR,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_TEX2,      0, SQ_TEX_INST_SAMPLE, tgsi_tex},
+       {TGSI_OPCODE_TXB2,      0, SQ_TEX_INST_SAMPLE_LB, tgsi_tex},
+       {TGSI_OPCODE_TXL2,      0, SQ_TEX_INST_SAMPLE_L, tgsi_tex},
        {TGSI_OPCODE_LAST,      0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
 };
 
@@ -5949,5 +6106,24 @@ static struct r600_shader_tgsi_instruction 
cm_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_UCMP,      0, 0, tgsi_unsupported},
        {TGSI_OPCODE_IABS,      0, 0, tgsi_iabs},
        {TGSI_OPCODE_ISSG,      0, 0, tgsi_issg},
+       {TGSI_OPCODE_LOAD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_STORE,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_MFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_LFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_SFENCE,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_BARRIER,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUADD,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXCHG,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMCAS,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMAND,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMOR,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMXOR,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMUMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMIN,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_ATOMIMAX,  0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
+       {TGSI_OPCODE_TEX2,      0, SQ_TEX_INST_SAMPLE, tgsi_tex},
+       {TGSI_OPCODE_TXB2,      0, SQ_TEX_INST_SAMPLE_LB, tgsi_tex},
+       {TGSI_OPCODE_TXL2,      0, SQ_TEX_INST_SAMPLE_L, tgsi_tex},
        {TGSI_OPCODE_LAST,      0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 
tgsi_unsupported},
 };
diff --git a/src/gallium/drivers/r600/r600_shader.h 
b/src/gallium/drivers/r600/r600_shader.h
index f76d591..b58a58a 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -60,6 +60,7 @@ struct r600_shader {
        /* flag is set if the shader writes VS_OUT_MISC_VEC (e.g. for PSIZE) */
        boolean                 vs_out_misc_write;
        boolean                 vs_out_point_size;
+       boolean                 has_txq_cube_array_z_comp;
 };
 
 struct r600_shader_key {
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index a7b602d..ab658da 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -118,6 +118,7 @@ static unsigned r600_tex_dim(unsigned dim, unsigned 
nr_samples)
        case PIPE_TEXTURE_3D:
                return V_038000_SQ_TEX_DIM_3D;
        case PIPE_TEXTURE_CUBE:
+       case PIPE_TEXTURE_CUBE_ARRAY:
                return V_038000_SQ_TEX_DIM_CUBEMAP;
        }
 }
@@ -1035,7 +1036,8 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
                depth = texture->array_size;
        } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
                depth = texture->array_size;
-       }
+       } else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY)
+               depth = texture->array_size / 6;
        switch (tmp->surface.level[offset_level].mode) {
        case RADEON_SURF_MODE_LINEAR_ALIGNED:
                array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index e7062c3..926cb1a 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -624,7 +624,7 @@ static void r600_set_sampler_views(struct pipe_context 
*pipe, unsigned shader,
        dst->views.dirty_mask |= new_mask;
        dst->views.compressed_depthtex_mask &= dst->views.enabled_mask;
        dst->views.compressed_colortex_mask &= dst->views.enabled_mask;
-
+       dst->views.dirty_txq_constants = TRUE;
        r600_sampler_views_dirty(rctx, &dst->views);
 
        if (dirty_sampler_states_mask) {
@@ -1023,6 +1023,35 @@ static void r600_set_sample_mask(struct pipe_context 
*pipe, unsigned sample_mask
        rctx->sample_mask.atom.dirty = true;
 }
 
+static void r600_setup_txq_cube_array_constants(struct r600_context *rctx, int 
shader_type)
+{
+       struct r600_textures_info *samplers = &rctx->samplers[shader_type];
+       int bits;
+       uint32_t array_size;
+       struct pipe_constant_buffer cb;
+       int i;
+
+       if (!samplers->views.dirty_txq_constants)
+               return;
+
+       samplers->views.dirty_txq_constants = FALSE;
+
+       bits = util_last_bit(samplers->views.enabled_mask);
+       array_size = bits * sizeof(uint32_t) * 4;
+       samplers->txq_constants = realloc(samplers->txq_constants, array_size);
+       memset(samplers->txq_constants, 0, array_size);
+       for (i = 0; i < bits; i++)
+               if (samplers->views.enabled_mask & (1 << i))
+                       samplers->txq_constants[i] = 
samplers->views.views[i]->base.texture->array_size / 6;
+
+       cb.buffer = NULL;
+       cb.user_buffer = samplers->txq_constants;
+       cb.buffer_offset = 0;
+       cb.buffer_size = array_size;
+       rctx->context.set_constant_buffer(&rctx->context, shader_type, 
R600_TXQ_CONST_BUFFER, &cb);
+       pipe_resource_reference(&cb.buffer, NULL);
+}
+
 static bool r600_update_derived_state(struct r600_context *rctx)
 {
        struct pipe_context * ctx = (struct pipe_context*)rctx;
@@ -1061,6 +1090,11 @@ static bool r600_update_derived_state(struct 
r600_context *rctx)
        if (ps_dirty)
                r600_context_pipe_state_set(rctx, 
&rctx->ps_shader->current->rstate);
 
+       if (rctx->ps_shader && 
rctx->ps_shader->current->shader.has_txq_cube_array_z_comp)
+               r600_setup_txq_cube_array_constants(rctx, PIPE_SHADER_FRAGMENT);
+       if (rctx->vs_shader && 
rctx->vs_shader->current->shader.has_txq_cube_array_z_comp)
+               r600_setup_txq_cube_array_constants(rctx, PIPE_SHADER_VERTEX);
+
        if (rctx->chip_class < EVERGREEN && rctx->ps_shader && rctx->vs_shader) 
{
                if (!r600_adjust_gprs(rctx)) {
                        /* discard rendering */
diff --git a/src/gallium/drivers/r600/r600_texture.c 
b/src/gallium/drivers/r600/r600_texture.c
index 75e7f87..c4d5bb4 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -133,6 +133,7 @@ static int r600_init_surface(struct r600_screen *rscreen,
                surface->array_size = ptex->array_size;
                break;
        case PIPE_TEXTURE_2D_ARRAY:
+       case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d layout for 
now */
                surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, 
TYPE);
                surface->array_size = ptex->array_size;
                break;
-- 
1.7.11.7

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to