r600g: add initial cube map array support (v2)
authorDave Airlie <airlied@gmail.com>
Sat, 3 Nov 2012 10:53:33 +0000 (20:53 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 9 Nov 2012 20:20:46 +0000 (06:20 +1000)
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.

Reviewed-by: Marek Olšák <maraeo@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/r600/r600_texture.c

index c105e55279f0a5238b60fffa14410ca22c1bb352..9b898cb10e6ba90dda745e3c71fc527e62183e6f 100644 (file)
@@ -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)) |
index a2ed17723f140005c62bc1084c05bb385f88d876..e39f4bd9cd1bf4d54af0b2dae8d39182e55e24f4 100644 (file)
@@ -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;
index 3a69eb23bf18843085d2e7181a00eab387e79fbb..296f812551d94b99f4263006714e76b8f56fa95f 100644 (file)
@@ -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. */
index 2287d6371ff8b8e8796cd6feca9adc62351f4f36..33ccefa13ca0b468a21d141246e829dd00c240a8 100644 (file)
 #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 {
index 8d0a9b4569ec7948fefc5e65268d5018f964e260..84821acb76f39f3fcfcffb65f7d960bd0926a98a 100644 (file)
@@ -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},
 };
index f76d591528147658134bf976dcc0115961901d6a..b58a58ab4dbf4a65cfceb43987099422a82d71b2 100644 (file)
@@ -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 {
index a7b602ddf7a451ca98d602fca6e285a55bf7edfd..ab658da812ab4d7635b9f4cdd5b673dce8bb72f0 100644 (file)
@@ -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;
index e7062c384a32961cb5dbd5233b76e676b9d934df..926cb1ae88902963d93fd480e3c789157af77b07 100644 (file)
@@ -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 */
index 75e7f870efbf87a9107fe4d3c6ed1026082ff34d..c4d5bb4dbbf2be3d454ba7ae009ad1ea98c770d8 100644 (file)
@@ -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;