mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 18:50:10 +01:00
radeonsi: emit TXQ in separate functions
TXQ is sufficiently different that having in it in the same code path as texture sampling/fetching opcodes doesn't make much sense. v2: guard against NULL pointer dereferences Reviewed-by: Marek Olšák <marek.olsak@amd.com> (v1)
This commit is contained in:
parent
d464bfd12a
commit
988fd6c922
1 changed files with 78 additions and 52 deletions
|
|
@ -3901,17 +3901,86 @@ static void tex_fetch_ptrs(
|
|||
|
||||
if (target == TGSI_TEXTURE_2D_MSAA ||
|
||||
target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
|
||||
*samp_ptr = NULL;
|
||||
*fmask_ptr = get_sampler_desc(ctx, ind_index, DESC_FMASK);
|
||||
if (samp_ptr)
|
||||
*samp_ptr = NULL;
|
||||
if (fmask_ptr)
|
||||
*fmask_ptr = get_sampler_desc(ctx, ind_index, DESC_FMASK);
|
||||
} else {
|
||||
*samp_ptr = get_sampler_desc(ctx, ind_index, DESC_SAMPLER);
|
||||
*samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr);
|
||||
*fmask_ptr = NULL;
|
||||
if (samp_ptr) {
|
||||
*samp_ptr = get_sampler_desc(ctx, ind_index, DESC_SAMPLER);
|
||||
*samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr);
|
||||
}
|
||||
if (fmask_ptr)
|
||||
*fmask_ptr = NULL;
|
||||
}
|
||||
} else {
|
||||
*res_ptr = ctx->sampler_views[sampler_index];
|
||||
*samp_ptr = ctx->sampler_states[sampler_index];
|
||||
*fmask_ptr = ctx->fmasks[sampler_index];
|
||||
if (samp_ptr)
|
||||
*samp_ptr = ctx->sampler_states[sampler_index];
|
||||
if (fmask_ptr)
|
||||
*fmask_ptr = ctx->fmasks[sampler_index];
|
||||
}
|
||||
}
|
||||
|
||||
static void txq_fetch_args(
|
||||
struct lp_build_tgsi_context *bld_base,
|
||||
struct lp_build_emit_data *emit_data)
|
||||
{
|
||||
struct si_shader_context *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 target = inst->Texture.Texture;
|
||||
LLVMValueRef res_ptr;
|
||||
LLVMValueRef address;
|
||||
|
||||
tex_fetch_ptrs(bld_base, emit_data, &res_ptr, NULL, NULL);
|
||||
|
||||
if (target == TGSI_TEXTURE_BUFFER) {
|
||||
/* Read the size from the buffer descriptor directly. */
|
||||
LLVMValueRef res = LLVMBuildBitCast(builder, res_ptr, ctx->v8i32, "");
|
||||
emit_data->args[0] = get_buffer_size(bld_base, res);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Textures - set the mip level. */
|
||||
address = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X);
|
||||
|
||||
set_tex_fetch_args(ctx, emit_data, TGSI_OPCODE_TXQ, target, res_ptr,
|
||||
NULL, &address, 1, 0xf);
|
||||
}
|
||||
|
||||
static void txq_emit(const struct lp_build_tgsi_action *action,
|
||||
struct lp_build_tgsi_context *bld_base,
|
||||
struct lp_build_emit_data *emit_data)
|
||||
{
|
||||
struct lp_build_context *base = &bld_base->base;
|
||||
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;
|
||||
}
|
||||
|
||||
emit_data->output[emit_data->chan] = lp_build_intrinsic(
|
||||
base->gallivm->builder, "llvm.SI.getresinfo.i32",
|
||||
emit_data->dst_type, emit_data->args, emit_data->arg_count,
|
||||
LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
|
||||
|
||||
/* 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, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3921,7 +3990,6 @@ static void tex_fetch_args(
|
|||
{
|
||||
struct si_shader_context *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;
|
||||
|
|
@ -3938,22 +4006,6 @@ static void tex_fetch_args(
|
|||
|
||||
tex_fetch_ptrs(bld_base, emit_data, &res_ptr, &samp_ptr, &fmask_ptr);
|
||||
|
||||
if (opcode == TGSI_OPCODE_TXQ) {
|
||||
if (target == TGSI_TEXTURE_BUFFER) {
|
||||
/* Read the size from the buffer descriptor directly. */
|
||||
LLVMValueRef res = LLVMBuildBitCast(builder, res_ptr, ctx->v8i32, "");
|
||||
emit_data->args[0] = get_buffer_size(bld_base, res);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Textures - set the mip level. */
|
||||
address[count++] = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X);
|
||||
|
||||
set_tex_fetch_args(ctx, emit_data, opcode, target, res_ptr,
|
||||
NULL, address, count, 0xf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (target == TGSI_TEXTURE_BUFFER) {
|
||||
LLVMTypeRef v2i128 = LLVMVectorType(ctx->i128, 2);
|
||||
|
||||
|
|
@ -4266,12 +4318,6 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
|
|||
const char *name = "llvm.SI.image.sample";
|
||||
const char *infix = "";
|
||||
|
||||
if (opcode == TGSI_OPCODE_TXQ && target == TGSI_TEXTURE_BUFFER) {
|
||||
/* Just return the buffer size. */
|
||||
emit_data->output[emit_data->chan] = emit_data->args[0];
|
||||
return;
|
||||
}
|
||||
|
||||
if (target == TGSI_TEXTURE_BUFFER) {
|
||||
emit_data->output[emit_data->chan] = lp_build_intrinsic(
|
||||
base->gallivm->builder,
|
||||
|
|
@ -4290,11 +4336,6 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
|
|||
is_shadow = false;
|
||||
has_offset = false;
|
||||
break;
|
||||
case TGSI_OPCODE_TXQ:
|
||||
name = "llvm.SI.getresinfo";
|
||||
is_shadow = false;
|
||||
has_offset = false;
|
||||
break;
|
||||
case TGSI_OPCODE_LODQ:
|
||||
name = "llvm.SI.getlod";
|
||||
is_shadow = false;
|
||||
|
|
@ -4333,22 +4374,6 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
|
|||
base->gallivm->builder, intr_name, emit_data->dst_type,
|
||||
emit_data->args, emit_data->arg_count,
|
||||
LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
|
||||
|
||||
/* Divide the number of layers by 6 to get the number of cubes. */
|
||||
if (opcode == TGSI_OPCODE_TXQ &&
|
||||
(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, "");
|
||||
}
|
||||
}
|
||||
|
||||
static void si_llvm_emit_txqs(
|
||||
|
|
@ -6007,7 +6032,8 @@ static void si_init_shader_ctx(struct si_shader_context *ctx,
|
|||
bld_base->op_actions[TGSI_OPCODE_TXL] = tex_action;
|
||||
bld_base->op_actions[TGSI_OPCODE_TXL2] = tex_action;
|
||||
bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
|
||||
bld_base->op_actions[TGSI_OPCODE_TXQ] = tex_action;
|
||||
bld_base->op_actions[TGSI_OPCODE_TXQ].fetch_args = txq_fetch_args;
|
||||
bld_base->op_actions[TGSI_OPCODE_TXQ].emit = txq_emit;
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue