[Mesa-dev] [PATCH 2/2] i965 Gen6: Implement gl_ClipVertex.
Paul Berry
stereotype441 at gmail.com
Tue Sep 27 11:05:22 PDT 2011
This patch implements proper support for gl_ClipVertex by causing the
new VS backend to populate the clip distance VUE slots using
VERT_RESULT_CLIP_VERTEX when appropriate, and by using the
untransformed clip planes in ctx->Transform.EyeUserPlane rather than
the transformed clip planes in ctx->Transform._ClipUserPlane.
When fixed functionality is in use the driver needs to do the old
behavior (clip based on VERT_RESULT_HPOS and
ctx->Transform._ClipUserPlane). This happens automatically because we
use the old VS backend for fixed functionality.
Fixes the following Piglit tests on i965 Gen6:
- vs-clip-vertex-const-accept
- vs-clip-vertex-const-reject
- vs-clip-vertex-different-from-position
- vs-clip-vertex-equal-to-position
- vs-clip-vertex-homogeneity
- vs-clip-based-on-position
- vs-clip-based-on-position-homogeneity
- clip-plane-transformation clipvert_pos
- clip-plane-transformation pos_clipvert
- clip-plane-transformation pos
---
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 31 ++++++++++++++++++++++-
src/mesa/drivers/dri/i965/brw_vs.c | 8 +++++-
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index e5eda22..f335a86 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -553,7 +553,16 @@ vec4_visitor::setup_uniform_clipplane_values()
this->userplane[compacted_clipplane_index] = dst_reg(UNIFORM, this->uniforms);
this->userplane[compacted_clipplane_index].type = BRW_REGISTER_TYPE_F;
for (int j = 0; j < 4; ++j) {
- c->prog_data.param[this->uniforms * 4 + j] = &ctx->Transform._ClipUserPlane[i][j];
+ /* For fixed functionality shaders, we need to clip based on
+ * ctx->Transform._ClipUserPlane (which has been transformed by
+ * Mesa core into clip coordinates). For user-supplied vertex
+ * shaders, we need to use the untransformed clip planes in
+ * ctx->Transform.EyeUserPlane. Since vec4_visitor is currently
+ * only used for user-supplied vertex shaders, we can hardcode
+ * this to EyeUserPlane for now.
+ */
+ c->prog_data.param[this->uniforms * 4 + j]
+ = &ctx->Transform.EyeUserPlane[i][j];
}
++compacted_clipplane_index;
++this->uniforms;
@@ -1840,9 +1849,27 @@ vec4_visitor::emit_clip_distances(struct brw_reg reg, int offset)
return;
}
+ /* 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_vert_result clip_vertex = VERT_RESULT_CLIP_VERTEX;
+ if (!(c->prog_data.outputs_written
+ & BITFIELD64_BIT(VERT_RESULT_CLIP_VERTEX))) {
+ clip_vertex = VERT_RESULT_HPOS;
+ }
+
for (int i = 0; i + offset < c->key.nr_userclip && i < 4; ++i) {
emit(DP4(dst_reg(brw_writemask(reg, 1 << i)),
- src_reg(output_reg[VERT_RESULT_HPOS]),
+ src_reg(output_reg[clip_vertex]),
src_reg(this->userplane[i + offset])));
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 93c6838..4fd260f 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -137,11 +137,17 @@ brw_compute_vue_map(struct brw_vue_map *vue_map,
/* The hardware doesn't care about the rest of the vertex outputs, so just
* assign them contiguously. Don't reassign outputs that already have a
* slot.
+ *
+ * Also, don't assign a slot for VERT_RESULT_CLIP_VERTEX, since it is
+ * unsupported in pre-GEN6, and in GEN6+ the vertex shader converts it into
+ * clip distances.
*/
for (int i = 0; i < VERT_RESULT_MAX; ++i) {
if ((outputs_written & BITFIELD64_BIT(i)) &&
vue_map->vert_result_to_slot[i] == -1) {
- assign_vue_slot(vue_map, i);
+ if (i != VERT_RESULT_CLIP_VERTEX) {
+ assign_vue_slot(vue_map, i);
+ }
}
}
}
--
1.7.6.2
More information about the mesa-dev
mailing list