Browse Source

ac: move ac_to_integer() and ac_to_float() to ac_llvm_build.c

We'll need to use ac_to_integer() for other stuff in ac_llvm_build.c.

Reviewed-by: Dave Airlie <airlied@redhat.com>
tags/17.3-branchpoint
Connor Abbott 8 years ago
parent
commit
50967cd0b0
3 changed files with 172 additions and 162 deletions
  1. 61
    0
      src/amd/common/ac_llvm_build.c
  2. 5
    0
      src/amd/common/ac_llvm_build.h
  3. 106
    162
      src/amd/common/ac_nir_to_llvm.c

+ 61
- 0
src/amd/common/ac_llvm_build.c View File

} }
} }


static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (t == ctx->f16 || t == ctx->i16)
return ctx->i16;
else if (t == ctx->f32 || t == ctx->i32)
return ctx->i32;
else if (t == ctx->f64 || t == ctx->i64)
return ctx->i64;
else
unreachable("Unhandled integer size");
}

LLVMTypeRef
ac_to_integer_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
LLVMTypeRef elem_type = LLVMGetElementType(t);
return LLVMVectorType(to_integer_type_scalar(ctx, elem_type),
LLVMGetVectorSize(t));
}
return to_integer_type_scalar(ctx, t);
}

LLVMValueRef
ac_to_integer(struct ac_llvm_context *ctx, LLVMValueRef v)
{
LLVMTypeRef type = LLVMTypeOf(v);
return LLVMBuildBitCast(ctx->builder, v, ac_to_integer_type(ctx, type), "");
}

static LLVMTypeRef to_float_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (t == ctx->i16 || t == ctx->f16)
return ctx->f16;
else if (t == ctx->i32 || t == ctx->f32)
return ctx->f32;
else if (t == ctx->i64 || t == ctx->f64)
return ctx->f64;
else
unreachable("Unhandled float size");
}

LLVMTypeRef
ac_to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
LLVMTypeRef elem_type = LLVMGetElementType(t);
return LLVMVectorType(to_float_type_scalar(ctx, elem_type),
LLVMGetVectorSize(t));
}
return to_float_type_scalar(ctx, t);
}

LLVMValueRef
ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v)
{
LLVMTypeRef type = LLVMTypeOf(v);
return LLVMBuildBitCast(ctx->builder, v, ac_to_float_type(ctx, type), "");
}


LLVMValueRef LLVMValueRef
ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name, ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
LLVMTypeRef return_type, LLVMValueRef *params, LLVMTypeRef return_type, LLVMValueRef *params,

+ 5
- 0
src/amd/common/ac_llvm_build.h View File



unsigned ac_get_type_size(LLVMTypeRef type); unsigned ac_get_type_size(LLVMTypeRef type);


LLVMTypeRef ac_to_integer_type(struct ac_llvm_context *ctx, LLVMTypeRef t);
LLVMValueRef ac_to_integer(struct ac_llvm_context *ctx, LLVMValueRef v);
LLVMTypeRef ac_to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t);
LLVMValueRef ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v);

LLVMValueRef LLVMValueRef
ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name, ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
LLVMTypeRef return_type, LLVMValueRef *params, LLVMTypeRef return_type, LLVMValueRef *params,

+ 106
- 162
src/amd/common/ac_nir_to_llvm.c View File

CONST_ADDR_SPACE); CONST_ADDR_SPACE);
} }


static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (t == ctx->f16 || t == ctx->i16)
return ctx->i16;
else if (t == ctx->f32 || t == ctx->i32)
return ctx->i32;
else if (t == ctx->f64 || t == ctx->i64)
return ctx->i64;
else
unreachable("Unhandled integer size");
}

static LLVMTypeRef to_integer_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
LLVMTypeRef elem_type = LLVMGetElementType(t);
return LLVMVectorType(to_integer_type_scalar(ctx, elem_type),
LLVMGetVectorSize(t));
}
return to_integer_type_scalar(ctx, t);
}

static LLVMValueRef to_integer(struct ac_llvm_context *ctx, LLVMValueRef v)
{
LLVMTypeRef type = LLVMTypeOf(v);
return LLVMBuildBitCast(ctx->builder, v, to_integer_type(ctx, type), "");
}

static LLVMTypeRef to_float_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (t == ctx->i16 || t == ctx->f16)
return ctx->f16;
else if (t == ctx->i32 || t == ctx->f32)
return ctx->f32;
else if (t == ctx->i64 || t == ctx->f64)
return ctx->f64;
else
unreachable("Unhandled float size");
}

static LLVMTypeRef to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (LLVMGetTypeKind(t) == LLVMVectorTypeKind) {
LLVMTypeRef elem_type = LLVMGetElementType(t);
return LLVMVectorType(to_float_type_scalar(ctx, elem_type),
LLVMGetVectorSize(t));
}
return to_float_type_scalar(ctx, t);
}

static LLVMValueRef to_float(struct ac_llvm_context *ctx, LLVMValueRef v)
{
LLVMTypeRef type = LLVMTypeOf(v);
return LLVMBuildBitCast(ctx->builder, v, to_float_type(ctx, type), "");
}

