From: Ilia Mirkin Date: Fri, 18 Sep 2015 23:08:35 +0000 (-0400) Subject: radeonsi: implement TXQS support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=72ebd532a163fd92d96a94a4260da1bfb75a62c8;p=mesa.git radeonsi: implement TXQS support Signed-off-by: Ilia Mirkin Tested-by: Fredrik Bruhn Reviewed-by: Marek Olšák --- diff --git a/docs/GL3.txt b/docs/GL3.txt index bd44d1293f5..92941cf0d74 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -194,7 +194,7 @@ GL 4.5, GLSL 4.50: GL_ARB_derivative_control DONE (i965, nv50, nvc0, r600, radeonsi) GL_ARB_direct_state_access DONE (all drivers) GL_ARB_get_texture_sub_image DONE (all drivers) - GL_ARB_shader_texture_image_samples DONE (i965, nv50, nvc0, r600) + GL_ARB_shader_texture_image_samples DONE (i965, nv50, nvc0, r600, radeonsi) GL_ARB_texture_barrier DONE (nv50, nvc0, r600, radeonsi) GL_KHR_context_flush_control DONE (all - but needs GLX/EGL extension to be useful) GL_KHR_robust_buffer_access_behavior not started diff --git a/docs/relnotes/11.1.0.html b/docs/relnotes/11.1.0.html index 24fdf2e9683..89b9a191176 100644 --- a/docs/relnotes/11.1.0.html +++ b/docs/relnotes/11.1.0.html @@ -45,7 +45,7 @@ Note: some of the new features are only available with certain drivers.
  • GL_ARB_blend_func_extended on freedreno (a3xx)
  • -
  • GL_ARB_shader_texture_image_samples on i965, nv50, nvc0, r600
  • +
  • GL_ARB_shader_texture_image_samples on i965, nv50, nvc0, r600, radeonsi
  • GL_ARB_texture_query_lod on softpipe
  • GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips
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;