summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2012-11-03 20:53:33 +1000
committerDave Airlie <airlied@redhat.com>2012-11-09 14:11:51 +1000
commitec94b7926bfea30e6f257429862dbb738f65a0d8 (patch)
tree7c740896fbc4ceaa7003af1433540e13d0968242
parent2c8f08813243b867801008a157c44ce9debdcfd2 (diff)
r600g: add initial cube map array support (v2)arb_texture_cube_map_array
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@redhat.com>
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c4
-rw-r--r--src/gallium/drivers/r600/r600_blit.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h7
-rw-r--r--src/gallium/drivers/r600/r600_shader.c198
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c4
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c36
-rw-r--r--src/gallium/drivers/r600/r600_texture.c1
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 c105e55279f..9b898cb10e6 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 a2ed17723f1..e39f4bd9cd1 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 3a69eb23bf1..296f812551d 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 2287d6371ff..33ccefa13ca 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 8d0a9b4569e..84821acb76f 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 f76d5915281..b58a58ab4db 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 a7b602ddf7a..ab658da812a 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 e7062c384a3..926cb1ae889 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 75e7f870efb..c4d5bb4dbbf 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;