<div dir="ltr"><div>Random side-note: this half-fixes one of my gripes with blorp-nir.  Now if only I could figure out how to fix it the rest of the way...<br></div>--Jason<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 18, 2016 at 3:00 PM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This handles gl_FragCoord transformations and other window system vs.<br>
user FBO coordinate system flipping by multiplying/adding uniform<br>
values, rather than recompiles.<br>
<br>
This is much better because we have no decent way to guess whether<br>
the application is going to use a shader with the window system FBO<br>
or a user FBO, much less the drawable height.  This led to a lot of<br>
recompiles in many applications.<br>
<br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/intel/vulkan/anv_pipeline.c                |  5 +++++<br>
 src/mesa/drivers/dri/i965/brw_defines.h        |  1 -<br>
 src/mesa/drivers/dri/i965/brw_fs.cpp           | 25 +++----------------------<br>
 src/mesa/drivers/dri/i965/brw_fs.h             |  6 ++----<br>
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp |  8 ++++----<br>
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp       | 22 +++++++---------------<br>
 src/mesa/drivers/dri/i965/brw_nir.c            | 13 +++++++++++++<br>
 src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp | 16 +++++-----------<br>
 8 files changed, 39 insertions(+), 57 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c<br>
index faa0adb..a9cecd6 100644<br>
--- a/src/intel/vulkan/anv_pipeline.c<br>
+++ b/src/intel/vulkan/anv_pipeline.c<br>
@@ -142,6 +142,11 @@ anv_shader_compile_to_nir(struct anv_device *device,<br>
<br>
       free(spec_entries);<br>
<br>
+      if (stage == MESA_SHADER_FRAGMENT) {<br>
+         nir_lower_wpos_center(nir);<br>
+         nir_validate_shader(nir);<br>
+      }<br>
+<br>
       nir_lower_returns(nir);<br>
       nir_validate_shader(nir);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h<br>
index 3395c9b..666dfd9 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_defines.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_defines.h<br>
@@ -1103,7 +1103,6 @@ enum opcode {<br>
    FS_OPCODE_DDX_FINE,<br>
    /**<br>
     * Compute dFdy(), dFdyCoarse(), or dFdyFine().<br>
-    * src1 is an immediate storing the key->render_to_fbo boolean.<br>
     */<br>
    FS_OPCODE_DDY_COARSE,<br>
    FS_OPCODE_DDY_FINE,<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
index 65b64b6..7b761f0 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
@@ -1058,37 +1058,18 @@ fs_visitor::import_uniforms(fs_visitor *v)<br>
 }<br>
<br>
 fs_reg *<br>
-fs_visitor::emit_fragcoord_interpolation(bool pixel_center_integer,<br>
-                                         bool origin_upper_left)<br>
+fs_visitor::emit_fragcoord_interpolation()<br>
 {<br>
    assert(stage == MESA_SHADER_FRAGMENT);<br>
-   brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;<br>
    fs_reg *reg = new(this->mem_ctx) fs_reg(vgrf(glsl_type::vec4_type));<br>
    fs_reg wpos = *reg;<br>
-   bool flip = !origin_upper_left ^ key->render_to_fbo;<br>
<br>
    /* gl_FragCoord.x */<br>
-   if (pixel_center_integer) {<br>
-      bld.MOV(wpos, this->pixel_x);<br>
-   } else {<br>
-      bld.ADD(wpos, this->pixel_x, brw_imm_f(0.5f));<br>
-   }<br>
+   bld.MOV(wpos, this->pixel_x);<br>
    wpos = offset(wpos, bld, 1);<br>
<br>
    /* gl_FragCoord.y */<br>
-   if (!flip && pixel_center_integer) {<br>
-      bld.MOV(wpos, this->pixel_y);<br>
-   } else {<br>
-      fs_reg pixel_y = this->pixel_y;<br>
-      float offset = (pixel_center_integer ? 0.0f : 0.5f);<br>
-<br>
-      if (flip) {<br>
-        pixel_y.negate = true;<br>
-        offset += key->drawable_height - 1.0f;<br>
-      }<br>
-<br>
-      bld.ADD(wpos, pixel_y, brw_imm_f(offset));<br>
-   }<br>
+   bld.MOV(wpos, this->pixel_y);<br>
    wpos = offset(wpos, bld, 1);<br>
<br>
    /* gl_FragCoord.z */<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h<br>
index ac270cd..bcfe032 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs.h<br>
@@ -183,8 +183,7 @@ public:<br>
<br>
    void emit_dummy_fs();<br>
    void emit_repclear_shader();<br>
-   fs_reg *emit_fragcoord_interpolation(bool pixel_center_integer,<br>
-                                        bool origin_upper_left);<br>
+   fs_reg *emit_fragcoord_interpolation();<br>
    fs_inst *emit_linterp(const fs_reg &attr, const fs_reg &interp,<br>
                          glsl_interp_qualifier interpolation_mode,<br>
                          bool is_centroid, bool is_sample);<br>
@@ -456,8 +455,7 @@ private:<br>
                          struct brw_reg dst,<br>
                          struct brw_reg src);<br>
    void generate_ddx(enum opcode op, struct brw_reg dst, struct brw_reg src);<br>
-   void generate_ddy(enum opcode op, struct brw_reg dst, struct brw_reg src,<br>
-                     bool negate_value);<br>
+   void generate_ddy(enum opcode op, struct brw_reg dst, struct brw_reg src);<br>
    void generate_scratch_write(fs_inst *inst, struct brw_reg src);<br>
    void generate_scratch_read(fs_inst *inst, struct brw_reg dst);<br>
    void generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst);<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
