program: Extend prog_to_nir handle system values.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 1 Feb 2019 05:52:50 +0000 (21:52 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 5 Feb 2019 21:51:51 +0000 (13:51 -0800)
Some drivers, such as radeonsi, use a system value for gl_FragCoord
rather than an input variable.  In this case, our Mesa IR will have
a PROGRAM_SYSTEM_VALUE register, which we need to translate.

This makes prog_to_nir work for Gallium drivers which expose the
PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL capability bit.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/program/prog_to_nir.c

index 0f7601a68687971d3143d62edf5c4c24d505d87a..afa490cdb363720acc93f25f75e5794e06b0d12e 100644 (file)
@@ -52,6 +52,7 @@ struct ptn_compile {
    nir_variable *parameters;
    nir_variable *input_vars[VARYING_SLOT_MAX];
    nir_variable *output_vars[VARYING_SLOT_MAX];
+   nir_variable *sysval_vars[SYSTEM_VALUE_MAX];
    nir_variable *sampler_vars[32]; /* matches number of bits in TexSrcUnit */
    nir_register **output_regs;
    nir_register **temp_regs;
@@ -142,6 +143,15 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
       src.src = nir_src_for_ssa(nir_load_var(b, var));
       break;
    }
+   case PROGRAM_SYSTEM_VALUE: {
+      assert(!prog_src->RelAddr);
+
+      assert(prog_src->Index >= 0 && prog_src->Index < SYSTEM_VALUE_MAX);
+
+      nir_variable *var = c->sysval_vars[prog_src->Index];
+      src.src = nir_src_for_ssa(nir_load_var(b, var));
+      break;
+   }
    case PROGRAM_STATE_VAR:
    case PROGRAM_CONSTANT: {
       /* We actually want to look at the type in the Parameters list for this,
@@ -902,6 +912,26 @@ setup_registers_and_variables(struct ptn_compile *c)
       c->input_vars[i] = var;
    }
 
+   /* Create system value variables */
+   uint64_t system_values_read = c->prog->info.system_values_read;
+   while (system_values_read) {
+      const int i = u_bit_scan64(&system_values_read);
+
+      nir_variable *var =
+         nir_variable_create(shader, nir_var_system_value, glsl_vec4_type(),
+                             ralloc_asprintf(shader, "sv_%d", i));
+      var->data.location = i;
+      var->data.index = 0;
+
+      if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
+          i == SYSTEM_VALUE_FRAG_COORD) {
+         var->data.origin_upper_left = c->prog->OriginUpperLeft;
+         var->data.pixel_center_integer = c->prog->PixelCenterInteger;
+      }
+
+      c->sysval_vars[i] = var;
+   }
+
    /* Create output registers and variables. */
    int max_outputs = util_last_bit(c->prog->info.outputs_written);
    c->output_regs = rzalloc_array(c, nir_register *, max_outputs);