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