From: Nicolai Hähnle <nicolai.haeh...@amd.com> Get most of the churn out of the way before actually loading samplers via the ABI. --- src/amd/common/ac_nir_to_llvm.c | 235 ++++++++++++++++++++-------------------- 1 file changed, 118 insertions(+), 117 deletions(-)
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 15285d6..5e85408 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -1009,21 +1009,21 @@ static LLVMValueRef llvm_extract_elem(struct ac_llvm_context *ac, int count = get_llvm_num_components(value); assert(index < count); if (count == 1) return value; return LLVMBuildExtractElement(ac->builder, value, LLVMConstInt(ac->i32, index, false), ""); } -static LLVMValueRef trim_vector(struct nir_to_llvm_context *ctx, +static LLVMValueRef trim_vector(struct ac_llvm_context *ctx, LLVMValueRef value, unsigned count) { unsigned num_components = get_llvm_num_components(value); if (count == num_components) return value; LLVMValueRef masks[] = { LLVMConstInt(ctx->i32, 0, false), LLVMConstInt(ctx->i32, 1, false), LLVMConstInt(ctx->i32, 2, false), LLVMConstInt(ctx->i32, 3, false)}; @@ -1906,41 +1906,41 @@ static void visit_load_const(struct ac_nir_context *ctx, static LLVMValueRef cast_ptr(struct nir_to_llvm_context *ctx, LLVMValueRef ptr, LLVMTypeRef type) { int addr_space = LLVMGetPointerAddressSpace(LLVMTypeOf(ptr)); return LLVMBuildBitCast(ctx->builder, ptr, LLVMPointerType(type, addr_space), ""); } static LLVMValueRef -get_buffer_size(struct nir_to_llvm_context *ctx, LLVMValueRef descriptor, bool in_elements) +get_buffer_size(struct ac_nir_context *ctx, LLVMValueRef descriptor, bool in_elements) { LLVMValueRef size = - LLVMBuildExtractElement(ctx->builder, descriptor, - LLVMConstInt(ctx->i32, 2, false), ""); + LLVMBuildExtractElement(ctx->ac.builder, descriptor, + LLVMConstInt(ctx->ac.i32, 2, false), ""); /* VI only */ - if (ctx->options->chip_class >= VI && in_elements) { + if (ctx->abi->chip_class >= VI && in_elements) { /* On VI, the descriptor contains the size in bytes, * but TXQ must return the size in elements. * The stride is always non-zero for resources using TXQ. */ LLVMValueRef stride = - LLVMBuildExtractElement(ctx->builder, descriptor, - LLVMConstInt(ctx->i32, 1, false), ""); - stride = LLVMBuildLShr(ctx->builder, stride, - LLVMConstInt(ctx->i32, 16, false), ""); - stride = LLVMBuildAnd(ctx->builder, stride, - LLVMConstInt(ctx->i32, 0x3fff, false), ""); + LLVMBuildExtractElement(ctx->ac.builder, descriptor, + LLVMConstInt(ctx->ac.i32, 1, false), ""); + stride = LLVMBuildLShr(ctx->ac.builder, stride, + LLVMConstInt(ctx->ac.i32, 16, false), ""); + stride = LLVMBuildAnd(ctx->ac.builder, stride, + LLVMConstInt(ctx->ac.i32, 0x3fff, false), ""); - size = LLVMBuildUDiv(ctx->builder, size, stride, ""); + size = LLVMBuildUDiv(ctx->ac.builder, size, stride, ""); } return size; } /** * Given the i32 or vNi32 \p type, generate the textual name (e.g. for use with * intrinsic names). */ static void build_int_type_name( LLVMTypeRef type, @@ -1948,48 +1948,48 @@ static void build_int_type_name( { assert(bufsize >= 6); if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) snprintf(buf, bufsize, "v%ui32", LLVMGetVectorSize(type)); else strcpy(buf, "i32"); } -static LLVMValueRef radv_lower_gather4_integer(struct nir_to_llvm_context *ctx, +static LLVMValueRef radv_lower_gather4_integer(struct ac_llvm_context *ctx, struct ac_image_args *args, const nir_tex_instr *instr) { enum glsl_base_type stype = glsl_get_sampler_result_type(instr->texture->var->type); LLVMValueRef coord = args->addr; LLVMValueRef half_texel[2]; LLVMValueRef compare_cube_wa; LLVMValueRef result; int c; unsigned coord_vgpr_index = (unsigned)args->offset + (unsigned)args->compare; //TODO Rect { struct ac_image_args txq_args = { 0 }; txq_args.da = instr->is_array || instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE; txq_args.opcode = ac_image_get_resinfo; txq_args.dmask = 0xf; - txq_args.addr = ctx->i32zero; + txq_args.addr = ctx->i32_0; txq_args.resource = args->resource; - LLVMValueRef size = ac_build_image_opcode(&ctx->ac, &txq_args); + LLVMValueRef size = ac_build_image_opcode(ctx, &txq_args); for (c = 0; c < 2; c++) { half_texel[c] = LLVMBuildExtractElement(ctx->builder, size, LLVMConstInt(ctx->i32, c, false), ""); half_texel[c] = LLVMBuildUIToFP(ctx->builder, half_texel[c], ctx->f32, ""); - half_texel[c] = ac_build_fdiv(&ctx->ac, ctx->f32one, half_texel[c]); + half_texel[c] = ac_build_fdiv(ctx, ctx->f32_1, half_texel[c]); half_texel[c] = LLVMBuildFMul(ctx->builder, half_texel[c], LLVMConstReal(ctx->f32, -0.5), ""); } } LLVMValueRef orig_coords = args->addr; for (c = 0; c < 2; c++) { LLVMValueRef tmp; LLVMValueRef index = LLVMConstInt(ctx->i32, coord_vgpr_index + c, 0); @@ -2011,50 +2011,50 @@ static LLVMValueRef radv_lower_gather4_integer(struct nir_to_llvm_context *ctx, * LLVM ends up dumping SGPRs into VGPRs to deal with the compare/select, * and then reads them back. -pro generates two selects, * one s_cmp for the descriptor rewriting * one v_cmp for the coordinate and result changes. */ if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) { LLVMValueRef tmp, tmp2; /* workaround 8/8/8/8 uint/sint cube gather bug */ /* first detect it then change to a scaled read and f2i */ - tmp = LLVMBuildExtractElement(ctx->builder, args->resource, ctx->i32one, ""); + tmp = LLVMBuildExtractElement(ctx->builder, args->resource, ctx->i32_1, ""); tmp2 = tmp; /* extract the DATA_FORMAT */ - tmp = ac_build_bfe(&ctx->ac, tmp, LLVMConstInt(ctx->i32, 20, false), + tmp = ac_build_bfe(ctx, tmp, LLVMConstInt(ctx->i32, 20, false), LLVMConstInt(ctx->i32, 6, false), false); /* is the DATA_FORMAT == 8_8_8_8 */ compare_cube_wa = LLVMBuildICmp(ctx->builder, LLVMIntEQ, tmp, LLVMConstInt(ctx->i32, V_008F14_IMG_DATA_FORMAT_8_8_8_8, false), ""); if (stype == GLSL_TYPE_UINT) /* Create a NUM FORMAT - 0x2 or 0x4 - USCALED or UINT */ tmp = LLVMBuildSelect(ctx->builder, compare_cube_wa, LLVMConstInt(ctx->i32, 0x8000000, false), LLVMConstInt(ctx->i32, 0x10000000, false), ""); else /* Create a NUM FORMAT - 0x3 or 0x5 - SSCALED or SINT */ tmp = LLVMBuildSelect(ctx->builder, compare_cube_wa, LLVMConstInt(ctx->i32, 0xc000000, false), LLVMConstInt(ctx->i32, 0x14000000, false), ""); /* replace the NUM FORMAT in the descriptor */ tmp2 = LLVMBuildAnd(ctx->builder, tmp2, LLVMConstInt(ctx->i32, C_008F14_NUM_FORMAT_GFX6, false), ""); tmp2 = LLVMBuildOr(ctx->builder, tmp2, tmp, ""); - args->resource = LLVMBuildInsertElement(ctx->builder, args->resource, tmp2, ctx->i32one, ""); + args->resource = LLVMBuildInsertElement(ctx->builder, args->resource, tmp2, ctx->i32_1, ""); /* don't modify the coordinates for this case */ coord = LLVMBuildSelect(ctx->builder, compare_cube_wa, orig_coords, coord, ""); } args->addr = coord; - result = ac_build_image_opcode(&ctx->ac, args); + result = ac_build_image_opcode(ctx, args); if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) { LLVMValueRef tmp, tmp2; /* if the cube workaround is in place, f2i the result. */ for (c = 0; c < 4; c++) { tmp = LLVMBuildExtractElement(ctx->builder, result, LLVMConstInt(ctx->i32, c, false), ""); if (stype == GLSL_TYPE_UINT) tmp2 = LLVMBuildFPToUI(ctx->builder, tmp, ctx->i32, ""); else @@ -2062,30 +2062,30 @@ static LLVMValueRef radv_lower_gather4_integer(struct nir_to_llvm_context *ctx, tmp = LLVMBuildBitCast(ctx->builder, tmp, ctx->i32, ""); tmp2 = LLVMBuildBitCast(ctx->builder, tmp2, ctx->i32, ""); tmp = LLVMBuildSelect(ctx->builder, compare_cube_wa, tmp2, tmp, ""); tmp = LLVMBuildBitCast(ctx->builder, tmp, ctx->f32, ""); result = LLVMBuildInsertElement(ctx->builder, result, tmp, LLVMConstInt(ctx->i32, c, false), ""); } } return result; } -static LLVMValueRef build_tex_intrinsic(struct nir_to_llvm_context *ctx, +static LLVMValueRef build_tex_intrinsic(struct ac_nir_context *ctx, const nir_tex_instr *instr, bool lod_is_zero, struct ac_image_args *args) { if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) { return ac_build_buffer_load_format(&ctx->ac, args->resource, args->addr, - LLVMConstInt(ctx->i32, 0, false), + LLVMConstInt(ctx->ac.i32, 0, false), true); } args->opcode = ac_image_sample; args->compare = instr->is_shadow; switch (instr->op) { case nir_texop_txf: case nir_texop_txf_ms: case nir_texop_samples_identical: @@ -2122,21 +2122,21 @@ static LLVMValueRef build_tex_intrinsic(struct nir_to_llvm_context *ctx, args->compare = false; args->offset = false; break; default: break; } if (instr->op == nir_texop_tg4) { enum glsl_base_type stype = glsl_get_sampler_result_type(instr->texture->var->type); if (stype == GLSL_TYPE_UINT || stype == GLSL_TYPE_INT) { - return radv_lower_gather4_integer(ctx, args, instr); + return radv_lower_gather4_integer(&ctx->ac, args, instr); } } return ac_build_image_opcode(&ctx->ac, args); } static LLVMValueRef visit_vulkan_resource_index(struct nir_to_llvm_context *ctx, nir_intrinsic_instr *instr) { LLVMValueRef index = get_src(ctx->nir, instr->src[0]); unsigned desc_set = nir_intrinsic_desc_set(instr); @@ -2175,24 +2175,24 @@ static LLVMValueRef visit_load_push_constant(struct nir_to_llvm_context *ctx, addr = LLVMConstInt(ctx->i32, nir_intrinsic_base(instr), 0); addr = LLVMBuildAdd(ctx->builder, addr, get_src(ctx->nir, instr->src[0]), ""); ptr = ac_build_gep0(&ctx->ac, ctx->push_constants, addr); ptr = cast_ptr(ctx, ptr, get_def_type(ctx->nir, &instr->dest.ssa)); return LLVMBuildLoad(ctx->builder, ptr, ""); } -static LLVMValueRef visit_get_buffer_size(struct nir_to_llvm_context *ctx, +static LLVMValueRef visit_get_buffer_size(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr) { - LLVMValueRef desc = get_src(ctx->nir, instr->src[0]); + LLVMValueRef desc = get_src(ctx, instr->src[0]); return get_buffer_size(ctx, desc, false); } static void visit_store_ssbo(struct nir_to_llvm_context *ctx, nir_intrinsic_instr *instr) { const char *store_name; LLVMValueRef src_data = get_src(ctx->nir, instr->src[0]); LLVMTypeRef data_type = ctx->f32; int elem_size_mult = get_elem_bits(&ctx->ac, LLVMTypeOf(src_data)) / 32; @@ -2206,21 +2206,21 @@ static void visit_store_ssbo(struct nir_to_llvm_context *ctx, params[1] = get_src(ctx->nir, instr->src[1]); params[2] = LLVMConstInt(ctx->i32, 0, false); /* vindex */ params[4] = ctx->i1false; /* glc */ params[5] = ctx->i1false; /* slc */ if (components_32bit > 1) data_type = LLVMVectorType(ctx->f32, components_32bit); base_data = to_float(&ctx->ac, src_data); - base_data = trim_vector(ctx, base_data, instr->num_components); + base_data = trim_vector(&ctx->ac, base_data, instr->num_components); base_data = LLVMBuildBitCast(ctx->builder, base_data, data_type, ""); base_offset = get_src(ctx->nir, instr->src[2]); /* voffset */ while (writemask) { int start, count; LLVMValueRef data; LLVMValueRef offset; LLVMValueRef tmp; u_bit_scan_consecutive_range(&writemask, &start, &count); @@ -2808,21 +2808,21 @@ load_tes_input(struct nir_to_llvm_context *ctx, if (instr->variables[0]->var->data.location == VARYING_SLOT_CLIP_DIST0 && is_compact && const_index > 3) { const_index -= 3; param++; } buf_addr = get_tcs_tes_buffer_address_params(ctx, param, const_index, is_compact, vertex_index, indir_index); result = ac_build_buffer_load(&ctx->ac, ctx->hs_ring_tess_offchip, instr->num_components, NULL, buf_addr, ctx->oc_lds, is_compact ? (4 * const_index) : 0, 1, 0, true, false); - result = trim_vector(ctx, result, instr->num_components); + result = trim_vector(&ctx->ac, result, instr->num_components); result = LLVMBuildBitCast(ctx->builder, result, get_def_type(ctx->nir, &instr->dest.ssa), ""); return result; } static LLVMValueRef load_gs_input(struct nir_to_llvm_context *ctx, nir_intrinsic_instr *instr) { LLVMValueRef indir_index, vtx_offset; unsigned const_index; @@ -3121,21 +3121,21 @@ static int image_type_to_components_count(enum glsl_sampler_dim dim, bool array) * should be fetched to get that sample. * * For example, 0x11111100 means there are only 2 samples stored and * the second sample covers 3/4 of the pixel. When reading samples 0 * and 1, return physical sample 0 (determined by the first two 0s * in FMASK), otherwise return physical sample 1. * * The sample index should be adjusted as follows: * sample_index = (fmask >> (sample_index * 4)) & 0xF; */ -static LLVMValueRef adjust_sample_index_using_fmask(struct nir_to_llvm_context *ctx, +static LLVMValueRef adjust_sample_index_using_fmask(struct ac_llvm_context *ctx, LLVMValueRef coord_x, LLVMValueRef coord_y, LLVMValueRef coord_z, LLVMValueRef sample_index, LLVMValueRef fmask_desc_ptr) { LLVMValueRef fmask_load_address[4]; LLVMValueRef res; fmask_load_address[0] = coord_x; fmask_load_address[1] = coord_y; @@ -3143,53 +3143,53 @@ static LLVMValueRef adjust_sample_index_using_fmask(struct nir_to_llvm_context * fmask_load_address[2] = coord_z; fmask_load_address[3] = LLVMGetUndef(ctx->i32); } struct ac_image_args args = {0}; args.opcode = ac_image_load; args.da = coord_z ? true : false; args.resource = fmask_desc_ptr; args.dmask = 0xf; - args.addr = ac_build_gather_values(&ctx->ac, fmask_load_address, coord_z ? 4 : 2); + args.addr = ac_build_gather_values(ctx, fmask_load_address, coord_z ? 4 : 2); - res = ac_build_image_opcode(&ctx->ac, &args); + res = ac_build_image_opcode(ctx, &args); - res = to_integer(&ctx->ac, res); + res = to_integer(ctx, res); LLVMValueRef four = LLVMConstInt(ctx->i32, 4, false); LLVMValueRef F = LLVMConstInt(ctx->i32, 0xf, false); LLVMValueRef fmask = LLVMBuildExtractElement(ctx->builder, res, - ctx->i32zero, ""); + ctx->i32_0, ""); LLVMValueRef sample_index4 = LLVMBuildMul(ctx->builder, sample_index, four, ""); LLVMValueRef shifted_fmask = LLVMBuildLShr(ctx->builder, fmask, sample_index4, ""); LLVMValueRef final_sample = LLVMBuildAnd(ctx->builder, shifted_fmask, F, ""); /* Don't rewrite the sample index if WORD1.DATA_FORMAT of the FMASK * resource descriptor is 0 (invalid), */ LLVMValueRef fmask_desc = LLVMBuildBitCast(ctx->builder, fmask_desc_ptr, ctx->v8i32, ""); LLVMValueRef fmask_word1 = LLVMBuildExtractElement(ctx->builder, fmask_desc, - ctx->i32one, ""); + ctx->i32_1, ""); LLVMValueRef word1_is_nonzero = LLVMBuildICmp(ctx->builder, LLVMIntNE, - fmask_word1, ctx->i32zero, ""); + fmask_word1, ctx->i32_0, ""); /* Replace the MSAA sample index. */ sample_index = LLVMBuildSelect(ctx->builder, word1_is_nonzero, final_sample, sample_index, ""); return sample_index; } static LLVMValueRef get_image_coords(struct nir_to_llvm_context *ctx, const nir_intrinsic_instr *instr) @@ -3224,21 +3224,21 @@ static LLVMValueRef get_image_coords(struct nir_to_llvm_context *ctx, fmask_load_address[0] = LLVMBuildExtractElement(ctx->builder, src0, masks[0], ""); fmask_load_address[1] = LLVMBuildExtractElement(ctx->builder, src0, masks[1], ""); if (glsl_sampler_type_is_array(type)) fmask_load_address[2] = LLVMBuildExtractElement(ctx->builder, src0, masks[2], ""); else fmask_load_address[2] = NULL; if (add_frag_pos) { for (chan = 0; chan < 2; ++chan) fmask_load_address[chan] = LLVMBuildAdd(ctx->builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->builder, ctx->frag_pos[chan], ctx->i32, ""), ""); } - sample_index = adjust_sample_index_using_fmask(ctx, + 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], DESC_FMASK)); } if (count == 1) { if (instr->src[0].ssa->num_components) res = LLVMBuildExtractElement(ctx->builder, src0, masks[0], ""); else @@ -3284,21 +3284,21 @@ static LLVMValueRef visit_image_load(struct nir_to_llvm_context *ctx, if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) { params[0] = get_sampler_desc(ctx, instr->variables[0], DESC_BUFFER); params[1] = LLVMBuildExtractElement(ctx->builder, get_src(ctx->nir, instr->src[0]), LLVMConstInt(ctx->i32, 0, false), ""); /* vindex */ params[2] = LLVMConstInt(ctx->i32, 0, false); /* voffset */ params[3] = ctx->i1false; /* glc */ params[4] = ctx->i1false; /* slc */ res = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.load.format.v4f32", ctx->v4f32, params, 5, 0); - res = trim_vector(ctx, res, instr->dest.ssa.num_components); + 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 ? ctx->i1true : ctx->i1false; LLVMValueRef glc = ctx->i1false; LLVMValueRef slc = ctx->i1false; params[0] = get_image_coords(ctx, instr); params[1] = get_sampler_desc(ctx, instr->variables[0], DESC_IMAGE); @@ -3452,51 +3452,51 @@ static LLVMValueRef visit_image_atomic(struct nir_to_llvm_context *ctx, abort(); } build_int_type_name(LLVMTypeOf(coords), coords_type, sizeof(coords_type)); snprintf(intrinsic_name, sizeof(intrinsic_name), "%s.%s.%s", base_name, atomic_name, coords_type); return ac_build_intrinsic(&ctx->ac, intrinsic_name, ctx->i32, params, param_count, 0); } -static LLVMValueRef visit_image_size(struct nir_to_llvm_context *ctx, +static LLVMValueRef visit_image_size(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr) { 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], DESC_BUFFER), true); + return get_buffer_size(ctx, get_sampler_desc(ctx->nctx, instr->variables[0], DESC_BUFFER), true); struct ac_image_args args = { 0 }; args.da = da; args.dmask = 0xf; - args.resource = get_sampler_desc(ctx, instr->variables[0], DESC_IMAGE); + args.resource = get_sampler_desc(ctx->nctx, instr->variables[0], DESC_IMAGE); args.opcode = ac_image_get_resinfo; - args.addr = ctx->i32zero; + 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->i32, 2, false); - LLVMValueRef six = LLVMConstInt(ctx->i32, 6, false); - LLVMValueRef z = LLVMBuildExtractElement(ctx->builder, res, two, ""); - z = LLVMBuildSDiv(ctx->builder, z, six, ""); - res = LLVMBuildInsertElement(ctx->builder, res, z, two, ""); + LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false); + LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false); + LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, res, two, ""); + z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); + res = LLVMBuildInsertElement(ctx->ac.builder, res, z, two, ""); } return res; } #define NOOP_WAITCNT 0xf7f #define LGKM_CNT 0x07f #define VM_CNT 0xf70 static void emit_waitcnt(struct nir_to_llvm_context *ctx, unsigned simm16) @@ -3951,21 +3951,21 @@ static void visit_intrinsic(struct ac_nir_context *ctx, case nir_intrinsic_ssbo_atomic_or: case nir_intrinsic_ssbo_atomic_xor: case nir_intrinsic_ssbo_atomic_exchange: case nir_intrinsic_ssbo_atomic_comp_swap: result = visit_atomic_ssbo(ctx->nctx, instr); break; case nir_intrinsic_load_ubo: result = visit_load_ubo_buffer(ctx, instr); break; case nir_intrinsic_get_buffer_size: - result = visit_get_buffer_size(ctx->nctx, instr); + result = visit_get_buffer_size(ctx, instr); break; case nir_intrinsic_load_var: result = visit_load_var(ctx, instr); break; case nir_intrinsic_store_var: visit_store_var(ctx, instr); break; case nir_intrinsic_image_load: result = visit_image_load(ctx->nctx, instr); break; @@ -3976,21 +3976,21 @@ static void visit_intrinsic(struct ac_nir_context *ctx, case nir_intrinsic_image_atomic_min: case nir_intrinsic_image_atomic_max: case nir_intrinsic_image_atomic_and: case nir_intrinsic_image_atomic_or: case nir_intrinsic_image_atomic_xor: case nir_intrinsic_image_atomic_exchange: case nir_intrinsic_image_atomic_comp_swap: result = visit_image_atomic(ctx->nctx, instr); break; case nir_intrinsic_image_size: - result = visit_image_size(ctx->nctx, instr); + result = visit_image_size(ctx, instr); break; case nir_intrinsic_discard: ctx->nctx->shader_info->fs.can_discard = true; ac_build_intrinsic(&ctx->ac, "llvm.AMDGPU.kilp", LLVMVoidTypeInContext(ctx->ac.context), NULL, 0, AC_FUNC_ATTR_LEGACY); break; case nir_intrinsic_discard_if: emit_discard_if(ctx->nctx, instr); break; @@ -4117,39 +4117,39 @@ static LLVMValueRef get_sampler_desc(struct nir_to_llvm_context *ctx, index = ctx->i32zero; 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 void set_tex_fetch_args(struct nir_to_llvm_context *ctx, +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) { unsigned is_rect = 0; bool da = instr->is_array || instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE; if (op == nir_texop_lod) da = false; /* Pad to power of two vector */ while (count < util_next_power_of_two(count)) param[count++] = LLVMGetUndef(ctx->i32); if (count > 1) - args->addr = ac_build_gather_values(&ctx->ac, param, count); + args->addr = ac_build_gather_values(ctx, param, count); else args->addr = param[0]; args->resource = res_ptr; args->sampler = samp_ptr; if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF && op == nir_texop_txf) { args->addr = param[0]; return; } @@ -4203,140 +4203,141 @@ static void tex_fetch_ptrs(struct nir_to_llvm_context *ctx, else *samp_ptr = get_sampler_desc(ctx, instr->texture, DESC_SAMPLER); 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, DESC_FMASK); } -static LLVMValueRef apply_round_slice(struct nir_to_llvm_context *ctx, +static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx, LLVMValueRef coord) { - coord = to_float(&ctx->ac, coord); - coord = ac_build_intrinsic(&ctx->ac, "llvm.rint.f32", ctx->f32, &coord, 1, 0); - coord = to_integer(&ctx->ac, 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; } -static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr) +static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr) { LLVMValueRef result = NULL; struct ac_image_args args = { 0 }; unsigned dmask = 0xf; LLVMValueRef address[16]; LLVMValueRef coords[5]; LLVMValueRef coord = NULL, lod = NULL, comparator = NULL; LLVMValueRef bias = NULL, offsets = NULL; LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL, sample_index = NULL; LLVMValueRef ddx = NULL, ddy = NULL; LLVMValueRef derivs[6]; unsigned chan, count = 0; unsigned const_src = 0, num_deriv_comp = 0; bool lod_is_zero = false; - tex_fetch_ptrs(ctx, instr, &res_ptr, &samp_ptr, &fmask_ptr); + + tex_fetch_ptrs(ctx->nctx, instr, &res_ptr, &samp_ptr, &fmask_ptr); for (unsigned i = 0; i < instr->num_srcs; i++) { switch (instr->src[i].src_type) { case nir_tex_src_coord: - coord = get_src(ctx->nir, instr->src[i].src); + coord = get_src(ctx, instr->src[i].src); break; case nir_tex_src_projector: break; case nir_tex_src_comparator: - comparator = get_src(ctx->nir, instr->src[i].src); + comparator = get_src(ctx, instr->src[i].src); break; case nir_tex_src_offset: - offsets = get_src(ctx->nir, instr->src[i].src); + offsets = get_src(ctx, instr->src[i].src); const_src = i; break; case nir_tex_src_bias: - bias = get_src(ctx->nir, instr->src[i].src); + bias = get_src(ctx, instr->src[i].src); break; case nir_tex_src_lod: { nir_const_value *val = nir_src_as_const_value(instr->src[i].src); if (val && val->i32[0] == 0) lod_is_zero = true; - lod = get_src(ctx->nir, instr->src[i].src); + lod = get_src(ctx, instr->src[i].src); break; } case nir_tex_src_ms_index: - sample_index = get_src(ctx->nir, instr->src[i].src); + sample_index = get_src(ctx, instr->src[i].src); break; case nir_tex_src_ms_mcs: break; case nir_tex_src_ddx: - ddx = get_src(ctx->nir, instr->src[i].src); + ddx = get_src(ctx, instr->src[i].src); num_deriv_comp = instr->src[i].src.ssa->num_components; break; case nir_tex_src_ddy: - ddy = get_src(ctx->nir, instr->src[i].src); + ddy = get_src(ctx, instr->src[i].src); break; case nir_tex_src_texture_offset: case nir_tex_src_sampler_offset: case nir_tex_src_plane: default: break; } } if (instr->op == nir_texop_txs && instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) { result = get_buffer_size(ctx, res_ptr, true); goto write_result; } if (instr->op == nir_texop_texture_samples) { LLVMValueRef res, samples, is_msaa; - res = LLVMBuildBitCast(ctx->builder, res_ptr, ctx->v8i32, ""); - samples = LLVMBuildExtractElement(ctx->builder, res, - LLVMConstInt(ctx->i32, 3, false), ""); - is_msaa = LLVMBuildLShr(ctx->builder, samples, - LLVMConstInt(ctx->i32, 28, false), ""); - is_msaa = LLVMBuildAnd(ctx->builder, is_msaa, - LLVMConstInt(ctx->i32, 0xe, false), ""); - is_msaa = LLVMBuildICmp(ctx->builder, LLVMIntEQ, is_msaa, - LLVMConstInt(ctx->i32, 0xe, false), ""); - - samples = LLVMBuildLShr(ctx->builder, samples, - LLVMConstInt(ctx->i32, 16, false), ""); - samples = LLVMBuildAnd(ctx->builder, samples, - LLVMConstInt(ctx->i32, 0xf, false), ""); - samples = LLVMBuildShl(ctx->builder, ctx->i32one, + res = LLVMBuildBitCast(ctx->ac.builder, res_ptr, ctx->ac.v8i32, ""); + samples = LLVMBuildExtractElement(ctx->ac.builder, res, + LLVMConstInt(ctx->ac.i32, 3, false), ""); + is_msaa = LLVMBuildLShr(ctx->ac.builder, samples, + LLVMConstInt(ctx->ac.i32, 28, false), ""); + is_msaa = LLVMBuildAnd(ctx->ac.builder, is_msaa, + LLVMConstInt(ctx->ac.i32, 0xe, false), ""); + is_msaa = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, is_msaa, + LLVMConstInt(ctx->ac.i32, 0xe, false), ""); + + samples = LLVMBuildLShr(ctx->ac.builder, samples, + LLVMConstInt(ctx->ac.i32, 16, false), ""); + samples = LLVMBuildAnd(ctx->ac.builder, samples, + LLVMConstInt(ctx->ac.i32, 0xf, false), ""); + samples = LLVMBuildShl(ctx->ac.builder, ctx->ac.i32_1, samples, ""); - samples = LLVMBuildSelect(ctx->builder, is_msaa, samples, - ctx->i32one, ""); + samples = LLVMBuildSelect(ctx->ac.builder, is_msaa, samples, + ctx->ac.i32_1, ""); result = samples; goto write_result; } if (coord) for (chan = 0; chan < instr->coord_components; chan++) coords[chan] = llvm_extract_elem(&ctx->ac, coord, chan); if (offsets && instr->op != nir_texop_txf) { LLVMValueRef offset[3], pack; for (chan = 0; chan < 3; ++chan) - offset[chan] = ctx->i32zero; + offset[chan] = ctx->ac.i32_0; args.offset = true; for (chan = 0; chan < get_llvm_num_components(offsets); chan++) { offset[chan] = llvm_extract_elem(&ctx->ac, offsets, chan); - offset[chan] = LLVMBuildAnd(ctx->builder, offset[chan], - LLVMConstInt(ctx->i32, 0x3f, false), ""); + offset[chan] = LLVMBuildAnd(ctx->ac.builder, offset[chan], + LLVMConstInt(ctx->ac.i32, 0x3f, false), ""); if (chan) - offset[chan] = LLVMBuildShl(ctx->builder, offset[chan], - LLVMConstInt(ctx->i32, chan * 8, false), ""); + offset[chan] = LLVMBuildShl(ctx->ac.builder, offset[chan], + LLVMConstInt(ctx->ac.i32, chan * 8, false), ""); } - pack = LLVMBuildOr(ctx->builder, offset[0], offset[1], ""); - pack = LLVMBuildOr(ctx->builder, pack, offset[2], ""); + pack = LLVMBuildOr(ctx->ac.builder, offset[0], offset[1], ""); + pack = LLVMBuildOr(ctx->ac.builder, pack, offset[2], ""); address[count++] = pack; } /* pack LOD bias value */ if (instr->op == nir_texop_txb && bias) { address[count++] = bias; } /* Pack depth comparison value */ if (instr->is_shadow && comparator) { @@ -4360,157 +4361,157 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr) } for (unsigned i = 0; i < num_deriv_comp; i++) { derivs[i] = to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddx, i)); derivs[num_deriv_comp + i] = to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddy, i)); } } if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE && coord) { if (instr->is_array && instr->op != nir_texop_lod) - coords[3] = apply_round_slice(ctx, coords[3]); + coords[3] = apply_round_slice(&ctx->ac, coords[3]); for (chan = 0; chan < instr->coord_components; chan++) coords[chan] = to_float(&ctx->ac, coords[chan]); if (instr->coord_components == 3) - coords[3] = LLVMGetUndef(ctx->f32); + coords[3] = LLVMGetUndef(ctx->ac.f32); ac_prepare_cube_coords(&ctx->ac, instr->op == nir_texop_txd, instr->is_array, coords, derivs); if (num_deriv_comp) num_deriv_comp--; } if (ddx || ddy) { for (unsigned i = 0; i < num_deriv_comp * 2; i++) address[count++] = derivs[i]; } /* Pack texture coordinates */ if (coord) { address[count++] = coords[0]; if (instr->coord_components > 1) { if (instr->sampler_dim == GLSL_SAMPLER_DIM_1D && instr->is_array && instr->op != nir_texop_txf) { - coords[1] = apply_round_slice(ctx, coords[1]); + coords[1] = apply_round_slice(&ctx->ac, coords[1]); } address[count++] = coords[1]; } if (instr->coord_components > 2) { /* This seems like a bit of a hack - but it passes Vulkan CTS with it */ if (instr->sampler_dim != GLSL_SAMPLER_DIM_3D && instr->sampler_dim != GLSL_SAMPLER_DIM_CUBE && instr->op != nir_texop_txf) { - coords[2] = apply_round_slice(ctx, coords[2]); + coords[2] = apply_round_slice(&ctx->ac, coords[2]); } address[count++] = coords[2]; } } /* Pack LOD */ if (lod && ((instr->op == nir_texop_txl && !lod_is_zero) || instr->op == nir_texop_txf)) { address[count++] = lod; } else if (instr->op == nir_texop_txf_ms && sample_index) { address[count++] = sample_index; } else if(instr->op == nir_texop_txs) { count = 0; if (lod) address[count++] = lod; else - address[count++] = ctx->i32zero; + address[count++] = ctx->ac.i32_0; } for (chan = 0; chan < count; chan++) { - address[chan] = LLVMBuildBitCast(ctx->builder, - address[chan], ctx->i32, ""); + address[chan] = LLVMBuildBitCast(ctx->ac.builder, + address[chan], ctx->ac.i32, ""); } if (instr->op == nir_texop_samples_identical) { LLVMValueRef txf_address[4]; struct ac_image_args txf_args = { 0 }; unsigned txf_count = count; memcpy(txf_address, address, sizeof(txf_address)); if (!instr->is_array) - txf_address[2] = ctx->i32zero; - txf_address[3] = ctx->i32zero; + txf_address[2] = ctx->ac.i32_0; + txf_address[3] = ctx->ac.i32_0; - set_tex_fetch_args(ctx, &txf_args, instr, nir_texop_txf, + set_tex_fetch_args(&ctx->ac, &txf_args, instr, nir_texop_txf, fmask_ptr, NULL, txf_address, txf_count, 0xf); result = build_tex_intrinsic(ctx, instr, false, &txf_args); - result = LLVMBuildExtractElement(ctx->builder, result, ctx->i32zero, ""); - result = emit_int_cmp(&ctx->ac, LLVMIntEQ, result, ctx->i32zero); + result = LLVMBuildExtractElement(ctx->ac.builder, result, ctx->ac.i32_0, ""); + result = emit_int_cmp(&ctx->ac, LLVMIntEQ, result, ctx->ac.i32_0); goto write_result; } if (instr->sampler_dim == GLSL_SAMPLER_DIM_MS && instr->op != nir_texop_txs) { unsigned sample_chan = instr->is_array ? 3 : 2; - address[sample_chan] = adjust_sample_index_using_fmask(ctx, + address[sample_chan] = adjust_sample_index_using_fmask(&ctx->ac, address[0], address[1], instr->is_array ? address[2] : NULL, address[sample_chan], fmask_ptr); } if (offsets && instr->op == nir_texop_txf) { nir_const_value *const_offset = nir_src_as_const_value(instr->src[const_src].src); int num_offsets = instr->src[const_src].src.ssa->num_components; assert(const_offset); num_offsets = MIN2(num_offsets, instr->coord_components); if (num_offsets > 2) - address[2] = LLVMBuildAdd(ctx->builder, - address[2], LLVMConstInt(ctx->i32, const_offset->i32[2], false), ""); + address[2] = LLVMBuildAdd(ctx->ac.builder, + address[2], LLVMConstInt(ctx->ac.i32, const_offset->i32[2], false), ""); if (num_offsets > 1) - address[1] = LLVMBuildAdd(ctx->builder, - address[1], LLVMConstInt(ctx->i32, const_offset->i32[1], false), ""); - address[0] = LLVMBuildAdd(ctx->builder, - address[0], LLVMConstInt(ctx->i32, const_offset->i32[0], false), ""); + address[1] = LLVMBuildAdd(ctx->ac.builder, + address[1], LLVMConstInt(ctx->ac.i32, const_offset->i32[1], false), ""); + address[0] = LLVMBuildAdd(ctx->ac.builder, + address[0], LLVMConstInt(ctx->ac.i32, const_offset->i32[0], false), ""); } /* TODO TG4 support */ if (instr->op == nir_texop_tg4) { if (instr->is_shadow) dmask = 1; else dmask = 1 << instr->component; } - set_tex_fetch_args(ctx, &args, instr, instr->op, + set_tex_fetch_args(&ctx->ac, &args, instr, instr->op, res_ptr, samp_ptr, address, count, dmask); result = build_tex_intrinsic(ctx, instr, lod_is_zero, &args); if (instr->op == nir_texop_query_levels) - result = LLVMBuildExtractElement(ctx->builder, result, LLVMConstInt(ctx->i32, 3, false), ""); + result = LLVMBuildExtractElement(ctx->ac.builder, result, LLVMConstInt(ctx->ac.i32, 3, false), ""); else if (instr->is_shadow && instr->op != nir_texop_txs && instr->op != nir_texop_lod && instr->op != nir_texop_tg4) - result = LLVMBuildExtractElement(ctx->builder, result, ctx->i32zero, ""); + result = LLVMBuildExtractElement(ctx->ac.builder, result, ctx->ac.i32_0, ""); else if (instr->op == nir_texop_txs && instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE && instr->is_array) { - LLVMValueRef two = LLVMConstInt(ctx->i32, 2, false); - LLVMValueRef six = LLVMConstInt(ctx->i32, 6, false); - LLVMValueRef z = LLVMBuildExtractElement(ctx->builder, result, two, ""); - z = LLVMBuildSDiv(ctx->builder, z, six, ""); - result = LLVMBuildInsertElement(ctx->builder, result, z, two, ""); + LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false); + LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false); + LLVMValueRef z = LLVMBuildExtractElement(ctx->ac.builder, result, two, ""); + z = LLVMBuildSDiv(ctx->ac.builder, z, six, ""); + result = LLVMBuildInsertElement(ctx->ac.builder, result, z, two, ""); } else if (instr->dest.ssa.num_components != 4) - result = trim_vector(ctx, result, instr->dest.ssa.num_components); + result = trim_vector(&ctx->ac, result, instr->dest.ssa.num_components); write_result: if (result) { assert(instr->dest.is_ssa); result = to_integer(&ctx->ac, result); - _mesa_hash_table_insert(ctx->nir->defs, &instr->dest.ssa, result); + _mesa_hash_table_insert(ctx->defs, &instr->dest.ssa, result); } } static void visit_phi(struct ac_nir_context *ctx, nir_phi_instr *instr) { LLVMTypeRef type = get_def_type(ctx, &instr->dest.ssa); LLVMValueRef result = LLVMBuildPhi(ctx->ac.builder, type, ""); _mesa_hash_table_insert(ctx->defs, &instr->dest.ssa, result); @@ -4585,21 +4586,21 @@ static void visit_block(struct ac_nir_context *ctx, nir_block *block) case nir_instr_type_alu: visit_alu(ctx, nir_instr_as_alu(instr)); break; case nir_instr_type_load_const: visit_load_const(ctx, nir_instr_as_load_const(instr)); break; case nir_instr_type_intrinsic: visit_intrinsic(ctx, nir_instr_as_intrinsic(instr)); break; case nir_instr_type_tex: - visit_tex(ctx->nctx, nir_instr_as_tex(instr)); + visit_tex(ctx, nir_instr_as_tex(instr)); break; case nir_instr_type_phi: visit_phi(ctx, nir_instr_as_phi(instr)); break; case nir_instr_type_ssa_undef: visit_ssa_undef(ctx, nir_instr_as_ssa_undef(instr)); break; case nir_instr_type_jump: visit_jump(ctx, nir_instr_as_jump(instr)); break; -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev