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)
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;
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,
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;
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);