static int get_elem_bits(struct ac_llvm_context *ctx, LLVMTypeRef type) static int get_elem_bits(struct ac_llvm_context *ctx, LLVMTypeRef type)
{ {
if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) if (LLVMGetTypeKind(type) == LLVMVectorTypeKind)
LLVMValueRef src1) LLVMValueRef src1)
{ {
LLVMValueRef result; LLVMValueRef result;
src0 = to_float(ctx, src0);
src1 = to_float(ctx, src1);
src0 = ac_to_float(ctx, src0);
src1 = ac_to_float(ctx, src1);
result = LLVMBuildFCmp(ctx->builder, pred, src0, src1, ""); result = LLVMBuildFCmp(ctx->builder, pred, src0, src1, "");
return LLVMBuildSelect(ctx->builder, result, return LLVMBuildSelect(ctx->builder, result,
LLVMConstInt(ctx->i32, 0xFFFFFFFF, false), LLVMConstInt(ctx->i32, 0xFFFFFFFF, false),
{ {
char name[64]; char name[64];
LLVMValueRef params[] = { LLVMValueRef params[] = {
to_float(ctx, src0),
ac_to_float(ctx, src0),
}; };


MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin, MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
{ {
char name[64]; char name[64];
LLVMValueRef params[] = { LLVMValueRef params[] = {
to_float(ctx, src0),
to_float(ctx, src1),
ac_to_float(ctx, src0),
ac_to_float(ctx, src1),
}; };


MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin, MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
{ {
char name[64]; char name[64];
LLVMValueRef params[] = { LLVMValueRef params[] = {
to_float(ctx, src0),
to_float(ctx, src1),
to_float(ctx, src2),
ac_to_float(ctx, src0),
ac_to_float(ctx, src1),
ac_to_float(ctx, src2),
}; };


MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin, MAYBE_UNUSED const int length = snprintf(name, sizeof(name), "%s.f%d", intrin,
LLVMValueRef src0) LLVMValueRef src0)
{ {
const char *intr = "llvm.floor.f32"; const char *intr = "llvm.floor.f32";
LLVMValueRef fsrc0 = to_float(ctx, src0);
LLVMValueRef fsrc0 = ac_to_float(ctx, src0);
LLVMValueRef params[] = { LLVMValueRef params[] = {
fsrc0, fsrc0,
}; };
static LLVMValueRef emit_f2b(struct ac_llvm_context *ctx, static LLVMValueRef emit_f2b(struct ac_llvm_context *ctx,
LLVMValueRef src0) LLVMValueRef src0)
{ {
src0 = to_float(ctx, src0);
src0 = ac_to_float(ctx, src0);
return LLVMBuildSExt(ctx->builder, return LLVMBuildSExt(ctx->builder,
LLVMBuildFCmp(ctx->builder, LLVMRealUNE, src0, ctx->f32_0, ""), LLVMBuildFCmp(ctx->builder, LLVMRealUNE, src0, ctx->f32_0, ""),
ctx->i32, ""); ctx->i32, "");
LLVMValueRef result; LLVMValueRef result;
LLVMValueRef cond = NULL; LLVMValueRef cond = NULL;


src0 = to_float(&ctx->ac, src0);
src0 = ac_to_float(&ctx->ac, src0);
result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->f16, ""); result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->f16, "");


if (ctx->options->chip_class >= VI) { if (ctx->options->chip_class >= VI) {
int i; int i;
LLVMValueRef comp[2]; LLVMValueRef comp[2];


src0 = to_float(ctx, src0);
src0 = ac_to_float(ctx, src0);
comp[0] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_0, ""); comp[0] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_0, "");
comp[1] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_1, ""); comp[1] = LLVMBuildExtractElement(ctx->builder, src0, ctx->i32_1, "");
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
result = src[0]; result = src[0];
break; break;
case nir_op_fneg: case nir_op_fneg:
src[0] = to_float(&ctx->ac, src[0]);
src[0] = ac_to_float(&ctx->ac, src[0]);
result = LLVMBuildFNeg(ctx->ac.builder, src[0], ""); result = LLVMBuildFNeg(ctx->ac.builder, src[0], "");
break; break;
case nir_op_ineg: case nir_op_ineg:
result = LLVMBuildAdd(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildAdd(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_fadd: case nir_op_fadd:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = LLVMBuildFAdd(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildFAdd(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_fsub: case nir_op_fsub:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = LLVMBuildFSub(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildFSub(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_isub: case nir_op_isub:
result = LLVMBuildURem(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildURem(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_fmod: case nir_op_fmod:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = ac_build_fdiv(&ctx->ac, src[0], src[1]); result = ac_build_fdiv(&ctx->ac, src[0], src[1]);
result = emit_intrin_1f_param(&ctx->ac, "llvm.floor", result = emit_intrin_1f_param(&ctx->ac, "llvm.floor",
to_float_type(&ctx->ac, def_type), result);
ac_to_float_type(&ctx->ac, def_type), result);
result = LLVMBuildFMul(ctx->ac.builder, src[1] , result, ""); result = LLVMBuildFMul(ctx->ac.builder, src[1] , result, "");
result = LLVMBuildFSub(ctx->ac.builder, src[0], result, ""); result = LLVMBuildFSub(ctx->ac.builder, src[0], result, "");
break; break;
case nir_op_frem: case nir_op_frem:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = LLVMBuildFRem(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildFRem(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_irem: case nir_op_irem:
result = LLVMBuildUDiv(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildUDiv(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_fmul: case nir_op_fmul:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = LLVMBuildFMul(ctx->ac.builder, src[0], src[1], ""); result = LLVMBuildFMul(ctx->ac.builder, src[0], src[1], "");
break; break;
case nir_op_fdiv: case nir_op_fdiv:
src[0] = to_float(&ctx->ac, src[0]);
src[1] = to_float(&ctx->ac, src[1]);
src[0] = ac_to_float(&ctx->ac, src[0]);
src[1] = ac_to_float(&ctx->ac, src[1]);
result = ac_build_fdiv(&ctx->ac, src[0], src[1]); result = ac_build_fdiv(&ctx->ac, src[0], src[1]);
break; break;
case nir_op_frcp: case nir_op_frcp:
src[0] = to_float(&ctx->ac, src[0]);
src[0] = ac_to_float(&ctx->ac, src[0]);
result = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, src[0]); result = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, src[0]);
break; break;
case nir_op_iand: case nir_op_iand:
break; break;
case nir_op_fabs: case nir_op_fabs:
result = emit_intrin_1f_param(&ctx->ac, "llvm.fabs", result = emit_intrin_1f_param(&ctx->ac, "llvm.fabs",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_iabs: case nir_op_iabs:
result = emit_iabs(&ctx->ac, src[0]); result = emit_iabs(&ctx->ac, src[0]);
result = emit_isign(&ctx->ac, src[0]); result = emit_isign(&ctx->ac, src[0]);
break; break;
case nir_op_fsign: case nir_op_fsign:
src[0] = to_float(&ctx->ac, src[0]);
src[0] = ac_to_float(&ctx->ac, src[0]);
result = emit_fsign(&ctx->ac, src[0]); result = emit_fsign(&ctx->ac, src[0]);
break; break;
case nir_op_ffloor: case nir_op_ffloor:
result = emit_intrin_1f_param(&ctx->ac, "llvm.floor", result = emit_intrin_1f_param(&ctx->ac, "llvm.floor",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_ftrunc: case nir_op_ftrunc:
result = emit_intrin_1f_param(&ctx->ac, "llvm.trunc", result = emit_intrin_1f_param(&ctx->ac, "llvm.trunc",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_fceil: case nir_op_fceil:
result = emit_intrin_1f_param(&ctx->ac, "llvm.ceil", result = emit_intrin_1f_param(&ctx->ac, "llvm.ceil",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_fround_even: case nir_op_fround_even:
result = emit_intrin_1f_param(&ctx->ac, "llvm.rint", result = emit_intrin_1f_param(&ctx->ac, "llvm.rint",
to_float_type(&ctx->ac, def_type),src[0]);
ac_to_float_type(&ctx->ac, def_type),src[0]);
break; break;
case nir_op_ffract: case nir_op_ffract:
result = emit_ffract(&ctx->ac, src[0]); result = emit_ffract(&ctx->ac, src[0]);
break; break;
case nir_op_fsin: case nir_op_fsin:
result = emit_intrin_1f_param(&ctx->ac, "llvm.sin", result = emit_intrin_1f_param(&ctx->ac, "llvm.sin",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_fcos: case nir_op_fcos:
result = emit_intrin_1f_param(&ctx->ac, "llvm.cos", result = emit_intrin_1f_param(&ctx->ac, "llvm.cos",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_fsqrt: case nir_op_fsqrt:
result = emit_intrin_1f_param(&ctx->ac, "llvm.sqrt", result = emit_intrin_1f_param(&ctx->ac, "llvm.sqrt",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_fexp2: case nir_op_fexp2:
result = emit_intrin_1f_param(&ctx->ac, "llvm.exp2", result = emit_intrin_1f_param(&ctx->ac, "llvm.exp2",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_flog2: case nir_op_flog2:
result = emit_intrin_1f_param(&ctx->ac, "llvm.log2", result = emit_intrin_1f_param(&ctx->ac, "llvm.log2",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
break; break;
case nir_op_frsq: case nir_op_frsq:
result = emit_intrin_1f_param(&ctx->ac, "llvm.sqrt", result = emit_intrin_1f_param(&ctx->ac, "llvm.sqrt",
to_float_type(&ctx->ac, def_type), src[0]);
ac_to_float_type(&ctx->ac, def_type), src[0]);
result = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, result); result = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, result);
break; break;
case nir_op_fpow: case nir_op_fpow:
result = emit_intrin_2f_param(&ctx->ac, "llvm.pow", result = emit_intrin_2f_param(&ctx->ac, "llvm.pow",
to_float_type(&ctx->ac, def_type), src[0], src[1]);
ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
break; break;
case nir_op_fmax: case nir_op_fmax:
result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum", result = emit_intrin_2f_param(&ctx->ac, "llvm.maxnum",
to_float_type(&ctx->ac, def_type), src[0], src[1]);
ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
if (instr->dest.dest.ssa.bit_size == 32) if (instr->dest.dest.ssa.bit_size == 32)
result = emit_intrin_1f_param(&ctx->ac, "llvm.canonicalize", result = emit_intrin_1f_param(&ctx->ac, "llvm.canonicalize",
to_float_type(&ctx->ac, def_type),
ac_to_float_type(&ctx->ac, def_type),
result); result);
break; break;
case nir_op_fmin: case nir_op_fmin:
result = emit_intrin_2f_param(&ctx->ac, "llvm.minnum", result = emit_intrin_2f_param(&ctx->ac, "llvm.minnum",
to_float_type(&ctx->ac, def_type), src[0], src[1]);
ac_to_float_type(&ctx->ac, def_type), src[0], src[1]);
if (instr->dest.dest.ssa.bit_size == 32) if (instr->dest.dest.ssa.bit_size == 32)
result = emit_intrin_1f_param(&ctx->ac, "llvm.canonicalize", result = emit_intrin_1f_param(&ctx->ac, "llvm.canonicalize",
to_float_type(&ctx->ac, def_type),
ac_to_float_type(&ctx->ac, def_type),
result); result);
break; break;
case nir_op_ffma: case nir_op_ffma:
result = emit_intrin_3f_param(&ctx->ac, "llvm.fma", result = emit_intrin_3f_param(&ctx->ac, "llvm.fma",
to_float_type(&ctx->ac, def_type), src[0], src[1], src[2]);
ac_to_float_type(&ctx->ac, def_type), src[0], src[1], src[2]);
break; break;
case nir_op_ibitfield_extract: case nir_op_ibitfield_extract:
result = emit_bitfield_extract(&ctx->ac, true, src); result = emit_bitfield_extract(&ctx->ac, true, src);
case nir_op_vec3: case nir_op_vec3:
case nir_op_vec4: case nir_op_vec4:
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
src[i] = to_integer(&ctx->ac, src[i]);
src[i] = ac_to_integer(&ctx->ac, src[i]);
result = ac_build_gather_values(&ctx->ac, src, num_components); result = ac_build_gather_values(&ctx->ac, src, num_components);
break; break;
case nir_op_f2i32: case nir_op_f2i32:
case nir_op_f2i64: case nir_op_f2i64:
src[0] = to_float(&ctx->ac, src[0]);
src[0] = ac_to_float(&ctx->ac, src[0]);
result = LLVMBuildFPToSI(ctx->ac.builder, src[0], def_type, ""); result = LLVMBuildFPToSI(ctx->ac.builder, src[0], def_type, "");
break; break;
case nir_op_f2u32: case nir_op_f2u32:
case nir_op_f2u64: case nir_op_f2u64:
src[0] = to_float(&ctx->ac, src[0]);
src[0] = ac_to_float(&ctx->ac, src[0]);
result = LLVMBuildFPToUI(ctx->ac.builder, src[0], def_type, ""); result = LLVMBuildFPToUI(ctx->ac.builder, src[0], def_type, "");
break; break;
case nir_op_i2f32: case nir_op_i2f32:
case nir_op_i2f64: case nir_op_i2f64:
src[0] = to_integer(&ctx->ac, src[0]);
result = LLVMBuildSIToFP(ctx->ac.builder, src[0], to_float_type(&ctx->ac, def_type), "");
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = LLVMBuildSIToFP(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break; break;
case nir_op_u2f32: case nir_op_u2f32:
case nir_op_u2f64: case nir_op_u2f64:
src[0] = to_integer(&ctx->ac, src[0]);
result = LLVMBuildUIToFP(ctx->ac.builder, src[0], to_float_type(&ctx->ac, def_type), "");
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = LLVMBuildUIToFP(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break; break;
case nir_op_f2f64: case nir_op_f2f64:
result = LLVMBuildFPExt(ctx->ac.builder, src[0], to_float_type(&ctx->ac, def_type), "");
result = LLVMBuildFPExt(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break; break;
case nir_op_f2f32: case nir_op_f2f32:
result = LLVMBuildFPTrunc(ctx->ac.builder, src[0], to_float_type(&ctx->ac, def_type), "");
result = LLVMBuildFPTrunc(ctx->ac.builder, src[0], ac_to_float_type(&ctx->ac, def_type), "");
break; break;
case nir_op_u2u32: case nir_op_u2u32:
case nir_op_u2u64: case nir_op_u2u64:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
if (get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < get_elem_bits(&ctx->ac, def_type)) if (get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < get_elem_bits(&ctx->ac, def_type))
result = LLVMBuildZExt(ctx->ac.builder, src[0], def_type, ""); result = LLVMBuildZExt(ctx->ac.builder, src[0], def_type, "");
else else
break; break;
case nir_op_i2i32: case nir_op_i2i32:
case nir_op_i2i64: case nir_op_i2i64:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
if (get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < get_elem_bits(&ctx->ac, def_type)) if (get_elem_bits(&ctx->ac, LLVMTypeOf(src[0])) < get_elem_bits(&ctx->ac, def_type))
result = LLVMBuildSExt(ctx->ac.builder, src[0], def_type, ""); result = LLVMBuildSExt(ctx->ac.builder, src[0], def_type, "");
else else
result = emit_bcsel(&ctx->ac, src[0], src[1], src[2]); result = emit_bcsel(&ctx->ac, src[0], src[1], src[2]);
break; break;
case nir_op_find_lsb: case nir_op_find_lsb:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = emit_find_lsb(&ctx->ac, src[0]); result = emit_find_lsb(&ctx->ac, src[0]);
break; break;
case nir_op_ufind_msb: case nir_op_ufind_msb:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = emit_ufind_msb(&ctx->ac, src[0]); result = emit_ufind_msb(&ctx->ac, src[0]);
break; break;
case nir_op_ifind_msb: case nir_op_ifind_msb:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = emit_ifind_msb(&ctx->ac, src[0]); result = emit_ifind_msb(&ctx->ac, src[0]);
break; break;
case nir_op_uadd_carry: case nir_op_uadd_carry:
src[0] = to_integer(&ctx->ac, src[0]);
src[1] = to_integer(&ctx->ac, src[1]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
src[1] = ac_to_integer(&ctx->ac, src[1]);
result = emit_uint_carry(&ctx->ac, "llvm.uadd.with.overflow.i32", src[0], src[1]); result = emit_uint_carry(&ctx->ac, "llvm.uadd.with.overflow.i32", src[0], src[1]);
break; break;
case nir_op_usub_borrow: case nir_op_usub_borrow:
src[0] = to_integer(&ctx->ac, src[0]);
src[1] = to_integer(&ctx->ac, src[1]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
src[1] = ac_to_integer(&ctx->ac, src[1]);
result = emit_uint_carry(&ctx->ac, "llvm.usub.with.overflow.i32", src[0], src[1]); result = emit_uint_carry(&ctx->ac, "llvm.usub.with.overflow.i32", src[0], src[1]);
break; break;
case nir_op_b2f: case nir_op_b2f:
result = emit_b2i(&ctx->ac, src[0]); result = emit_b2i(&ctx->ac, src[0]);
break; break;
case nir_op_i2b: case nir_op_i2b:
src[0] = to_integer(&ctx->ac, src[0]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
result = emit_i2b(&ctx->ac, src[0]); result = emit_i2b(&ctx->ac, src[0]);
break; break;
case nir_op_fquantize2f16: case nir_op_fquantize2f16:
result = emit_f2f16(ctx->nctx, src[0]); result = emit_f2f16(ctx->nctx, src[0]);
break; break;
case nir_op_umul_high: case nir_op_umul_high:
src[0] = to_integer(&ctx->ac, src[0]);
src[1] = to_integer(&ctx->ac, src[1]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
src[1] = ac_to_integer(&ctx->ac, src[1]);
result = emit_umul_high(&ctx->ac, src[0], src[1]); result = emit_umul_high(&ctx->ac, src[0], src[1]);
break; break;
case nir_op_imul_high: case nir_op_imul_high:
src[0] = to_integer(&ctx->ac, src[0]);
src[1] = to_integer(&ctx->ac, src[1]);
src[0] = ac_to_integer(&ctx->ac, src[0]);
src[1] = ac_to_integer(&ctx->ac, src[1]);
result = emit_imul_high(&ctx->ac, src[0], src[1]); result = emit_imul_high(&ctx->ac, src[0], src[1]);
break; break;
case nir_op_pack_half_2x16: case nir_op_pack_half_2x16:


if (result) { if (result) {
assert(instr->dest.dest.is_ssa); assert(instr->dest.dest.is_ssa);
result = to_integer(&ctx->ac, result);
result = ac_to_integer(&ctx->ac, result);
_mesa_hash_table_insert(ctx->defs, &instr->dest.dest.ssa, _mesa_hash_table_insert(ctx->defs, &instr->dest.dest.ssa,
result); result);
} }
if (components_32bit > 1) if (components_32bit > 1)
data_type = LLVMVectorType(ctx->ac.f32, components_32bit); data_type = LLVMVectorType(ctx->ac.f32, components_32bit);


base_data = to_float(&ctx->ac, src_data);
base_data = ac_to_float(&ctx->ac, src_data);
base_data = trim_vector(&ctx->ac, base_data, instr->num_components); base_data = trim_vector(&ctx->ac, base_data, instr->num_components);
base_data = LLVMBuildBitCast(ctx->ac.builder, base_data, base_data = LLVMBuildBitCast(ctx->ac.builder, base_data,
data_type, ""); data_type, "");
{ {
LLVMValueRef temp_ptr, value; LLVMValueRef temp_ptr, value;
int idx = instr->variables[0]->var->data.driver_location; int idx = instr->variables[0]->var->data.driver_location;
LLVMValueRef src = to_float(&ctx->ac, get_src(ctx, instr->src[0]));
LLVMValueRef src = ac_to_float(&ctx->ac, get_src(ctx, instr->src[0]));
int writemask = instr->const_index[0]; int writemask = instr->const_index[0];
LLVMValueRef indir_index; LLVMValueRef indir_index;
unsigned const_index; unsigned const_index;


res = ac_build_image_opcode(ctx, &args); res = ac_build_image_opcode(ctx, &args);


res = to_integer(ctx, res);
res = ac_to_integer(ctx, res);
LLVMValueRef four = LLVMConstInt(ctx->i32, 4, false); LLVMValueRef four = LLVMConstInt(ctx->i32, 4, false);
LLVMValueRef F = LLVMConstInt(ctx->i32, 0xf, false); LLVMValueRef F = LLVMConstInt(ctx->i32, 0xf, false);


LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan], LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan],
LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan],
ctx->ac.i32, ""), ""); ctx->ac.i32, ""), "");
fmask_load_address[2] = to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
fmask_load_address[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
} }
sample_index = adjust_sample_index_using_fmask(&ctx->ac, sample_index = adjust_sample_index_using_fmask(&ctx->ac,
fmask_load_address[0], fmask_load_address[0],
for (chan = 0; chan < 2; ++chan) for (chan = 0; chan < 2; ++chan)
coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan], coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan],
ctx->ac.i32, ""), ""); ctx->ac.i32, ""), "");
coords[2] = to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
coords[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
count++; count++;
} }
if (is_ms) { if (is_ms) {
params, 5, 0); params, 5, 0);


res = trim_vector(&ctx->ac, res, instr->dest.ssa.num_components); res = trim_vector(&ctx->ac, res, instr->dest.ssa.num_components);
res = to_integer(&ctx->ac, res);
res = ac_to_integer(&ctx->ac, res);
} else { } else {
bool is_da = glsl_sampler_type_is_array(type) || bool is_da = glsl_sampler_type_is_array(type) ||
glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE || glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE ||
res = ac_build_intrinsic(&ctx->ac, intrinsic_name, ctx->ac.v4f32, res = ac_build_intrinsic(&ctx->ac, intrinsic_name, ctx->ac.v4f32,
params, 7, AC_FUNC_ATTR_READONLY); params, 7, AC_FUNC_ATTR_READONLY);
} }
return to_integer(&ctx->ac, res);
return ac_to_integer(&ctx->ac, res);
} }


static void visit_image_store(struct ac_nir_context *ctx, static void visit_image_store(struct ac_nir_context *ctx,
glc = i1true; glc = i1true;


if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) { if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) {
params[0] = to_float(&ctx->ac, get_src(ctx, instr->src[2])); /* data */
params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[2])); /* data */
params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, true, true); 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]), params[2] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]),
ctx->ac.i32_0, ""); /* vindex */ ctx->ac.i32_0, ""); /* vindex */
LLVMValueRef da = is_da ? i1true : i1false; LLVMValueRef da = is_da ? i1true : i1false;
LLVMValueRef slc = i1false; LLVMValueRef slc = i1false;


params[0] = to_float(&ctx->ac, get_src(ctx, instr->src[2]));
params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[2]));
params[1] = get_image_coords(ctx, instr); /* coords */ params[1] = get_image_coords(ctx, instr); /* coords */
params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, true); params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, true);
params[3] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */ params[3] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */
return NULL; return NULL;
} }


result = LLVMBuildAtomicRMW(ctx->builder, op, ptr, to_integer(&ctx->ac, src),
result = LLVMBuildAtomicRMW(ctx->builder, op, ptr, ac_to_integer(&ctx->ac, src),
LLVMAtomicOrderingSequentiallyConsistent, LLVMAtomicOrderingSequentiallyConsistent,
false); false);
} }
} }


if (instr->intrinsic == nir_intrinsic_interp_var_at_offset) { if (instr->intrinsic == nir_intrinsic_interp_var_at_offset) {
src_c0 = to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->i32zero, ""));
src_c1 = to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->i32one, ""));
src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->i32zero, ""));
src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->i32one, ""));
} else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) { } else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) {
LLVMValueRef sample_position; LLVMValueRef sample_position;
LLVMValueRef halfval = LLVMConstReal(ctx->f32, 0.5f); LLVMValueRef halfval = LLVMConstReal(ctx->f32, 0.5f);
static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx, static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx,
LLVMValueRef coord) LLVMValueRef coord)
{ {
coord = to_float(ctx, coord);
coord = ac_to_float(ctx, coord);
coord = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32, &coord, 1, 0); coord = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32, &coord, 1, 0);
coord = to_integer(ctx, coord);
coord = ac_to_integer(ctx, coord);
return coord; return coord;
} }




