args->out[i] = ac_to_float(&ctx->ac, args->out[i]);
}
+static void
+radv_export_param(struct nir_to_llvm_context *ctx, unsigned index,
+ LLVMValueRef *values)
+{
+ struct ac_export_args args;
+
+ si_llvm_init_export_args(ctx, values,
+ V_008DFC_SQ_EXP_PARAM + index, &args);
+ ac_build_export(&ctx->ac, &args);
+}
+
+static LLVMValueRef
+radv_load_output(struct nir_to_llvm_context *ctx, unsigned index, unsigned chan)
+{
+ LLVMValueRef output =
+ ctx->nir->outputs[radeon_llvm_reg_index_soa(index, chan)];
+
+ return LLVMBuildLoad(ctx->builder, output, "");
+}
+
static void
handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
bool export_prim_id,
i = VARYING_SLOT_CLIP_DIST0;
for (j = 0; j < ctx->num_output_clips + ctx->num_output_culls; j++)
- slots[j] = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));
+ slots[j] = ac_to_float(&ctx->ac, radv_load_output(ctx, i, j));
for (i = ctx->num_output_clips + ctx->num_output_culls; i < 8; i++)
slots[i] = LLVMGetUndef(ctx->ac.f32);
LLVMValueRef pos_values[4] = {ctx->ac.f32_0, ctx->ac.f32_0, ctx->ac.f32_0, ctx->ac.f32_1};
if (ctx->output_mask & (1ull << VARYING_SLOT_POS)) {
for (unsigned j = 0; j < 4; j++)
- pos_values[j] = LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(VARYING_SLOT_POS, j)], "");
+ pos_values[j] = radv_load_output(ctx, VARYING_SLOT_POS, j);
}
si_llvm_init_export_args(ctx, pos_values, V_008DFC_SQ_EXP_POS, &pos_args[0]);
if (ctx->output_mask & (1ull << VARYING_SLOT_PSIZ)) {
outinfo->writes_pointsize = true;
- psize_value = LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(VARYING_SLOT_PSIZ, 0)], "");
+ psize_value = radv_load_output(ctx, VARYING_SLOT_PSIZ, 0);
}
if (ctx->output_mask & (1ull << VARYING_SLOT_LAYER)) {
outinfo->writes_layer = true;
- layer_value = LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)], "");
+ layer_value = radv_load_output(ctx, VARYING_SLOT_LAYER, 0);
}
if (ctx->output_mask & (1ull << VARYING_SLOT_VIEWPORT)) {
outinfo->writes_viewport_index = true;
- viewport_index_value = LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(VARYING_SLOT_VIEWPORT, 0)], "");
+ viewport_index_value = radv_load_output(ctx, VARYING_SLOT_VIEWPORT, 0);
}
if (outinfo->writes_pointsize ||
if (!(ctx->output_mask & (1ull << i)))
continue;
- for (unsigned j = 0; j < 4; 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) {
- target = V_008DFC_SQ_EXP_PARAM + param_count;
- outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = param_count;
- param_count++;
- } else if (i == VARYING_SLOT_PRIMITIVE_ID) {
- target = V_008DFC_SQ_EXP_PARAM + param_count;
- outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
- param_count++;
- } else if (i >= VARYING_SLOT_VAR0) {
- outinfo->export_mask |= 1u << (i - VARYING_SLOT_VAR0);
- target = V_008DFC_SQ_EXP_PARAM + param_count;
- outinfo->vs_output_param_offset[i] = param_count;
- param_count++;
- } else
+ if (i != VARYING_SLOT_LAYER &&
+ i != VARYING_SLOT_PRIMITIVE_ID &&
+ i < VARYING_SLOT_VAR0)
continue;
- si_llvm_init_export_args(ctx, values, target, &args);
- ac_build_export(&ctx->ac, &args);
+ for (unsigned j = 0; j < 4; j++)
+ values[j] = ac_to_float(&ctx->ac, radv_load_output(ctx, i, j));
+
+ radv_export_param(ctx, param_count, values);
+
+ outinfo->vs_output_param_offset[i] = param_count++;
}
if (export_prim_id) {
LLVMValueRef values[4];
- target = V_008DFC_SQ_EXP_PARAM + param_count;
- outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
- param_count++;
values[0] = ctx->vs_prim_id;
ctx->shader_info->vs.vgpr_comp_cnt = MAX2(2,
ctx->shader_info->vs.vgpr_comp_cnt);
for (unsigned j = 1; j < 4; j++)
values[j] = ctx->ac.f32_0;
- si_llvm_init_export_args(ctx, values, target, &args);
- ac_build_export(&ctx->ac, &args);
+
+ radv_export_param(ctx, param_count, values);
+
+ outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
outinfo->export_prim_id = true;
}
static bool
si_export_mrt_color(struct nir_to_llvm_context *ctx,
- LLVMValueRef *color, unsigned param, bool is_last,
+ LLVMValueRef *color, unsigned index, bool is_last,
struct ac_export_args *args)
{
/* Export */
- si_llvm_init_export_args(ctx, color, param,
- args);
+ si_llvm_init_export_args(ctx, color,
+ V_008DFC_SQ_EXP_MRT + index, args);
if (is_last) {
args->valid_mask = 1; /* whether the EXEC mask is valid */
for (unsigned i = 0; i < RADEON_LLVM_MAX_OUTPUTS; ++i) {
LLVMValueRef values[4];
+ bool last = false;
if (!(ctx->output_mask & (1ull << i)))
continue;
- if (i == FRAG_RESULT_DEPTH) {
- ctx->shader_info->fs.writes_z = true;
- depth = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
- } else if (i == FRAG_RESULT_STENCIL) {
- ctx->shader_info->fs.writes_stencil = true;
- stencil = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
- } else if (i == FRAG_RESULT_SAMPLE_MASK) {
- ctx->shader_info->fs.writes_sample_mask = true;
- samplemask = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(i, 0)], ""));
- } else {
- bool last = false;
- for (unsigned j = 0; j < 4; j++)
- values[j] = ac_to_float(&ctx->ac, LLVMBuildLoad(ctx->builder,
- ctx->nir->outputs[radeon_llvm_reg_index_soa(i, j)], ""));
+ if (i < FRAG_RESULT_DATA0)
+ continue;
- if (!ctx->shader_info->fs.writes_z && !ctx->shader_info->fs.writes_stencil && !ctx->shader_info->fs.writes_sample_mask)
- last = ctx->output_mask <= ((1ull << (i + 1)) - 1);
+ for (unsigned j = 0; j < 4; j++)
+ values[j] = ac_to_float(&ctx->ac,
+ radv_load_output(ctx, i, j));
- bool ret = si_export_mrt_color(ctx, values, V_008DFC_SQ_EXP_MRT + (i - FRAG_RESULT_DATA0), last, &color_args[index]);
- if (ret)
- index++;
- }
+ if (!ctx->shader_info->info.ps.writes_z &&
+ !ctx->shader_info->info.ps.writes_stencil &&
+ !ctx->shader_info->info.ps.writes_sample_mask)
+ last = ctx->output_mask <= ((1ull << (i + 1)) - 1);
+
+ bool ret = si_export_mrt_color(ctx, values,
+ i - FRAG_RESULT_DATA0,
+ last, &color_args[index]);
+ if (ret)
+ index++;
}
+ /* Process depth, stencil, samplemask. */
+ if (ctx->shader_info->info.ps.writes_z) {
+ depth = ac_to_float(&ctx->ac,
+ radv_load_output(ctx, FRAG_RESULT_DEPTH, 0));
+ }
+ if (ctx->shader_info->info.ps.writes_stencil) {
+ stencil = ac_to_float(&ctx->ac,
+ radv_load_output(ctx, FRAG_RESULT_STENCIL, 0));
+ }
+ if (ctx->shader_info->info.ps.writes_sample_mask) {
+ samplemask = ac_to_float(&ctx->ac,
+ radv_load_output(ctx, FRAG_RESULT_SAMPLE_MASK, 0));
+ }
+
+ /* Export PS outputs. */
for (unsigned i = 0; i < index; i++)
ac_build_export(&ctx->ac, &color_args[i]);
+
if (depth || stencil || samplemask)
radv_export_mrt_z(ctx, depth, stencil, samplemask);
- else if (!index) {
+ else if (!index)
ac_build_export_null(&ctx->ac);
- }
}
static void