diff options
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 198 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 36 | ||||
-rw-r--r-- | 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 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; |