/* Pack depth comparison value */ /* Pack depth comparison value */
if (instr->is_shadow && comparator) { if (instr->is_shadow && comparator) {
LLVMValueRef z = to_float(&ctx->ac,
llvm_extract_elem(&ctx->ac, comparator, 0));
LLVMValueRef z = ac_to_float(&ctx->ac,
llvm_extract_elem(&ctx->ac, comparator, 0));


/* TC-compatible HTILE promotes Z16 and Z24 to Z32_FLOAT, /* TC-compatible HTILE promotes Z16 and Z24 to Z32_FLOAT,
* so the depth comparison value isn't clamped for Z16 and * so the depth comparison value isn't clamped for Z16 and
} }


for (unsigned i = 0; i < num_deriv_comp; i++) { 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));
derivs[i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddx, i));
derivs[num_deriv_comp + i] = ac_to_float(&ctx->ac, llvm_extract_elem(&ctx->ac, ddy, i));
} }
} }


if (instr->is_array && instr->op != nir_texop_lod) if (instr->is_array && instr->op != nir_texop_lod)
coords[3] = apply_round_slice(&ctx->ac, coords[3]); coords[3] = apply_round_slice(&ctx->ac, coords[3]);
for (chan = 0; chan < instr->coord_components; chan++) for (chan = 0; chan < instr->coord_components; chan++)
coords[chan] = to_float(&ctx->ac, coords[chan]);
coords[chan] = ac_to_float(&ctx->ac, coords[chan]);
if (instr->coord_components == 3) if (instr->coord_components == 3)
coords[3] = LLVMGetUndef(ctx->ac.f32); coords[3] = LLVMGetUndef(ctx->ac.f32);
ac_prepare_cube_coords(&ctx->ac, ac_prepare_cube_coords(&ctx->ac,
write_result: write_result:
if (result) { if (result) {
assert(instr->dest.is_ssa); assert(instr->dest.is_ssa);
result = to_integer(&ctx->ac, result);
result = ac_to_integer(&ctx->ac, result);
_mesa_hash_table_insert(ctx->defs, &instr->dest.ssa, result); _mesa_hash_table_insert(ctx->defs, &instr->dest.ssa, result);
} }
} }
for (unsigned chan = 0; chan < 4; chan++) { for (unsigned chan = 0; chan < 4; chan++) {
LLVMValueRef llvm_chan = LLVMConstInt(ctx->i32, chan, false); LLVMValueRef llvm_chan = LLVMConstInt(ctx->i32, chan, false);
ctx->inputs[radeon_llvm_reg_index_soa(idx, chan)] = ctx->inputs[radeon_llvm_reg_index_soa(idx, chan)] =
to_integer(&ctx->ac, LLVMBuildExtractElement(ctx->builder,
ac_to_integer(&ctx->ac, LLVMBuildExtractElement(ctx->builder,
input, llvm_chan, "")); input, llvm_chan, ""));
} }
} }
static LLVMValueRef static LLVMValueRef
emit_float_saturate(struct ac_llvm_context *ctx, LLVMValueRef v, float lo, float hi) emit_float_saturate(struct ac_llvm_context *ctx, LLVMValueRef v, float lo, float hi)
{ {
v = to_float(ctx, v);
v = ac_to_float(ctx, v);
v = emit_intrin_2f_param(ctx, "llvm.maxnum", ctx->f32, v, LLVMConstReal(ctx->f32, lo)); v = emit_intrin_2f_param(ctx, "llvm.maxnum", ctx->f32, v, LLVMConstReal(ctx->f32, lo));
return emit_intrin_2f_param(ctx, "llvm.minnum", ctx->f32, v, LLVMConstReal(ctx->f32, hi)); return emit_intrin_2f_param(ctx, "llvm.minnum", ctx->f32, v, LLVMConstReal(ctx->f32, hi));
} }
LLVMValueRef max_alpha = !is_int10 ? max_rgb : LLVMConstInt(ctx->i32, 3, 0); LLVMValueRef max_alpha = !is_int10 ? max_rgb : LLVMConstInt(ctx->i32, 3, 0);


for (unsigned chan = 0; chan < 4; chan++) { for (unsigned chan = 0; chan < 4; chan++) {
val[chan] = to_integer(&ctx->ac, values[chan]);
val[chan] = ac_to_integer(&ctx->ac, values[chan]);
val[chan] = emit_minmax_int(&ctx->ac, LLVMIntULT, val[chan], chan == 3 ? max_alpha : max_rgb); val[chan] = emit_minmax_int(&ctx->ac, LLVMIntULT, val[chan], chan == 3 ? max_alpha : max_rgb);
} }




/* Clamp. */ /* Clamp. */
for (unsigned chan = 0; chan < 4; chan++) { for (unsigned chan = 0; chan < 4; chan++) {
val[chan] = to_integer(&ctx->ac, values[chan]);
val[chan] = ac_to_integer(&ctx->ac, values[chan]);
val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSLT, val[chan], chan == 3 ? max_alpha : max_rgb); val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSLT, val[chan], chan == 3 ? max_alpha : max_rgb);
val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSGT, val[chan], chan == 3 ? min_alpha : min_rgb); val[chan] = emit_minmax_int(&ctx->ac, LLVMIntSGT, val[chan], chan == 3 ? min_alpha : min_rgb);
} }
memcpy(&args->out[0], values, sizeof(values[0]) * 4); memcpy(&args->out[0], values, sizeof(values[0]) * 4);


