diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/Makefile.sources | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_link.cpp | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp | 353 |
5 files changed, 1 insertions, 358 deletions
diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 1c33ea55fae..0a7ba1bb34d 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -128,7 +128,6 @@ i965_FILES = \ brw_gs_state.c \ brw_gs_surface_state.c \ brw_link.cpp \ - brw_lower_texture_gradients.cpp \ brw_meta_util.c \ brw_meta_util.h \ brw_misc_state.c \ diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 550eefedcc2..46091b65717 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -1707,8 +1707,6 @@ 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 brw_context *brw, - struct exec_list *instructions); extern const char * const conditional_modifier[16]; extern const char *const pred_ctrl_align16[16]; diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index c5b50e1f73e..4ef1a292b11 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -700,7 +700,7 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src break; case SHADER_OPCODE_TXD: if (inst->shadow_compare) { - /* Gen7.5+. Otherwise, lowered by brw_lower_texture_gradients(). */ + /* Gen7.5+. Otherwise, lowered in NIR */ assert(devinfo->gen >= 8 || devinfo->is_haswell); msg_type = HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE; } else { diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp index ca934174067..6f374286318 100644 --- a/src/mesa/drivers/dri/i965/brw_link.cpp +++ b/src/mesa/drivers/dri/i965/brw_link.cpp @@ -128,7 +128,6 @@ process_glsl_ir(struct brw_context *brw, lower_if_to_cond_assign(shader->Stage, shader->ir, 16); do_lower_texture_projection(shader->ir); - brw_lower_texture_gradients(brw, shader->ir); do_vec_index_to_cond_assign(shader->ir); lower_vector_insert(shader->ir, true); lower_offset_arrays(shader->ir); diff --git a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp b/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp deleted file mode 100644 index 7ae69f8b7c0..00000000000 --- a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file brw_lower_texture_gradients.cpp - */ - -#include "compiler/glsl/ir.h" -#include "compiler/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(bool has_sample_d_c) - : has_sample_d_c(has_sample_d_c) - { - progress = false; - } - - ir_visitor_status visit_leave(ir_texture *ir); - - - bool progress; - bool has_sample_d_c; - -private: - void emit(ir_variable *, ir_rvalue *); - ir_variable *temp(void *ctx, const glsl_type *type, const char *name); -}; - -/** - * Emit a variable declaration and an assignment to initialize it. - */ -void -lower_texture_grad_visitor::emit(ir_variable *var, ir_rvalue *value) -{ - base_ir->insert_before(var); - base_ir->insert_before(assign(var, value)); -} - -/** - * Emit a temporary variable declaration - */ -ir_variable * -lower_texture_grad_visitor::temp(void *ctx, const glsl_type *type, const char *name) -{ - ir_variable *var = new(ctx) ir_variable(type, name, ir_var_temporary); - base_ir->insert_before(var); - return var; -} - -static const glsl_type * -txs_type(const glsl_type *type) -{ - unsigned dims; - switch (type->sampler_dimensionality) { - case GLSL_SAMPLER_DIM_1D: - dims = 1; - break; - case GLSL_SAMPLER_DIM_2D: - case GLSL_SAMPLER_DIM_RECT: - case GLSL_SAMPLER_DIM_CUBE: - dims = 2; - break; - case GLSL_SAMPLER_DIM_3D: - dims = 3; - break; - default: - unreachable("Should not get here: invalid sampler dimensionality"); - } - - if (type->sampler_array) - dims++; - - return glsl_type::get_instance(GLSL_TYPE_INT, dims, 1); -} - -ir_visitor_status -lower_texture_grad_visitor::visit_leave(ir_texture *ir) -{ - /* 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_comparator)) - return visit_continue; - - /* 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." - */ - 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; - - /* Use textureSize() to get the width and height of LOD 0; swizzle away - * the depth/number of array slices. - */ - ir_texture *txs = new(mem_ctx) ir_texture(ir_txs); - txs->set_sampler(ir->sampler->clone(mem_ctx, NULL), - txs_type(ir->sampler->type)); - txs->lod_info.lod = new(mem_ctx) ir_constant(0); - ir_variable *size = - 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, - 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, - swizzle_for_size(txs, grad_type->vector_elements))); - } - - /* Scale the gradients by width and height. Effectively, the incoming - * gradients are s'(x,y), t'(x,y), and r'(x,y) from equation 3.19 in the - * GL 3.0 spec; we want u'(x,y), which is w_t * s'(x,y). - */ - ir_variable *dPdx = - new(mem_ctx) ir_variable(grad_type, "dPdx", ir_var_temporary); - emit(dPdx, mul(size, ir->lod_info.grad.dPdx)); - - ir_variable *dPdy = - new(mem_ctx) ir_variable(grad_type, "dPdy", ir_var_temporary); - emit(dPdy, mul(size, ir->lod_info.grad.dPdy)); - - ir->op = ir_txl; - if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) { - /* Cubemap texture lookups first generate a texture coordinate normalized - * to [-1, 1] on the appropiate face. The appropiate face is determined - * by which component has largest magnitude and its sign. The texture - * coordinate is the quotient of the remaining texture coordinates against - * that absolute value of the component of largest magnitude. This - * division requires that the computing of the derivative of the texel - * coordinate must use the quotient rule. The high level GLSL code is as - * follows: - * - * Step 1: selection - * - * vec3 abs_p, Q, dQdx, dQdy; - * abs_p = abs(ir->coordinate); - * if (abs_p.x >= max(abs_p.y, abs_p.z)) { - * Q = ir->coordinate.yzx; - * dQdx = ir->lod_info.grad.dPdx.yzx; - * dQdy = ir->lod_info.grad.dPdy.yzx; - * } - * if (abs_p.y >= max(abs_p.x, abs_p.z)) { - * Q = ir->coordinate.xzy; - * dQdx = ir->lod_info.grad.dPdx.xzy; - * dQdy = ir->lod_info.grad.dPdy.xzy; - * } - * if (abs_p.z >= max(abs_p.x, abs_p.y)) { - * Q = ir->coordinate; - * dQdx = ir->lod_info.grad.dPdx; - * dQdy = ir->lod_info.grad.dPdy; - * } - * - * Step 2: use quotient rule to compute derivative. The normalized to - * [-1, 1] texel coordinate is given by Q.xy / (sign(Q.z) * Q.z). We are - * only concerned with the magnitudes of the derivatives whose values are - * not affected by the sign. We drop the sign from the computation. - * - * vec2 dx, dy; - * float recip; - * - * recip = 1.0 / Q.z; - * dx = recip * ( dQdx.xy - Q.xy * (dQdx.z * recip) ); - * dy = recip * ( dQdy.xy - Q.xy * (dQdy.z * recip) ); - * - * Step 3: compute LOD. At this point we have the derivatives of the - * texture coordinates normalized to [-1,1]. We take the LOD to be - * result = log2(max(sqrt(dot(dx, dx)), sqrt(dy, dy)) * 0.5 * L) - * = -1.0 + log2(max(sqrt(dot(dx, dx)), sqrt(dy, dy)) * L) - * = -1.0 + log2(sqrt(max(dot(dx, dx), dot(dy,dy))) * L) - * = -1.0 + log2(sqrt(L * L * max(dot(dx, dx), dot(dy,dy)))) - * = -1.0 + 0.5 * log2(L * L * max(dot(dx, dx), dot(dy,dy))) - * where L is the dimension of the cubemap. The code is: - * - * float M, result; - * M = max(dot(dx, dx), dot(dy, dy)); - * L = textureSize(sampler, 0).x; - * result = -1.0 + 0.5 * log2(L * L * M); - */ - -/* Helpers to make code more human readable. */ -#define EMIT(instr) base_ir->insert_before(instr) -#define THEN(irif, instr) irif->then_instructions.push_tail(instr) -#define CLONE(x) x->clone(mem_ctx, NULL) - - ir_variable *abs_p = temp(mem_ctx, glsl_type::vec3_type, "abs_p"); - - EMIT(assign(abs_p, swizzle_for_size(abs(CLONE(ir->coordinate)), 3))); - - ir_variable *Q = temp(mem_ctx, glsl_type::vec3_type, "Q"); - ir_variable *dQdx = temp(mem_ctx, glsl_type::vec3_type, "dQdx"); - ir_variable *dQdy = temp(mem_ctx, glsl_type::vec3_type, "dQdy"); - - /* unmodified dPdx, dPdy values */ - ir_rvalue *dPdx = ir->lod_info.grad.dPdx; - ir_rvalue *dPdy = ir->lod_info.grad.dPdy; - - /* 1. compute selector */ - - /* if (abs_p.x >= max(abs_p.y, abs_p.z)) ... */ - ir_if *branch_x = - new(mem_ctx) ir_if(gequal(swizzle_x(abs_p), - max2(swizzle_y(abs_p), swizzle_z(abs_p)))); - - /* Q = p.yzx; - * dQdx = dPdx.yzx; - * dQdy = dPdy.yzx; - */ - int yzx = MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, 0); - THEN(branch_x, assign(Q, swizzle(CLONE(ir->coordinate), yzx, 3))); - THEN(branch_x, assign(dQdx, swizzle(CLONE(dPdx), yzx, 3))); - THEN(branch_x, assign(dQdy, swizzle(CLONE(dPdy), yzx, 3))); - EMIT(branch_x); - - /* if (abs_p.y >= max(abs_p.x, abs_p.z)) */ - ir_if *branch_y = - new(mem_ctx) ir_if(gequal(swizzle_y(abs_p), - max2(swizzle_x(abs_p), swizzle_z(abs_p)))); - - /* Q = p.xzy; - * dQdx = dPdx.xzy; - * dQdy = dPdy.xzy; - */ - int xzy = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Z, SWIZZLE_Y, 0); - THEN(branch_y, assign(Q, swizzle(CLONE(ir->coordinate), xzy, 3))); - THEN(branch_y, assign(dQdx, swizzle(CLONE(dPdx), xzy, 3))); - THEN(branch_y, assign(dQdy, swizzle(CLONE(dPdy), xzy, 3))); - EMIT(branch_y); - - /* if (abs_p.z >= max(abs_p.x, abs_p.y)) */ - ir_if *branch_z = - new(mem_ctx) ir_if(gequal(swizzle_z(abs_p), - max2(swizzle_x(abs_p), swizzle_y(abs_p)))); - - /* Q = p; - * dQdx = dPdx; - * dQdy = dPdy; - */ - THEN(branch_z, assign(Q, swizzle_for_size(CLONE(ir->coordinate), 3))); - THEN(branch_z, assign(dQdx, CLONE(dPdx))); - THEN(branch_z, assign(dQdy, CLONE(dPdy))); - EMIT(branch_z); - - /* 2. quotient rule */ - ir_variable *recip = temp(mem_ctx, glsl_type::float_type, "recip"); - EMIT(assign(recip, expr(ir_unop_rcp, swizzle_z(Q)))); - - ir_variable *dx = temp(mem_ctx, glsl_type::vec2_type, "dx"); - ir_variable *dy = temp(mem_ctx, glsl_type::vec2_type, "dy"); - - /* tmp = Q.xy * recip; - * dx = recip * ( dQdx.xy - (tmp * dQdx.z) ); - * dy = recip * ( dQdy.xy - (tmp * dQdy.z) ); - */ - ir_variable *tmp = temp(mem_ctx, glsl_type::vec2_type, "tmp"); - EMIT(assign(tmp, mul(swizzle_xy(Q), recip))); - EMIT(assign(dx, mul(recip, sub(swizzle_xy(dQdx), - mul(tmp, swizzle_z(dQdx)))))); - EMIT(assign(dy, mul(recip, sub(swizzle_xy(dQdy), - mul(tmp, swizzle_z(dQdy)))))); - - /* M = max(dot(dx, dx), dot(dy, dy)); */ - ir_variable *M = temp(mem_ctx, glsl_type::float_type, "M"); - EMIT(assign(M, max2(dot(dx, dx), dot(dy, dy)))); - - /* size has textureSize() of LOD 0 */ - ir_variable *L = temp(mem_ctx, glsl_type::float_type, "L"); - EMIT(assign(L, swizzle_x(size))); - - ir_variable *result = temp(mem_ctx, glsl_type::float_type, "result"); - - /* result = -1.0 + 0.5 * log2(L * L * M); */ - EMIT(assign(result, - add(new(mem_ctx)ir_constant(-1.0f), - mul(new(mem_ctx)ir_constant(0.5f), - expr(ir_unop_log2, mul(mul(L, L), M)))))); - - /* 3. final assignment of parameters to textureLod call */ - ir->lod_info.lod = new (mem_ctx) ir_dereference_variable(result); - -#undef THEN -#undef EMIT - - } else { - /* Calculate rho from equation 3.20 of the GL 3.0 specification. */ - ir_rvalue *rho; - if (dPdx->type->is_scalar()) { - rho = expr(ir_binop_max, expr(ir_unop_abs, dPdx), - expr(ir_unop_abs, dPdy)); - } else { - rho = expr(ir_binop_max, expr(ir_unop_sqrt, dot(dPdx, dPdx)), - expr(ir_unop_sqrt, dot(dPdy, dPdy))); - } - - /* lambda_base = log2(rho). We're ignoring GL state biases for now. */ - ir->lod_info.lod = expr(ir_unop_log2, rho); - } - - progress = true; - return visit_continue; -} - -extern "C" { - -bool -brw_lower_texture_gradients(struct brw_context *brw, - struct exec_list *instructions) -{ - 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); - - return v.progress; -} - -} |