LLVMValueRef gs2vs_offset;
LLVMValueRef gs_wave_id;
LLVMValueRef gs_vtx_offset[6];
- LLVMValueRef gs_prim_id, gs_invocation_id;
LLVMValueRef esgs_ring;
LLVMValueRef gsvs_ring;
LLVMValueRef persp_sample, persp_center, persp_centroid;
LLVMValueRef linear_sample, linear_center, linear_centroid;
- LLVMTypeRef i16;
- LLVMTypeRef i64;
- LLVMTypeRef v2i32;
- LLVMTypeRef v3i32;
- LLVMTypeRef v4i32;
- LLVMTypeRef v8i32;
- LLVMTypeRef f64;
- LLVMTypeRef f32;
- LLVMTypeRef f16;
- LLVMTypeRef v2f32;
- LLVMTypeRef v4f32;
-
- unsigned uniform_md_kind;
- LLVMValueRef empty_md;
gl_shader_stage stage;
LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS * 4];
unsigned tes_primitive_mode;
uint64_t tess_outputs_written;
uint64_t tess_patch_outputs_written;
+
+ uint32_t tcs_patch_outputs_read;
+ uint64_t tcs_outputs_read;
};
static inline struct nir_to_llvm_context *
return container_of(abi, ctx, abi);
}
+static LLVMTypeRef
+nir2llvmtype(struct ac_nir_context *ctx,
+ const struct glsl_type *type)
+{
+ switch (glsl_get_base_type(glsl_without_array(type))) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ return ctx->ac.i32;
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64:
+ return ctx->ac.i64;
+ case GLSL_TYPE_DOUBLE:
+ return ctx->ac.f64;
+ case GLSL_TYPE_FLOAT:
+ return ctx->ac.f32;
+ default:
+ assert(!"Unsupported type in nir2llvmtype()");
+ break;
+ }
+ return 0;
+}
+
static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
const nir_deref_var *deref,
enum ac_descriptor_type desc_type,
switch (ctx->stage) {
case MESA_SHADER_COMPUTE:
- user_sgpr_info->sgpr_count += ctx->shader_info->info.cs.grid_components_used;
+ if (ctx->shader_info->info.cs.uses_grid_size)
+ user_sgpr_info->sgpr_count += 3;
break;
case MESA_SHADER_FRAGMENT:
user_sgpr_info->sgpr_count += ctx->shader_info->info.ps.needs_sample_positions;
{
if (!ctx->is_gs_copy_shader && (stage == MESA_SHADER_VERTEX || (has_previous_stage && previous_stage == MESA_SHADER_VERTEX))) {
if (ctx->shader_info->info.vs.has_vertex_buffers)
- add_user_sgpr_argument(args, const_array(ctx->v4i32, 16), &ctx->vertex_buffers); /* vertex buffers */
+ add_user_sgpr_argument(args, const_array(ctx->ac.v4i32, 16), &ctx->vertex_buffers); /* vertex buffers */
add_user_sgpr_argument(args, ctx->ac.i32, &ctx->abi.base_vertex); // base vertex
add_user_sgpr_argument(args, ctx->ac.i32, &ctx->abi.start_instance);// start instance
if (ctx->shader_info->info.vs.needs_draw_id)
allocate_user_sgprs(ctx, &user_sgpr_info);
if (user_sgpr_info.need_ring_offsets && !ctx->options->supports_spill) {
- add_user_sgpr_argument(&args, const_array(ctx->v4i32, 16), &ctx->ring_offsets); /* address of rings */
+ add_user_sgpr_argument(&args, const_array(ctx->ac.v4i32, 16), &ctx->ring_offsets); /* address of rings */
}
switch (stage) {
case MESA_SHADER_COMPUTE:
radv_define_common_user_sgprs_phase1(ctx, stage, has_previous_stage, previous_stage, &user_sgpr_info, &args, &desc_sets);
- if (ctx->shader_info->info.cs.grid_components_used)
- add_user_sgpr_argument(&args, LLVMVectorType(ctx->ac.i32, ctx->shader_info->info.cs.grid_components_used), &ctx->num_work_groups); /* grid size */
- add_sgpr_argument(&args, LLVMVectorType(ctx->ac.i32, 3), &ctx->workgroup_ids);
+ if (ctx->shader_info->info.cs.uses_grid_size) {
+ add_user_sgpr_argument(&args, ctx->ac.v3i32,
+ &ctx->num_work_groups);
+ }
+ add_sgpr_argument(&args, ctx->ac.v3i32, &ctx->workgroup_ids);
add_sgpr_argument(&args, ctx->ac.i32, &ctx->tg_size);
- add_vgpr_argument(&args, LLVMVectorType(ctx->ac.i32, 3), &ctx->local_invocation_ids);
+ add_vgpr_argument(&args, ctx->ac.v3i32, &ctx->local_invocation_ids);
break;
case MESA_SHADER_VERTEX:
radv_define_common_user_sgprs_phase1(ctx, stage, has_previous_stage, previous_stage, &user_sgpr_info, &args, &desc_sets);
add_sgpr_argument(&args, ctx->ac.i32, NULL); //
add_sgpr_argument(&args, ctx->ac.i32, &ctx->oc_lds); // OC LDS
}
- add_vgpr_argument(&args, ctx->f32, &ctx->tes_u); // tes_u
- add_vgpr_argument(&args, ctx->f32, &ctx->tes_v); // tes_v
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->tes_u); // tes_u
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->tes_v); // tes_v
add_vgpr_argument(&args, ctx->ac.i32, &ctx->tes_rel_patch_id); // tes rel patch id
add_vgpr_argument(&args, ctx->ac.i32, &ctx->tes_patch_id); // tes patch id
break;
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[0]); // vtx01
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[2]); // vtx23
- add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_prim_id); // prim id
- add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_invocation_id);
+ add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.gs_prim_id); // prim id
+ add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.gs_invocation_id);
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[4]);
if (previous_stage == MESA_SHADER_VERTEX) {
add_vgpr_argument(&args, ctx->ac.i32, &ctx->vs_prim_id); // vs prim id
add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.instance_id); // instance id
} else {
- add_vgpr_argument(&args, ctx->f32, &ctx->tes_u); // tes_u
- add_vgpr_argument(&args, ctx->f32, &ctx->tes_v); // tes_v
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->tes_u); // tes_u
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->tes_v); // tes_v
add_vgpr_argument(&args, ctx->ac.i32, &ctx->tes_rel_patch_id); // tes rel patch id
add_vgpr_argument(&args, ctx->ac.i32, &ctx->tes_patch_id); // tes patch id
}
add_sgpr_argument(&args, ctx->ac.i32, &ctx->gs_wave_id); // wave id
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[0]); // vtx0
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[1]); // vtx1
- add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_prim_id); // prim id
+ add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.gs_prim_id); // prim id
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[2]);
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[3]);
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[4]);
add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_vtx_offset[5]);
- add_vgpr_argument(&args, ctx->ac.i32, &ctx->gs_invocation_id);
+ add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.gs_invocation_id);
}
break;
case MESA_SHADER_FRAGMENT:
if (ctx->shader_info->info.ps.needs_sample_positions)
add_user_sgpr_argument(&args, ctx->ac.i32, &ctx->sample_pos_offset); /* sample position offset */
add_sgpr_argument(&args, ctx->ac.i32, &ctx->prim_mask); /* prim mask */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_sample); /* persp sample */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_center); /* persp center */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_centroid); /* persp centroid */
- add_vgpr_argument(&args, ctx->v3i32, NULL); /* persp pull model */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_sample); /* linear sample */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_center); /* linear center */
- add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_centroid); /* linear centroid */
- add_vgpr_argument(&args, ctx->f32, NULL); /* line stipple tex */
- add_vgpr_argument(&args, ctx->f32, &ctx->abi.frag_pos[0]); /* pos x float */
- add_vgpr_argument(&args, ctx->f32, &ctx->abi.frag_pos[1]); /* pos y float */
- add_vgpr_argument(&args, ctx->f32, &ctx->abi.frag_pos[2]); /* pos z float */
- add_vgpr_argument(&args, ctx->f32, &ctx->abi.frag_pos[3]); /* pos w float */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->persp_sample); /* persp sample */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->persp_center); /* persp center */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->persp_centroid); /* persp centroid */
+ add_vgpr_argument(&args, ctx->ac.v3i32, NULL); /* persp pull model */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->linear_sample); /* linear sample */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->linear_center); /* linear center */
+ add_vgpr_argument(&args, ctx->ac.v2i32, &ctx->linear_centroid); /* linear centroid */
+ add_vgpr_argument(&args, ctx->ac.f32, NULL); /* line stipple tex */
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->abi.frag_pos[0]); /* pos x float */
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->abi.frag_pos[1]); /* pos y float */
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->abi.frag_pos[2]); /* pos z float */
+ add_vgpr_argument(&args, ctx->ac.f32, &ctx->abi.frag_pos[3]); /* pos w float */
add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.front_face); /* front face */
add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.ancillary); /* ancillary */
add_vgpr_argument(&args, ctx->ac.i32, &ctx->abi.sample_coverage); /* sample coverage */
LLVMPointerType(ctx->ac.i8, CONST_ADDR_SPACE),
NULL, 0, AC_FUNC_ATTR_READNONE);
ctx->ring_offsets = LLVMBuildBitCast(ctx->builder, ctx->ring_offsets,
- const_array(ctx->v4i32, 16), "");
+ const_array(ctx->ac.v4i32, 16), "");
}
}
switch (stage) {
case MESA_SHADER_COMPUTE:
- if (ctx->shader_info->info.cs.grid_components_used) {
- set_userdata_location_shader(ctx, AC_UD_CS_GRID_SIZE, &user_sgpr_idx, ctx->shader_info->info.cs.grid_components_used);
+ if (ctx->shader_info->info.cs.uses_grid_size) {
+ set_userdata_location_shader(ctx, AC_UD_CS_GRID_SIZE,
+ &user_sgpr_idx, 3);
}
break;
case MESA_SHADER_VERTEX:
ctx->shader_info->num_user_sgprs = user_sgpr_idx;
}
-static void setup_types(struct nir_to_llvm_context *ctx)
-{
- ctx->i16 = LLVMIntTypeInContext(ctx->context, 16);
- ctx->i64 = LLVMIntTypeInContext(ctx->context, 64);
- ctx->v2i32 = LLVMVectorType(ctx->ac.i32, 2);
- ctx->v3i32 = LLVMVectorType(ctx->ac.i32, 3);
- ctx->v4i32 = LLVMVectorType(ctx->ac.i32, 4);
- ctx->v8i32 = LLVMVectorType(ctx->ac.i32, 8);
- ctx->f32 = LLVMFloatTypeInContext(ctx->context);
- ctx->f16 = LLVMHalfTypeInContext(ctx->context);
- ctx->f64 = LLVMDoubleTypeInContext(ctx->context);
- ctx->v2f32 = LLVMVectorType(ctx->f32, 2);
- ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
-
- ctx->uniform_md_kind =
- LLVMGetMDKindIDInContext(ctx->context, "amdgpu.uniform", 14);
- ctx->empty_md = LLVMMDNodeInContext(ctx->context, NULL, 0);
-}
-
static int get_llvm_num_components(LLVMValueRef value)
{
LLVMTypeRef type = LLVMTypeOf(value);
LLVMValueRef cond = NULL;
src0 = ac_to_float(&ctx->ac, src0);
- result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->f16, "");
+ result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->ac.f16, "");
if (ctx->options->chip_class >= VI) {
LLVMValueRef args[2];
}
/* need to convert back up to f32 */
- result = LLVMBuildFPExt(ctx->builder, result, ctx->f32, "");
+ result = LLVMBuildFPExt(ctx->builder, result, ctx->ac.f32, "");
if (ctx->options->chip_class >= VI)
result = LLVMBuildSelect(ctx->builder, cond, ctx->ac.f32_0, result, "");
*/
LLVMValueRef temp, cond2;
temp = emit_intrin_1f_param(&ctx->ac, "llvm.fabs",
- ctx->f32, result);
+ ctx->ac.f32, result);
cond = LLVMBuildFCmp(ctx->builder, LLVMRealUGT,
- LLVMBuildBitCast(ctx->builder, LLVMConstInt(ctx->ac.i32, 0x38800000, false), ctx->f32, ""),
+ LLVMBuildBitCast(ctx->builder, LLVMConstInt(ctx->ac.i32, 0x38800000, false), ctx->ac.f32, ""),
temp, "");
cond2 = LLVMBuildFCmp(ctx->builder, LLVMRealUNE,
temp, ctx->ac.f32_0, "");
static LLVMValueRef emit_pack_half_2x16(struct ac_llvm_context *ctx,
LLVMValueRef src0)
{
- LLVMValueRef const16 = LLVMConstInt(ctx->i32, 16, false);
- int i;
LLVMValueRef comp[2];
src0 = ac_to_float(ctx, src0);
comp[0] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_0, "");
comp[1] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_1, "");
- for (i = 0; i < 2; i++) {
- comp[i] = LLVMBuildFPTrunc(ctx->builder, comp[i], ctx->f16, "");
- comp[i] = LLVMBuildBitCast(ctx->builder, comp[i], ctx->i16, "");
- comp[i] = LLVMBuildZExt(ctx->builder, comp[i], ctx->i32, "");
- }
- comp[1] = LLVMBuildShl(ctx->builder, comp[1], const16, "");
- comp[0] = LLVMBuildOr(ctx->builder, comp[0], comp[1], "");
-
- return comp[0];
+ return ac_build_cvt_pkrtz_f16(ctx, comp);
}
static LLVMValueRef emit_unpack_half_2x16(struct ac_llvm_context *ctx,
temps[i] = LLVMBuildFPExt(ctx->builder, val, ctx->f32, "");
}
- LLVMTypeRef v2f32 = LLVMVectorType(ctx->f32, 2);
- result = LLVMBuildInsertElement(ctx->builder, LLVMGetUndef(v2f32), temps[0],
+ result = LLVMBuildInsertElement(ctx->builder, LLVMGetUndef(ctx->v2f32), temps[0],
ctx->i32_0, "");
result = LLVMBuildInsertElement(ctx->builder, result, temps[1],
ctx->i32_1, "");
result = LLVMBuildUIToFP(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break;
case nir_op_f2f64:
+ src[0] = ac_to_float(&ctx->ac, src[0]);
result = LLVMBuildFPExt(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break;
case nir_op_f2f32:
case nir_op_unpack_64_2x32_split_x: {
assert(instr->src[0].src.ssa->num_components == 1);
LLVMValueRef tmp = LLVMBuildBitCast(ctx->ac.builder, src[0],
- LLVMVectorType(ctx->ac.i32, 2),
+ ctx->ac.v2i32,
"");
result = LLVMBuildExtractElement(ctx->ac.builder, tmp,
ctx->ac.i32_0, "");
case nir_op_unpack_64_2x32_split_y: {
assert(instr->src[0].src.ssa->num_components == 1);
LLVMValueRef tmp = LLVMBuildBitCast(ctx->ac.builder, src[0],
- LLVMVectorType(ctx->ac.i32, 2),
+ ctx->ac.v2i32,
"");
result = LLVMBuildExtractElement(ctx->ac.builder, tmp,
ctx->ac.i32_1, "");
}
case nir_op_pack_64_2x32_split: {
- LLVMValueRef tmp = LLVMGetUndef(LLVMVectorType(ctx->ac.i32, 2));
+ LLVMValueRef tmp = LLVMGetUndef(ctx->ac.v2i32);
tmp = LLVMBuildInsertElement(ctx->ac.builder, tmp,
src[0], ctx->ac.i32_0, "");
tmp = LLVMBuildInsertElement(ctx->ac.builder, tmp,
offset = LLVMBuildAdd(ctx->builder, offset, index, "");
desc_ptr = ac_build_gep0(&ctx->ac, desc_ptr, offset);
- desc_ptr = cast_ptr(ctx, desc_ptr, ctx->v4i32);
- LLVMSetMetadata(desc_ptr, ctx->uniform_md_kind, ctx->empty_md);
+ desc_ptr = cast_ptr(ctx, desc_ptr, ctx->ac.v4i32);
+ LLVMSetMetadata(desc_ptr, ctx->ac.uniform_md_kind, ctx->ac.empty_md);
+
+ return desc_ptr;
+}
+
+static LLVMValueRef visit_vulkan_resource_reindex(struct nir_to_llvm_context *ctx,
+ nir_intrinsic_instr *instr)
+{
+ LLVMValueRef ptr = get_src(ctx->nir, instr->src[0]);
+ LLVMValueRef index = get_src(ctx->nir, instr->src[1]);
- return LLVMBuildLoad(ctx->builder, desc_ptr, "");
+ LLVMValueRef result = LLVMBuildGEP(ctx->builder, ptr, &index, 1, "");
+ LLVMSetMetadata(result, ctx->ac.uniform_md_kind, ctx->ac.empty_md);
+ return result;
}
static LLVMValueRef visit_load_push_constant(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, instr->src[0]);
+ LLVMValueRef ptr = get_src(ctx, instr->src[0]);
- return get_buffer_size(ctx, desc, false);
+ return get_buffer_size(ctx, LLVMBuildLoad(ctx->ac.builder, ptr, ""), false);
}
static void visit_store_ssbo(struct ac_nir_context *ctx,
nir_intrinsic_instr *instr)
store_name = "llvm.amdgcn.buffer.store.v4f32";
data = base_data;
} else if (count == 2) {
- LLVMTypeRef v2f32 = LLVMVectorType(ctx->ac.f32, 2);
-
tmp = LLVMBuildExtractElement(ctx->ac.builder,
base_data, LLVMConstInt(ctx->ac.i32, start, false), "");
- data = LLVMBuildInsertElement(ctx->ac.builder, LLVMGetUndef(v2f32), tmp,
+ data = LLVMBuildInsertElement(ctx->ac.builder, LLVMGetUndef(ctx->ac.v2f32), tmp,
ctx->ac.i32_0, "");
tmp = LLVMBuildExtractElement(ctx->ac.builder,
}
- ret = ac_build_gather_values(&ctx->ac, results, instr->num_components);
+ ret = ac_build_gather_values(&ctx->ac, results, num_components);
return LLVMBuildBitCast(ctx->ac.builder, ret,
get_def_type(ctx, &instr->dest.ssa), "");
}
return dw_addr;
}
-static LLVMValueRef
-build_varying_gather_values(struct ac_llvm_context *ctx, LLVMValueRef *values,
- unsigned value_count, unsigned component)
-{
- LLVMValueRef vec = NULL;
-
- if (value_count == 1) {
- return values[component];
- } else if (!value_count)
- unreachable("value_count is 0");
-
- for (unsigned i = component; i < value_count + component; i++) {
- LLVMValueRef value = values[i];
-
- if (!i)
- vec = LLVMGetUndef( LLVMVectorType(LLVMTypeOf(value), value_count));
- LLVMValueRef index = LLVMConstInt(ctx->i32, i - component, false);
- vec = LLVMBuildInsertElement(ctx->builder, vec, value, index, "");
- }
- return vec;
-}
-
static LLVMValueRef
load_tcs_input(struct nir_to_llvm_context *ctx,
nir_intrinsic_instr *instr)
dw_addr = LLVMBuildAdd(ctx->builder, dw_addr,
ctx->ac.i32_1, "");
}
- result = build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
+ result = ac_build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
result = LLVMBuildBitCast(ctx->builder, result, get_def_type(ctx->nir, &instr->dest.ssa), "");
return result;
}
dw_addr = LLVMBuildAdd(ctx->builder, dw_addr,
ctx->ac.i32_1, "");
}
- result = build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
+ result = ac_build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
result = LLVMBuildBitCast(ctx->builder, result, get_def_type(ctx->nir, &instr->dest.ssa), "");
return result;
}
const unsigned comp = instr->variables[0]->var->data.location_frac;
const bool per_vertex = nir_is_per_vertex_io(instr->variables[0]->var, ctx->stage);
const bool is_compact = instr->variables[0]->var->data.compact;
+ bool store_lds = true;
+ if (instr->variables[0]->var->data.patch) {
+ if (!(ctx->tcs_patch_outputs_read & (1U << instr->variables[0]->var->data.location)))
+ store_lds = false;
+ } else {
+ if (!(ctx->tcs_outputs_read & (1ULL << instr->variables[0]->var->data.location)))
+ store_lds = false;
+ }
get_deref_offset(ctx->nir, instr->variables[0],
false, NULL, per_vertex ? &vertex_index : NULL,
&const_index, &indir_index);
continue;
LLVMValueRef value = llvm_extract_elem(&ctx->ac, src, chan - comp);
- ac_lds_store(&ctx->ac, dw_addr, value);
+ if (store_lds || is_tess_factor)
+ ac_lds_store(&ctx->ac, dw_addr, value);
if (!is_tess_factor && writemask != 0xF)
ac_build_buffer_store_dword(&ctx->ac, ctx->hs_ring_tess_offchip, value, 1,
}
static LLVMValueRef
-load_gs_input(struct nir_to_llvm_context *ctx,
- nir_intrinsic_instr *instr)
+load_gs_input(struct ac_shader_abi *abi,
+ unsigned location,
+ unsigned driver_location,
+ unsigned component,
+ unsigned num_components,
+ unsigned vertex_index,
+ unsigned const_index,
+ LLVMTypeRef type)
{
- LLVMValueRef indir_index, vtx_offset;
- unsigned const_index;
+ struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
+ LLVMValueRef vtx_offset;
LLVMValueRef args[9];
unsigned param, vtx_offset_param;
LLVMValueRef value[4], result;
- unsigned vertex_index;
- get_deref_offset(ctx->nir, instr->variables[0],
- false, &vertex_index, NULL,
- &const_index, &indir_index);
+
vtx_offset_param = vertex_index;
assert(vtx_offset_param < 6);
vtx_offset = LLVMBuildMul(ctx->builder, ctx->gs_vtx_offset[vtx_offset_param],
LLVMConstInt(ctx->ac.i32, 4, false), "");
- param = shader_io_get_unique_index(instr->variables[0]->var->data.location);
+ param = shader_io_get_unique_index(location);
- unsigned comp = instr->variables[0]->var->data.location_frac;
- for (unsigned i = comp; i < instr->num_components + comp; i++) {
+ for (unsigned i = component; i < num_components + component; i++) {
if (ctx->ac.chip_class >= GFX9) {
LLVMValueRef dw_addr = ctx->gs_vtx_offset[vtx_offset_param];
dw_addr = LLVMBuildAdd(ctx->ac.builder, dw_addr,
AC_FUNC_ATTR_LEGACY);
}
}
- result = build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
+ result = ac_build_varying_gather_values(&ctx->ac, value, num_components, component);
return result;
}
if (ctx->stage == MESA_SHADER_TESS_EVAL)
return load_tes_input(ctx->nctx, instr);
if (ctx->stage == MESA_SHADER_GEOMETRY) {
- return load_gs_input(ctx->nctx, instr);
+ LLVMValueRef indir_index;
+ unsigned const_index, vertex_index;
+ get_deref_offset(ctx, instr->variables[0],
+ false, &vertex_index, NULL,
+ &const_index, &indir_index);
+ return ctx->abi->load_inputs(ctx->abi, instr->variables[0]->var->data.location,
+ instr->variables[0]->var->data.driver_location,
+ instr->variables[0]->var->data.location_frac, ve,
+ vertex_index, const_index,
+ nir2llvmtype(ctx, instr->variables[0]->var->type));
}
for (unsigned chan = comp; chan < ve + comp; chan++) {
default:
unreachable("unhandle variable mode");
}
- ret = build_varying_gather_values(&ctx->ac, values, ve, comp);
+ ret = ac_build_varying_gather_values(&ctx->ac, values, ve, comp);
return LLVMBuildBitCast(ctx->ac.builder, ret, get_def_type(ctx, &instr->dest.ssa), "");
}
ctx->ac.voidt, args, 1, 0);
}
+static void emit_membar(struct nir_to_llvm_context *ctx,
+ const nir_intrinsic_instr *instr)
+{
+ unsigned waitcnt = NOOP_WAITCNT;
+
+ switch (instr->intrinsic) {
+ case nir_intrinsic_memory_barrier:
+ case nir_intrinsic_group_memory_barrier:
+ waitcnt &= VM_CNT & LGKM_CNT;
+ break;
+ case nir_intrinsic_memory_barrier_atomic_counter:
+ case nir_intrinsic_memory_barrier_buffer:
+ case nir_intrinsic_memory_barrier_image:
+ waitcnt &= VM_CNT;
+ break;
+ case nir_intrinsic_memory_barrier_shared:
+ waitcnt &= LGKM_CNT;
+ break;
+ default:
+ break;
+ }
+ if (waitcnt != NOOP_WAITCNT)
+ emit_waitcnt(ctx, waitcnt);
+}
+
static void emit_barrier(struct nir_to_llvm_context *ctx)
{
/* SI only (thanks to a hw bug workaround):
LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_PS_SAMPLE_POSITIONS, false));
ptr = LLVMBuildBitCast(ctx->builder, ptr,
- const_array(ctx->v2f32, 64), "");
+ const_array(ctx->ac.v2f32, 64), "");
sample_id = LLVMBuildAdd(ctx->builder, sample_id, ctx->sample_pos_offset, "");
result = ac_build_load_invariant(&ctx->ac, ptr, sample_id);
src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->ac.i32_1, ""));
} else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) {
LLVMValueRef sample_position;
- LLVMValueRef halfval = LLVMConstReal(ctx->f32, 0.5f);
+ LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
/* fetch sample ID */
sample_position = load_sample_position(ctx, src0);
LLVMValueRef temp1, temp2;
interp_el = LLVMBuildBitCast(ctx->builder, interp_el,
- ctx->f32, "");
+ ctx->ac.f32, "");
temp1 = LLVMBuildFMul(ctx->builder, ddx_el, src_c0, "");
temp1 = LLVMBuildFAdd(ctx->builder, temp1, interp_el, "");
if (interp_param) {
interp_param = LLVMBuildBitCast(ctx->builder,
- interp_param, LLVMVectorType(ctx->f32, 2), "");
+ interp_param, ctx->ac.v2f32, "");
LLVMValueRef i = LLVMBuildExtractElement(
ctx->builder, interp_param, ctx->ac.i32_0, "");
LLVMValueRef j = LLVMBuildExtractElement(
ctx->prim_mask);
}
}
- return build_varying_gather_values(&ctx->ac, result, instr->num_components,
- instr->variables[0]->var->data.location_frac);
+ return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components,
+ instr->variables[0]->var->data.location_frac);
}
static void
-visit_emit_vertex(struct nir_to_llvm_context *ctx,
- const nir_intrinsic_instr *instr)
+visit_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVMValueRef *addrs)
{
LLVMValueRef gs_next_vertex;
LLVMValueRef can_emit;
int idx;
+ struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
- assert(instr->const_index[0] == 0);
/* Write vertex attribute values to GSVS ring */
gs_next_vertex = LLVMBuildLoad(ctx->builder,
ctx->gs_next_vertex,
/* loop num outputs */
idx = 0;
for (unsigned i = 0; i < RADEON_LLVM_MAX_OUTPUTS; ++i) {
- LLVMValueRef *out_ptr = &ctx->nir->outputs[i * 4];
+ LLVMValueRef *out_ptr = &addrs[i * 4];
int length = 4;
int slot = idx;
int slot_inc = 1;
if (ctx->stage == MESA_SHADER_TESS_CTRL)
result = unpack_param(&ctx->ac, ctx->nctx->tcs_rel_ids, 8, 5);
else
- result = ctx->nctx->gs_invocation_id;
+ result = ctx->abi->gs_invocation_id;
break;
case nir_intrinsic_load_primitive_id:
if (ctx->stage == MESA_SHADER_GEOMETRY) {
- ctx->nctx->shader_info->gs.uses_prim_id = true;
- result = ctx->nctx->gs_prim_id;
+ if (ctx->nctx)
+ ctx->nctx->shader_info->gs.uses_prim_id = true;
+ result = ctx->abi->gs_prim_id;
} else if (ctx->stage == MESA_SHADER_TESS_CTRL) {
ctx->nctx->shader_info->tcs.uses_prim_id = true;
result = ctx->nctx->tcs_patch_id;
case nir_intrinsic_vulkan_resource_index:
result = visit_vulkan_resource_index(ctx->nctx, instr);
break;
+ case nir_intrinsic_vulkan_resource_reindex:
+ result = visit_vulkan_resource_reindex(ctx->nctx, instr);
+ break;
case nir_intrinsic_store_ssbo:
visit_store_ssbo(ctx, instr);
break;
emit_discard_if(ctx, instr);
break;
case nir_intrinsic_memory_barrier:
- emit_waitcnt(ctx->nctx, VM_CNT);
+ case nir_intrinsic_group_memory_barrier:
+ case nir_intrinsic_memory_barrier_atomic_counter:
+ case nir_intrinsic_memory_barrier_buffer:
+ case nir_intrinsic_memory_barrier_image:
+ case nir_intrinsic_memory_barrier_shared:
+ emit_membar(ctx->nctx, instr);
break;
case nir_intrinsic_barrier:
emit_barrier(ctx->nctx);
result = visit_interp(ctx->nctx, instr);
break;
case nir_intrinsic_emit_vertex:
- visit_emit_vertex(ctx->nctx, instr);
+ assert(instr->const_index[0] == 0);
+ ctx->abi->emit_vertex(ctx->abi, 0, ctx->outputs);
break;
case nir_intrinsic_end_primitive:
visit_end_primitive(ctx->nctx, instr);
}
static LLVMValueRef radv_load_ssbo(struct ac_shader_abi *abi,
- LLVMValueRef buffer, bool write)
+ LLVMValueRef buffer_ptr, bool write)
{
struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
if (write && ctx->stage == MESA_SHADER_FRAGMENT)
ctx->shader_info->fs.writes_memory = true;
- return buffer;
+ return LLVMBuildLoad(ctx->builder, buffer_ptr, "");
+}
+
+static LLVMValueRef radv_load_ubo(struct ac_shader_abi *abi, LLVMValueRef buffer_ptr)
+{
+ struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
+
+ return LLVMBuildLoad(ctx->builder, buffer_ptr, "");
}
static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi,
switch (desc_type) {
case AC_DESC_IMAGE:
- type = ctx->v8i32;
+ type = ctx->ac.v8i32;
type_size = 32;
break;
case AC_DESC_FMASK:
- type = ctx->v8i32;
+ type = ctx->ac.v8i32;
offset += 32;
type_size = 32;
break;
case AC_DESC_SAMPLER:
- type = ctx->v4i32;
+ type = ctx->ac.v4i32;
if (binding->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
offset += 64;
type_size = 16;
break;
case AC_DESC_BUFFER:
- type = ctx->v4i32;
+ type = ctx->ac.v4i32;
type_size = 16;
break;
default:
*/
if (interp) {
interp_param = LLVMBuildBitCast(ctx->builder, interp_param,
- LLVMVectorType(ctx->f32, 2), "");
+ ctx->ac.v2f32, "");
i = LLVMBuildExtractElement(ctx->builder, interp_param,
ctx->ac.i32_0, "");
case GLSL_TYPE_SUBROUTINE:
return ctx->ac.i32;
case GLSL_TYPE_FLOAT: /* TODO handle mediump */
- return ctx->f32;
+ return ctx->ac.f32;
case GLSL_TYPE_INT64:
case GLSL_TYPE_UINT64:
- return ctx->i64;
+ return ctx->ac.i64;
case GLSL_TYPE_DOUBLE:
- return ctx->f64;
+ return ctx->ac.f64;
default:
unreachable("unknown GLSL type");
}
args->target = target;
args->compr = false;
- args->out[0] = LLVMGetUndef(ctx->f32);
- args->out[1] = LLVMGetUndef(ctx->f32);
- args->out[2] = LLVMGetUndef(ctx->f32);
- args->out[3] = LLVMGetUndef(ctx->f32);
+ args->out[0] = LLVMGetUndef(ctx->ac.f32);
+ args->out[1] = LLVMGetUndef(ctx->ac.f32);
+ args->out[2] = LLVMGetUndef(ctx->ac.f32);
+ args->out[3] = LLVMGetUndef(ctx->ac.f32);
if (!values)
return;
for (unsigned chan = 0; chan < 4; chan++) {
val[chan] = ac_build_clamp(&ctx->ac, values[chan]);
val[chan] = LLVMBuildFMul(ctx->builder, val[chan],
- LLVMConstReal(ctx->f32, 65535), "");
+ LLVMConstReal(ctx->ac.f32, 65535), "");
val[chan] = LLVMBuildFAdd(ctx->builder, val[chan],
- LLVMConstReal(ctx->f32, 0.5), "");
+ LLVMConstReal(ctx->ac.f32, 0.5), "");
val[chan] = LLVMBuildFPToUI(ctx->builder, val[chan],
ctx->ac.i32, "");
}
for (unsigned chan = 0; chan < 4; chan++) {
val[chan] = emit_float_saturate(&ctx->ac, values[chan], -1, 1);
val[chan] = LLVMBuildFMul(ctx->builder, val[chan],
- LLVMConstReal(ctx->f32, 32767), "");
+ LLVMConstReal(ctx->ac.f32, 32767), "");
/* If positive, add 0.5, else add -0.5. */
val[chan] = LLVMBuildFAdd(ctx->builder, val[chan],
LLVMBuildSelect(ctx->builder,
LLVMBuildFCmp(ctx->builder, LLVMRealOGE,
val[chan], ctx->ac.f32_0, ""),
- LLVMConstReal(ctx->f32, 0.5),
- LLVMConstReal(ctx->f32, -0.5), ""), "");
+ LLVMConstReal(ctx->ac.f32, 0.5),
+ LLVMConstReal(ctx->ac.f32, -0.5), ""), "");
val[chan] = LLVMBuildFPToSI(ctx->builder, val[chan], ctx->ac.i32, "");
}
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));
for (i = ctx->num_output_clips + ctx->num_output_culls; i < 8; i++)
- slots[i] = LLVMGetUndef(ctx->f32);
+ slots[i] = LLVMGetUndef(ctx->ac.f32);
if (ctx->num_output_clips + ctx->num_output_culls > 4) {
target = V_008DFC_SQ_EXP_POS + 3;
args.target = V_008DFC_SQ_EXP_MRTZ;
args.compr = false;
- args.out[0] = LLVMGetUndef(ctx->f32); /* R, depth */
- args.out[1] = LLVMGetUndef(ctx->f32); /* G, stencil test val[0:7], stencil op val[8:15] */
- args.out[2] = LLVMGetUndef(ctx->f32); /* B, sample mask */
- args.out[3] = LLVMGetUndef(ctx->f32); /* A, alpha to mask */
+ args.out[0] = LLVMGetUndef(ctx->ac.f32); /* R, depth */
+ args.out[1] = LLVMGetUndef(ctx->ac.f32); /* G, stencil test val[0:7], stencil op val[8:15] */
+ args.out[2] = LLVMGetUndef(ctx->ac.f32); /* B, sample mask */
+ args.out[3] = LLVMGetUndef(ctx->ac.f32); /* A, alpha to mask */
if (depth) {
args.out[0] = depth;
ctx->esgs_ring = ac_build_load_to_sgpr(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_ESGS_GS, false));
ctx->gsvs_ring = ac_build_load_to_sgpr(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_GSVS_GS, false));
- ctx->gsvs_ring = LLVMBuildBitCast(ctx->builder, ctx->gsvs_ring, ctx->v4i32, "");
+ ctx->gsvs_ring = LLVMBuildBitCast(ctx->builder, ctx->gsvs_ring, ctx->ac.v4i32, "");
ctx->gsvs_ring = LLVMBuildInsertElement(ctx->builder, ctx->gsvs_ring, ctx->gsvs_num_entries, LLVMConstInt(ctx->ac.i32, 2, false), "");
tmp = LLVMBuildExtractElement(ctx->builder, ctx->gsvs_ring, ctx->ac.i32_1, "");
LLVMDisposeTargetData(data_layout);
LLVMDisposeMessage(data_layout_str);
- setup_types(&ctx);
ctx.builder = LLVMCreateBuilderInContext(ctx.context);
ctx.ac.builder = ctx.builder;
ctx.abi.inputs = &ctx.inputs[0];
ctx.abi.emit_outputs = handle_shader_outputs_post;
+ ctx.abi.emit_vertex = visit_emit_vertex;
+ ctx.abi.load_ubo = radv_load_ubo;
ctx.abi.load_ssbo = radv_load_ssbo;
ctx.abi.load_sampler_desc = radv_get_sampler_desc;
ctx.abi.clamp_shadow_reference = false;
if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY) {
ctx.gs_next_vertex = ac_build_alloca(&ctx.ac, ctx.ac.i32, "gs_next_vertex");
-
ctx.gs_max_out_vertices = shaders[i]->info.gs.vertices_out;
+ ctx.abi.load_inputs = load_gs_input;
+ } else if (shaders[i]->info.stage == MESA_SHADER_TESS_CTRL) {
+ ctx.tcs_outputs_read = shaders[i]->info.outputs_read;
+ ctx.tcs_patch_outputs_read = shaders[i]->info.patch_outputs_read;
} else if (shaders[i]->info.stage == MESA_SHADER_TESS_EVAL) {
ctx.tes_primitive_mode = shaders[i]->info.tess.primitive_mode;
} else if (shaders[i]->info.stage == MESA_SHADER_VERTEX) {
ctx.is_gs_copy_shader = true;
LLVMSetTarget(ctx.module, "amdgcn--");
- setup_types(&ctx);
ctx.builder = LLVMCreateBuilderInContext(ctx.context);
ctx.ac.builder = ctx.builder;