[Mesa-dev] [PATCH] r600g: add initial cube map array support (v2)

Marek Olšák maraeo at gmail.com
Fri Nov 9 04:35:44 PST 2012


Reviewed-by: Marek Olšák <maraeo at gmail.com>

Marek

On Fri, Nov 9, 2012 at 5:12 AM, Dave Airlie <airlied at gmail.com> wrote:
> 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 <airlied at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list