[Mesa-dev] [PATCH 04/12] i965: Move legacy clip plane handling to vec4_vs_visitor.

Kenneth Graunke kenneth at whitecape.org
Sat Aug 29 02:23:58 PDT 2015


This is now only used for the vertex shader, so it makes sense to get it
out of any paths run by the geometry shader.

By wrapping the run() method, we can eliminate the bogus NULL
parameter in the GS case, and do VS things only for the VS.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_vec4.cpp            | 10 ++--
 src/mesa/drivers/dri/i965/brw_vec4.h              |  4 +-
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp |  4 +-
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp    | 56 --------------------
 src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp | 62 +++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_vs.h                |  5 ++
 6 files changed, 74 insertions(+), 67 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 4f5e85b..c6f64fb 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1719,7 +1719,7 @@ vec4_visitor::emit_shader_time_write(int shader_time_subindex, src_reg value)
 }
 
 bool
-vec4_visitor::run(gl_clip_plane *clip_planes)
+vec4_visitor::run()
 {
    bool use_vec4_nir =
       compiler->glsl_compiler_options[stage].NirOptions != NULL;
@@ -1748,9 +1748,6 @@ vec4_visitor::run(gl_clip_plane *clip_planes)
    }
    base_ir = NULL;
 
-   if (key->nr_userclip_plane_consts > 0)
-      setup_uniform_clipplane_values(clip_planes);
-
    emit_thread_end();
 
    calculate_cfg();