index b9000d6..ed790b5 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
@@ -1099,9 +1099,10 @@ fs_generator::generate_ddx(enum opcode opcode,<br>
  */<br>
 void<br>
 fs_generator::generate_ddy(enum opcode opcode,<br>
-                           struct brw_reg dst, struct brw_reg src,<br>
-                           bool negate_value)<br>
+                           struct brw_reg dst, struct brw_reg src)<br>
 {<br>
+   bool negate_value = true;<br>
+<br>
    if (opcode == FS_OPCODE_DDY_FINE) {<br>
       /* From the Ivy Bridge PRM, volume 4 part 3, section 3.3.9 (Register<br>
        * Region Restrictions):<br>
@@ -2140,8 +2141,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)<br>
          break;<br>
       case FS_OPCODE_DDY_COARSE:<br>
       case FS_OPCODE_DDY_FINE:<br>
-         assert(src[1].file == BRW_IMMEDIATE_VALUE);<br>
-         generate_ddy(inst->opcode, dst, src[0], src[1].ud);<br>
+         generate_ddy(inst->opcode, dst, src[0]);<br>
         break;<br>
<br>
       case SHADER_OPCODE_GEN4_SCRATCH_WRITE:<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
index ebcc92a..a3ff8d4 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
@@ -62,8 +62,7 @@ fs_visitor::nir_setup_inputs()<br>
<br>
       fs_reg reg;<br>
       if (var->data.location == VARYING_SLOT_POS) {<br>
-         reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,<br>
-                                             var->data.origin_upper_left);<br>
+         reg = *emit_fragcoord_interpolation();<br>
          emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),<br>
                                    input, reg), 0xF);<br>
       } else if (var->data.location == VARYING_SLOT_LAYER) {<br>
@@ -879,22 +878,18 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)<br>
       break;<br>
    case nir_op_fddy:<br>
       if (fs_key->high_quality_derivatives) {<br>
-         inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0],<br>
-                         brw_imm_d(fs_key->render_to_fbo));<br>
+         inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0]);<br>
       } else {<br>
-         inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0],<br>
-                         brw_imm_d(fs_key->render_to_fbo));<br>
+         inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0]);<br>
       }<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
    case nir_op_fddy_fine:<br>
-      inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0],<br>
-                      brw_imm_d(fs_key->render_to_fbo));<br>
+      inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0]);<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
    case nir_op_fddy_coarse:<br>
-      inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0],<br>
-                      brw_imm_d(fs_key->render_to_fbo));<br>
+      inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0]);<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
<br>
@@ -3064,12 +3059,9 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld,<br>
       case nir_intrinsic_interp_var_at_offset: {<br>
          nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);<br>
<br>
-         const bool flip = !wm_key->render_to_fbo;<br>
-<br>
          if (const_offset) {<br>
             unsigned off_x = MIN2((int)(const_offset->f32[0] * 16), 7) & 0xf;<br>
-            unsigned off_y = MIN2((int)(const_offset->f32[1] * 16 *<br>
-                                        (flip ? -1 : 1)), 7) & 0xf;<br>
+            unsigned off_y = MIN2((int)(const_offset->f32[1] * 16), 7) & 0xf;<br>
<br>
             emit_pixel_interpolater_send(bld,<br>
                                          FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET,<br>
@@ -3086,7 +3078,7 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld,<br>
                bld.MUL(temp, offset(offset_src, bld, i), brw_imm_f(16.0f));<br>
                fs_reg itemp = vgrf(glsl_type::int_type);<br>
                /* float to int */<br>
-               bld.MOV(itemp, (i == 1 && flip) ? negate(temp) : temp);<br>
+               bld.MOV(itemp, temp);<br>
<br>
                /* Clamp the upper end of the range to +7/16.<br>
                 * ARB_gpu_shader5 requires that we support a maximum offset<br>
diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c<br>
index 9afd036..372b746 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_nir.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_nir.c<br>
@@ -27,6 +27,7 @@<br>
 #include "compiler/nir/glsl_to_nir.h"<br>
 #include "compiler/nir/nir_builder.h"<br>
 #include "program/prog_to_nir.h"<br>
+#include "program/prog_parameter.h"<br>
<br>
 static bool<br>
 is_input(nir_intrinsic_instr *intrin)<br>
@@ -573,6 +574,18 @@ brw_create_nir(struct brw_context *brw,<br>
<br>
    nir = brw_preprocess_nir(brw->intelScreen->compiler, nir);<br>
<br>
+   if (stage == MESA_SHADER_FRAGMENT) {<br>
+      static const struct nir_lower_wpos_ytransform_options wpos_options = {<br>
+         .state_tokens = {STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0},<br>
+         .fs_coord_pixel_center_integer = 1,<br>
+         .fs_coord_origin_upper_left = 1,<br>
+      };<br>
+      _mesa_add_state_reference(prog->Parameters,<br>
+                                (gl_state_index *) wpos_options.state_tokens);<br>
+<br>
+      OPT(nir_lower_wpos_ytransform, &wpos_options);<br>
+   }<br>
+<br>
    OPT(nir_lower_system_values);<br>
    OPT_V(brw_nir_lower_uniforms, is_scalar);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp<br>
index 15d99fa..b752ad5 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp<br>
@@ -157,17 +157,11 @@ brw_nir_setup_arb_uniforms(nir_shader *shader, struct gl_program *prog,<br>
 {<br>
    struct gl_program_parameter_list *plist = prog->Parameters;<br>
<br>
-#ifndef NDEBUG<br>
-   if (!shader->uniforms.is_empty()) {<br>
-      /* For ARB programs, only a single "parameters" variable is generated to<br>
-       * support uniform data.<br>
-       */<br>
-      assert(shader->uniforms.length() == 1);<br>
-      nir_variable *var = (nir_variable *) shader->uniforms.get_head();<br>
-      assert(strcmp(var->name, "parameters") == 0);<br>
-      assert(var->type->array_size() == (int)plist->NumParameters);<br>
-   }<br>
-#endif<br>
+   /* For ARB programs, prog_to_nir generates a single "parameters" variable<br>
+    * for all uniform data.  nir_lower_wpos_ytransform may also create an<br>
+    * additional variable.<br>
+    */<br>
+   assert(shader->uniforms.length() <= 2);<br>
<br>
    for (unsigned p = 0; p < plist->NumParameters; p++) {<br>
       /* Parameters should be either vec4 uniforms or single component<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.8.2<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>