i965/fs: Lower 32x32 bit multiplication on BXT.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_lower_texture_gradients.cpp
index e4e10b0d76a8105675e18d93d792cd0685c5c881..7a5f9834423e86b114c89d06e24269d00c65546e 100644 (file)
@@ -77,8 +77,7 @@ txs_type(const glsl_type *type)
       dims = 3;
       break;
    default:
-      assert(!"Should not get here: invalid sampler dimensionality");
-      dims = 2;
+      unreachable("Should not get here: invalid sampler dimensionality");
    }
 
    if (type->sampler_array)
@@ -90,19 +89,18 @@ txs_type(const glsl_type *type)
 ir_visitor_status
 lower_texture_grad_visitor::visit_leave(ir_texture *ir)
 {
-   /* Only lower textureGrad with shadow samplers */
-   if (ir->op != ir_txd || !ir->shadow_comparitor)
+   /* Only lower textureGrad with cube maps or shadow samplers */
+   if (ir->op != ir_txd ||
+      (ir->sampler->type->sampler_dimensionality != GLSL_SAMPLER_DIM_CUBE &&
+       !ir->shadow_comparitor))
       return visit_continue;
 
-   /* Lower textureGrad() with samplerCubeShadow even if we have the sample_d_c
+   /* Lower textureGrad() with samplerCube* 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;
@@ -125,7 +123,9 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
       new(mem_ctx) ir_variable(grad_type, "size", ir_var_temporary);
    if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
       base_ir->insert_before(size);
-      base_ir->insert_before(assign(size, expr(ir_unop_i2f, txs), WRITEMASK_XY));
+      base_ir->insert_before(assign(size,
+                                    swizzle_for_size(expr(ir_unop_i2f, txs), 2),
+                                    WRITEMASK_XY));
       base_ir->insert_before(assign(size, new(mem_ctx) ir_constant(1.0f), WRITEMASK_Z));
    } else {
       emit(size, expr(ir_unop_i2f,
@@ -154,9 +154,20 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
                               expr(ir_unop_sqrt, dot(dPdy, dPdy)));
    }
 
-   /* lambda_base = log2(rho).  We're ignoring GL state biases for now. */
+   /* lambda_base = log2(rho).  We're ignoring GL state biases for now.
+    *
+    * For cube maps the result of these formulas is giving us a value of rho
+    * that is twice the value we should use, so divide it by 2 or,
+    * alternatively, remove one unit from the result of the log2 computation.
+    */
    ir->op = ir_txl;
-   ir->lod_info.lod = expr(ir_unop_log2, rho);
+   if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
+      ir->lod_info.lod = expr(ir_binop_add,
+                              expr(ir_unop_log2, rho),
+                              new(mem_ctx) ir_constant(-1.0f));
+   } else {
+      ir->lod_info.lod = expr(ir_unop_log2, rho);
+   }
 
    progress = true;
    return visit_continue;
@@ -168,8 +179,7 @@ bool
 brw_lower_texture_gradients(struct brw_context *brw,
                             struct exec_list *instructions)
 {
-   struct intel_context *intel = &brw->intel;
-   bool has_sample_d_c = intel->gen >= 8 || brw->is_haswell;
+   bool has_sample_d_c = brw->gen >= 8 || brw->is_haswell;
    lower_texture_grad_visitor v(has_sample_d_c);
 
    visit_list_elements(&v, instructions);