@@ -1977,9 +1974,10 @@ brw_vs_emit(struct brw_context *brw,
       prog_data->base.dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
 
       vec4_vs_visitor v(brw->intelScreen->compiler, brw, key, prog_data,
-                        vp, prog, mem_ctx, st_index,
+                        vp, prog, brw_select_clip_planes(&brw->ctx),
+                        mem_ctx, st_index,
                         !_mesa_is_gles3(&brw->ctx));
-      if (!v.run(brw_select_clip_planes(&brw->ctx))) {
+      if (!v.run()) {
          if (prog) {
             prog->LinkStatus = false;
             ralloc_strcat(&prog->InfoLog, v.fail_msg);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 673a29e..7c31932 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -173,10 +173,9 @@ public:
 
    struct hash_table *variable_ht;
 
-   bool run(gl_clip_plane *clip_planes);
+   bool run();
    void fail(const char *msg, ...);
 
-   void setup_uniform_clipplane_values(gl_clip_plane *clip_planes);
    virtual void setup_vec4_uniform_value(unsigned param_offset,
                                          const gl_constant_value *values,
                                          unsigned n);
@@ -359,7 +358,6 @@ public:
 
    void emit_ndc_computation();
    void emit_psiz_and_flags(dst_reg reg);
-   void emit_clip_distances(dst_reg reg, int offset);
    vec4_instruction *emit_generic_urb_slot(dst_reg reg, int varying);
    void emit_urb_slot(dst_reg reg, int varying);
 
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
index 019efec..4fd626f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
@@ -679,7 +679,7 @@ brw_gs_emit(struct brw_context *brw,
 
          vec4_gs_visitor v(brw->intelScreen->compiler, brw,
                            c, prog, mem_ctx, true /* no_spills */, st_index);
-         if (v.run(NULL /* clip planes */)) {
+         if (v.run()) {
             return generate_assembly(brw, prog, &c->gp->program.Base,
                                      &c->prog_data.base, mem_ctx, v.cfg,
                                      final_assembly_size);
@@ -727,7 +727,7 @@ brw_gs_emit(struct brw_context *brw,
                                c, prog, mem_ctx, false /* no_spills */,
                                st_index);
 
-   if (!gs->run(NULL /* clip planes */)) {
+   if (!gs->run()) {
       prog->LinkStatus = false;
       ralloc_strcat(&prog->InfoLog, gs->fail_msg);
    } else {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 4d3d281..978d28c 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -755,22 +755,6 @@ vec4_visitor::setup_uniform_values(ir_variable *ir)
    }
 }
 
-void
-vec4_visitor::setup_uniform_clipplane_values(gl_clip_plane *clip_planes)
-{
-   for (int i = 0; i < key->nr_userclip_plane_consts; ++i) {
-      assert(this->uniforms < uniform_array_size);
-      this->uniform_vector_size[this->uniforms] = 4;
-      this->userplane[i] = dst_reg(UNIFORM, this->uniforms);
-      this->userplane[i].type = BRW_REGISTER_TYPE_F;
-      for (int j = 0; j < 4; ++j) {
-         stage_prog_data->param[this->uniforms * 4 + j] =
-            (gl_constant_value *) &clip_planes[i][j];
-      }
-      ++this->uniforms;
-   }
-}
-
 /* Our support for builtin uniforms is even scarier than non-builtin.
  * It sits on top of the PROG_STATE_VAR parameters that are
  * automatically updated from GL context state.
@@ -3203,35 +3187,6 @@ vec4_visitor::emit_psiz_and_flags(dst_reg reg)
    }
 }
 
-void
-vec4_visitor::emit_clip_distances(dst_reg reg, int offset)
-{
-   /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special Variables):
-    *
-    *     "If a linked set of shaders forming the vertex stage contains no
-    *     static write to gl_ClipVertex or gl_ClipDistance, but the
-    *     application has requested clipping against user clip planes through
-    *     the API, then the coordinate written to gl_Position is used for
-    *     comparison against the user clip planes."
-    *
-    * This function is only called if the shader didn't write to
-    * gl_ClipDistance.  Accordingly, we use gl_ClipVertex to perform clipping
-    * if the user wrote to it; otherwise we use gl_Position.
-    */
-   gl_varying_slot clip_vertex = VARYING_SLOT_CLIP_VERTEX;
-   if (!(prog_data->vue_map.slots_valid & VARYING_BIT_CLIP_VERTEX)) {
-      clip_vertex = VARYING_SLOT_POS;
-   }
-
-   for (int i = 0; i + offset < key->nr_userclip_plane_consts && i < 4;
-        ++i) {
-      reg.writemask = 1 << i;
-      emit(DP4(reg,
-               src_reg(output_reg[clip_vertex]),
-               src_reg(this->userplane[i + offset])));
-   }
-}
-
 vec4_instruction *
 vec4_visitor::emit_generic_urb_slot(dst_reg reg, int varying)
 {
@@ -3354,17 +3309,6 @@ vec4_visitor::emit_vertex()
       emit_ndc_computation();
    }
 
-   /* Lower legacy ff and ClipVertex clipping to clip distances */
-   if (key->nr_userclip_plane_consts > 0) {
-      current_annotation = "user clip distances";
-
-      output_reg[VARYING_SLOT_CLIP_DIST0] = dst_reg(this, glsl_type::vec4_type);
-      output_reg[VARYING_SLOT_CLIP_DIST1] = dst_reg(this, glsl_type::vec4_type);
-
-      emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST0], 0);
-      emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST1], 4);
-   }
-
    /* We may need to split this up into several URB writes, so do them in a
     * loop.
     */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
index 620f652..f81ee4e 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
@@ -202,8 +202,68 @@ vec4_vs_visitor::emit_urb_write_opcode(bool complete)
 
 
 void
+vec4_vs_visitor::emit_clip_distances(dst_reg reg, int offset)
+{
+   /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special Variables):
+    *
+    *     "If a linked set of shaders forming the vertex stage contains no
+    *     static write to gl_ClipVertex or gl_ClipDistance, but the
+    *     application has requested clipping against user clip planes through
+    *     the API, then the coordinate written to gl_Position is used for
+    *     comparison against the user clip planes."
+    *
+    * This function is only called if the shader didn't write to
+    * gl_ClipDistance.  Accordingly, we use gl_ClipVertex to perform clipping
+    * if the user wrote to it; otherwise we use gl_Position.
+    */
+   gl_varying_slot clip_vertex = VARYING_SLOT_CLIP_VERTEX;
+   if (!(prog_data->vue_map.slots_valid & VARYING_BIT_CLIP_VERTEX)) {
+      clip_vertex = VARYING_SLOT_POS;
+   }
+
+   for (int i = 0; i + offset < key->base.nr_userclip_plane_consts && i < 4;
+        ++i) {
+      reg.writemask = 1 << i;
+      emit(DP4(reg,
+               src_reg(output_reg[clip_vertex]),
+               src_reg(this->userplane[i + offset])));
+   }
+}
+
+
+void
+vec4_vs_visitor::setup_uniform_clipplane_values()
+{
+   for (int i = 0; i < key->base.nr_userclip_plane_consts; ++i) {
+      assert(this->uniforms < uniform_array_size);
+      this->uniform_vector_size[this->uniforms] = 4;
+      this->userplane[i] = dst_reg(UNIFORM, this->uniforms);
+      this->userplane[i].type = BRW_REGISTER_TYPE_F;
+      for (int j = 0; j < 4; ++j) {
+         stage_prog_data->param[this->uniforms * 4 + j] =
+            (gl_constant_value *) &clip_planes[i][j];
+      }
+      ++this->uniforms;
+   }
+}
+
+
+void
 vec4_vs_visitor::emit_thread_end()
 {
+   setup_uniform_clipplane_values();
+
+   /* Lower legacy ff and ClipVertex clipping to clip distances */
+   if (key->base.nr_userclip_plane_consts > 0) {
+      current_annotation = "user clip distances";
+
+      output_reg[VARYING_SLOT_CLIP_DIST0] = dst_reg(this, glsl_type::vec4_type);
+      output_reg[VARYING_SLOT_CLIP_DIST1] = dst_reg(this, glsl_type::vec4_type);
+
+      emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST0], 0);
+      emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST1], 4);
+   }
+
    /* For VS, we always end the thread by emitting a single vertex.
     * emit_urb_write_opcode() will take care of setting the eot flag on the
     * SEND instruction.
@@ -218,6 +278,7 @@ vec4_vs_visitor::vec4_vs_visitor(const struct brw_compiler *compiler,
                                  struct brw_vs_prog_data *vs_prog_data,
                                  struct gl_vertex_program *vp,
                                  struct gl_shader_program *prog,
+                                 gl_clip_plane *clip_planes,
                                  void *mem_ctx,
                                  int shader_time_index,
                                  bool use_legacy_snorm_formula)
@@ -229,6 +290,7 @@ vec4_vs_visitor::vec4_vs_visitor(const struct brw_compiler *compiler,
      key(key),
      vs_prog_data(vs_prog_data),
      vp(vp),
+     clip_planes(clip_planes),
      use_legacy_snorm_formula(use_legacy_snorm_formula)
 {
 }
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 1d9bee1..e98679a 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -90,6 +90,7 @@ public:
                    struct brw_vs_prog_data *vs_prog_data,
                    struct gl_vertex_program *vp,
                    struct gl_shader_program *prog,
+                   gl_clip_plane *clip_planes,
                    void *mem_ctx,
                    int shader_time_index,
                    bool use_legacy_snorm_formula);
@@ -107,6 +108,8 @@ protected:
 private:
    int setup_attributes(int payload_reg);
    void setup_vp_regs();
+   void setup_uniform_clipplane_values();
+   void emit_clip_distances(dst_reg reg, int offset);
    dst_reg get_vp_dst_reg(const prog_dst_register &dst);
    src_reg get_vp_src_reg(const prog_src_register &src);
 
@@ -116,6 +119,8 @@ private:
    src_reg *vp_temp_regs;
    src_reg vp_addr_reg;
 
+   gl_clip_plane *clip_planes;
+
    bool use_legacy_snorm_formula;
 };
 
-- 
2.5.0



More information about the mesa-dev mailing list