2015-03-27 14:18:11 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2015 Broadcom
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
2015-09-16 16:49:14 -04:00
|
|
|
* This lowering pass supports (as configured via nir_lower_tex_options)
|
|
|
|
|
* various texture related conversions:
|
|
|
|
|
* + texture projector lowering: converts the coordinate division for
|
|
|
|
|
* texture projection to be done in ALU instructions instead of
|
|
|
|
|
* asking the texture operation to do so.
|
|
|
|
|
* + lowering RECT: converts the un-normalized RECT texture coordinates
|
|
|
|
|
* to normalized coordinates with txs plus ALU instructions
|
2015-09-18 10:44:27 -04:00
|
|
|
* + saturate s/t/r coords: to emulate certain texture clamp/wrap modes,
|
|
|
|
|
* inserts instructions to clamp specified coordinates to [0.0, 1.0].
|
|
|
|
|
* Note that this automatically triggers texture projector lowering if
|
|
|
|
|
* needed, since clamping must happen after projector lowering.
|
2022-05-21 23:25:02 +00:00
|
|
|
* + YUV-to-RGB conversion: to allow sampling YUV values as RGB values
|
|
|
|
|
* according to a specific YUV color space and range.
|
2015-03-27 14:18:11 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "nir.h"
|
|
|
|
|
#include "nir_builder.h"
|
2019-12-22 17:35:56 +01:00
|
|
|
#include "nir_builtin_builder.h"
|
2018-07-12 18:23:34 -07:00
|
|
|
#include "nir_format_convert.h"
|
2015-03-27 14:18:11 -07:00
|
|
|
|
2020-11-11 16:59:04 -08:00
|
|
|
typedef struct nir_const_value_3_4 {
|
|
|
|
|
nir_const_value v[3][4];
|
|
|
|
|
} nir_const_value_3_4;
|
|
|
|
|
|
2022-05-21 23:25:02 +00:00
|
|
|
static const nir_const_value_3_4 bt601_limited_range_csc_coeffs = { {
|
2020-11-11 16:59:04 -08:00
|
|
|
{ { .f32 = 1.16438356f }, { .f32 = 1.16438356f }, { .f32 = 1.16438356f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.39176229f }, { .f32 = 2.01723214f } },
|
|
|
|
|
{ { .f32 = 1.59602678f }, { .f32 = -0.81296764f }, { .f32 = 0.0f } },
|
|
|
|
|
} };
|
2022-05-21 23:25:02 +00:00
|
|
|
static const nir_const_value_3_4 bt601_full_range_csc_coeffs = { {
|
|
|
|
|
{ { .f32 = 1.0f }, { .f32 = 1.0f }, { .f32 = 1.0f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.34413629f }, { .f32 = 1.772f } },
|
|
|
|
|
{ { .f32 = 1.402f }, { .f32 = -0.71413629f }, { .f32 = 0.0f } },
|
|
|
|
|
} };
|
|
|
|
|
static const nir_const_value_3_4 bt709_limited_range_csc_coeffs = { {
|
2020-11-11 16:59:04 -08:00
|
|
|
{ { .f32 = 1.16438356f }, { .f32 = 1.16438356f }, { .f32 = 1.16438356f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.21324861f }, { .f32 = 2.11240179f } },
|
|
|
|
|
{ { .f32 = 1.79274107f }, { .f32 = -0.53290933f }, { .f32 = 0.0f } },
|
|
|
|
|
} };
|
2022-05-21 23:25:02 +00:00
|
|
|
static const nir_const_value_3_4 bt709_full_range_csc_coeffs = { {
|
|
|
|
|
{ { .f32 = 1.0f }, { .f32 = 1.0f }, { .f32 = 1.0f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.18732427f }, { .f32 = 1.8556f } },
|
|
|
|
|
{ { .f32 = 1.5748f }, { .f32 = -0.46812427f }, { .f32 = 0.0f } },
|
|
|
|
|
} };
|
|
|
|
|
static const nir_const_value_3_4 bt2020_limited_range_csc_coeffs = { {
|
2020-11-11 16:59:04 -08:00
|
|
|
{ { .f32 = 1.16438356f }, { .f32 = 1.16438356f }, { .f32 = 1.16438356f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.18732610f }, { .f32 = 2.14177232f } },
|
2022-05-21 23:25:02 +00:00
|
|
|
{ { .f32 = 1.67878795f }, { .f32 = -0.65046843f }, { .f32 = 0.0f } },
|
|
|
|
|
} };
|
|
|
|
|
static const nir_const_value_3_4 bt2020_full_range_csc_coeffs = { {
|
|
|
|
|
{ { .f32 = 1.0f }, { .f32 = 1.0f }, { .f32 = 1.0f } },
|
|
|
|
|
{ { .f32 = 0.0f }, { .f32 = -0.16455313f }, { .f32 = 1.88140000f } },
|
|
|
|
|
{ { .f32 = 1.4747f }, { .f32 = -0.57139187f }, { .f32 = 0.0f } },
|
2020-11-11 16:59:04 -08:00
|
|
|
} };
|
|
|
|
|
|
2022-05-21 23:25:02 +00:00
|
|
|
static const float bt601_limited_range_csc_offsets[3] = {
|
2020-07-08 13:23:22 +09:00
|
|
|
-0.874202218f, 0.531667823f, -1.085630789f
|
|
|
|
|
};
|
2022-05-21 23:25:02 +00:00
|
|
|
static const float bt601_full_range_csc_offsets[3] = {
|
|
|
|
|
-0.701000000f, 0.529136286f, -0.886000000f
|
|
|
|
|
};
|
|
|
|
|
static const float bt709_limited_range_csc_offsets[3] = {
|
2020-07-08 13:23:22 +09:00
|
|
|
-0.972945075f, 0.301482665f, -1.133402218f
|
|
|
|
|
};
|
2022-05-21 23:25:02 +00:00
|
|
|
static const float bt709_full_range_csc_offsets[3] = {
|
|
|
|
|
-0.787400000f, 0.327724273f, -0.927800000f
|
|
|
|
|
};
|
|
|
|
|
static const float bt2020_limited_range_csc_offsets[3] = {
|
|
|
|
|
-0.915745075f, 0.347480639f, -1.148145075f
|
|
|
|
|
};
|
|
|
|
|
static const float bt2020_full_range_csc_offsets[3] = {
|
|
|
|
|
-0.737350000f, 0.367972500f, -0.940700000f
|
2020-07-08 13:23:22 +09:00
|
|
|
};
|
|
|
|
|
|
2019-06-17 11:23:33 +02:00
|
|
|
static bool
|
2015-09-16 12:53:12 -04:00
|
|
|
project_src(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
2023-06-07 18:00:45 -04:00
|
|
|
nir_ssa_def *proj = nir_steal_tex_src(tex, nir_tex_src_projector);
|
|
|
|
|
if (!proj)
|
2019-06-17 11:23:33 +02:00
|
|
|
return false;
|
2015-09-16 12:53:12 -04:00
|
|
|
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
2023-06-07 18:00:45 -04:00
|
|
|
nir_ssa_def *inv_proj = nir_frcp(b, proj);
|
2015-09-16 12:53:12 -04:00
|
|
|
|
|
|
|
|
/* Walk through the sources projecting the arguments. */
|
|
|
|
|
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
|
|
|
|
switch (tex->src[i].src_type) {
|
|
|
|
|
case nir_tex_src_coord:
|
2016-12-12 08:32:38 -05:00
|
|
|
case nir_tex_src_comparator:
|
2015-09-16 12:53:12 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
nir_ssa_def *unprojected =
|
|
|
|
|
nir_ssa_for_src(b, tex->src[i].src, nir_tex_instr_src_size(tex, i));
|
|
|
|
|
nir_ssa_def *projected = nir_fmul(b, unprojected, inv_proj);
|
|
|
|
|
|
|
|
|
|
/* Array indices don't get projected, so make an new vector with the
|
|
|
|
|
* coordinate's array index untouched.
|
|
|
|
|
*/
|
|
|
|
|
if (tex->is_array && tex->src[i].src_type == nir_tex_src_coord) {
|
|
|
|
|
switch (tex->coord_components) {
|
|
|
|
|
case 4:
|
|
|
|
|
projected = nir_vec4(b,
|
|
|
|
|
nir_channel(b, projected, 0),
|
|
|
|
|
nir_channel(b, projected, 1),
|
|
|
|
|
nir_channel(b, projected, 2),
|
|
|
|
|
nir_channel(b, unprojected, 3));
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
projected = nir_vec3(b,
|
|
|
|
|
nir_channel(b, projected, 0),
|
|
|
|
|
nir_channel(b, projected, 1),
|
|
|
|
|
nir_channel(b, unprojected, 2));
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
projected = nir_vec2(b,
|
|
|
|
|
nir_channel(b, projected, 0),
|
|
|
|
|
nir_channel(b, unprojected, 1));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
unreachable("bad texture coord count for array");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nir_instr_rewrite_src(&tex->instr,
|
|
|
|
|
&tex->src[i].src,
|
|
|
|
|
nir_src_for_ssa(projected));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 11:23:33 +02:00
|
|
|
return true;
|
2015-09-16 12:53:12 -04:00
|
|
|
}
|
|
|
|
|
|
2016-07-20 20:32:31 -07:00
|
|
|
static bool
|
|
|
|
|
lower_offset(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
2023-06-07 18:00:45 -04:00
|
|
|
nir_ssa_def *offset = nir_steal_tex_src(tex, nir_tex_src_offset);
|
|
|
|
|
if (!offset)
|
2016-07-20 20:32:31 -07:00
|
|
|
return false;
|
|
|
|
|
|
2016-09-08 14:05:39 -04:00
|
|
|
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
2016-07-20 20:32:31 -07:00
|
|
|
assert(coord_index >= 0);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *coord = tex->src[coord_index].src.ssa;
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *offset_coord;
|
|
|
|
|
if (nir_tex_instr_src_type(tex, coord_index) == nir_type_float) {
|
2017-11-21 13:42:08 -08:00
|
|
|
if (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
|
|
|
|
|
offset_coord = nir_fadd(b, coord, nir_i2f32(b, offset));
|
|
|
|
|
} else {
|
2023-07-08 17:37:35 +02:00
|
|
|
nir_ssa_def *scale = NULL;
|
|
|
|
|
|
|
|
|
|
if (b->shader->options->has_texture_scaling) {
|
|
|
|
|
nir_ssa_def *idx = nir_imm_int(b, tex->texture_index);
|
|
|
|
|
scale = nir_load_texture_scale(b, 32, idx);
|
|
|
|
|
} else {
|
|
|
|
|
nir_ssa_def *txs = nir_i2f32(b, nir_get_texture_size(b, tex));
|
|
|
|
|
scale = nir_frcp(b, txs);
|
|
|
|
|
}
|
2017-11-21 13:42:08 -08:00
|
|
|
|
|
|
|
|
offset_coord = nir_fadd(b, coord,
|
|
|
|
|
nir_fmul(b,
|
|
|
|
|
nir_i2f32(b, offset),
|
|
|
|
|
scale));
|
|
|
|
|
}
|
2016-07-20 20:32:31 -07:00
|
|
|
} else {
|
|
|
|
|
offset_coord = nir_iadd(b, coord, offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tex->is_array) {
|
|
|
|
|
/* The offset is not applied to the array index */
|
|
|
|
|
if (tex->coord_components == 2) {
|
|
|
|
|
offset_coord = nir_vec2(b, nir_channel(b, offset_coord, 0),
|
|
|
|
|
nir_channel(b, coord, 1));
|
|
|
|
|
} else if (tex->coord_components == 3) {
|
|
|
|
|
offset_coord = nir_vec3(b, nir_channel(b, offset_coord, 0),
|
|
|
|
|
nir_channel(b, offset_coord, 1),
|
|
|
|
|
nir_channel(b, coord, 2));
|
|
|
|
|
} else {
|
|
|
|
|
unreachable("Invalid number of components");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nir_instr_rewrite_src(&tex->instr, &tex->src[coord_index].src,
|
|
|
|
|
nir_src_for_ssa(offset_coord));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-16 16:49:14 -04:00
|
|
|
static void
|
|
|
|
|
lower_rect(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
2019-06-17 11:31:51 +02:00
|
|
|
/* Set the sampler_dim to 2D here so that get_texture_size picks up the
|
|
|
|
|
* right dimensionality.
|
|
|
|
|
*/
|
|
|
|
|
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
|
|
|
|
|
|
2020-02-20 17:19:50 -06:00
|
|
|
nir_ssa_def *txs = nir_i2f32(b, nir_get_texture_size(b, tex));
|
2015-09-16 16:49:14 -04:00
|
|
|
nir_ssa_def *scale = nir_frcp(b, txs);
|
2021-02-11 13:13:42 +01:00
|
|
|
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
2015-09-16 16:49:14 -04:00
|
|
|
|
2021-02-11 13:13:42 +01:00
|
|
|
if (coord_index != -1) {
|
2015-09-16 16:49:14 -04:00
|
|
|
nir_ssa_def *coords =
|
2021-02-11 13:13:42 +01:00
|
|
|
nir_ssa_for_src(b, tex->src[coord_index].src, tex->coord_components);
|
2015-09-16 16:49:14 -04:00
|
|
|
nir_instr_rewrite_src(&tex->instr,
|
2021-02-11 13:13:42 +01:00
|
|
|
&tex->src[coord_index].src,
|
2015-09-16 16:49:14 -04:00
|
|
|
nir_src_for_ssa(nir_fmul(b, coords, scale)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-01 11:13:19 +01:00
|
|
|
static void
|
|
|
|
|
lower_rect_tex_scale(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *idx = nir_imm_int(b, tex->texture_index);
|
2023-07-08 17:43:31 +02:00
|
|
|
nir_ssa_def *scale = nir_load_texture_scale(b, 32, idx);
|
2021-02-11 13:13:42 +01:00
|
|
|
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
2021-02-01 11:13:19 +01:00
|
|
|
|
2021-02-11 13:13:42 +01:00
|
|
|
if (coord_index != -1) {
|
2021-02-01 11:13:19 +01:00
|
|
|
nir_ssa_def *coords =
|
2021-02-11 13:13:42 +01:00
|
|
|
nir_ssa_for_src(b, tex->src[coord_index].src, tex->coord_components);
|
2021-02-01 11:13:19 +01:00
|
|
|
nir_instr_rewrite_src(&tex->instr,
|
2021-02-11 13:13:42 +01:00
|
|
|
&tex->src[coord_index].src,
|
2021-02-01 11:13:19 +01:00
|
|
|
nir_src_for_ssa(nir_fmul(b, coords, scale)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-11 14:14:29 -05:00
|
|
|
static void
|
2021-07-09 11:34:23 -05:00
|
|
|
lower_lod(nir_builder *b, nir_tex_instr *tex, nir_ssa_def *lod)
|
2018-10-11 14:14:29 -05:00
|
|
|
{
|
|
|
|
|
assert(tex->op == nir_texop_tex || tex->op == nir_texop_txb);
|
|
|
|
|
assert(nir_tex_instr_src_index(tex, nir_tex_src_lod) < 0);
|
|
|
|
|
assert(nir_tex_instr_src_index(tex, nir_tex_src_ddx) < 0);
|
|
|
|
|
assert(nir_tex_instr_src_index(tex, nir_tex_src_ddy) < 0);
|
|
|
|
|
|
2023-06-07 18:00:45 -04:00
|
|
|
/* If we have a bias, add it in */
|
|
|
|
|
nir_ssa_def *bias = nir_steal_tex_src(tex, nir_tex_src_bias);
|
|
|
|
|
if (bias)
|
|
|
|
|
lod = nir_fadd(b, lod, bias);
|
2018-10-11 14:14:29 -05:00
|
|
|
|
2023-06-07 18:00:45 -04:00
|
|
|
/* If we have a minimum LOD, clamp LOD accordingly */
|
|
|
|
|
nir_ssa_def *min_lod = nir_steal_tex_src(tex, nir_tex_src_min_lod);
|
|
|
|
|
if (min_lod)
|
|
|
|
|
lod = nir_fmax(b, lod, min_lod);
|
2018-10-11 14:14:29 -05:00
|
|
|
|
|
|
|
|
nir_tex_instr_add_src(tex, nir_tex_src_lod, nir_src_for_ssa(lod));
|
|
|
|
|
tex->op = nir_texop_txl;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-09 11:34:23 -05:00
|
|
|
static void
|
|
|
|
|
lower_implicit_lod(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
lower_lod(b, tex, nir_get_texture_lod(b, tex));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
lower_zero_lod(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
if (tex->op == nir_texop_lod) {
|
|
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, nir_imm_int(b, 0));
|
|
|
|
|
nir_instr_remove(&tex->instr);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lower_lod(b, tex, nir_imm_int(b, 0));
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-01 21:13:37 -07:00
|
|
|
static nir_ssa_def *
|
2019-02-11 09:25:18 +02:00
|
|
|
sample_plane(nir_builder *b, nir_tex_instr *tex, int plane,
|
|
|
|
|
const nir_lower_tex_options *options)
|
2016-05-01 21:13:37 -07:00
|
|
|
{
|
|
|
|
|
assert(nir_tex_instr_dest_size(tex) == 4);
|
|
|
|
|
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
|
|
|
|
|
assert(tex->op == nir_texop_tex);
|
|
|
|
|
assert(tex->coord_components == 2);
|
|
|
|
|
|
2018-03-27 09:32:57 -07:00
|
|
|
nir_tex_instr *plane_tex =
|
|
|
|
|
nir_tex_instr_create(b->shader, tex->num_srcs + 1);
|
|
|
|
|
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
2021-09-08 16:41:00 +01:00
|
|
|
nir_src_copy(&plane_tex->src[i].src, &tex->src[i].src, &plane_tex->instr);
|
2018-03-27 09:32:57 -07:00
|
|
|
plane_tex->src[i].src_type = tex->src[i].src_type;
|
|
|
|
|
}
|
2023-05-25 16:51:33 -04:00
|
|
|
plane_tex->src[tex->num_srcs] = nir_tex_src_for_ssa(nir_tex_src_plane,
|
|
|
|
|
nir_imm_int(b, plane));
|
2016-05-01 21:13:37 -07:00
|
|
|
plane_tex->op = nir_texop_tex;
|
2016-09-08 15:49:49 -04:00
|
|
|
plane_tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
|
2020-12-08 13:45:55 +01:00
|
|
|
plane_tex->dest_type = nir_type_float | nir_dest_bit_size(tex->dest);
|
2016-05-01 21:13:37 -07:00
|
|
|
plane_tex->coord_components = 2;
|
|
|
|
|
|
|
|
|
|
plane_tex->texture_index = tex->texture_index;
|
|
|
|
|
plane_tex->sampler_index = tex->sampler_index;
|
|
|
|
|
|
2020-06-03 11:34:09 -07:00
|
|
|
nir_ssa_dest_init(&plane_tex->instr, &plane_tex->dest, 4,
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_dest_bit_size(tex->dest));
|
2016-05-01 21:13:37 -07:00
|
|
|
|
|
|
|
|
nir_builder_instr_insert(b, &plane_tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
/* If scaling_factor is set, return a scaled value. */
|
|
|
|
|
if (options->scale_factors[tex->texture_index])
|
|
|
|
|
return nir_fmul_imm(b, &plane_tex->dest.ssa,
|
|
|
|
|
options->scale_factors[tex->texture_index]);
|
|
|
|
|
|
2016-05-01 21:13:37 -07:00
|
|
|
return &plane_tex->dest.ssa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
convert_yuv_to_rgb(nir_builder *b, nir_tex_instr *tex,
|
2018-11-09 10:33:37 +00:00
|
|
|
nir_ssa_def *y, nir_ssa_def *u, nir_ssa_def *v,
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_ssa_def *a,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2016-05-01 21:13:37 -07:00
|
|
|
{
|
2020-07-08 13:23:22 +09:00
|
|
|
|
2020-11-11 16:59:04 -08:00
|
|
|
const float *offset_vals;
|
|
|
|
|
const nir_const_value_3_4 *m;
|
2020-07-08 13:23:22 +09:00
|
|
|
assert((options->bt709_external & options->bt2020_external) == 0);
|
2022-05-21 23:25:02 +00:00
|
|
|
if (options->yuv_full_range_external & (1u << texture_index)) {
|
|
|
|
|
if (options->bt709_external & (1u << texture_index)) {
|
|
|
|
|
m = &bt709_full_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt709_full_range_csc_offsets;
|
|
|
|
|
} else if (options->bt2020_external & (1u << texture_index)) {
|
|
|
|
|
m = &bt2020_full_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt2020_full_range_csc_offsets;
|
|
|
|
|
} else {
|
|
|
|
|
m = &bt601_full_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt601_full_range_csc_offsets;
|
|
|
|
|
}
|
2020-07-08 13:23:22 +09:00
|
|
|
} else {
|
2022-05-21 23:25:02 +00:00
|
|
|
if (options->bt709_external & (1u << texture_index)) {
|
|
|
|
|
m = &bt709_limited_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt709_limited_range_csc_offsets;
|
|
|
|
|
} else if (options->bt2020_external & (1u << texture_index)) {
|
|
|
|
|
m = &bt2020_limited_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt2020_limited_range_csc_offsets;
|
|
|
|
|
} else {
|
|
|
|
|
m = &bt601_limited_range_csc_coeffs;
|
|
|
|
|
offset_vals = bt601_limited_range_csc_offsets;
|
|
|
|
|
}
|
2020-07-08 13:23:22 +09:00
|
|
|
}
|
|
|
|
|
|
2020-06-03 11:34:09 -07:00
|
|
|
unsigned bit_size = nir_dest_bit_size(tex->dest);
|
2016-05-01 21:13:37 -07:00
|
|
|
|
2018-11-29 21:43:12 -05:00
|
|
|
nir_ssa_def *offset =
|
2016-05-01 21:13:37 -07:00
|
|
|
nir_vec4(b,
|
2021-04-07 19:29:40 +02:00
|
|
|
nir_imm_floatN_t(b, offset_vals[0], a->bit_size),
|
|
|
|
|
nir_imm_floatN_t(b, offset_vals[1], a->bit_size),
|
|
|
|
|
nir_imm_floatN_t(b, offset_vals[2], a->bit_size),
|
2018-11-29 21:43:12 -05:00
|
|
|
a);
|
|
|
|
|
|
2020-06-03 11:34:09 -07:00
|
|
|
offset = nir_f2fN(b, offset, bit_size);
|
|
|
|
|
|
2020-11-11 16:59:04 -08:00
|
|
|
nir_ssa_def *m0 = nir_f2fN(b, nir_build_imm(b, 4, 32, m->v[0]), bit_size);
|
|
|
|
|
nir_ssa_def *m1 = nir_f2fN(b, nir_build_imm(b, 4, 32, m->v[1]), bit_size);
|
|
|
|
|
nir_ssa_def *m2 = nir_f2fN(b, nir_build_imm(b, 4, 32, m->v[2]), bit_size);
|
2020-06-03 11:34:09 -07:00
|
|
|
|
2018-11-29 21:43:12 -05:00
|
|
|
nir_ssa_def *result =
|
2020-06-03 11:34:09 -07:00
|
|
|
nir_ffma(b, y, m0, nir_ffma(b, u, m1, nir_ffma(b, v, m2, offset)));
|
2016-05-01 21:13:37 -07:00
|
|
|
|
2021-03-03 00:13:38 -06:00
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, result);
|
2016-05-01 21:13:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2019-02-11 09:25:18 +02:00
|
|
|
lower_y_uv_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2016-05-01 21:13:37 -07:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *uv = sample_plane(b, tex, 1, options);
|
2016-05-01 21:13:37 -07:00
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 0),
|
|
|
|
|
nir_channel(b, uv, 0),
|
2018-11-09 10:33:37 +00:00
|
|
|
nir_channel(b, uv, 1),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
static void
|
|
|
|
|
lower_y_vu_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *vu = sample_plane(b, tex, 1, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 0),
|
|
|
|
|
nir_channel(b, vu, 1),
|
|
|
|
|
nir_channel(b, vu, 0),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-01 21:13:37 -07:00
|
|
|
static void
|
2019-02-11 09:25:18 +02:00
|
|
|
lower_y_u_v_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2016-05-01 21:13:37 -07:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *u = sample_plane(b, tex, 1, options);
|
|
|
|
|
nir_ssa_def *v = sample_plane(b, tex, 2, options);
|
2016-05-01 21:13:37 -07:00
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 0),
|
|
|
|
|
nir_channel(b, u, 0),
|
2018-11-09 10:33:37 +00:00
|
|
|
nir_channel(b, v, 0),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2019-02-11 09:25:18 +02:00
|
|
|
lower_yx_xuxv_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2016-05-01 21:13:37 -07:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *xuxv = sample_plane(b, tex, 1, options);
|
2016-05-01 21:13:37 -07:00
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 0),
|
|
|
|
|
nir_channel(b, xuxv, 1),
|
2018-11-09 10:33:37 +00:00
|
|
|
nir_channel(b, xuxv, 3),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
static void
|
|
|
|
|
lower_yx_xvxu_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *xvxu = sample_plane(b, tex, 1, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 0),
|
|
|
|
|
nir_channel(b, xvxu, 3),
|
|
|
|
|
nir_channel(b, xvxu, 1),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 13:40:31 +08:00
|
|
|
static void
|
2019-02-11 09:25:18 +02:00
|
|
|
lower_xy_uxvx_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2017-06-16 13:40:31 +08:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *uxvx = sample_plane(b, tex, 1, options);
|
2017-06-16 13:40:31 +08:00
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 1),
|
|
|
|
|
nir_channel(b, uxvx, 0),
|
2018-11-09 10:33:37 +00:00
|
|
|
nir_channel(b, uxvx, 2),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2017-06-16 13:40:31 +08:00
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
static void
|
|
|
|
|
lower_xy_vxux_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *y = sample_plane(b, tex, 0, options);
|
|
|
|
|
nir_ssa_def *vxux = sample_plane(b, tex, 1, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y, 1),
|
|
|
|
|
nir_channel(b, vxux, 2),
|
|
|
|
|
nir_channel(b, vxux, 0),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-08 16:28:20 +00:00
|
|
|
static void
|
2019-02-11 09:25:18 +02:00
|
|
|
lower_ayuv_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2018-11-08 16:28:20 +00:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2019-02-11 09:25:18 +02:00
|
|
|
nir_ssa_def *ayuv = sample_plane(b, tex, 0, options);
|
2018-11-08 16:28:20 +00:00
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, ayuv, 2),
|
|
|
|
|
nir_channel(b, ayuv, 1),
|
|
|
|
|
nir_channel(b, ayuv, 0),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_channel(b, ayuv, 3),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2018-11-08 16:28:20 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-10 19:49:05 -08:00
|
|
|
static void
|
|
|
|
|
lower_y41x_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *y41x = sample_plane(b, tex, 0, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, y41x, 1),
|
|
|
|
|
nir_channel(b, y41x, 0),
|
|
|
|
|
nir_channel(b, y41x, 2),
|
|
|
|
|
nir_channel(b, y41x, 3),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-12 16:02:20 -08:00
|
|
|
static void
|
|
|
|
|
lower_xyuv_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2019-02-12 16:02:20 -08:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *xyuv = sample_plane(b, tex, 0, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, xyuv, 2),
|
|
|
|
|
nir_channel(b, xyuv, 1),
|
|
|
|
|
nir_channel(b, xyuv, 0),
|
2020-07-08 13:23:22 +09:00
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2019-02-12 16:02:20 -08:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:11:18 +00:00
|
|
|
static void
|
|
|
|
|
lower_yuv_external(nir_builder *b, nir_tex_instr *tex,
|
2021-03-30 21:37:32 +02:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
2020-09-28 20:11:18 +00:00
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *yuv = sample_plane(b, tex, 0, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, yuv, 0),
|
|
|
|
|
nir_channel(b, yuv, 1),
|
|
|
|
|
nir_channel(b, yuv, 2),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
2021-03-30 21:37:32 +02:00
|
|
|
options,
|
|
|
|
|
texture_index);
|
2020-09-28 20:11:18 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-12 23:07:09 -08:00
|
|
|
static void
|
|
|
|
|
lower_yu_yv_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *yuv = sample_plane(b, tex, 0, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, yuv, 1),
|
|
|
|
|
nir_channel(b, yuv, 2),
|
|
|
|
|
nir_channel(b, yuv, 0),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
static void
|
|
|
|
|
lower_yv_yu_external(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
unsigned texture_index)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *yuv = sample_plane(b, tex, 0, options);
|
|
|
|
|
|
|
|
|
|
convert_yuv_to_rgb(b, tex,
|
|
|
|
|
nir_channel(b, yuv, 2),
|
|
|
|
|
nir_channel(b, yuv, 1),
|
|
|
|
|
nir_channel(b, yuv, 0),
|
|
|
|
|
nir_imm_float(b, 1.0f),
|
|
|
|
|
options,
|
|
|
|
|
texture_index);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 09:40:43 +01:00
|
|
|
/*
|
2018-10-11 14:27:26 -05:00
|
|
|
* Converts a nir_texop_txd instruction to nir_texop_txl with the given lod
|
|
|
|
|
* computed from the gradients.
|
2016-11-30 09:40:43 +01:00
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
replace_gradient_with_lod(nir_builder *b, nir_ssa_def *lod, nir_tex_instr *tex)
|
|
|
|
|
{
|
2018-10-11 14:27:26 -05:00
|
|
|
assert(tex->op == nir_texop_txd);
|
2016-11-30 09:40:43 +01:00
|
|
|
|
2018-10-11 14:27:26 -05:00
|
|
|
nir_tex_instr_remove_src(tex, nir_tex_instr_src_index(tex, nir_tex_src_ddx));
|
|
|
|
|
nir_tex_instr_remove_src(tex, nir_tex_instr_src_index(tex, nir_tex_src_ddy));
|
2016-11-30 09:40:43 +01:00
|
|
|
|
2023-06-07 18:00:45 -04:00
|
|
|
/* If we have a minimum LOD, clamp LOD accordingly */
|
|
|
|
|
nir_ssa_def *min_lod = nir_steal_tex_src(tex, nir_tex_src_min_lod);
|
|
|
|
|
if (min_lod)
|
|
|
|
|
lod = nir_fmax(b, lod, min_lod);
|
2018-10-11 14:14:29 -05:00
|
|
|
|
2018-10-11 14:27:26 -05:00
|
|
|
nir_tex_instr_add_src(tex, nir_tex_src_lod, nir_src_for_ssa(lod));
|
|
|
|
|
tex->op = nir_texop_txl;
|
2016-11-30 09:40:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
lower_gradient_cube_map(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
assert(tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE);
|
|
|
|
|
assert(tex->op == nir_texop_txd);
|
|
|
|
|
|
|
|
|
|
/* Use textureSize() to get the width and height of LOD 0 */
|
2020-02-20 17:19:50 -06:00
|
|
|
nir_ssa_def *size = nir_i2f32(b, nir_get_texture_size(b, tex));
|
2016-11-30 09:40:43 +01:00
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* coordinate */
|
|
|
|
|
nir_ssa_def *p =
|
|
|
|
|
tex->src[nir_tex_instr_src_index(tex, nir_tex_src_coord)].src.ssa;
|
|
|
|
|
|
|
|
|
|
/* unmodified dPdx, dPdy values */
|
|
|
|
|
nir_ssa_def *dPdx =
|
|
|
|
|
tex->src[nir_tex_instr_src_index(tex, nir_tex_src_ddx)].src.ssa;
|
|
|
|
|
nir_ssa_def *dPdy =
|
|
|
|
|
tex->src[nir_tex_instr_src_index(tex, nir_tex_src_ddy)].src.ssa;
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *abs_p = nir_fabs(b, p);
|
|
|
|
|
nir_ssa_def *abs_p_x = nir_channel(b, abs_p, 0);
|
|
|
|
|
nir_ssa_def *abs_p_y = nir_channel(b, abs_p, 1);
|
|
|
|
|
nir_ssa_def *abs_p_z = nir_channel(b, abs_p, 2);
|
|
|
|
|
|
|
|
|
|
/* 1. compute selector */
|
|
|
|
|
nir_ssa_def *Q, *dQdx, *dQdy;
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *cond_z = nir_fge(b, abs_p_z, nir_fmax(b, abs_p_x, abs_p_y));
|
|
|
|
|
nir_ssa_def *cond_y = nir_fge(b, abs_p_y, nir_fmax(b, abs_p_x, abs_p_z));
|
|
|
|
|
|
2018-07-13 03:33:22 +02:00
|
|
|
unsigned yzx[3] = { 1, 2, 0 };
|
|
|
|
|
unsigned xzy[3] = { 0, 2, 1 };
|
2016-11-30 09:40:43 +01:00
|
|
|
|
|
|
|
|
Q = nir_bcsel(b, cond_z,
|
|
|
|
|
p,
|
|
|
|
|
nir_bcsel(b, cond_y,
|
2019-05-06 10:23:26 -05:00
|
|
|
nir_swizzle(b, p, xzy, 3),
|
|
|
|
|
nir_swizzle(b, p, yzx, 3)));
|
2016-11-30 09:40:43 +01:00
|
|
|
|
|
|
|
|
dQdx = nir_bcsel(b, cond_z,
|
|
|
|
|
dPdx,
|
|
|
|
|
nir_bcsel(b, cond_y,
|
2019-05-06 10:23:26 -05:00
|
|
|
nir_swizzle(b, dPdx, xzy, 3),
|
|
|
|
|
nir_swizzle(b, dPdx, yzx, 3)));
|
2016-11-30 09:40:43 +01:00
|
|
|
|
|
|
|
|
dQdy = nir_bcsel(b, cond_z,
|
|
|
|
|
dPdy,
|
|
|
|
|
nir_bcsel(b, cond_y,
|
2019-05-06 10:23:26 -05:00
|
|
|
nir_swizzle(b, dPdy, xzy, 3),
|
|
|
|
|
nir_swizzle(b, dPdy, yzx, 3)));
|
2016-11-30 09:40:43 +01:00
|
|
|
|
|
|
|
|
/* 2. quotient rule */
|
|
|
|
|
|
|
|
|
|
/* tmp = Q.xy * recip;
|
|
|
|
|
* dx = recip * ( dQdx.xy - (tmp * dQdx.z) );
|
|
|
|
|
* dy = recip * ( dQdy.xy - (tmp * dQdy.z) );
|
|
|
|
|
*/
|
|
|
|
|
nir_ssa_def *rcp_Q_z = nir_frcp(b, nir_channel(b, Q, 2));
|
|
|
|
|
|
treewide: Use nir_trim_vector more
Via Coccinelle patches
@@
expression a, b, c;
@@
-nir_channels(b, a, (1 << c) - 1)
+nir_trim_vector(b, a, c)
@@
expression a, b, c;
@@
-nir_channels(b, a, BITFIELD_MASK(c))
+nir_trim_vector(b, a, c)
@@
expression a, b;
@@
-nir_channels(b, a, 3)
+nir_trim_vector(b, a, 2)
@@
expression a, b;
@@
-nir_channels(b, a, 7)
+nir_trim_vector(b, a, 3)
Plus a fixup for pointless trimming an immediate in RADV and radeonsi.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23352>
2023-05-31 21:08:47 -04:00
|
|
|
nir_ssa_def *Q_xy = nir_trim_vector(b, Q, 2);
|
2016-11-30 09:40:43 +01:00
|
|
|
nir_ssa_def *tmp = nir_fmul(b, Q_xy, rcp_Q_z);
|
|
|
|
|
|
treewide: Use nir_trim_vector more
Via Coccinelle patches
@@
expression a, b, c;
@@
-nir_channels(b, a, (1 << c) - 1)
+nir_trim_vector(b, a, c)
@@
expression a, b, c;
@@
-nir_channels(b, a, BITFIELD_MASK(c))
+nir_trim_vector(b, a, c)
@@
expression a, b;
@@
-nir_channels(b, a, 3)
+nir_trim_vector(b, a, 2)
@@
expression a, b;
@@
-nir_channels(b, a, 7)
+nir_trim_vector(b, a, 3)
Plus a fixup for pointless trimming an immediate in RADV and radeonsi.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23352>
2023-05-31 21:08:47 -04:00
|
|
|
nir_ssa_def *dQdx_xy = nir_trim_vector(b, dQdx, 2);
|
2016-11-30 09:40:43 +01:00
|
|
|
nir_ssa_def *dQdx_z = nir_channel(b, dQdx, 2);
|
|
|
|
|
nir_ssa_def *dx =
|
|
|
|
|
nir_fmul(b, rcp_Q_z, nir_fsub(b, dQdx_xy, nir_fmul(b, tmp, dQdx_z)));
|
|
|
|
|
|
treewide: Use nir_trim_vector more
Via Coccinelle patches
@@
expression a, b, c;
@@
-nir_channels(b, a, (1 << c) - 1)
+nir_trim_vector(b, a, c)
@@
expression a, b, c;
@@
-nir_channels(b, a, BITFIELD_MASK(c))
+nir_trim_vector(b, a, c)
@@
expression a, b;
@@
-nir_channels(b, a, 3)
+nir_trim_vector(b, a, 2)
@@
expression a, b;
@@
-nir_channels(b, a, 7)
+nir_trim_vector(b, a, 3)
Plus a fixup for pointless trimming an immediate in RADV and radeonsi.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23352>
2023-05-31 21:08:47 -04:00
|
|
|
nir_ssa_def *dQdy_xy = nir_trim_vector(b, dQdy, 2);
|
2016-11-30 09:40:43 +01:00
|
|
|
nir_ssa_def *dQdy_z = nir_channel(b, dQdy, 2);
|
|
|
|
|
nir_ssa_def *dy =
|
|
|
|
|
nir_fmul(b, rcp_Q_z, nir_fsub(b, dQdy_xy, nir_fmul(b, tmp, dQdy_z)));
|
|
|
|
|
|
|
|
|
|
/* M = max(dot(dx, dx), dot(dy, dy)); */
|
|
|
|
|
nir_ssa_def *M = nir_fmax(b, nir_fdot(b, dx, dx), nir_fdot(b, dy, dy));
|
|
|
|
|
|
|
|
|
|
/* size has textureSize() of LOD 0 */
|
|
|
|
|
nir_ssa_def *L = nir_channel(b, size, 0);
|
|
|
|
|
|
|
|
|
|
/* lod = -1.0 + 0.5 * log2(L * L * M); */
|
|
|
|
|
nir_ssa_def *lod =
|
|
|
|
|
nir_fadd(b,
|
|
|
|
|
nir_imm_float(b, -1.0f),
|
|
|
|
|
nir_fmul(b,
|
|
|
|
|
nir_imm_float(b, 0.5f),
|
|
|
|
|
nir_flog2(b, nir_fmul(b, L, nir_fmul(b, L, M)))));
|
|
|
|
|
|
|
|
|
|
/* 3. Replace the gradient instruction with an equivalent lod instruction */
|
|
|
|
|
replace_gradient_with_lod(b, lod, tex);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 11:31:01 +01:00
|
|
|
static void
|
2017-11-21 16:21:36 -08:00
|
|
|
lower_gradient(nir_builder *b, nir_tex_instr *tex)
|
2016-11-30 11:31:01 +01:00
|
|
|
{
|
2018-10-11 12:56:21 -05:00
|
|
|
/* Cubes are more complicated and have their own function */
|
|
|
|
|
if (tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE) {
|
|
|
|
|
lower_gradient_cube_map(b, tex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 11:31:01 +01:00
|
|
|
assert(tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE);
|
|
|
|
|
assert(tex->op == nir_texop_txd);
|
|
|
|
|
|
|
|
|
|
/* Use textureSize() to get the width and height of LOD 0 */
|
|
|
|
|
unsigned component_mask;
|
|
|
|
|
switch (tex->sampler_dim) {
|
|
|
|
|
case GLSL_SAMPLER_DIM_3D:
|
|
|
|
|
component_mask = 7;
|
|
|
|
|
break;
|
|
|
|
|
case GLSL_SAMPLER_DIM_1D:
|
|
|
|
|
component_mask = 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
component_mask = 3;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *size =
|
2020-02-20 17:19:50 -06:00
|
|
|
nir_channels(b, nir_i2f32(b, nir_get_texture_size(b, tex)),
|
|
|
|
|
component_mask);
|
2016-11-30 11:31:01 +01:00
|
|
|
|
|
|
|
|
/* 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).
|
|
|
|
|
*/
|
|
|
|
|
nir_ssa_def *ddx =
|
|
|
|
|
tex->src[nir_tex_instr_src_index(tex, nir_tex_src_ddx)].src.ssa;
|
|
|
|
|
nir_ssa_def *ddy =
|
|
|
|
|
tex->src[nir_tex_instr_src_index(tex, nir_tex_src_ddy)].src.ssa;
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *dPdx = nir_fmul(b, ddx, size);
|
|
|
|
|
nir_ssa_def *dPdy = nir_fmul(b, ddy, size);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *rho;
|
|
|
|
|
if (dPdx->num_components == 1) {
|
|
|
|
|
rho = nir_fmax(b, nir_fabs(b, dPdx), nir_fabs(b, dPdy));
|
|
|
|
|
} else {
|
|
|
|
|
rho = nir_fmax(b,
|
|
|
|
|
nir_fsqrt(b, nir_fdot(b, dPdx, dPdx)),
|
|
|
|
|
nir_fsqrt(b, nir_fdot(b, dPdy, dPdy)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* lod = log2(rho). We're ignoring GL state biases for now. */
|
|
|
|
|
nir_ssa_def *lod = nir_flog2(b, rho);
|
|
|
|
|
|
|
|
|
|
/* Replace the gradient instruction with an equivalent lod instruction */
|
|
|
|
|
replace_gradient_with_lod(b, lod, tex);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 17:15:06 -05:00
|
|
|
/* tex(s, coord) = txd(s, coord, dfdx(coord), dfdy(coord)) */
|
|
|
|
|
static nir_tex_instr *
|
|
|
|
|
lower_tex_to_txd(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
nir_tex_instr *txd = nir_tex_instr_create(b->shader, tex->num_srcs + 2);
|
|
|
|
|
|
|
|
|
|
txd->op = nir_texop_txd;
|
|
|
|
|
txd->sampler_dim = tex->sampler_dim;
|
|
|
|
|
txd->dest_type = tex->dest_type;
|
|
|
|
|
txd->coord_components = tex->coord_components;
|
|
|
|
|
txd->texture_index = tex->texture_index;
|
|
|
|
|
txd->sampler_index = tex->sampler_index;
|
2022-04-14 13:30:39 +12:00
|
|
|
txd->is_array = tex->is_array;
|
|
|
|
|
txd->is_shadow = tex->is_shadow;
|
|
|
|
|
txd->is_new_style_shadow = tex->is_new_style_shadow;
|
2021-02-12 17:15:06 -05:00
|
|
|
|
|
|
|
|
/* reuse existing srcs */
|
|
|
|
|
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
2021-09-08 16:41:00 +01:00
|
|
|
nir_src_copy(&txd->src[i].src, &tex->src[i].src, &txd->instr);
|
2021-02-12 17:15:06 -05:00
|
|
|
txd->src[i].src_type = tex->src[i].src_type;
|
|
|
|
|
}
|
2021-02-21 17:31:30 -08:00
|
|
|
int coord = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
2021-02-12 17:15:06 -05:00
|
|
|
assert(coord >= 0);
|
|
|
|
|
nir_ssa_def *dfdx = nir_fddx(b, tex->src[coord].src.ssa);
|
|
|
|
|
nir_ssa_def *dfdy = nir_fddy(b, tex->src[coord].src.ssa);
|
2023-05-25 16:51:33 -04:00
|
|
|
txd->src[tex->num_srcs] = nir_tex_src_for_ssa(nir_tex_src_ddx, dfdx);
|
|
|
|
|
txd->src[tex->num_srcs + 1] = nir_tex_src_for_ssa(nir_tex_src_ddy, dfdy);
|
2021-02-12 17:15:06 -05:00
|
|
|
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_ssa_dest_init(&txd->instr, &txd->dest,
|
|
|
|
|
nir_dest_num_components(tex->dest),
|
|
|
|
|
nir_dest_bit_size(tex->dest));
|
2021-02-12 17:15:06 -05:00
|
|
|
nir_builder_instr_insert(b, &txd->instr);
|
2021-03-03 00:13:38 -06:00
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, &txd->dest.ssa);
|
2021-02-12 17:15:06 -05:00
|
|
|
nir_instr_remove(&tex->instr);
|
|
|
|
|
return txd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* txb(s, coord, bias) = txl(s, coord, lod(s, coord).y + bias) */
|
|
|
|
|
static nir_tex_instr *
|
|
|
|
|
lower_txb_to_txl(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
nir_tex_instr *txl = nir_tex_instr_create(b->shader, tex->num_srcs);
|
|
|
|
|
|
|
|
|
|
txl->op = nir_texop_txl;
|
|
|
|
|
txl->sampler_dim = tex->sampler_dim;
|
|
|
|
|
txl->dest_type = tex->dest_type;
|
|
|
|
|
txl->coord_components = tex->coord_components;
|
|
|
|
|
txl->texture_index = tex->texture_index;
|
|
|
|
|
txl->sampler_index = tex->sampler_index;
|
2022-04-14 13:30:39 +12:00
|
|
|
txl->is_array = tex->is_array;
|
|
|
|
|
txl->is_shadow = tex->is_shadow;
|
|
|
|
|
txl->is_new_style_shadow = tex->is_new_style_shadow;
|
2021-02-12 17:15:06 -05:00
|
|
|
|
|
|
|
|
/* reuse all but bias src */
|
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
|
if (tex->src[i].src_type != nir_tex_src_bias) {
|
2021-09-08 16:41:00 +01:00
|
|
|
nir_src_copy(&txl->src[i].src, &tex->src[i].src, &txl->instr);
|
2021-02-12 17:15:06 -05:00
|
|
|
txl->src[i].src_type = tex->src[i].src_type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nir_ssa_def *lod = nir_get_texture_lod(b, txl);
|
|
|
|
|
|
|
|
|
|
int bias_idx = nir_tex_instr_src_index(tex, nir_tex_src_bias);
|
|
|
|
|
assert(bias_idx >= 0);
|
|
|
|
|
lod = nir_fadd(b, nir_channel(b, lod, 1), nir_ssa_for_src(b, tex->src[bias_idx].src, 1));
|
2023-05-25 16:51:33 -04:00
|
|
|
txl->src[tex->num_srcs - 1] = nir_tex_src_for_ssa(nir_tex_src_lod, lod);
|
2021-02-12 17:15:06 -05:00
|
|
|
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_ssa_dest_init(&txl->instr, &txl->dest,
|
|
|
|
|
nir_dest_num_components(tex->dest),
|
|
|
|
|
nir_dest_bit_size(tex->dest));
|
2021-02-12 17:15:06 -05:00
|
|
|
nir_builder_instr_insert(b, &txl->instr);
|
2021-03-03 00:13:38 -06:00
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, &txl->dest.ssa);
|
2021-02-12 17:15:06 -05:00
|
|
|
nir_instr_remove(&tex->instr);
|
|
|
|
|
return txl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static nir_tex_instr *
|
2015-09-18 10:44:27 -04:00
|
|
|
saturate_src(nir_builder *b, nir_tex_instr *tex, unsigned sat_mask)
|
|
|
|
|
{
|
2021-02-12 17:15:06 -05:00
|
|
|
if (tex->op == nir_texop_tex)
|
|
|
|
|
tex = lower_tex_to_txd(b, tex);
|
|
|
|
|
else if (tex->op == nir_texop_txb)
|
|
|
|
|
tex = lower_txb_to_txl(b, tex);
|
|
|
|
|
|
2015-09-18 10:44:27 -04:00
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
2021-02-11 13:13:42 +01:00
|
|
|
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
2015-09-18 10:44:27 -04:00
|
|
|
|
2021-02-11 13:13:42 +01:00
|
|
|
if (coord_index != -1) {
|
2015-09-18 10:44:27 -04:00
|
|
|
nir_ssa_def *src =
|
2021-02-11 13:13:42 +01:00
|
|
|
nir_ssa_for_src(b, tex->src[coord_index].src, tex->coord_components);
|
2015-09-18 10:44:27 -04:00
|
|
|
|
|
|
|
|
/* split src into components: */
|
|
|
|
|
nir_ssa_def *comp[4];
|
|
|
|
|
|
2016-05-18 10:38:40 -04:00
|
|
|
assume(tex->coord_components >= 1);
|
|
|
|
|
|
2015-09-18 10:44:27 -04:00
|
|
|
for (unsigned j = 0; j < tex->coord_components; j++)
|
|
|
|
|
comp[j] = nir_channel(b, src, j);
|
|
|
|
|
|
|
|
|
|
/* clamp requested components, array index does not get clamped: */
|
|
|
|
|
unsigned ncomp = tex->coord_components;
|
|
|
|
|
if (tex->is_array)
|
|
|
|
|
ncomp--;
|
|
|
|
|
|
|
|
|
|
for (unsigned j = 0; j < ncomp; j++) {
|
|
|
|
|
if ((1 << j) & sat_mask) {
|
|
|
|
|
if (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
|
|
|
|
|
/* non-normalized texture coords, so clamp to texture
|
|
|
|
|
* size rather than [0.0, 1.0]
|
|
|
|
|
*/
|
2020-02-20 17:19:50 -06:00
|
|
|
nir_ssa_def *txs = nir_i2f32(b, nir_get_texture_size(b, tex));
|
2015-09-18 10:44:27 -04:00
|
|
|
comp[j] = nir_fmax(b, comp[j], nir_imm_float(b, 0.0));
|
|
|
|
|
comp[j] = nir_fmin(b, comp[j], nir_channel(b, txs, j));
|
|
|
|
|
} else {
|
|
|
|
|
comp[j] = nir_fsat(b, comp[j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* and move the result back into a single vecN: */
|
2015-09-18 13:23:36 -04:00
|
|
|
src = nir_vec(b, comp, tex->coord_components);
|
2015-09-18 10:44:27 -04:00
|
|
|
|
|
|
|
|
nir_instr_rewrite_src(&tex->instr,
|
2021-02-11 13:13:42 +01:00
|
|
|
&tex->src[coord_index].src,
|
2015-09-18 10:44:27 -04:00
|
|
|
nir_src_for_ssa(src));
|
|
|
|
|
}
|
2021-02-12 17:15:06 -05:00
|
|
|
return tex;
|
2015-09-18 10:44:27 -04:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 18:30:31 -08:00
|
|
|
static nir_ssa_def *
|
|
|
|
|
get_zero_or_one(nir_builder *b, nir_alu_type type, uint8_t swizzle_val)
|
|
|
|
|
{
|
2019-03-27 00:59:03 +01:00
|
|
|
nir_const_value v[4];
|
2015-11-11 18:30:31 -08:00
|
|
|
|
|
|
|
|
memset(&v, 0, sizeof(v));
|
|
|
|
|
|
|
|
|
|
if (swizzle_val == 4) {
|
2019-03-27 00:59:03 +01:00
|
|
|
v[0].u32 = v[1].u32 = v[2].u32 = v[3].u32 = 0;
|
2015-11-11 18:30:31 -08:00
|
|
|
} else {
|
|
|
|
|
assert(swizzle_val == 5);
|
2020-12-08 13:50:14 +01:00
|
|
|
if (type == nir_type_float32)
|
2019-03-27 00:59:03 +01:00
|
|
|
v[0].f32 = v[1].f32 = v[2].f32 = v[3].f32 = 1.0;
|
2015-11-11 18:30:31 -08:00
|
|
|
else
|
2019-03-27 00:59:03 +01:00
|
|
|
v[0].u32 = v[1].u32 = v[2].u32 = v[3].u32 = 1;
|
2015-11-11 18:30:31 -08:00
|
|
|
}
|
|
|
|
|
|
2016-03-23 10:43:03 +01:00
|
|
|
return nir_build_imm(b, 4, 32, v);
|
2015-11-11 18:30:31 -08:00
|
|
|
}
|
|
|
|
|
|
2018-12-26 22:45:04 -08:00
|
|
|
static void
|
|
|
|
|
swizzle_tg4_broadcom(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
assert(nir_tex_instr_dest_size(tex) == 4);
|
|
|
|
|
unsigned swiz[4] = { 2, 3, 1, 0 };
|
2019-05-06 10:23:26 -05:00
|
|
|
nir_ssa_def *swizzled = nir_swizzle(b, &tex->dest.ssa, swiz, 4);
|
2018-12-26 22:45:04 -08:00
|
|
|
|
2021-03-03 10:35:36 -06:00
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, swizzled,
|
2018-12-26 22:45:04 -08:00
|
|
|
swizzled->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-11 18:30:31 -08:00
|
|
|
static void
|
|
|
|
|
swizzle_result(nir_builder *b, nir_tex_instr *tex, const uint8_t swizzle[4])
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *swizzled;
|
|
|
|
|
if (tex->op == nir_texop_tg4) {
|
|
|
|
|
if (swizzle[tex->component] < 4) {
|
|
|
|
|
/* This one's easy */
|
|
|
|
|
tex->component = swizzle[tex->component];
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
swizzled = get_zero_or_one(b, tex->dest_type, swizzle[tex->component]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
assert(nir_tex_instr_dest_size(tex) == 4);
|
|
|
|
|
if (swizzle[0] < 4 && swizzle[1] < 4 &&
|
|
|
|
|
swizzle[2] < 4 && swizzle[3] < 4) {
|
|
|
|
|
unsigned swiz[4] = { swizzle[0], swizzle[1], swizzle[2], swizzle[3] };
|
2017-02-27 17:21:42 -08:00
|
|
|
/* We have no 0s or 1s, just emit a swizzling MOV */
|
2019-05-06 10:23:26 -05:00
|
|
|
swizzled = nir_swizzle(b, &tex->dest.ssa, swiz, 4);
|
2015-11-11 18:30:31 -08:00
|
|
|
} else {
|
2022-02-03 12:23:34 -08:00
|
|
|
nir_ssa_scalar srcs[4];
|
2015-11-11 18:30:31 -08:00
|
|
|
for (unsigned i = 0; i < 4; i++) {
|
|
|
|
|
if (swizzle[i] < 4) {
|
2022-02-03 12:23:34 -08:00
|
|
|
srcs[i] = nir_get_ssa_scalar(&tex->dest.ssa, swizzle[i]);
|
2015-11-11 18:30:31 -08:00
|
|
|
} else {
|
2022-02-03 12:23:34 -08:00
|
|
|
srcs[i] = nir_get_ssa_scalar(get_zero_or_one(b, tex->dest_type, swizzle[i]), 0);
|
2015-11-11 18:30:31 -08:00
|
|
|
}
|
|
|
|
|
}
|
2022-02-03 12:23:34 -08:00
|
|
|
swizzled = nir_vec_scalars(b, srcs, 4);
|
2015-11-11 18:30:31 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 10:35:36 -06:00
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, swizzled,
|
2015-11-11 18:30:31 -08:00
|
|
|
swizzled->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-19 08:28:22 -04:00
|
|
|
static void
|
|
|
|
|
linearize_srgb_result(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
assert(nir_tex_instr_dest_size(tex) == 4);
|
|
|
|
|
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2018-07-12 18:23:34 -07:00
|
|
|
nir_ssa_def *rgb =
|
treewide: Use nir_trim_vector more
Via Coccinelle patches
@@
expression a, b, c;
@@
-nir_channels(b, a, (1 << c) - 1)
+nir_trim_vector(b, a, c)
@@
expression a, b, c;
@@
-nir_channels(b, a, BITFIELD_MASK(c))
+nir_trim_vector(b, a, c)
@@
expression a, b;
@@
-nir_channels(b, a, 3)
+nir_trim_vector(b, a, 2)
@@
expression a, b;
@@
-nir_channels(b, a, 7)
+nir_trim_vector(b, a, 3)
Plus a fixup for pointless trimming an immediate in RADV and radeonsi.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23352>
2023-05-31 21:08:47 -04:00
|
|
|
nir_format_srgb_to_linear(b, nir_trim_vector(b, &tex->dest.ssa, 3));
|
2016-04-19 08:28:22 -04:00
|
|
|
|
|
|
|
|
/* alpha is untouched: */
|
|
|
|
|
nir_ssa_def *result = nir_vec4(b,
|
|
|
|
|
nir_channel(b, rgb, 0),
|
|
|
|
|
nir_channel(b, rgb, 1),
|
|
|
|
|
nir_channel(b, rgb, 2),
|
|
|
|
|
nir_channel(b, &tex->dest.ssa, 3));
|
|
|
|
|
|
2021-03-03 10:35:36 -06:00
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, result,
|
2016-04-19 08:28:22 -04:00
|
|
|
result->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-19 13:53:39 -08:00
|
|
|
/**
|
|
|
|
|
* Lowers texture instructions from giving a vec4 result to a vec2 of f16,
|
|
|
|
|
* i16, or u16, or a single unorm4x8 value.
|
|
|
|
|
*
|
|
|
|
|
* Note that we don't change the destination num_components, because
|
|
|
|
|
* nir_tex_instr_dest_size() will still return 4. The driver is just expected
|
|
|
|
|
* to not store the other channels, given that nothing at the NIR level will
|
|
|
|
|
* read them.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
lower_tex_packing(nir_builder *b, nir_tex_instr *tex,
|
|
|
|
|
const nir_lower_tex_options *options)
|
|
|
|
|
{
|
|
|
|
|
nir_ssa_def *color = &tex->dest.ssa;
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
switch (options->lower_tex_packing[tex->sampler_index]) {
|
|
|
|
|
case nir_lower_tex_packing_none:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case nir_lower_tex_packing_16: {
|
|
|
|
|
static const unsigned bits[4] = {16, 16, 16, 16};
|
|
|
|
|
|
|
|
|
|
switch (nir_alu_type_get_base_type(tex->dest_type)) {
|
|
|
|
|
case nir_type_float:
|
2020-07-11 00:36:23 +02:00
|
|
|
switch (nir_tex_instr_dest_size(tex)) {
|
|
|
|
|
case 1:
|
|
|
|
|
assert(tex->is_shadow && tex->is_new_style_shadow);
|
2018-12-19 13:53:39 -08:00
|
|
|
color = nir_unpack_half_2x16_split_x(b, nir_channel(b, color, 0));
|
2020-07-11 00:36:23 +02:00
|
|
|
break;
|
|
|
|
|
case 2: {
|
|
|
|
|
nir_ssa_def *rg = nir_channel(b, color, 0);
|
|
|
|
|
color = nir_vec2(b,
|
|
|
|
|
nir_unpack_half_2x16_split_x(b, rg),
|
|
|
|
|
nir_unpack_half_2x16_split_y(b, rg));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 4: {
|
2018-12-19 13:53:39 -08:00
|
|
|
nir_ssa_def *rg = nir_channel(b, color, 0);
|
|
|
|
|
nir_ssa_def *ba = nir_channel(b, color, 1);
|
|
|
|
|
color = nir_vec4(b,
|
|
|
|
|
nir_unpack_half_2x16_split_x(b, rg),
|
|
|
|
|
nir_unpack_half_2x16_split_y(b, rg),
|
|
|
|
|
nir_unpack_half_2x16_split_x(b, ba),
|
|
|
|
|
nir_unpack_half_2x16_split_y(b, ba));
|
2020-07-11 00:36:23 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
unreachable("wrong dest_size");
|
2018-12-19 13:53:39 -08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case nir_type_int:
|
|
|
|
|
color = nir_format_unpack_sint(b, color, bits, 4);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case nir_type_uint:
|
|
|
|
|
color = nir_format_unpack_uint(b, color, bits, 4);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
unreachable("unknown base type");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case nir_lower_tex_packing_8:
|
|
|
|
|
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
|
|
|
|
|
color = nir_unpack_unorm_4x8(b, nir_channel(b, color, 0));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 10:35:36 -06:00
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, color,
|
2018-12-19 13:53:39 -08:00
|
|
|
color->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-08 17:51:24 -06:00
|
|
|
static bool
|
|
|
|
|
sampler_index_lt(nir_tex_instr *tex, unsigned max)
|
|
|
|
|
{
|
|
|
|
|
assert(nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref) == -1);
|
|
|
|
|
|
|
|
|
|
unsigned sampler_index = tex->sampler_index;
|
|
|
|
|
|
|
|
|
|
int sampler_offset_idx =
|
|
|
|
|
nir_tex_instr_src_index(tex, nir_tex_src_sampler_offset);
|
|
|
|
|
if (sampler_offset_idx >= 0) {
|
|
|
|
|
if (!nir_src_is_const(tex->src[sampler_offset_idx].src))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
sampler_index += nir_src_as_uint(tex->src[sampler_offset_idx].src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sampler_index < max;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 18:47:20 +01:00
|
|
|
static bool
|
|
|
|
|
lower_tg4_offsets(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
assert(tex->op == nir_texop_tg4);
|
|
|
|
|
assert(nir_tex_instr_has_explicit_tg4_offsets(tex));
|
|
|
|
|
assert(nir_tex_instr_src_index(tex, nir_tex_src_offset) == -1);
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2022-02-03 12:23:34 -08:00
|
|
|
nir_ssa_scalar dest[5] = { 0 };
|
|
|
|
|
nir_ssa_def *residency = NULL;
|
2019-03-19 18:47:20 +01:00
|
|
|
for (unsigned i = 0; i < 4; ++i) {
|
|
|
|
|
nir_tex_instr *tex_copy = nir_tex_instr_create(b->shader, tex->num_srcs + 1);
|
|
|
|
|
tex_copy->op = tex->op;
|
|
|
|
|
tex_copy->coord_components = tex->coord_components;
|
|
|
|
|
tex_copy->sampler_dim = tex->sampler_dim;
|
|
|
|
|
tex_copy->is_array = tex->is_array;
|
|
|
|
|
tex_copy->is_shadow = tex->is_shadow;
|
|
|
|
|
tex_copy->is_new_style_shadow = tex->is_new_style_shadow;
|
2020-12-07 13:36:47 +00:00
|
|
|
tex_copy->is_sparse = tex->is_sparse;
|
2023-04-13 14:13:35 +01:00
|
|
|
tex_copy->is_gather_implicit_lod = tex->is_gather_implicit_lod;
|
2019-03-19 18:47:20 +01:00
|
|
|
tex_copy->component = tex->component;
|
|
|
|
|
tex_copy->dest_type = tex->dest_type;
|
2023-06-13 10:27:57 +02:00
|
|
|
tex_copy->texture_index = tex->texture_index;
|
|
|
|
|
tex_copy->sampler_index = tex->sampler_index;
|
2019-03-19 18:47:20 +01:00
|
|
|
|
|
|
|
|
for (unsigned j = 0; j < tex->num_srcs; ++j) {
|
2021-09-08 16:41:00 +01:00
|
|
|
nir_src_copy(&tex_copy->src[j].src, &tex->src[j].src, &tex_copy->instr);
|
2019-03-19 18:47:20 +01:00
|
|
|
tex_copy->src[j].src_type = tex->src[j].src_type;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-25 16:51:33 -04:00
|
|
|
nir_ssa_def *offset = nir_imm_ivec2(b, tex->tg4_offsets[i][0],
|
|
|
|
|
tex->tg4_offsets[i][1]);
|
|
|
|
|
nir_tex_src src = nir_tex_src_for_ssa(nir_tex_src_offset, offset);
|
2019-03-19 18:47:20 +01:00
|
|
|
tex_copy->src[tex_copy->num_srcs - 1] = src;
|
|
|
|
|
|
|
|
|
|
nir_ssa_dest_init(&tex_copy->instr, &tex_copy->dest,
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_tex_instr_dest_size(tex), 32);
|
2019-03-19 18:47:20 +01:00
|
|
|
|
|
|
|
|
nir_builder_instr_insert(b, &tex_copy->instr);
|
|
|
|
|
|
2022-02-03 12:23:34 -08:00
|
|
|
dest[i] = nir_get_ssa_scalar(&tex_copy->dest.ssa, 3);
|
2020-12-07 13:36:47 +00:00
|
|
|
if (tex->is_sparse) {
|
|
|
|
|
nir_ssa_def *code = nir_channel(b, &tex_copy->dest.ssa, 4);
|
2022-02-03 12:23:34 -08:00
|
|
|
if (residency)
|
|
|
|
|
residency = nir_sparse_residency_code_and(b, residency, code);
|
|
|
|
|
else
|
|
|
|
|
residency = code;
|
2020-12-07 13:36:47 +00:00
|
|
|
}
|
2019-03-19 18:47:20 +01:00
|
|
|
}
|
2022-02-03 12:23:34 -08:00
|
|
|
dest[4] = nir_get_ssa_scalar(residency, 0);
|
2019-03-19 18:47:20 +01:00
|
|
|
|
2022-02-03 12:23:34 -08:00
|
|
|
nir_ssa_def *res = nir_vec_scalars(b, dest, tex->dest.ssa.num_components);
|
2021-03-03 00:13:38 -06:00
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, res);
|
2019-03-19 18:47:20 +01:00
|
|
|
nir_instr_remove(&tex->instr);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 11:43:13 +02:00
|
|
|
static bool
|
|
|
|
|
nir_lower_txs_lod(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
int lod_idx = nir_tex_instr_src_index(tex, nir_tex_src_lod);
|
|
|
|
|
if (lod_idx < 0 ||
|
|
|
|
|
(nir_src_is_const(tex->src[lod_idx].src) &&
|
|
|
|
|
nir_src_as_int(tex->src[lod_idx].src) == 0))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
unsigned dest_size = nir_tex_instr_dest_size(tex);
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
nir_ssa_def *lod = nir_ssa_for_src(b, tex->src[lod_idx].src, 1);
|
|
|
|
|
|
|
|
|
|
/* Replace the non-0-LOD in the initial TXS operation by a 0-LOD. */
|
|
|
|
|
nir_instr_rewrite_src(&tex->instr, &tex->src[lod_idx].src,
|
|
|
|
|
nir_src_for_ssa(nir_imm_int(b, 0)));
|
|
|
|
|
|
2021-06-16 15:49:25 -07:00
|
|
|
/* TXS(LOD) = max(TXS(0) >> LOD, 1)
|
|
|
|
|
* But we do min(TXS(0), TXS(LOD)) to catch the case of a null surface,
|
|
|
|
|
* which should return 0, not 1.
|
|
|
|
|
*/
|
2019-06-17 11:43:13 +02:00
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
2021-06-16 15:49:25 -07:00
|
|
|
nir_ssa_def *minified = nir_imin(b, &tex->dest.ssa,
|
|
|
|
|
nir_imax(b, nir_ushr(b, &tex->dest.ssa, lod),
|
|
|
|
|
nir_imm_int(b, 1)));
|
2019-06-17 11:43:13 +02:00
|
|
|
|
|
|
|
|
/* Make sure the component encoding the array size (if any) is not
|
|
|
|
|
* minified.
|
|
|
|
|
*/
|
|
|
|
|
if (tex->is_array) {
|
|
|
|
|
nir_ssa_def *comp[3];
|
|
|
|
|
|
2019-06-19 15:05:34 +02:00
|
|
|
assert(dest_size <= ARRAY_SIZE(comp));
|
2019-06-17 11:43:13 +02:00
|
|
|
for (unsigned i = 0; i < dest_size - 1; i++)
|
|
|
|
|
comp[i] = nir_channel(b, minified, i);
|
|
|
|
|
|
|
|
|
|
comp[dest_size - 1] = nir_channel(b, &tex->dest.ssa, dest_size - 1);
|
|
|
|
|
minified = nir_vec(b, comp, dest_size);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 10:35:36 -06:00
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, minified,
|
2019-06-17 11:43:13 +02:00
|
|
|
minified->parent_instr);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-21 16:39:15 -05:00
|
|
|
static void
|
|
|
|
|
nir_lower_txs_cube_array(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
assert(tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && tex->is_array);
|
|
|
|
|
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
assert(tex->dest.ssa.num_components == 3);
|
|
|
|
|
nir_ssa_def *size = &tex->dest.ssa;
|
2022-08-05 16:34:30 +01:00
|
|
|
size = nir_vec3(b, nir_channel(b, size, 1),
|
2021-07-21 16:39:15 -05:00
|
|
|
nir_channel(b, size, 1),
|
|
|
|
|
nir_idiv(b, nir_channel(b, size, 2),
|
|
|
|
|
nir_imm_int(b, 6)));
|
|
|
|
|
|
|
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, size, size->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-24 15:40:47 -05:00
|
|
|
/* Adjust the sample index according to AMD FMASK (fragment mask).
|
|
|
|
|
*
|
|
|
|
|
* For uncompressed MSAA surfaces, FMASK should return 0x76543210,
|
|
|
|
|
* which is the identity mapping. Each nibble says which physical sample
|
|
|
|
|
* should be fetched to get that sample.
|
|
|
|
|
*
|
|
|
|
|
* For example, 0x11111100 means there are only 2 samples stored and
|
|
|
|
|
* the second sample covers 3/4 of the pixel. When reading samples 0
|
|
|
|
|
* and 1, return physical sample 0 (determined by the first two 0s
|
|
|
|
|
* in FMASK), otherwise return physical sample 1.
|
|
|
|
|
*
|
|
|
|
|
* The sample index should be adjusted as follows:
|
|
|
|
|
* sample_index = ubfe(fmask, sample_index * 4, 3);
|
|
|
|
|
*
|
|
|
|
|
* Only extract 3 bits because EQAA can generate number 8 in FMASK, which
|
|
|
|
|
* means the physical sample index is unknown. We can map 8 to any valid
|
|
|
|
|
* sample index, and extracting only 3 bits will map it to 0, which works
|
|
|
|
|
* with all MSAA modes.
|
|
|
|
|
*/
|
2021-08-04 16:17:39 +01:00
|
|
|
static void
|
|
|
|
|
nir_lower_ms_txf_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
lower_offset(b, tex);
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
/* Create FMASK fetch. */
|
|
|
|
|
assert(tex->texture_index == 0);
|
|
|
|
|
nir_tex_instr *fmask_fetch = nir_tex_instr_create(b->shader, tex->num_srcs - 1);
|
|
|
|
|
fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
|
|
|
|
|
fmask_fetch->coord_components = tex->coord_components;
|
|
|
|
|
fmask_fetch->sampler_dim = tex->sampler_dim;
|
|
|
|
|
fmask_fetch->is_array = tex->is_array;
|
|
|
|
|
fmask_fetch->texture_non_uniform = tex->texture_non_uniform;
|
|
|
|
|
fmask_fetch->dest_type = nir_type_uint32;
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32);
|
2021-08-04 16:17:39 +01:00
|
|
|
|
|
|
|
|
fmask_fetch->num_srcs = 0;
|
|
|
|
|
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
|
|
|
|
if (tex->src[i].src_type == nir_tex_src_ms_index)
|
|
|
|
|
continue;
|
|
|
|
|
nir_tex_src *src = &fmask_fetch->src[fmask_fetch->num_srcs++];
|
|
|
|
|
src->src = nir_src_for_ssa(tex->src[i].src.ssa);
|
|
|
|
|
src->src_type = tex->src[i].src_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nir_builder_instr_insert(b, &fmask_fetch->instr);
|
|
|
|
|
|
|
|
|
|
/* Obtain new sample index. */
|
|
|
|
|
int ms_index = nir_tex_instr_src_index(tex, nir_tex_src_ms_index);
|
|
|
|
|
assert(ms_index >= 0);
|
|
|
|
|
nir_src sample = tex->src[ms_index].src;
|
2023-02-24 15:40:47 -05:00
|
|
|
nir_ssa_def *new_sample = nir_ubfe(b, &fmask_fetch->dest.ssa,
|
|
|
|
|
nir_ishl_imm(b, sample.ssa, 2), nir_imm_int(b, 3));
|
2021-08-04 16:17:39 +01:00
|
|
|
|
|
|
|
|
/* Update instruction. */
|
|
|
|
|
tex->op = nir_texop_fragment_fetch_amd;
|
|
|
|
|
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[ms_index].src, new_sample);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nir_lower_samples_identical_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
nir_tex_instr *fmask_fetch = nir_instr_as_tex(nir_instr_clone(b->shader, &tex->instr));
|
|
|
|
|
fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
|
|
|
|
|
fmask_fetch->dest_type = nir_type_uint32;
|
nir: Drop unused name from nir_ssa_dest_init
Since 624e799cc34 ("nir: Drop nir_ssa_def::name and nir_register::name"), SSA
defs don't have names, making the name argument unused. Drop it from the
signature and fix the call sites. This was done with the help of the following
Coccinelle semantic patch:
@@
expression A, B, C, D, E;
@@
-nir_ssa_dest_init(A, B, C, D, E);
+nir_ssa_dest_init(A, B, C, D);
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23078>
2023-05-17 09:08:22 -04:00
|
|
|
nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32);
|
2021-08-04 16:17:39 +01:00
|
|
|
nir_builder_instr_insert(b, &fmask_fetch->instr);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def_rewrite_uses(&tex->dest.ssa, nir_ieq_imm(b, &fmask_fetch->dest.ssa, 0));
|
|
|
|
|
nir_instr_remove_v(&tex->instr);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 13:45:36 +01:00
|
|
|
static void
|
|
|
|
|
nir_lower_lod_zero_width(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
|
|
|
|
assert(coord_index >= 0);
|
|
|
|
|
|
|
|
|
|
b->cursor = nir_after_instr(&tex->instr);
|
|
|
|
|
|
2023-06-05 14:54:54 +02:00
|
|
|
nir_ssa_def *is_zero = nir_imm_true(b);
|
2021-12-10 13:45:36 +01:00
|
|
|
for (unsigned i = 0; i < tex->coord_components; i++) {
|
|
|
|
|
nir_ssa_def *coord = nir_channel(b, tex->src[coord_index].src.ssa, i);
|
|
|
|
|
|
|
|
|
|
/* Compute the sum of the absolute values of derivatives. */
|
|
|
|
|
nir_ssa_def *dfdx = nir_fddx(b, coord);
|
|
|
|
|
nir_ssa_def *dfdy = nir_fddy(b, coord);
|
|
|
|
|
nir_ssa_def *fwidth = nir_fadd(b, nir_fabs(b, dfdx), nir_fabs(b, dfdy));
|
|
|
|
|
|
|
|
|
|
/* Check if the sum is 0. */
|
2023-05-08 14:00:41 +02:00
|
|
|
is_zero = nir_iand(b, is_zero, nir_feq_imm(b, fwidth, 0.0));
|
2021-12-10 13:45:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Replace the raw LOD by -FLT_MAX if the sum is 0 for all coordinates. */
|
|
|
|
|
nir_ssa_def *adjusted_lod =
|
|
|
|
|
nir_bcsel(b, is_zero, nir_imm_float(b, -FLT_MAX),
|
|
|
|
|
nir_channel(b, &tex->dest.ssa, 1));
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *def =
|
|
|
|
|
nir_vec2(b, nir_channel(b, &tex->dest.ssa, 0), adjusted_lod);
|
|
|
|
|
|
|
|
|
|
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, def, def->parent_instr);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 22:59:07 -05:00
|
|
|
static bool
|
|
|
|
|
lower_index_to_offset(nir_builder *b, nir_tex_instr *tex)
|
|
|
|
|
{
|
|
|
|
|
bool progress = false;
|
|
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
|
|
|
|
unsigned *index;
|
|
|
|
|
switch (tex->src[i].src_type) {
|
|
|
|
|
case nir_tex_src_texture_offset:
|
|
|
|
|
index = &tex->texture_index;
|
|
|
|
|
break;
|
|
|
|
|
case nir_tex_src_sampler_offset:
|
|
|
|
|
index = &tex->sampler_index;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If there's no base index, there's nothing to lower */
|
|
|
|
|
if ((*index) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
nir_ssa_def *sum = nir_iadd_imm(b, tex->src[i].src.ssa, *index);
|
|
|
|
|
nir_instr_rewrite_src(&tex->instr, &tex->src[i].src,
|
|
|
|
|
nir_src_for_ssa(sum));
|
|
|
|
|
*index = 0;
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return progress;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 14:18:11 -07:00
|
|
|
static bool
|
2016-04-08 16:30:23 -04:00
|
|
|
nir_lower_tex_block(nir_block *block, nir_builder *b,
|
2021-02-01 11:13:19 +01:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
const struct nir_shader_compiler_options *compiler_options)
|
2015-03-27 14:18:11 -07:00
|
|
|
{
|
2016-04-08 16:30:23 -04:00
|
|
|
bool progress = false;
|
2015-03-27 14:18:11 -07:00
|
|
|
|
2016-04-26 18:34:19 -07:00
|
|
|
nir_foreach_instr_safe(instr, block) {
|
2015-03-27 14:18:11 -07:00
|
|
|
if (instr->type != nir_instr_type_tex)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
2016-04-19 07:46:50 -04:00
|
|
|
bool lower_txp = !!(options->lower_txp & (1 << tex->sampler_dim));
|
2015-09-16 12:56:58 -04:00
|
|
|
|
2015-09-18 10:44:27 -04:00
|
|
|
/* mask of src coords to saturate (clamp): */
|
|
|
|
|
unsigned sat_mask = 0;
|
2023-06-20 13:48:05 -04:00
|
|
|
/* ignore saturate for txf ops: these don't use samplers and can't GL_CLAMP */
|
|
|
|
|
if (nir_tex_instr_need_sampler(tex)) {
|
|
|
|
|
if ((1 << tex->sampler_index) & options->saturate_r)
|
|
|
|
|
sat_mask |= (1 << 2); /* .z */
|
|
|
|
|
if ((1 << tex->sampler_index) & options->saturate_t)
|
|
|
|
|
sat_mask |= (1 << 1); /* .y */
|
|
|
|
|
if ((1 << tex->sampler_index) & options->saturate_s)
|
|
|
|
|
sat_mask |= (1 << 0); /* .x */
|
|
|
|
|
}
|
2015-09-18 10:44:27 -04:00
|
|
|
|
2023-02-25 22:59:07 -05:00
|
|
|
if (options->lower_index_to_offset)
|
|
|
|
|
progress |= lower_index_to_offset(b, tex);
|
|
|
|
|
|
2015-09-18 10:44:27 -04:00
|
|
|
/* If we are clamping any coords, we must lower projector first
|
|
|
|
|
* as clamping happens *after* projection:
|
|
|
|
|
*/
|
2022-03-22 10:56:43 -04:00
|
|
|
if (lower_txp || sat_mask ||
|
|
|
|
|
(options->lower_txp_array && tex->is_array)) {
|
2019-06-17 11:23:33 +02:00
|
|
|
progress |= project_src(b, tex);
|
2015-11-11 10:46:09 -08:00
|
|
|
}
|
2015-03-27 14:18:11 -07:00
|
|
|
|
2016-07-20 20:32:31 -07:00
|
|
|
if ((tex->op == nir_texop_txf && options->lower_txf_offset) ||
|
2017-11-21 13:42:08 -08:00
|
|
|
(sat_mask && nir_tex_instr_src_index(tex, nir_tex_src_coord) >= 0) ||
|
2016-07-20 20:32:31 -07:00
|
|
|
(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT &&
|
2021-12-09 12:55:21 -08:00
|
|
|
options->lower_rect_offset) ||
|
|
|
|
|
(options->lower_offset_filter &&
|
|
|
|
|
options->lower_offset_filter(instr, options->callback_data))) {
|
2016-07-20 20:32:31 -07:00
|
|
|
progress = lower_offset(b, tex) || progress;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-19 17:52:31 +02:00
|
|
|
if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) && options->lower_rect &&
|
2022-04-12 11:42:14 -04:00
|
|
|
tex->op != nir_texop_txf) {
|
|
|
|
|
if (nir_tex_instr_is_query(tex))
|
|
|
|
|
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
|
2023-07-10 22:24:46 +02:00
|
|
|
else if (compiler_options->has_texture_scaling)
|
2021-02-01 11:13:19 +01:00
|
|
|
lower_rect_tex_scale(b, tex);
|
2023-07-10 22:24:46 +02:00
|
|
|
else
|
|
|
|
|
lower_rect(b, tex);
|
2021-02-01 11:13:19 +01:00
|
|
|
|
2016-04-08 16:30:23 -04:00
|
|
|
progress = true;
|
2015-11-11 10:46:09 -08:00
|
|
|
}
|
2015-09-18 10:44:27 -04:00
|
|
|
|
2021-03-30 21:37:32 +02:00
|
|
|
unsigned texture_index = tex->texture_index;
|
2021-04-05 14:56:46 +01:00
|
|
|
uint32_t texture_mask = 1u << texture_index;
|
2021-03-30 21:37:32 +02:00
|
|
|
int tex_index = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
|
|
|
|
|
if (tex_index >= 0) {
|
|
|
|
|
nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_index].src);
|
2021-04-05 14:56:46 +01:00
|
|
|
nir_variable *var = nir_deref_instr_get_variable(deref);
|
|
|
|
|
texture_index = var ? var->data.binding : 0;
|
2021-09-16 17:24:46 +01:00
|
|
|
texture_mask = var && texture_index < 32 ? (1u << texture_index) : 0u;
|
2021-03-30 21:37:32 +02:00
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_y_uv_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_y_uv_external(b, tex, options, texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
if (texture_mask & options->lower_y_vu_external) {
|
|
|
|
|
lower_y_vu_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_y_u_v_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_y_u_v_external(b, tex, options, texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_yx_xuxv_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_yx_xuxv_external(b, tex, options, texture_index);
|
2016-05-01 21:13:37 -07:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
if (texture_mask & options->lower_yx_xvxu_external) {
|
|
|
|
|
lower_yx_xvxu_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_xy_uxvx_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_xy_uxvx_external(b, tex, options, texture_index);
|
2017-06-16 13:40:31 +08:00
|
|
|
progress = true;
|
|
|
|
|
}
|
2016-05-01 21:13:37 -07:00
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
if (texture_mask & options->lower_xy_vxux_external) {
|
|
|
|
|
lower_xy_vxux_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_ayuv_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_ayuv_external(b, tex, options, texture_index);
|
2018-11-08 16:28:20 +00:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_xyuv_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_xyuv_external(b, tex, options, texture_index);
|
2019-02-12 16:02:20 -08:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if (texture_mask & options->lower_yuv_external) {
|
2021-03-30 21:37:32 +02:00
|
|
|
lower_yuv_external(b, tex, options, texture_index);
|
2020-09-28 20:11:18 +00:00
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-12 23:07:09 -08:00
|
|
|
if ((1 << tex->texture_index) & options->lower_yu_yv_external) {
|
|
|
|
|
lower_yu_yv_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 12:39:33 +00:00
|
|
|
if ((1 << tex->texture_index) & options->lower_yv_yu_external) {
|
|
|
|
|
lower_yv_yu_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-10 19:49:05 -08:00
|
|
|
if ((1 << tex->texture_index) & options->lower_y41x_external) {
|
|
|
|
|
lower_y41x_external(b, tex, options, texture_index);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-11 10:46:09 -08:00
|
|
|
if (sat_mask) {
|
2021-02-12 17:15:06 -05:00
|
|
|
tex = saturate_src(b, tex, sat_mask);
|
2016-04-08 16:30:23 -04:00
|
|
|
progress = true;
|
2015-11-11 10:46:09 -08:00
|
|
|
}
|
2015-11-11 18:30:31 -08:00
|
|
|
|
2018-12-26 22:45:04 -08:00
|
|
|
if (tex->op == nir_texop_tg4 && options->lower_tg4_broadcom_swizzle) {
|
|
|
|
|
swizzle_tg4_broadcom(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 14:56:46 +01:00
|
|
|
if ((texture_mask & options->swizzle_result) &&
|
2015-11-11 18:30:31 -08:00
|
|
|
!nir_tex_instr_is_query(tex) &&
|
|
|
|
|
!(tex->is_shadow && tex->is_new_style_shadow)) {
|
2016-04-19 07:46:50 -04:00
|
|
|
swizzle_result(b, tex, options->swizzles[tex->texture_index]);
|
2016-04-08 16:30:23 -04:00
|
|
|
progress = true;
|
2015-11-11 18:30:31 -08:00
|
|
|
}
|
2016-04-19 08:28:22 -04:00
|
|
|
|
|
|
|
|
/* should be after swizzle so we know which channels are rgb: */
|
2021-04-05 14:56:46 +01:00
|
|
|
if ((texture_mask & options->lower_srgb) &&
|
2016-04-19 08:28:22 -04:00
|
|
|
!nir_tex_instr_is_query(tex) && !tex->is_shadow) {
|
|
|
|
|
linearize_srgb_result(b, tex);
|
2016-04-08 16:30:23 -04:00
|
|
|
progress = true;
|
2016-04-19 08:28:22 -04:00
|
|
|
}
|
2016-11-30 09:40:43 +01:00
|
|
|
|
2018-10-11 14:14:29 -05:00
|
|
|
const bool has_min_lod =
|
|
|
|
|
nir_tex_instr_src_index(tex, nir_tex_src_min_lod) >= 0;
|
|
|
|
|
const bool has_offset =
|
|
|
|
|
nir_tex_instr_src_index(tex, nir_tex_src_offset) >= 0;
|
|
|
|
|
|
|
|
|
|
if (tex->op == nir_texop_txb && tex->is_shadow && has_min_lod &&
|
|
|
|
|
options->lower_txb_shadow_clamp) {
|
|
|
|
|
lower_implicit_lod(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-19 13:53:39 -08:00
|
|
|
if (options->lower_tex_packing[tex->sampler_index] !=
|
|
|
|
|
nir_lower_tex_packing_none &&
|
|
|
|
|
tex->op != nir_texop_txs &&
|
2020-08-04 11:18:46 +02:00
|
|
|
tex->op != nir_texop_query_levels &&
|
|
|
|
|
tex->op != nir_texop_texture_samples) {
|
2018-12-19 13:53:39 -08:00
|
|
|
lower_tex_packing(b, tex, options);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 16:21:36 -08:00
|
|
|
if (tex->op == nir_texop_txd &&
|
|
|
|
|
(options->lower_txd ||
|
2018-10-11 12:56:21 -05:00
|
|
|
(options->lower_txd_shadow && tex->is_shadow) ||
|
2018-10-11 14:14:29 -05:00
|
|
|
(options->lower_txd_shadow_clamp && tex->is_shadow && has_min_lod) ||
|
|
|
|
|
(options->lower_txd_offset_clamp && has_offset && has_min_lod) ||
|
2019-02-08 17:56:52 -06:00
|
|
|
(options->lower_txd_clamp_bindless_sampler && has_min_lod &&
|
|
|
|
|
nir_tex_instr_src_index(tex, nir_tex_src_sampler_handle) != -1) ||
|
2019-02-08 17:51:24 -06:00
|
|
|
(options->lower_txd_clamp_if_sampler_index_not_lt_16 &&
|
|
|
|
|
has_min_lod && !sampler_index_lt(tex, 16)) ||
|
2018-10-11 12:56:21 -05:00
|
|
|
(options->lower_txd_cube_map &&
|
2018-12-13 11:40:58 -08:00
|
|
|
tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE) ||
|
|
|
|
|
(options->lower_txd_3d &&
|
2022-03-30 16:36:06 -07:00
|
|
|
tex->sampler_dim == GLSL_SAMPLER_DIM_3D) ||
|
|
|
|
|
(options->lower_txd_array && tex->is_array))) {
|
2017-11-21 16:21:36 -08:00
|
|
|
lower_gradient(b, tex);
|
2016-11-30 11:31:01 +01:00
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-10-09 12:24:06 +02:00
|
|
|
|
|
|
|
|
/* TXF, TXS and TXL require a LOD but not everything we implement using those
|
|
|
|
|
* three opcodes provides one. Provide a default LOD of 0.
|
|
|
|
|
*/
|
|
|
|
|
if ((nir_tex_instr_src_index(tex, nir_tex_src_lod) == -1) &&
|
|
|
|
|
(tex->op == nir_texop_txf || tex->op == nir_texop_txs ||
|
2021-07-09 11:34:23 -05:00
|
|
|
tex->op == nir_texop_txl || tex->op == nir_texop_query_levels)) {
|
2017-10-09 12:24:06 +02:00
|
|
|
b->cursor = nir_before_instr(&tex->instr);
|
|
|
|
|
nir_tex_instr_add_src(tex, nir_tex_src_lod, nir_src_for_ssa(nir_imm_int(b, 0)));
|
|
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-03-19 18:47:20 +01:00
|
|
|
|
2021-07-09 11:34:23 -05:00
|
|
|
/* Only fragment and compute (in some cases) support implicit
|
|
|
|
|
* derivatives. Lower those opcodes which use implicit derivatives to
|
|
|
|
|
* use an explicit LOD of 0.
|
2022-04-07 14:49:07 -04:00
|
|
|
* But don't touch RECT samplers because they don't have mips.
|
2021-07-09 11:34:23 -05:00
|
|
|
*/
|
2022-04-25 16:55:45 -07:00
|
|
|
if (options->lower_invalid_implicit_lod &&
|
|
|
|
|
nir_tex_instr_has_implicit_derivative(tex) &&
|
2022-04-07 14:49:07 -04:00
|
|
|
tex->sampler_dim != GLSL_SAMPLER_DIM_RECT &&
|
2021-07-29 14:59:11 -07:00
|
|
|
!nir_shader_supports_implicit_lod(b->shader)) {
|
2021-07-09 11:34:23 -05:00
|
|
|
lower_zero_lod(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 11:43:13 +02:00
|
|
|
if (options->lower_txs_lod && tex->op == nir_texop_txs) {
|
|
|
|
|
progress |= nir_lower_txs_lod(b, tex);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-21 16:39:15 -05:00
|
|
|
if (options->lower_txs_cube_array && tex->op == nir_texop_txs &&
|
|
|
|
|
tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && tex->is_array) {
|
|
|
|
|
nir_lower_txs_cube_array(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 18:47:20 +01:00
|
|
|
/* has to happen after all the other lowerings as the original tg4 gets
|
|
|
|
|
* replaced by 4 tg4 instructions.
|
|
|
|
|
*/
|
|
|
|
|
if (tex->op == nir_texop_tg4 &&
|
|
|
|
|
nir_tex_instr_has_explicit_tg4_offsets(tex) &&
|
|
|
|
|
options->lower_tg4_offsets) {
|
|
|
|
|
progress |= lower_tg4_offsets(b, tex);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-08-04 16:17:39 +01:00
|
|
|
|
|
|
|
|
if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_txf_ms) {
|
|
|
|
|
nir_lower_ms_txf_to_fragment_fetch(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_samples_identical) {
|
|
|
|
|
nir_lower_samples_identical_to_fragment_fetch(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-12-10 13:45:36 +01:00
|
|
|
|
|
|
|
|
if (options->lower_lod_zero_width && tex->op == nir_texop_lod) {
|
|
|
|
|
nir_lower_lod_zero_width(b, tex);
|
|
|
|
|
progress = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2015-03-27 14:18:11 -07:00
|
|
|
}
|
|
|
|
|
|
2016-04-08 16:30:23 -04:00
|
|
|
return progress;
|
2015-03-27 14:18:11 -07:00
|
|
|
}
|
|
|
|
|
|
2016-04-08 16:30:23 -04:00
|
|
|
static bool
|
|
|
|
|
nir_lower_tex_impl(nir_function_impl *impl,
|
2021-02-01 11:13:19 +01:00
|
|
|
const nir_lower_tex_options *options,
|
|
|
|
|
const struct nir_shader_compiler_options *compiler_options)
|
2015-03-27 14:18:11 -07:00
|
|
|
{
|
2016-04-08 16:30:23 -04:00
|
|
|
bool progress = false;
|
2023-06-26 10:42:29 -04:00
|
|
|
nir_builder builder = nir_builder_create(impl);
|
2015-03-27 14:18:11 -07:00
|
|
|
|
2016-04-08 16:30:23 -04:00
|
|
|
nir_foreach_block(block, impl) {
|
2021-02-01 11:13:19 +01:00
|
|
|
progress |= nir_lower_tex_block(block, &builder, options, compiler_options);
|
2016-04-08 16:30:23 -04:00
|
|
|
}
|
2015-03-27 14:18:11 -07:00
|
|
|
|
|
|
|
|
nir_metadata_preserve(impl, nir_metadata_block_index |
|
|
|
|
|
nir_metadata_dominance);
|
2016-04-08 16:30:23 -04:00
|
|
|
return progress;
|
2015-03-27 14:18:11 -07:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 10:46:09 -08:00
|
|
|
bool
|
2015-09-16 12:56:58 -04:00
|
|
|
nir_lower_tex(nir_shader *shader, const nir_lower_tex_options *options)
|
2015-03-27 14:18:11 -07:00
|
|
|
{
|
2016-04-08 16:30:23 -04:00
|
|
|
bool progress = false;
|
2015-11-11 10:46:09 -08:00
|
|
|
|
2023-06-15 10:19:17 +02:00
|
|
|
/* lower_tg4_offsets injects new tg4 instructions that won't be lowered
|
|
|
|
|
* if lower_tg4_broadcom_swizzle is also requested so when both are set
|
|
|
|
|
* we want to run lower_tg4_offsets in a separate pass first.
|
|
|
|
|
*/
|
|
|
|
|
if (options->lower_tg4_offsets && options->lower_tg4_broadcom_swizzle) {
|
|
|
|
|
nir_lower_tex_options _options = {
|
|
|
|
|
.lower_tg4_offsets = true,
|
|
|
|
|
};
|
|
|
|
|
progress = nir_lower_tex(shader, &_options);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-22 13:27:59 -04:00
|
|
|
nir_foreach_function_impl(impl, shader) {
|
|
|
|
|
progress |= nir_lower_tex_impl(impl, options, shader->options);
|
2015-03-27 14:18:11 -07:00
|
|
|
}
|
2015-11-11 10:46:09 -08:00
|
|
|
|
2016-04-08 16:30:23 -04:00
|
|
|
return progress;
|
2015-03-27 14:18:11 -07:00
|
|
|
}
|