for (unsigned i = 0; i < 4; ++i) for (unsigned i = 0; i < 4; ++i)
args->out[i] = to_float(&ctx->ac, args->out[i]);
args->out[i] = ac_to_float(&ctx->ac, args->out[i]);
} }


static void static void
si_build_alloca_undef(&ctx->ac, ctx->ac.f32, ""); si_build_alloca_undef(&ctx->ac, ctx->ac.f32, "");
} }


LLVMBuildStore(ctx->builder, to_float(&ctx->ac, ctx->view_index), *tmp_out);
LLVMBuildStore(ctx->builder, ac_to_float(&ctx->ac, ctx->view_index), *tmp_out);
ctx->output_mask |= 1ull << VARYING_SLOT_LAYER; ctx->output_mask |= 1ull << VARYING_SLOT_LAYER;
} }




i = VARYING_SLOT_CLIP_DIST0; i = VARYING_SLOT_CLIP_DIST0;
for (j = 0; j < ctx->num_output_clips + ctx->num_output_culls; j++) for (j = 0; j < ctx->num_output_clips + ctx->num_output_culls; j++)
slots[j] = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
slots[j] = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], "")); ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));


for (i = ctx->num_output_clips + ctx->num_output_culls; i < 8; i++) for (i = ctx->num_output_clips + ctx->num_output_culls; i < 8; i++)
* index in out.z[19:16]. * index in out.z[19:16].
*/ */
LLVMValueRef v = viewport_index_value; LLVMValueRef v = viewport_index_value;
v = to_integer(&ctx->ac, v);
v = ac_to_integer(&ctx->ac, v);
v = LLVMBuildShl(ctx->builder, v, v = LLVMBuildShl(ctx->builder, v,
LLVMConstInt(ctx->i32, 16, false), LLVMConstInt(ctx->i32, 16, false),
""); "");
v = LLVMBuildOr(ctx->builder, v, v = LLVMBuildOr(ctx->builder, v,
to_integer(&ctx->ac, pos_args[1].out[2]), "");
ac_to_integer(&ctx->ac, pos_args[1].out[2]), "");


