From: Nicolai Hähnle <nicolai.haeh...@amd.com> --- src/amd/common/ac_nir_to_llvm.c | 43 ++++++++++++++++------------ src/amd/common/ac_shader_abi.h | 4 ++- src/gallium/drivers/radeonsi/si_shader_nir.c | 3 +- 3 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 62131ca..5d7f53e 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -181,21 +181,22 @@ struct nir_to_llvm_context { static inline struct nir_to_llvm_context * nir_to_llvm_context_from_abi(struct ac_shader_abi *abi) { struct nir_to_llvm_context *ctx = NULL; return container_of(abi, ctx, abi); } static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx, const nir_deref_var *deref, - enum ac_descriptor_type desc_type); + enum ac_descriptor_type desc_type, + bool image, bool write); static unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan) { return (index * 4) + chan; } static unsigned shader_io_get_unique_index(gl_varying_slot slot) { /* handle patch indices separate */ if (slot == VARYING_SLOT_TESS_LEVEL_OUTER) @@ -3290,21 +3291,21 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx, fmask_load_address[2] = NULL; if (add_frag_pos) { for (chan = 0; chan < 2; ++chan) fmask_load_address[chan] = LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->nctx->frag_pos[chan], ctx->ac.i32, ""), ""); } sample_index = adjust_sample_index_using_fmask(&ctx->ac, fmask_load_address[0], fmask_load_address[1], fmask_load_address[2], sample_index, - get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK)); + get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, true, false)); } if (count == 1) { if (instr->src[0].ssa->num_components) res = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], ""); else res = src0; } else { int chan; if (is_ms) count--; @@ -3339,40 +3340,40 @@ static LLVMValueRef visit_image_load(struct ac_nir_context *ctx, const nir_variable *var = instr->variables[0]->var; const struct glsl_type *type = var->type; LLVMValueRef i1false = LLVMConstInt(ctx->ac.i1, 0, false); LLVMValueRef i1true = LLVMConstInt(ctx->ac.i1, 1, false); if(instr->variables[0]->deref.child) type = instr->variables[0]->deref.child->type; type = glsl_without_array(type); if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) { - params[0] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER); + params[0] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, true, false); params[1] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]), ctx->ac.i32_0, ""); /* vindex */ params[2] = ctx->ac.i32_0; /* voffset */ params[3] = i1false; /* glc */ params[4] = i1false; /* slc */ res = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.load.format.v4f32", ctx->ac.v4f32, params, 5, 0); res = trim_vector(&ctx->ac, res, instr->dest.ssa.num_components); res = to_integer(&ctx->ac, res); } else { bool is_da = glsl_sampler_type_is_array(type) || glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE; LLVMValueRef da = is_da ? i1true : i1false; LLVMValueRef glc = i1false; LLVMValueRef slc = i1false; params[0] = get_image_coords(ctx, instr); - params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE); + params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, false); params[2] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */ if (HAVE_LLVM <= 0x0309) { params[3] = i1false; /* r128 */ params[4] = da; params[5] = glc; params[6] = slc; } else { LLVMValueRef lwe = i1false; params[3] = glc; params[4] = slc; @@ -3400,38 +3401,38 @@ static void visit_image_store(struct ac_nir_context *ctx, const nir_variable *var = instr->variables[0]->var; const struct glsl_type *type = glsl_without_array(var->type); LLVMValueRef i1false = LLVMConstInt(ctx->ac.i1, 0, false); LLVMValueRef i1true = LLVMConstInt(ctx->ac.i1, 1, false); if (ctx->stage == MESA_SHADER_FRAGMENT) ctx->nctx->shader_info->fs.writes_memory = true; if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) { params[0] = to_float(&ctx->ac, get_src(ctx, instr->src[2])); /* data */ - params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER); + params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, true, true); params[2] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]), ctx->ac.i32_0, ""); /* vindex */ params[3] = ctx->ac.i32_0; /* voffset */ params[4] = i1false; /* glc */ params[5] = i1false; /* slc */ ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.store.format.v4f32", ctx->ac.voidt, params, 6, 0); } else { bool is_da = glsl_sampler_type_is_array(type) || glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE; LLVMValueRef da = is_da ? i1true : i1false; LLVMValueRef glc = i1false; LLVMValueRef slc = i1false; params[0] = to_float(&ctx->ac, get_src(ctx, instr->src[2])); params[1] = get_image_coords(ctx, instr); /* coords */ - params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE); + params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, true); params[3] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */ if (HAVE_LLVM <= 0x0309) { params[4] = i1false; /* r128 */ params[5] = da; params[6] = glc; params[7] = slc; } else { LLVMValueRef lwe = i1false; params[4] = glc; params[5] = slc; @@ -3495,36 +3496,38 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx, break; default: abort(); } params[param_count++] = get_src(ctx, instr->src[2]); if (instr->intrinsic == nir_intrinsic_image_atomic_comp_swap) params[param_count++] = get_src(ctx, instr->src[3]); if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) { - params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER); + params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, + true, true); params[param_count++] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]), ctx->ac.i32_0, ""); /* vindex */ params[param_count++] = ctx->ac.i32_0; /* voffset */ params[param_count++] = i1false; /* slc */ length = snprintf(intrinsic_name, sizeof(intrinsic_name), "llvm.amdgcn.buffer.atomic.%s", atomic_name); } else { char coords_type[8]; bool da = glsl_sampler_type_is_array(type) || glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE; LLVMValueRef coords = params[param_count++] = get_image_coords(ctx, instr); - params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE); + params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, + true, true); params[param_count++] = i1false; /* r128 */ params[param_count++] = da ? i1true : i1false; /* da */ params[param_count++] = i1false; /* slc */ build_int_type_name(LLVMTypeOf(coords), coords_type, sizeof(coords_type)); length = snprintf(intrinsic_name, sizeof(intrinsic_name), "llvm.amdgcn.image.atomic.%s.%s", atomic_name, coords_type); } @@ -3538,27 +3541,29 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx, { LLVMValueRef res; const nir_variable *var = instr->variables[0]->var; const struct glsl_type *type = instr->variables[0]->var->type; bool da = glsl_sampler_type_is_array(var->type) || glsl_get_sampler_dim(var->type) == GLSL_SAMPLER_DIM_CUBE; if(instr->variables[0]->deref.child) type = instr->variables[0]->deref.child->type; if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) - return get_buffer_size(ctx, get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER), true); + return get_buffer_size(ctx, + get_sampler_desc(ctx, instr->variables[0], + AC_DESC_BUFFER, true, false), true); struct ac_image_args args = { 0 }; args.da = da; args.dmask = 0xf; - args.resource = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE); + args.resource = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, false); args.opcode = ac_image_get_resinfo; args.addr = ctx->ac.i32_0; res = ac_build_image_opcode(&ctx->ac, &args); if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE && glsl_sampler_type_is_array(type)) { LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false); LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false); LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, ""); @@ -4115,21 +4120,22 @@ static void visit_intrinsic(struct ac_nir_context *ctx, if (result) { _mesa_hash_table_insert(ctx->defs, &instr->dest.ssa, result); } } static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi, unsigned descriptor_set, unsigned base_index, unsigned constant_index, LLVMValueRef index, - enum ac_descriptor_type desc_type) + enum ac_descriptor_type desc_type, + bool image, bool write) { struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi); LLVMValueRef list = ctx->descriptor_sets[descriptor_set]; struct radv_descriptor_set_layout *layout = ctx->options->layout->set[descriptor_set].layout; struct radv_descriptor_set_binding_layout *binding = layout->binding + base_index; unsigned offset = binding->offset; unsigned stride = binding->size; unsigned type_size; LLVMBuilderRef builder = ctx->builder; LLVMTypeRef type; @@ -4187,21 +4193,22 @@ static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi, index = LLVMBuildMul(builder, index, LLVMConstInt(ctx->i32, stride / type_size, 0), ""); list = ac_build_gep0(&ctx->ac, list, LLVMConstInt(ctx->i32, offset, 0)); list = LLVMBuildPointerCast(builder, list, const_array(type, 0), ""); return ac_build_indexed_load_const(&ctx->ac, list, index); } static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx, const nir_deref_var *deref, - enum ac_descriptor_type desc_type) + enum ac_descriptor_type desc_type, + bool image, bool write) { LLVMValueRef index = NULL; unsigned constant_index = 0; const nir_deref *tail = &deref->deref; while (tail->child) { const nir_deref_array *child = nir_deref_as_array(tail->child); unsigned array_size = glsl_get_aoa_size(tail->child->type); if (!array_size) @@ -4223,21 +4230,21 @@ static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx, constant_index += child->base_offset * array_size; tail = &child->deref; } return ctx->abi->load_sampler_desc(ctx->abi, deref->var->data.descriptor_set, deref->var->data.binding, constant_index, index, - desc_type); + desc_type, image, write); } static void set_tex_fetch_args(struct ac_llvm_context *ctx, struct ac_image_args *args, const nir_tex_instr *instr, nir_texop op, LLVMValueRef res_ptr, LLVMValueRef samp_ptr, LLVMValueRef *param, unsigned count, unsigned dmask) { @@ -4296,34 +4303,34 @@ static LLVMValueRef sici_fix_sampler_aniso(struct ac_nir_context *ctx, return LLVMBuildInsertElement(builder, samp, samp0, LLVMConstInt(ctx->ac.i32, 0, 0), ""); } static void tex_fetch_ptrs(struct ac_nir_context *ctx, nir_tex_instr *instr, LLVMValueRef *res_ptr, LLVMValueRef *samp_ptr, LLVMValueRef *fmask_ptr) { if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) - *res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_BUFFER); + *res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_BUFFER, false, false); else - *res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_IMAGE); + *res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_IMAGE, false, false); if (samp_ptr) { if (instr->sampler) - *samp_ptr = get_sampler_desc(ctx, instr->sampler, AC_DESC_SAMPLER); + *samp_ptr = get_sampler_desc(ctx, instr->sampler, AC_DESC_SAMPLER, false, false); else - *samp_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_SAMPLER); + *samp_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_SAMPLER, false, false); if (instr->sampler_dim < GLSL_SAMPLER_DIM_RECT) *samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr); } if (fmask_ptr && !instr->sampler && (instr->op == nir_texop_txf_ms || instr->op == nir_texop_samples_identical)) - *fmask_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_FMASK); + *fmask_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_FMASK, false, false); } static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx, LLVMValueRef coord) { coord = to_float(ctx, coord); coord = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32, &coord, 1, 0); coord = to_integer(ctx, coord); return coord; } diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h index 63d31c8..fe804cf 100644 --- a/src/amd/common/ac_shader_abi.h +++ b/src/amd/common/ac_shader_abi.h @@ -60,20 +60,22 @@ struct ac_shader_abi { /** * Load a descriptor associated to a sampler. * * \param descriptor_set the descriptor set index (only for Vulkan) * \param base_index the base index of the sampler variable * \param constant_index constant part of an array index (or 0, if the * sampler variable is not an array) * \param index non-constant part of an array index (may be NULL) * \param desc_type the type of descriptor to load + * \param image whether the descriptor is loaded for an image operation */ LLVMValueRef (*load_sampler_desc)(struct ac_shader_abi *abi, unsigned descriptor_set, unsigned base_index, unsigned constant_index, LLVMValueRef index, - enum ac_descriptor_type desc_type); + enum ac_descriptor_type desc_type, + bool image, bool write); }; #endif /* AC_SHADER_ABI_H */ diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index a278ef2..9ad68f4 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -339,21 +339,22 @@ static void declare_nir_input_fs(struct si_shader_context *ctx, } si_llvm_load_input_fs(ctx, *fs_attr_idx, out); (*fs_attr_idx)++; } static LLVMValueRef si_nir_load_sampler_desc(struct ac_shader_abi *abi, unsigned descriptor_set, unsigned base_index, unsigned constant_index, LLVMValueRef dynamic_index, - enum ac_descriptor_type desc_type) + enum ac_descriptor_type desc_type, bool image, + bool write) { struct si_shader_context *ctx = si_shader_context_from_abi(abi); LLVMBuilderRef builder = ctx->ac.builder; LLVMValueRef list = LLVMGetParam(ctx->main_fn, ctx->param_samplers_and_images); LLVMValueRef index = dynamic_index; assert(!descriptor_set); if (!index) index = ctx->ac.i32_0; -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev