summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp27
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp3
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);