From 72ebd532a163fd92d96a94a4260da1bfb75a62c8 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 18 Sep 2015 19:08:35 -0400 Subject: radeonsi: implement TXQS support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ilia Mirkin Tested-by: Fredrik Bruhn Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_pipe.c | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 92 +++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index ae1ff7eef43..01fa5252f71 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -284,6 +284,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_DEPTH_BOUNDS_TEST: case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_TEXTURE_GATHER_SM5: + case PIPE_CAP_TGSI_TXQS: return 1; case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: @@ -325,7 +326,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_GATHER_OFFSETS: case PIPE_CAP_SAMPLER_VIEW_TARGET: case PIPE_CAP_VERTEXID_NOBASE: - case PIPE_CAP_TGSI_TXQS: return 0; case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index e92a3d2a2ec..2e49a215763 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2305,29 +2305,17 @@ static void set_tex_fetch_args(struct gallivm_state *gallivm, static const struct lp_build_tgsi_action tex_action; -static void tex_fetch_args( +static void tex_fetch_ptrs( struct lp_build_tgsi_context * bld_base, - struct lp_build_emit_data * emit_data) + struct lp_build_emit_data * emit_data, + LLVMValueRef *res_ptr, LLVMValueRef *samp_ptr, LLVMValueRef *fmask_ptr) { struct si_shader_context *si_shader_ctx = si_shader_context(bld_base); struct gallivm_state *gallivm = bld_base->base.gallivm; - LLVMBuilderRef builder = gallivm->builder; const struct tgsi_full_instruction * inst = emit_data->inst; - unsigned opcode = inst->Instruction.Opcode; unsigned target = inst->Texture.Texture; - LLVMValueRef coords[5], derivs[6]; - LLVMValueRef address[16]; - int ref_pos; - unsigned num_coords = tgsi_util_get_texture_coord_dim(target, &ref_pos); - unsigned count = 0; - unsigned chan; unsigned sampler_src; unsigned sampler_index; - unsigned num_deriv_channels = 0; - bool has_offset = inst->Texture.NumOffsets > 0; - LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL; - LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context); - unsigned dmask = 0xf; sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1; sampler_index = emit_data->inst->Src[sampler_src].Register.Index; @@ -2338,25 +2326,50 @@ static void tex_fetch_args( ind_index = get_indirect_index(si_shader_ctx, ®->Indirect, reg->Register.Index); - res_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); - res_ptr = build_indexed_load_const(si_shader_ctx, res_ptr, ind_index); + *res_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); + *res_ptr = build_indexed_load_const(si_shader_ctx, *res_ptr, ind_index); - samp_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_SAMPLER); - samp_ptr = build_indexed_load_const(si_shader_ctx, samp_ptr, ind_index); + *samp_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_SAMPLER); + *samp_ptr = build_indexed_load_const(si_shader_ctx, *samp_ptr, ind_index); if (target == TGSI_TEXTURE_2D_MSAA || target == TGSI_TEXTURE_2D_ARRAY_MSAA) { ind_index = LLVMBuildAdd(gallivm->builder, ind_index, lp_build_const_int32(gallivm, SI_FMASK_TEX_OFFSET), ""); - fmask_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); - fmask_ptr = build_indexed_load_const(si_shader_ctx, fmask_ptr, ind_index); + *fmask_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); + *fmask_ptr = build_indexed_load_const(si_shader_ctx, *fmask_ptr, ind_index); } } else { - res_ptr = si_shader_ctx->resources[sampler_index]; - samp_ptr = si_shader_ctx->samplers[sampler_index]; - fmask_ptr = si_shader_ctx->resources[SI_FMASK_TEX_OFFSET + sampler_index]; + *res_ptr = si_shader_ctx->resources[sampler_index]; + *samp_ptr = si_shader_ctx->samplers[sampler_index]; + *fmask_ptr = si_shader_ctx->resources[SI_FMASK_TEX_OFFSET + sampler_index]; } +} + +static void tex_fetch_args( + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + struct si_shader_context *si_shader_ctx = si_shader_context(bld_base); + struct gallivm_state *gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + const struct tgsi_full_instruction * inst = emit_data->inst; + unsigned opcode = inst->Instruction.Opcode; + unsigned target = inst->Texture.Texture; + LLVMValueRef coords[5], derivs[6]; + LLVMValueRef address[16]; + int ref_pos; + unsigned num_coords = tgsi_util_get_texture_coord_dim(target, &ref_pos); + unsigned count = 0; + unsigned chan; + unsigned num_deriv_channels = 0; + bool has_offset = inst->Texture.NumOffsets > 0; + LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL; + LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context); + unsigned dmask = 0xf; + + tex_fetch_ptrs(bld_base, emit_data, &res_ptr, &samp_ptr, &fmask_ptr); if (opcode == TGSI_OPCODE_TXQ) { if (target == TGSI_TEXTURE_BUFFER) { @@ -2800,6 +2813,36 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action, } } +static void si_llvm_emit_txqs( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context); + LLVMTypeRef v8i32 = LLVMVectorType(i32, 8); + LLVMValueRef res, samples; + LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL; + + tex_fetch_ptrs(bld_base, emit_data, &res_ptr, &samp_ptr, &fmask_ptr); + + + /* Read the samples from the descriptor directly. */ + res = LLVMBuildBitCast(builder, res_ptr, v8i32, ""); + samples = LLVMBuildExtractElement( + builder, res, + lp_build_const_int32(gallivm, 3), ""); + samples = LLVMBuildLShr(builder, samples, + lp_build_const_int32(gallivm, 16), ""); + samples = LLVMBuildAnd(builder, samples, + lp_build_const_int32(gallivm, 0xf), ""); + samples = LLVMBuildShl(builder, lp_build_const_int32(gallivm, 1), + samples, ""); + + emit_data->output[emit_data->chan] = samples; +} + /* * SI implements derivatives using the local data store (LDS) * All writes to the LDS happen in all executing threads at @@ -3975,6 +4018,7 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm, bld_base->op_actions[TGSI_OPCODE_TXQ] = tex_action; bld_base->op_actions[TGSI_OPCODE_TG4] = tex_action; bld_base->op_actions[TGSI_OPCODE_LODQ] = tex_action; + bld_base->op_actions[TGSI_OPCODE_TXQS].emit = si_llvm_emit_txqs; bld_base->op_actions[TGSI_OPCODE_DDX].emit = si_llvm_emit_ddxy; bld_base->op_actions[TGSI_OPCODE_DDY].emit = si_llvm_emit_ddxy; -- cgit v1.2.3