assert(cond);
LLVMValueRef alpha_ref = LLVMGetParam(ctx->main_fn, SI_PARAM_ALPHA_REF);
+ if (LLVMTypeOf(alpha) == ctx->ac.f16)
+ alpha_ref = LLVMBuildFPTrunc(ctx->ac.builder, alpha_ref, ctx->ac.f16, "");
+
LLVMValueRef alpha_pass = LLVMBuildFCmp(ctx->ac.builder, cond, alpha, alpha_ref, "");
ac_build_kill_if_false(&ctx->ac, alpha_pass);
} else {
coverage = LLVMBuildFMul(ctx->ac.builder, coverage,
LLVMConstReal(ctx->ac.f32, 1.0 / SI_NUM_SMOOTH_AA_SAMPLES), "");
+ if (LLVMTypeOf(alpha) == ctx->ac.f16)
+ coverage = LLVMBuildFPTrunc(ctx->ac.builder, coverage, ctx->ac.f16, "");
+
return LLVMBuildFMul(ctx->ac.builder, alpha, coverage, "");
}
struct ac_export_args args[10];
};
+static LLVMValueRef pack_two_16bit(struct ac_llvm_context *ctx, LLVMValueRef args[2])
+{
+ LLVMValueRef tmp = ac_build_gather_values(ctx, args, 2);
+ return LLVMBuildBitCast(ctx->builder, tmp, ctx->v2f16, "");
+}
+
+static LLVMValueRef get_color_32bit(struct si_shader_context *ctx, unsigned color_type,
+ LLVMValueRef value)
+{
+ switch (color_type) {
+ case SI_TYPE_FLOAT16:
+ return LLVMBuildFPExt(ctx->ac.builder, value, ctx->ac.f32, "");
+ case SI_TYPE_INT16:
+ value = ac_to_integer(&ctx->ac, value);
+ value = LLVMBuildSExt(ctx->ac.builder, value, ctx->ac.i32, "");
+ return ac_to_float(&ctx->ac, value);
+ case SI_TYPE_UINT16:
+ value = ac_to_integer(&ctx->ac, value);
+ value = LLVMBuildZExt(ctx->ac.builder, value, ctx->ac.i32, "");
+ return ac_to_float(&ctx->ac, value);
+ case SI_TYPE_ANY32:
+ return value;
+ }
+ return NULL;
+}
+
/* Initialize arguments for the shader export intrinsic */
static void si_llvm_init_ps_export_args(struct si_shader_context *ctx, LLVMValueRef *values,
unsigned cbuf, unsigned compacted_mrt_index,
- struct ac_export_args *args)
+ unsigned color_type, struct ac_export_args *args)
{
const struct si_shader_key *key = &ctx->shader->key;
unsigned col_formats = key->part.ps.epilog.spi_shader_col_format;
case V_028714_SPI_SHADER_32_R:
args->enabled_channels = 1; /* writemask */
- args->out[0] = values[0];
+ args->out[0] = get_color_32bit(ctx, color_type, values[0]);
break;
case V_028714_SPI_SHADER_32_GR:
args->enabled_channels = 0x3; /* writemask */
- args->out[0] = values[0];
- args->out[1] = values[1];
+ args->out[0] = get_color_32bit(ctx, color_type, values[0]);
+ args->out[1] = get_color_32bit(ctx, color_type, values[1]);
break;
case V_028714_SPI_SHADER_32_AR:
if (ctx->screen->info.chip_class >= GFX10) {
args->enabled_channels = 0x3; /* writemask */
- args->out[0] = values[0];
- args->out[1] = values[3];
+ args->out[0] = get_color_32bit(ctx, color_type, values[0]);
+ args->out[1] = get_color_32bit(ctx, color_type, values[3]);
} else {
args->enabled_channels = 0x9; /* writemask */
- args->out[0] = values[0];
- args->out[3] = values[3];
+ args->out[0] = get_color_32bit(ctx, color_type, values[0]);
+ args->out[3] = get_color_32bit(ctx, color_type, values[3]);
}
break;
case V_028714_SPI_SHADER_FP16_ABGR:
- packf = ac_build_cvt_pkrtz_f16;
+ if (color_type != SI_TYPE_ANY32)
+ packf = pack_two_16bit;
+ else
+ packf = ac_build_cvt_pkrtz_f16;
break;
case V_028714_SPI_SHADER_UNORM16_ABGR:
- packf = ac_build_cvt_pknorm_u16;
+ if (color_type != SI_TYPE_ANY32)
+ packf = ac_build_cvt_pknorm_u16_f16;
+ else
+ packf = ac_build_cvt_pknorm_u16;
break;
case V_028714_SPI_SHADER_SNORM16_ABGR:
- packf = ac_build_cvt_pknorm_i16;
+ if (color_type != SI_TYPE_ANY32)
+ packf = ac_build_cvt_pknorm_i16_f16;
+ else
+ packf = ac_build_cvt_pknorm_i16;
break;
case V_028714_SPI_SHADER_UINT16_ABGR:
- packi = ac_build_cvt_pk_u16;
+ if (color_type != SI_TYPE_ANY32)
+ packf = pack_two_16bit;
+ else
+ packi = ac_build_cvt_pk_u16;
break;
case V_028714_SPI_SHADER_SINT16_ABGR:
- packi = ac_build_cvt_pk_i16;
+ if (color_type != SI_TYPE_ANY32)
+ packf = pack_two_16bit;
+ else
+ packi = ac_build_cvt_pk_i16;
break;
case V_028714_SPI_SHADER_32_ABGR:
- memcpy(&args->out[0], values, sizeof(values[0]) * 4);
+ for (unsigned i = 0; i < 4; i++)
+ args->out[i] = get_color_32bit(ctx, color_type, values[i]);
break;
}
static bool si_export_mrt_color(struct si_shader_context *ctx, LLVMValueRef *color, unsigned index,
unsigned compacted_mrt_index, unsigned samplemask_param,
- bool is_last, struct si_ps_exports *exp)
+ bool is_last, unsigned color_type, struct si_ps_exports *exp)
{
int i;
/* Alpha to one */
if (ctx->shader->key.part.ps.epilog.alpha_to_one)
- color[3] = ctx->ac.f32_1;
+ color[3] = LLVMConstReal(LLVMTypeOf(color[0]), 1);
/* Alpha test */
if (index == 0 && ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS)
/* Get the export arguments, also find out what the last one is. */
for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; c++) {
- si_llvm_init_ps_export_args(ctx, color, c, compacted_mrt_index, &args[c]);
+ si_llvm_init_ps_export_args(ctx, color, c, compacted_mrt_index,
+ color_type, &args[c]);
if (args[c].enabled_channels) {
compacted_mrt_index++;
last = c;
struct ac_export_args args;
/* Export */
- si_llvm_init_ps_export_args(ctx, color, index, compacted_mrt_index, &args);
+ si_llvm_init_ps_export_args(ctx, color, index, compacted_mrt_index,
+ color_type, &args);
if (is_last) {
args.valid_mask = 1; /* whether the EXEC mask is valid */
args.done = 1; /* DONE bit */
if (!color[i][0])
continue;
- for (j = 0; j < 4; j++)
- ret = LLVMBuildInsertValue(builder, ret, color[i][j], vgpr++, "");
+ if (LLVMTypeOf(color[i][0]) == ctx->ac.f16) {
+ for (j = 0; j < 2; j++) {
+ LLVMValueRef tmp = ac_build_gather_values(&ctx->ac, &color[i][j * 2], 2);
+ tmp = LLVMBuildBitCast(builder, tmp, ctx->ac.f32, "");
+ ret = LLVMBuildInsertValue(builder, ret, tmp, vgpr++, "");
+ }
+ vgpr += 2;
+ } else {
+ for (j = 0; j < 4; j++)
+ ret = LLVMBuildInsertValue(builder, ret, color[i][j], vgpr++, "");
+ }
}
if (depth)
ret = LLVMBuildInsertValue(builder, ret, depth, vgpr++, "");
while (colors_written) {
LLVMValueRef color[4];
int output_index = u_bit_scan(&colors_written);
+ unsigned color_type = (key->ps_epilog.color_types >> (output_index * 2)) & 0x3;
- for (i = 0; i < 4; i++)
- color[i] = LLVMGetParam(ctx->main_fn, vgpr++);
+ if (color_type != SI_TYPE_ANY32) {
+ for (i = 0; i < 4; i++) {
+ color[i] = LLVMGetParam(ctx->main_fn, vgpr + i / 2);
+ color[i] = LLVMBuildBitCast(ctx->ac.builder, color[i], ctx->ac.v2f16, "");
+ color[i] = ac_llvm_extract_elem(&ctx->ac, color[i], i % 2);
+ }
+ vgpr += 4;
+ } else {
+ for (i = 0; i < 4; i++)
+ color[i] = LLVMGetParam(ctx->main_fn, vgpr++);
+ }
if (si_export_mrt_color(ctx, color, output_index, num_compacted_mrts,
ctx->args.arg_count - 1,
- output_index == last_color_export, &exp))
+ output_index == last_color_export, color_type, &exp))
num_compacted_mrts++;
}