pos_args[1].out[2] = to_float(&ctx->ac, v);
pos_args[1].out[2] = ac_to_float(&ctx->ac, v);
pos_args[1].enabled_channels |= 1 << 2; pos_args[1].enabled_channels |= 1 << 2;
} else { } else {
pos_args[1].out[3] = viewport_index_value; pos_args[1].out[3] = viewport_index_value;
continue; continue;


for (unsigned j = 0; j < 4; j++) for (unsigned j = 0; j < 4; j++)
values[j] = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));
values[j] = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));


if (i == VARYING_SLOT_LAYER) { if (i == VARYING_SLOT_LAYER) {
target = V_008DFC_SQ_EXP_PARAM + param_count; target = V_008DFC_SQ_EXP_PARAM + param_count;


if (i == FRAG_RESULT_DEPTH) { if (i == FRAG_RESULT_DEPTH) {
ctx->shader_info->fs.writes_z = true; ctx->shader_info->fs.writes_z = true;
depth = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
depth = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], "")); ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
} else if (i == FRAG_RESULT_STENCIL) { } else if (i == FRAG_RESULT_STENCIL) {
ctx->shader_info->fs.writes_stencil = true; ctx->shader_info->fs.writes_stencil = true;
stencil = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
stencil = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], "")); ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
} else if (i == FRAG_RESULT_SAMPLE_MASK) { } else if (i == FRAG_RESULT_SAMPLE_MASK) {
ctx->shader_info->fs.writes_sample_mask = true; ctx->shader_info->fs.writes_sample_mask = true;
samplemask = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
samplemask = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], "")); ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
} else { } else {
bool last = false; bool last = false;
for (unsigned j = 0; j < 4; j++) for (unsigned j = 0; j < 4; j++)
values[j] = to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
values[j] = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], "")); ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));


if (!ctx->shader_info->fs.writes_z && !ctx->shader_info->fs.writes_stencil && !ctx->shader_info->fs.writes_sample_mask) if (!ctx->shader_info->fs.writes_z && !ctx->shader_info->fs.writes_stencil && !ctx->shader_info->fs.writes_sample_mask)
AC_FUNC_ATTR_LEGACY); AC_FUNC_ATTR_LEGACY);


LLVMBuildStore(ctx->builder, LLVMBuildStore(ctx->builder,
to_float(&ctx->ac, value), ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)]);
ac_to_float(&ctx->ac, value), ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)]);
} }
idx += slot_inc; idx += slot_inc;
} }

Loading…
Cancel
Save