summaryrefslogtreecommitdiffstats
path: root/src/mesa/program/prog_to_nir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/program/prog_to_nir.c')
-rw-r--r--src/mesa/program/prog_to_nir.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c
index d3e3f15c959..d54f934247d 100644
--- a/src/mesa/program/prog_to_nir.c
+++ b/src/mesa/program/prog_to_nir.c
@@ -924,10 +924,23 @@ ptn_add_output_stores(struct ptn_compile *c)
foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
nir_intrinsic_instr *store =
nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
- store->num_components = 4;
+ store->num_components = glsl_get_vector_elements(var->type);
store->variables[0] =
nir_deref_var_create(store, c->output_vars[var->data.location]);
- store->src[0].reg.reg = c->output_regs[var->data.location];
+
+ if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
+ var->data.location == FRAG_RESULT_DEPTH) {
+ /* result.depth has this strange convention of being the .z component of
+ * a vec4 with undefined .xyw components. We resolve it to a scalar, to
+ * match GLSL's gl_FragDepth and the expectations of most backends.
+ */
+ nir_alu_src alu_src = { NIR_SRC_INIT };
+ alu_src.src = nir_src_for_reg(c->output_regs[FRAG_RESULT_DEPTH]);
+ alu_src.swizzle[0] = SWIZZLE_Z;
+ store->src[0] = nir_src_for_ssa(nir_fmov_alu(b, alu_src, 1));
+ } else {
+ store->src[0].reg.reg = c->output_regs[var->data.location];
+ }
nir_instr_insert_after_cf_list(c->build.cf_node_list, &store->instr);
}
}
@@ -1020,7 +1033,10 @@ setup_registers_and_variables(struct ptn_compile *c)
reg->num_components = 4;
nir_variable *var = rzalloc(shader, nir_variable);
- var->type = glsl_vec4_type();
+ if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB && i == FRAG_RESULT_DEPTH)
+ var->type = glsl_float_type();
+ else
+ var->type = glsl_vec4_type();
var->data.mode = nir_var_shader_out;
var->name = ralloc_asprintf(var, "out_%d", i);