diff options
-rw-r--r-- | src/gallium/auxiliary/nir/tgsi_to_nir.c | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index 8efae63b639..7437c80679e 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -71,6 +71,9 @@ struct ttn_compile { nir_variable **inputs; nir_variable **outputs; + nir_variable *input_var_face; + nir_variable *input_var_position; + /** * Stack of nir_cursors where instructions should be pushed as we pop * back out of the control flow stack. @@ -284,8 +287,22 @@ ttn_emit_declaration(struct ttn_compile *c) if (c->scan->processor == PIPE_SHADER_FRAGMENT) { if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) { - var->data.location = SYSTEM_VALUE_FRONT_FACE; - var->data.mode = nir_var_system_value; + var->type = glsl_bool_type(); + if (c->cap_face_is_sysval) { + var->data.mode = nir_var_system_value; + var->data.location = SYSTEM_VALUE_FRONT_FACE; + } else { + var->data.location = VARYING_SLOT_FACE; + } + c->input_var_face = var; + } else if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) { + if (c->cap_position_is_sysval) { + var->data.mode = nir_var_system_value; + var->data.location = SYSTEM_VALUE_FRAG_COORD; + } else { + var->data.location = VARYING_SLOT_POS; + } + c->input_var_position = var; } else { var->data.location = tgsi_varying_semantic_to_slot(decl->Semantic.Name, @@ -441,20 +458,43 @@ ttn_array_deref(struct ttn_compile *c, nir_variable *var, unsigned offset, } /* Special case: Turn the frontface varying into a load of the - * frontface intrinsic plus math, and appending the silly floats. + * frontface variable, and create the vector as required by TGSI. */ static nir_ssa_def * ttn_emulate_tgsi_front_face(struct ttn_compile *c) { - nir_ssa_def *tgsi_frontface[4] = { - nir_bcsel(&c->build, - nir_load_front_face(&c->build, 1), - nir_imm_float(&c->build, 1.0), - nir_imm_float(&c->build, -1.0)), - nir_imm_float(&c->build, 0.0), - nir_imm_float(&c->build, 0.0), - nir_imm_float(&c->build, 1.0), - }; + nir_ssa_def *tgsi_frontface[4]; + + if (c->cap_face_is_sysval) { + /* When it's a system value, it should be an integer vector: (F, 0, 0, 1) + * F is 0xffffffff if front-facing, 0 if not. + */ + + nir_ssa_def *frontface = nir_load_front_face(&c->build, 1); + + tgsi_frontface[0] = nir_bcsel(&c->build, + frontface, + nir_imm_int(&c->build, 0xffffffff), + nir_imm_int(&c->build, 0)); + tgsi_frontface[1] = nir_imm_int(&c->build, 0); + tgsi_frontface[2] = nir_imm_int(&c->build, 0); + tgsi_frontface[3] = nir_imm_int(&c->build, 1); + } else { + /* When it's an input, it should be a float vector: (F, 0.0, 0.0, 1.0) + * F is positive if front-facing, negative if not. + */ + + assert(c->input_var_face); + nir_ssa_def *frontface = nir_load_var(&c->build, c->input_var_face); + + tgsi_frontface[0] = nir_bcsel(&c->build, + frontface, + nir_imm_float(&c->build, 1.0), + nir_imm_float(&c->build, -1.0)); + tgsi_frontface[1] = nir_imm_float(&c->build, 0.0); + tgsi_frontface[2] = nir_imm_float(&c->build, 0.0); + tgsi_frontface[3] = nir_imm_float(&c->build, 1.0); + } return nir_vec(&c->build, tgsi_frontface, 4); } @@ -521,6 +561,16 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index, op = nir_intrinsic_load_instance_id; load = nir_load_instance_id(b); break; + case TGSI_SEMANTIC_FACE: + assert(c->cap_face_is_sysval); + op = nir_intrinsic_load_front_face; + load = ttn_emulate_tgsi_front_face(c); + break; + case TGSI_SEMANTIC_POSITION: + assert(c->cap_position_is_sysval); + op = nir_intrinsic_load_frag_coord; + load = nir_load_frag_coord(b); + break; default: unreachable("bad system value"); } @@ -535,7 +585,12 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index, case TGSI_FILE_INPUT: if (c->scan->processor == PIPE_SHADER_FRAGMENT && c->scan->input_semantic_name[index] == TGSI_SEMANTIC_FACE) { + assert(!c->cap_face_is_sysval && c->input_var_face); return nir_src_for_ssa(ttn_emulate_tgsi_front_face(c)); + } else if (c->scan->processor == PIPE_SHADER_FRAGMENT && + c->scan->input_semantic_name[index] == TGSI_SEMANTIC_POSITION) { + assert(!c->cap_position_is_sysval && c->input_var_position); + return nir_src_for_ssa(nir_load_var(&c->build, c->input_var_position)); } else { /* Indirection on input arrays isn't supported by TTN. */ assert(!dim); @@ -1971,6 +2026,7 @@ ttn_finalize_nir(struct ttn_compile *c) NIR_PASS_V(nir, nir_lower_global_vars_to_local); NIR_PASS_V(nir, nir_split_var_copies); NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS_V(nir, nir_lower_system_values); if (c->cap_packed_uniforms) NIR_PASS_V(nir, nir_lower_uniforms_to_ubo, 16); |