2 * Copyright © 2016 Red Hat
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 /* Lowers the additional tex_src_plane src, generated by nir_lower_tex
25 * for planar YUV textures, into separate samplers, matching the logic
26 * that mesa/st uses to insert additional sampler view/state (since both
27 * sides need to agree).
29 * This should run after nir_lower_samplers.
32 #include "compiler/nir/nir.h"
36 unsigned lower_2plane
;
37 unsigned lower_3plane
;
39 /* Maps a primary sampler (used for Y) to the U or UV sampler. In
40 * case of 3-plane YUV format, the V plane is next sampler after U.
42 unsigned char sampler_map
[PIPE_MAX_SAMPLERS
][2];
43 } lower_tex_src_state
;
46 assign_extra_samplers(lower_tex_src_state
*state
, unsigned free_slots
)
48 unsigned mask
= state
->lower_2plane
| state
->lower_3plane
;
51 unsigned extra
, y_samp
= u_bit_scan(&mask
);
53 extra
= u_bit_scan(&free_slots
);
54 state
->sampler_map
[y_samp
][0] = extra
;
56 if (state
->lower_3plane
& (1 << y_samp
)) {
57 extra
= u_bit_scan(&free_slots
);
58 state
->sampler_map
[y_samp
][1] = extra
;
64 lower_tex_src_plane_block(lower_tex_src_state
*state
, nir_block
*block
)
66 nir_foreach_instr(instr
, block
) {
67 if (instr
->type
!= nir_instr_type_tex
)
70 nir_tex_instr
*tex
= nir_instr_as_tex(instr
);
71 int plane_index
= nir_tex_instr_src_index(tex
, nir_tex_src_plane
);
76 nir_const_value
*plane
= nir_src_as_const_value(tex
->src
[plane_index
].src
);
79 if (plane
->i32
[0] > 0) {
80 unsigned y_samp
= tex
->texture_index
;
82 assume(tex
->texture_index
== tex
->sampler_index
);
83 assume(((state
->lower_3plane
& (1 << y_samp
)) && plane
->i32
[0] < 3) ||
86 tex
->texture_index
= tex
->sampler_index
=
87 state
->sampler_map
[y_samp
][plane
->i32
[0] - 1];
90 nir_tex_instr_remove_src(tex
, plane_index
);
95 lower_tex_src_plane_impl(lower_tex_src_state
*state
, nir_function_impl
*impl
)
97 nir_foreach_block(block
, impl
) {
98 lower_tex_src_plane_block(state
, block
);
101 nir_metadata_preserve(impl
, nir_metadata_block_index
|
102 nir_metadata_dominance
);
106 st_nir_lower_tex_src_plane(struct nir_shader
*shader
, unsigned free_slots
,
107 unsigned lower_2plane
, unsigned lower_3plane
)
109 lower_tex_src_state state
= {0};
111 state
.lower_2plane
= lower_2plane
;
112 state
.lower_3plane
= lower_3plane
;
114 assign_extra_samplers(&state
, free_slots
);
116 nir_foreach_function(function
, shader
) {
118 lower_tex_src_plane_impl(&state
, function
->impl
);