diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp | 27 | ||||
-rw-r--r-- | 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 7ef3186ab1c..c6825018ddc 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 d0c1ea48dc2..c5294bcf0cb 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 a8209527d53..75468b1d194 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); |