diff options
author | Kenneth Graunke <[email protected]> | 2015-06-04 17:00:17 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2015-06-06 13:26:10 -0700 |
commit | 7b8f20ec5505a25958bcd98aabe73a7ca2b6cbba (patch) | |
tree | c399b0bd6e0ff32b57425d6198514e7399161790 | |
parent | 52e5ad7bf8c731280ca4506b7d38e8c7a8e734b9 (diff) |
prog_to_nir: Fix fragment depth writes.
In the ARB_fragment_program specification, the result.depth output
variable is treated as a vec4, where the fragment depth is stored in the
.z component, and the other three components are undefined.
This is different than GLSL, which uses a scalar value (gl_FragDepth).
To make this consistent for driver backends, this patch makes
prog_to_nir use a scalar output variable for FRAG_RESULT_DEPTH,
moving result.depth.z into the first component.
Fixes Glean's fragProg1 "Z-write test" subtest.
Cc: [email protected]
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90000
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
-rw-r--r-- | src/mesa/program/prog_to_nir.c | 22 |
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); |