GLSL provides gradients for the 'r' coordinate (face ID), while our
hardware apparently ignores them.  Sadly, this means that sample_d and
sample_d_c appear to be unsuitable for OpenGL, and need to be lowered.

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 <kenn...@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 5095602..10abb7c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1308,7 +1308,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 9e661a1..a192d0e 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 *);
@@ -90,6 +93,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;
@@ -145,9 +164,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 c71715e..ed2947e 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -164,8 +164,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);
-- 
1.8.1.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to