From 2484daa4fd0d54877175767d98d4d33ef0bac30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 22 Apr 2014 21:23:29 +0200 Subject: [PATCH] radeonsi: implement ARB_texture_cube_map_array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No LLVM changes needed. Reviewed-by: Michel Dänzer v2: updated GL3.txt and relnotes --- docs/GL3.txt | 2 +- docs/relnotes/10.3.html | 1 + src/gallium/drivers/radeonsi/si_pipe.c | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 47 ++++++++++++++++++++++-- src/gallium/drivers/radeonsi/si_state.c | 4 +- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/docs/GL3.txt b/docs/GL3.txt index ae1dfd69466..c360f2cb7a7 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -118,7 +118,7 @@ GL 4.0: GL_ARB_shader_subroutine not started GL_ARB_tessellation_shader not started GL_ARB_texture_buffer_object_rgb32 DONE (i965, nvc0, r600, radeonsi, softpipe) - GL_ARB_texture_cube_map_array DONE (i965, nv50, nvc0, r600, softpipe) + GL_ARB_texture_cube_map_array DONE (i965, nv50, nvc0, r600, radeonsi, softpipe) GL_ARB_texture_gather DONE (i965, nv50, nvc0) GL_ARB_transform_feedback2 DONE (i965, nv50, nvc0, r600, radeonsi) GL_ARB_transform_feedback3 DONE (i965, nv50, nvc0, r600, radeonsi) diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html index aebc3ff3307..6bb9e7989ba 100644 --- a/docs/relnotes/10.3.html +++ b/docs/relnotes/10.3.html @@ -45,6 +45,7 @@ Note: some of the new features are only available with certain drivers. diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 873115b8142..24068e3192d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -209,6 +209,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_VS_LAYER: case PIPE_CAP_QUERY_PIPELINE_STATISTICS: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: + case PIPE_CAP_CUBE_MAP_ARRAY: return 1; case PIPE_CAP_TEXTURE_MULTISAMPLE: @@ -237,7 +238,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_VERTEX_COLOR_CLAMPED: case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: case PIPE_CAP_USER_VERTEX_BUFFERS: - case PIPE_CAP_CUBE_MAP_ARRAY: case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: case PIPE_CAP_TEXTURE_GATHER_SM5: case PIPE_CAP_TGSI_TEXCOORD: diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 0d070d3cef6..a27f7f8a39e 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1539,8 +1539,13 @@ static void tex_fetch_args( /* Pack LOD bias value */ if (opcode == TGSI_OPCODE_TXB) address[count++] = coords[3]; + if (opcode == TGSI_OPCODE_TXB2) + address[count++] = lp_build_emit_fetch(bld_base, inst, 1, 0); - if (target == TGSI_TEXTURE_CUBE || target == TGSI_TEXTURE_SHADOWCUBE) + if (target == TGSI_TEXTURE_CUBE || + target == TGSI_TEXTURE_CUBE_ARRAY || + target == TGSI_TEXTURE_SHADOWCUBE || + target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords); /* Pack depth comparison value */ @@ -1577,6 +1582,8 @@ static void tex_fetch_args( /* Pack LOD or sample index */ if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXF) address[count++] = coords[3]; + if (opcode == TGSI_OPCODE_TXL2) + address[count++] = lp_build_emit_fetch(bld_base, inst, 1, 0); if (count > 16) { assert(!"Cannot handle more than 16 texture address parameters"); @@ -1732,6 +1739,13 @@ static void tex_fetch_args( emit_data->arg_count = 4; } + /* The fetch opcode has been converted to a 2D array fetch. + * This simplifies the LLVM backend. */ + if (target == TGSI_TEXTURE_CUBE_ARRAY) + target = TGSI_TEXTURE_2D_ARRAY; + else if (target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) + target = TGSI_TEXTURE_SHADOW2D_ARRAY; + /* Dimensions */ emit_data->args[emit_data->arg_count - 1] = lp_build_const_int32(bld_base->base.gallivm, target); @@ -1775,8 +1789,9 @@ static void txq_fetch_args( struct si_shader_context *si_shader_ctx = si_shader_context(bld_base); const struct tgsi_full_instruction *inst = emit_data->inst; struct gallivm_state *gallivm = bld_base->base.gallivm; + unsigned target = inst->Texture.Texture; - if (inst->Texture.Texture == TGSI_TEXTURE_BUFFER) { + if (target == TGSI_TEXTURE_BUFFER) { LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef v8i32 = LLVMVectorType(i32, 8); @@ -1795,7 +1810,11 @@ static void txq_fetch_args( /* Resource */ emit_data->args[1] = si_shader_ctx->resources[inst->Src[1].Register.Index]; - /* Dimensions */ + /* Texture target */ + if (target == TGSI_TEXTURE_CUBE_ARRAY || + target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) + target = TGSI_TEXTURE_2D_ARRAY; + emit_data->args[2] = lp_build_const_int32(bld_base->base.gallivm, inst->Texture.Texture); @@ -1810,13 +1829,30 @@ static void build_txq_intrinsic(const struct lp_build_tgsi_action * action, struct lp_build_tgsi_context * bld_base, struct lp_build_emit_data * emit_data) { - if (emit_data->inst->Texture.Texture == TGSI_TEXTURE_BUFFER) { + unsigned target = emit_data->inst->Texture.Texture; + + if (target == TGSI_TEXTURE_BUFFER) { /* Just return the buffer size. */ emit_data->output[emit_data->chan] = emit_data->args[0]; return; } build_tgsi_intrinsic_nomem(action, bld_base, emit_data); + + /* Divide the number of layers by 6 to get the number of cubes. */ + if (target == TGSI_TEXTURE_CUBE_ARRAY || + target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) { + LLVMBuilderRef builder = bld_base->base.gallivm->builder; + LLVMValueRef two = lp_build_const_int32(bld_base->base.gallivm, 2); + LLVMValueRef six = lp_build_const_int32(bld_base->base.gallivm, 6); + + LLVMValueRef v4 = emit_data->output[emit_data->chan]; + LLVMValueRef z = LLVMBuildExtractElement(builder, v4, two, ""); + z = LLVMBuildSDiv(builder, z, six, ""); + + emit_data->output[emit_data->chan] = + LLVMBuildInsertElement(builder, v4, z, two, ""); + } } #if HAVE_LLVM >= 0x0304 @@ -2496,12 +2532,15 @@ int si_pipe_shader_create( bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant; bld_base->op_actions[TGSI_OPCODE_TEX] = tex_action; + bld_base->op_actions[TGSI_OPCODE_TEX2] = tex_action; bld_base->op_actions[TGSI_OPCODE_TXB] = txb_action; + bld_base->op_actions[TGSI_OPCODE_TXB2] = txb_action; #if HAVE_LLVM >= 0x0304 bld_base->op_actions[TGSI_OPCODE_TXD] = txd_action; #endif bld_base->op_actions[TGSI_OPCODE_TXF] = txf_action; bld_base->op_actions[TGSI_OPCODE_TXL] = txl_action; + bld_base->op_actions[TGSI_OPCODE_TXL2] = txl_action; bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action; bld_base->op_actions[TGSI_OPCODE_TXQ] = txq_action; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 6d5408b1877..d25dc60cec8 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1312,6 +1312,7 @@ static unsigned si_tex_dim(unsigned dim, unsigned nr_samples) case PIPE_TEXTURE_3D: return V_008F1C_SQ_RSRC_IMG_3D; case PIPE_TEXTURE_CUBE: + case PIPE_TEXTURE_CUBE_ARRAY: return V_008F1C_SQ_RSRC_IMG_CUBE; } } @@ -2477,7 +2478,8 @@ static struct pipe_sampler_view *si_create_sampler_view(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; va = r600_resource_va(ctx->screen, texture); va += surflevel[0].offset;