Mesa (master): i965: Lower textureGrad() for samplerCubeShadow.

Kenneth Graunke kwg at kemper.freedesktop.org
Wed May 1 17:57:58 UTC 2013


Module: Mesa
Branch: master
Commit: e2f887b243fd34ef82e4782a968baca485b07b15
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2f887b243fd34ef82e4782a968baca485b07b15

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Feb 12 21:51:16 2013 -0800

i965: Lower textureGrad() for samplerCubeShadow.

According to the Ivybridge PRM, Volume 4 Part 1, page 130, in the
section for the sample_d message: "The r coordinate contains the faceid,
and the r gradients are ignored by hardware."

This doesn't match GLSL, which provides gradients for all of the
coordinates.  So we would need to do some math to compute the face ID
before using sample_d.  We currently don't have any code to do that.

However, we do have a lowering pass that converts textureGrad to
textureLod, which solves this problem.  Since textureGrad on three
components is sufficiently obscure, it's not a performance path.

For now, only handle samplerCubeShadow; we need tests for samplerCube
and samplerCubeArray.

Fixes es3conform's shadow_comparison_frag test on Haswell.

NOTE: This is a candidate for stable branches.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_context.h            |    3 +-
 .../dri/i965/brw_lower_texture_gradients.cpp       |   27 +++++++++++++++++--
 src/mesa/drivers/dri/i965/brw_shader.cpp           |    3 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 7ef3186..c682501 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1337,7 +1337,8 @@ brw_program_reloc(struct brw_context *brw, uint32_t state_offset,
 }
 
 bool brw_do_cubemap_normalize(struct exec_list *instructions);
-bool brw_lower_texture_gradients(struct exec_list *instructions);
+bool brw_lower_texture_gradients(struct intel_context *intel,
+                                 struct exec_list *instructions);
 
 struct opcode_desc {
     char    *name;
diff --git a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp b/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
index d0c1ea4..c5294bc 100644
--- a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
+++ b/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
@@ -28,12 +28,14 @@
 #include "glsl/ir.h"
 #include "glsl/ir_builder.h"
 #include "program/prog_instruction.h"
+#include "brw_context.h"
 
 using namespace ir_builder;
 
 class lower_texture_grad_visitor : public ir_hierarchical_visitor {
 public:
-   lower_texture_grad_visitor()
+   lower_texture_grad_visitor(bool has_sample_d_c)
+      : has_sample_d_c(has_sample_d_c)
    {
       progress = false;
    }
@@ -42,6 +44,7 @@ public:
 
 
    bool progress;
+   bool has_sample_d_c;
 
 private:
    void emit(ir_variable *, ir_rvalue *);
@@ -91,6 +94,22 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
    if (ir->op != ir_txd || !ir->shadow_comparitor)
       return visit_continue;
 
+   /* Lower textureGrad() with samplerCubeShadow even if we have the sample_d_c
+    * message.  GLSL provides gradients for the 'r' coordinate.  Unfortunately:
+    *
+    * From the Ivybridge PRM, Volume 4, Part 1, sample_d message description:
+    * "The r coordinate contains the faceid, and the r gradients are ignored
+    *  by hardware."
+    *
+    * We likely need to do a similar treatment for samplerCube and
+    * samplerCubeArray, but we have insufficient testing for that at the moment.
+    */
+   bool need_lowering = !has_sample_d_c ||
+      ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE;
+
+   if (!need_lowering)
+      return visit_continue;
+
    void *mem_ctx = ralloc_parent(ir);
 
    const glsl_type *grad_type = ir->lod_info.grad.dPdx->type;
@@ -146,9 +165,11 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
 extern "C" {
 
 bool
-brw_lower_texture_gradients(struct exec_list *instructions)
+brw_lower_texture_gradients(struct intel_context *intel,
+                            struct exec_list *instructions)
 {
-   lower_texture_grad_visitor v;
+   bool has_sample_d_c = intel->gen >= 8 || intel->is_haswell;
+   lower_texture_grad_visitor v(has_sample_d_c);
 
    visit_list_elements(&v, instructions);
 
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index a820952..75468b1 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -168,8 +168,7 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
 	 lower_if_to_cond_assign(shader->ir, 16);
 
       do_lower_texture_projection(shader->ir);
-      if (intel->gen < 8 && !intel->is_haswell)
-         brw_lower_texture_gradients(shader->ir);
+      brw_lower_texture_gradients(intel, shader->ir);
       do_vec_index_to_cond_assign(shader->ir);
       brw_do_cubemap_normalize(shader->ir);
       lower_noise(shader->ir);




More information about the mesa-commit mailing list