1 /*
2 * Copyright © 2017 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "nir_format_convert.h"
25
26 #include "util/format_rgb9e5.h"
27 #include "util/format/u_format.h"
28 #include "util/macros.h"
29
30 nir_def *
nir_format_mask_uvec(nir_builder * b,nir_def * src,const unsigned * bits)31 nir_format_mask_uvec(nir_builder *b, nir_def *src, const unsigned *bits)
32 {
33 nir_const_value mask[NIR_MAX_VEC_COMPONENTS];
34 memset(mask, 0, sizeof(mask));
35 for (unsigned i = 0; i < src->num_components; i++) {
36 assert(bits[i] <= 32);
37 mask[i].u32 = BITFIELD_MASK(bits[i]);
38 }
39 return nir_iand(b, src, nir_build_imm(b, src->num_components, 32, mask));
40 }
41
42 nir_def *
nir_format_sign_extend_ivec(nir_builder * b,nir_def * src,const unsigned * bits)43 nir_format_sign_extend_ivec(nir_builder *b, nir_def *src,
44 const unsigned *bits)
45 {
46 assert(src->num_components <= 4);
47 nir_def *comps[4];
48 for (unsigned i = 0; i < src->num_components; i++) {
49 unsigned shift = src->bit_size - bits[i];
50 comps[i] = nir_ishr_imm(b, nir_ishl_imm(b, nir_channel(b, src, i), shift),
51 shift);
52 }
53 return nir_vec(b, comps, src->num_components);
54 }
55
56 nir_def *
nir_format_unpack_int(nir_builder * b,nir_def * packed,const unsigned * bits,unsigned num_components,bool sign_extend)57 nir_format_unpack_int(nir_builder *b, nir_def *packed,
58 const unsigned *bits, unsigned num_components,
59 bool sign_extend)
60 {
61 assert(num_components >= 1 && num_components <= 4);
62 const unsigned bit_size = packed->bit_size;
63 nir_def *comps[4];
64
65 if (bits[0] >= bit_size) {
66 assert(bits[0] == bit_size);
67 assert(num_components == 1);
68 return packed;
69 }
70
71 unsigned next_chan = 0;
72 unsigned offset = 0;
73 for (unsigned i = 0; i < num_components; i++) {
74 assert(bits[i] < bit_size);
75 assert(offset + bits[i] <= bit_size);
76 if (bits[i] == 0) {
77 comps[i] = nir_imm_int(b, 0);
78 continue;
79 }
80
81 nir_def *chan = nir_channel(b, packed, next_chan);
82 unsigned lshift = bit_size - (offset + bits[i]);
83 unsigned rshift = bit_size - bits[i];
84 if (sign_extend)
85 comps[i] = nir_ishr_imm(b, nir_ishl_imm(b, chan, lshift), rshift);
86 else
87 comps[i] = nir_ushr_imm(b, nir_ishl_imm(b, chan, lshift), rshift);
88 offset += bits[i];
89 if (offset >= bit_size) {
90 next_chan++;
91 offset -= bit_size;
92 }
93 }
94
95 return nir_vec(b, comps, num_components);
96 }
97
98 nir_def *
nir_format_pack_uint_unmasked(nir_builder * b,nir_def * color,const unsigned * bits,unsigned num_components)99 nir_format_pack_uint_unmasked(nir_builder *b, nir_def *color,
100 const unsigned *bits, unsigned num_components)
101 {
102 assert(num_components >= 1 && num_components <= 4);
103 nir_def *packed = nir_imm_int(b, 0);
104 unsigned offset = 0;
105
106 color = nir_u2u32(b, color);
107 for (unsigned i = 0; i < num_components; i++) {
108 if (bits[i] == 0)
109 continue;
110
111 packed = nir_ior(b, packed, nir_shift_imm(b, nir_channel(b, color, i), offset));
112 offset += bits[i];
113 }
114 assert(offset <= packed->bit_size);
115
116 return packed;
117 }
118
119 nir_def *
nir_format_pack_uint_unmasked_ssa(nir_builder * b,nir_def * color,nir_def * bits)120 nir_format_pack_uint_unmasked_ssa(nir_builder *b, nir_def *color,
121 nir_def *bits)
122 {
123 nir_def *packed = nir_imm_int(b, 0);
124 nir_def *offset = nir_imm_int(b, 0);
125
126 color = nir_u2u32(b, color);
127 for (unsigned i = 0; i < bits->num_components; i++) {
128 packed = nir_ior(b, packed, nir_ishl(b, nir_channel(b, color, i), offset));
129 offset = nir_iadd(b, offset, nir_channel(b, bits, i));
130 }
131 return packed;
132 }
133
134 nir_def *
nir_format_pack_uint(nir_builder * b,nir_def * color,const unsigned * bits,unsigned num_components)135 nir_format_pack_uint(nir_builder *b, nir_def *color,
136 const unsigned *bits, unsigned num_components)
137 {
138 return nir_format_pack_uint_unmasked(b, nir_format_mask_uvec(b, color, bits),
139 bits, num_components);
140 }
141
142 nir_def *
nir_format_bitcast_uvec_unmasked(nir_builder * b,nir_def * src,unsigned src_bits,unsigned dst_bits)143 nir_format_bitcast_uvec_unmasked(nir_builder *b, nir_def *src,
144 unsigned src_bits, unsigned dst_bits)
145 {
146 assert(src->bit_size >= src_bits && src->bit_size >= dst_bits);
147 assert(src_bits == 8 || src_bits == 16 || src_bits == 32);
148 assert(dst_bits == 8 || dst_bits == 16 || dst_bits == 32);
149
150 if (src_bits == dst_bits)
151 return src;
152
153 const unsigned dst_components =
154 DIV_ROUND_UP(src->num_components * src_bits, dst_bits);
155 assert(dst_components <= 4);
156
157 nir_def *dst_chan[4] = { 0 };
158 if (dst_bits > src_bits) {
159 unsigned shift = 0;
160 unsigned dst_idx = 0;
161 for (unsigned i = 0; i < src->num_components; i++) {
162 nir_def *shifted = nir_ishl_imm(b, nir_channel(b, src, i),
163 shift);
164 if (shift == 0) {
165 dst_chan[dst_idx] = shifted;
166 } else {
167 dst_chan[dst_idx] = nir_ior(b, dst_chan[dst_idx], shifted);
168 }
169
170 shift += src_bits;
171 if (shift >= dst_bits) {
172 dst_idx++;
173 shift = 0;
174 }
175 }
176 } else {
177 unsigned mask = ~0u >> (32 - dst_bits);
178
179 unsigned src_idx = 0;
180 unsigned shift = 0;
181 for (unsigned i = 0; i < dst_components; i++) {
182 dst_chan[i] = nir_iand_imm(b,
183 nir_ushr_imm(b,
184 nir_channel(b, src, src_idx),
185 shift),
186 mask);
187 shift += dst_bits;
188 if (shift >= src_bits) {
189 src_idx++;
190 shift = 0;
191 }
192 }
193 }
194
195 return nir_vec(b, dst_chan, dst_components);
196 }
197
198 static nir_def *
_nir_format_norm_factor(nir_builder * b,const unsigned * bits,unsigned num_components,bool is_signed)199 _nir_format_norm_factor(nir_builder *b, const unsigned *bits,
200 unsigned num_components,
201 bool is_signed)
202 {
203 nir_const_value factor[NIR_MAX_VEC_COMPONENTS];
204 memset(factor, 0, sizeof(factor));
205 for (unsigned i = 0; i < num_components; i++) {
206 /* A 16-bit float only has 23 bits of mantissa. This isn't enough to
207 * convert 24 or 32-bit UNORM/SNORM accurately. For that, we would need
208 * fp64 or some sort of fixed-point math.
209 *
210 * Unfortunately, GL is silly and includes 32-bit normalized vertex
211 * formats even though you're guaranteed to lose precision. Those formats
212 * are broken by design, but we do need to support them with the
213 * bugginess, and the loss of precision here is acceptable for GL. This
214 * helper is used for the vertex format conversion on Asahi, so we can't
215 * assert(bits[i] <= 16). But if it's not, you get to pick up the pieces.
216 */
217 factor[i].f32 = (1ull << (bits[i] - is_signed)) - 1;
218 }
219 return nir_build_imm(b, num_components, 32, factor);
220 }
221
222 nir_def *
nir_format_unorm_to_float(nir_builder * b,nir_def * u,const unsigned * bits)223 nir_format_unorm_to_float(nir_builder *b, nir_def *u, const unsigned *bits)
224 {
225 nir_def *factor =
226 _nir_format_norm_factor(b, bits, u->num_components, false);
227
228 return nir_fdiv(b, nir_u2f32(b, u), factor);
229 }
230
231 nir_def *
nir_format_snorm_to_float(nir_builder * b,nir_def * s,const unsigned * bits)232 nir_format_snorm_to_float(nir_builder *b, nir_def *s, const unsigned *bits)
233 {
234 nir_def *factor =
235 _nir_format_norm_factor(b, bits, s->num_components, true);
236
237 return nir_fmax(b, nir_fdiv(b, nir_i2f32(b, s), factor),
238 nir_imm_float(b, -1.0f));
239 }
240
241 nir_def *
nir_format_float_to_unorm(nir_builder * b,nir_def * f,const unsigned * bits)242 nir_format_float_to_unorm(nir_builder *b, nir_def *f, const unsigned *bits)
243 {
244 nir_def *factor =
245 _nir_format_norm_factor(b, bits, f->num_components, false);
246
247 /* Clamp to the range [0, 1] */
248 f = nir_fsat(b, f);
249
250 return nir_f2u32(b, nir_fround_even(b, nir_fmul(b, f, factor)));
251 }
252
253 nir_def *
nir_format_float_to_snorm(nir_builder * b,nir_def * f,const unsigned * bits)254 nir_format_float_to_snorm(nir_builder *b, nir_def *f, const unsigned *bits)
255 {
256 nir_def *factor =
257 _nir_format_norm_factor(b, bits, f->num_components, true);
258
259 /* Clamp to the range [-1, 1] */
260 f = nir_fmin(b, nir_fmax(b, f, nir_imm_float(b, -1)), nir_imm_float(b, 1));
261
262 return nir_f2i32(b, nir_fround_even(b, nir_fmul(b, f, factor)));
263 }
264
265 static nir_def *
nir_format_float_to_uscaled(nir_builder * b,nir_def * f,const unsigned * bits)266 nir_format_float_to_uscaled(nir_builder *b, nir_def *f, const unsigned *bits)
267 {
268 nir_const_value max[NIR_MAX_VEC_COMPONENTS];
269 memset(max, 0, sizeof(max));
270 for (unsigned i = 0; i < f->num_components; i++) {
271 assert(bits[i] <= 32);
272 max[i].f32 = u_uintN_max(bits[i]);
273 }
274
275 f = nir_fclamp(b, f, nir_imm_float(b, 0),
276 nir_build_imm(b, f->num_components, 32, max));
277
278 return nir_f2u32(b, nir_fround_even(b, f));
279 }
280
281 static nir_def *
nir_format_float_to_sscaled(nir_builder * b,nir_def * f,const unsigned * bits)282 nir_format_float_to_sscaled(nir_builder *b, nir_def *f, const unsigned *bits)
283 {
284 nir_const_value min[NIR_MAX_VEC_COMPONENTS], max[NIR_MAX_VEC_COMPONENTS];
285 memset(min, 0, sizeof(min));
286 memset(max, 0, sizeof(max));
287 for (unsigned i = 0; i < f->num_components; i++) {
288 assert(bits[i] <= 32);
289 max[i].f32 = u_intN_max(bits[i]);
290 min[i].f32 = u_intN_min(bits[i]);
291 }
292
293 f = nir_fclamp(b, f, nir_build_imm(b, f->num_components, 32, min),
294 nir_build_imm(b, f->num_components, 32, max));
295
296 return nir_f2i32(b, nir_fround_even(b, f));
297 }
298
299 /* Converts a vector of floats to a vector of half-floats packed in the low 16
300 * bits.
301 */
302 nir_def *
nir_format_float_to_half(nir_builder * b,nir_def * f)303 nir_format_float_to_half(nir_builder *b, nir_def *f)
304 {
305 nir_def *zero = nir_imm_float(b, 0);
306 nir_def *f16comps[4];
307 for (unsigned i = 0; i < f->num_components; i++)
308 f16comps[i] = nir_pack_half_2x16_split(b, nir_channel(b, f, i), zero);
309 return nir_vec(b, f16comps, f->num_components);
310 }
311
312 nir_def *
nir_format_linear_to_srgb(nir_builder * b,nir_def * c)313 nir_format_linear_to_srgb(nir_builder *b, nir_def *c)
314 {
315 nir_def *linear = nir_fmul_imm(b, c, 12.92f);
316 nir_def *curved =
317 nir_fadd_imm(b, nir_fmul_imm(b, nir_fpow_imm(b, c, 1.0 / 2.4), 1.055f),
318 -0.055f);
319
320 return nir_fsat(b, nir_bcsel(b, nir_flt_imm(b, c, 0.0031308f),
321 linear, curved));
322 }
323
324 nir_def *
nir_format_srgb_to_linear(nir_builder * b,nir_def * c)325 nir_format_srgb_to_linear(nir_builder *b, nir_def *c)
326 {
327 nir_def *linear = nir_fdiv_imm(b, c, 12.92f);
328 nir_def *curved =
329 nir_fpow(b, nir_fmul_imm(b, nir_fadd_imm(b, c, 0.055f), 1.0 / 1.055f),
330 nir_imm_float(b, 2.4f));
331
332 return nir_fsat(b, nir_bcsel(b, nir_fle_imm(b, c, 0.04045f),
333 linear, curved));
334 }
335
336 /* Clamps a vector of uints so they don't extend beyond the given number of
337 * bits per channel.
338 */
339 nir_def *
nir_format_clamp_uint(nir_builder * b,nir_def * f,const unsigned * bits)340 nir_format_clamp_uint(nir_builder *b, nir_def *f, const unsigned *bits)
341 {
342 if (bits[0] == 32)
343 return f;
344
345 nir_const_value max[NIR_MAX_VEC_COMPONENTS];
346 memset(max, 0, sizeof(max));
347 for (unsigned i = 0; i < f->num_components; i++) {
348 assert(bits[i] < 32 && bits[i] <= f->bit_size);
349 max[i].u32 = u_uintN_max(bits[i]);
350 }
351 return nir_umin(b, f, nir_u2uN(b, nir_build_imm(b, f->num_components, 32, max), f->bit_size));
352 }
353
354 /* Clamps a vector of sints so they don't extend beyond the given number of
355 * bits per channel.
356 */
357 nir_def *
nir_format_clamp_sint(nir_builder * b,nir_def * f,const unsigned * bits)358 nir_format_clamp_sint(nir_builder *b, nir_def *f, const unsigned *bits)
359 {
360 if (bits[0] == 32)
361 return f;
362
363 nir_const_value min[NIR_MAX_VEC_COMPONENTS], max[NIR_MAX_VEC_COMPONENTS];
364 memset(min, 0, sizeof(min));
365 memset(max, 0, sizeof(max));
366 for (unsigned i = 0; i < f->num_components; i++) {
367 assert(bits[i] < 32 && bits[i] <= f->bit_size);
368 max[i].i32 = u_intN_max(bits[i]);
369 min[i].i32 = u_intN_min(bits[i]);
370 }
371 f = nir_imin(b, f, nir_i2iN(b, nir_build_imm(b, f->num_components, 32, max), f->bit_size));
372 f = nir_imax(b, f, nir_i2iN(b, nir_build_imm(b, f->num_components, 32, min), f->bit_size));
373
374 return f;
375 }
376
377 nir_def *
nir_format_unpack_11f11f10f(nir_builder * b,nir_def * packed)378 nir_format_unpack_11f11f10f(nir_builder *b, nir_def *packed)
379 {
380 nir_def *chans[3];
381 chans[0] = nir_mask_shift(b, packed, 0x000007ff, 4);
382 chans[1] = nir_mask_shift(b, packed, 0x003ff800, -7);
383 chans[2] = nir_mask_shift(b, packed, 0xffc00000, -17);
384
385 for (unsigned i = 0; i < 3; i++)
386 chans[i] = nir_unpack_half_2x16_split_x(b, chans[i]);
387
388 return nir_vec(b, chans, 3);
389 }
390
391 nir_def *
nir_format_pack_11f11f10f(nir_builder * b,nir_def * color)392 nir_format_pack_11f11f10f(nir_builder *b, nir_def *color)
393 {
394 /* 10 and 11-bit floats are unsigned. Clamp to non-negative */
395 nir_def *clamped = nir_fmax(b, color, nir_imm_float(b, 0));
396
397 nir_def *undef = nir_undef(b, 1, color->bit_size);
398 nir_def *p1 = nir_pack_half_2x16_split(b, nir_channel(b, clamped, 0),
399 nir_channel(b, clamped, 1));
400 nir_def *p2 = nir_pack_half_2x16_split(b, nir_channel(b, clamped, 2),
401 undef);
402
403 /* A 10 or 11-bit float has the same exponent as a 16-bit float but with
404 * fewer mantissa bits and no sign bit. All we have to do is throw away
405 * the sign bit and the bottom mantissa bits and shift it into place.
406 */
407 nir_def *packed = nir_imm_int(b, 0);
408 packed = nir_mask_shift_or(b, packed, p1, 0x00007ff0, -4);
409 packed = nir_mask_shift_or(b, packed, p1, 0x7ff00000, -9);
410 packed = nir_mask_shift_or(b, packed, p2, 0x00007fe0, 17);
411
412 return packed;
413 }
414
415 nir_def *
nir_format_unpack_r9g9b9e5(nir_builder * b,nir_def * packed)416 nir_format_unpack_r9g9b9e5(nir_builder *b, nir_def *packed)
417 {
418 nir_def *rgb = nir_vec3(b, nir_ubitfield_extract_imm(b, packed, 0, 9),
419 nir_ubitfield_extract_imm(b, packed, 9, 9),
420 nir_ubitfield_extract_imm(b, packed, 18, 9));
421
422 /* exponent = (rgb >> 27) - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS;
423 * scale.u = (exponent + 127) << 23;
424 */
425 nir_def *exp = nir_ubitfield_extract_imm(b, packed, 27, 5);
426 exp = nir_iadd_imm(b, exp, 127 - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS);
427 nir_def *scale = nir_ishl_imm(b, exp, 23);
428
429 return nir_fmul(b, rgb, scale);
430 }
431
432 nir_def *
nir_format_pack_r9g9b9e5(nir_builder * b,nir_def * color)433 nir_format_pack_r9g9b9e5(nir_builder *b, nir_def *color)
434 {
435 /* See also float3_to_rgb9e5 */
436
437 /* First, we need to clamp it to range. The fmax(color, 0) will also flush
438 * NaN to 0. We set exact to ensure that nothing optimizes this behavior
439 * away from us.
440 */
441 float exact_save = b->exact;
442 b->exact = true;
443 nir_def *clamped =
444 nir_fmin(b, nir_fmax(b, color, nir_imm_float(b, 0)),
445 nir_imm_float(b, MAX_RGB9E5));
446 b->exact = exact_save;
447
448 /* maxrgb.u = MAX3(rc.u, gc.u, bc.u); */
449 nir_def *maxu = nir_umax(b, nir_channel(b, clamped, 0),
450 nir_umax(b, nir_channel(b, clamped, 1),
451 nir_channel(b, clamped, 2)));
452
453 /* maxrgb.u += maxrgb.u & (1 << (23-9)); */
454 maxu = nir_iadd(b, maxu, nir_iand_imm(b, maxu, 1 << 14));
455
456 /* exp_shared = MAX2((maxrgb.u >> 23), -RGB9E5_EXP_BIAS - 1 + 127) +
457 * 1 + RGB9E5_EXP_BIAS - 127;
458 */
459 nir_def *exp_shared =
460 nir_iadd_imm(b, nir_umax(b, nir_ushr_imm(b, maxu, 23), nir_imm_int(b, -RGB9E5_EXP_BIAS - 1 + 127)),
461 1 + RGB9E5_EXP_BIAS - 127);
462
463 /* revdenom_biasedexp = 127 - (exp_shared - RGB9E5_EXP_BIAS -
464 * RGB9E5_MANTISSA_BITS) + 1;
465 */
466 nir_def *revdenom_biasedexp =
467 nir_isub_imm(b, 127 + RGB9E5_EXP_BIAS + RGB9E5_MANTISSA_BITS + 1,
468 exp_shared);
469
470 /* revdenom.u = revdenom_biasedexp << 23; */
471 nir_def *revdenom =
472 nir_ishl_imm(b, revdenom_biasedexp, 23);
473
474 /* rm = (int) (rc.f * revdenom.f);
475 * gm = (int) (gc.f * revdenom.f);
476 * bm = (int) (bc.f * revdenom.f);
477 */
478 nir_def *mantissa =
479 nir_f2i32(b, nir_fmul(b, clamped, revdenom));
480
481 /* rm = (rm & 1) + (rm >> 1);
482 * gm = (gm & 1) + (gm >> 1);
483 * bm = (bm & 1) + (bm >> 1);
484 */
485 mantissa = nir_iadd(b, nir_iand_imm(b, mantissa, 1),
486 nir_ushr_imm(b, mantissa, 1));
487
488 nir_def *packed = nir_channel(b, mantissa, 0);
489 packed = nir_mask_shift_or(b, packed, nir_channel(b, mantissa, 1), ~0, 9);
490 packed = nir_mask_shift_or(b, packed, nir_channel(b, mantissa, 2), ~0, 18);
491 packed = nir_mask_shift_or(b, packed, exp_shared, ~0, 27);
492
493 return packed;
494 }
495
496 nir_def *
nir_format_unpack_rgba(nir_builder * b,nir_def * packed,enum pipe_format format)497 nir_format_unpack_rgba(nir_builder *b, nir_def *packed,
498 enum pipe_format format)
499 {
500 switch (format) {
501 case PIPE_FORMAT_R9G9B9E5_FLOAT: {
502 nir_def *rgb = nir_format_unpack_r9g9b9e5(b, packed);
503 return nir_vec4(b, nir_channel(b, rgb, 0),
504 nir_channel(b, rgb, 1),
505 nir_channel(b, rgb, 2),
506 nir_imm_float(b, 1.0));
507 }
508
509 case PIPE_FORMAT_R11G11B10_FLOAT: {
510 nir_def *rgb = nir_format_unpack_11f11f10f(b, packed);
511 return nir_vec4(b, nir_channel(b, rgb, 0),
512 nir_channel(b, rgb, 1),
513 nir_channel(b, rgb, 2),
514 nir_imm_float(b, 1.0));
515 }
516
517 default:
518 /* Handled below */
519 break;
520 }
521
522 const struct util_format_description *desc = util_format_description(format);
523 assert(desc->layout == UTIL_FORMAT_LAYOUT_PLAIN);
524
525 nir_def *unpacked;
526 if (desc->block.bits <= 32) {
527 unsigned bits[4] = { 0, };
528 for (uint32_t c = 0; c < desc->nr_channels; c++) {
529 if (c != 0) {
530 assert(desc->channel[c].shift ==
531 desc->channel[c - 1].shift + desc->channel[c - 1].size);
532 }
533 bits[c] = desc->channel[c].size;
534 }
535 unpacked = nir_format_unpack_uint(b, packed, bits, desc->nr_channels);
536 } else {
537 unsigned bits = desc->channel[0].size;
538 for (uint32_t c = 1; c < desc->nr_channels; c++)
539 assert(desc->channel[c].size == bits);
540 unpacked = nir_format_bitcast_uvec_unmasked(b, packed, 32, bits);
541
542 /* 3-channel formats can unpack extra components */
543 unpacked = nir_trim_vector(b, unpacked, desc->nr_channels);
544 }
545
546 nir_def *comps[4] = { NULL, };
547 for (uint32_t c = 0; c < desc->nr_channels; c++) {
548 const struct util_format_channel_description *chan = &desc->channel[c];
549
550 nir_def *raw = nir_channel(b, unpacked, c);
551
552 /* Most of the helpers work on an array of bits */
553 unsigned bits[1] = { chan->size };
554
555 switch (chan->type) {
556 case UTIL_FORMAT_TYPE_VOID:
557 comps[c] = nir_imm_int(b, 0);
558 break;
559
560 case UTIL_FORMAT_TYPE_UNSIGNED:
561 if (chan->normalized) {
562 comps[c] = nir_format_unorm_to_float(b, raw, bits);
563 } else if (chan->pure_integer) {
564 comps[c] = nir_u2u32(b, raw);
565 } else {
566 comps[c] = nir_u2f32(b, raw);
567 }
568 break;
569
570 case UTIL_FORMAT_TYPE_SIGNED:
571 raw = nir_format_sign_extend_ivec(b, raw, bits);
572 if (chan->normalized) {
573 comps[c] = nir_format_snorm_to_float(b, raw, bits);
574 } else if (chan->pure_integer) {
575 comps[c] = nir_i2i32(b, raw);
576 } else {
577 comps[c] = nir_i2f32(b, raw);
578 }
579 break;
580
581 case UTIL_FORMAT_TYPE_FIXED:
582 unreachable("Fixed formats not supported");
583
584 case UTIL_FORMAT_TYPE_FLOAT:
585 switch (chan->size) {
586 case 16:
587 comps[c] = nir_unpack_half_2x16_split_x(b, raw);
588 break;
589
590 case 32:
591 comps[c] = raw;
592 break;
593
594 default:
595 unreachable("Unknown number of float bits");
596 }
597 break;
598
599 default:
600 unreachable("Unknown format channel type");
601 }
602 }
603
604 nir_def *swiz_comps[4] = { NULL, };
605 for (uint32_t i = 0; i < 4; i++) {
606 enum pipe_swizzle s = desc->swizzle[i];
607 switch (s) {
608 case PIPE_SWIZZLE_X:
609 case PIPE_SWIZZLE_Y:
610 case PIPE_SWIZZLE_Z:
611 case PIPE_SWIZZLE_W:
612 swiz_comps[i] = comps[s - PIPE_SWIZZLE_X];
613 break;
614
615 case PIPE_SWIZZLE_0:
616 case PIPE_SWIZZLE_NONE:
617 swiz_comps[i] = nir_imm_int(b, 0);
618 break;
619
620 case PIPE_SWIZZLE_1:
621 if (util_format_is_pure_integer(format))
622 swiz_comps[i] = nir_imm_int(b, 1);
623 else
624 swiz_comps[i] = nir_imm_float(b, 1.0);
625 break;
626
627 default:
628 unreachable("Unknown swizzle");
629 }
630 }
631 nir_def *rgba = nir_vec(b, swiz_comps, 4);
632
633 assert(desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
634 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
635 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
636 nir_def *linear = nir_format_srgb_to_linear(b, rgba);
637 if (rgba->num_components == 4)
638 linear = nir_vector_insert_imm(b, linear, nir_channel(b, rgba, 3), 3);
639 rgba = linear;
640 }
641
642 return rgba;
643 }
644
645 nir_def *
nir_format_pack_rgba(nir_builder * b,enum pipe_format format,nir_def * rgba)646 nir_format_pack_rgba(nir_builder *b, enum pipe_format format, nir_def *rgba)
647 {
648 assert(rgba->num_components <= 4);
649
650 switch (format) {
651 case PIPE_FORMAT_R9G9B9E5_FLOAT:
652 return nir_format_pack_r9g9b9e5(b, rgba);
653
654 case PIPE_FORMAT_R11G11B10_FLOAT:
655 return nir_format_pack_11f11f10f(b, rgba);
656
657 default:
658 /* Handled below */
659 break;
660 }
661
662 const struct util_format_description *desc = util_format_description(format);
663 assert(desc->layout == UTIL_FORMAT_LAYOUT_PLAIN);
664
665 assert(desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
666 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
667 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
668 nir_def *srgb = nir_format_linear_to_srgb(b, rgba);
669 if (rgba->num_components == 4)
670 srgb = nir_vector_insert_imm(b, srgb, nir_channel(b, rgba, 3), 3);
671 rgba = srgb;
672 }
673
674 nir_def *comps[4] = { NULL, };
675 for (uint32_t i = 0; i < 4; i++) {
676 enum pipe_swizzle s = desc->swizzle[i];
677 if (s < PIPE_SWIZZLE_X || s > PIPE_SWIZZLE_W)
678 continue;
679
680 /* This is backwards from what you might think because we're packing and
681 * the swizzles are in terms of unpacking.
682 */
683 comps[s - PIPE_SWIZZLE_X] = nir_channel(b, rgba, i);
684 }
685
686 for (uint32_t c = 0; c < desc->nr_channels; c++) {
687 const struct util_format_channel_description *chan = &desc->channel[c];
688 if (comps[c] == NULL) {
689 comps[c] = nir_imm_int(b, 0);
690 continue;
691 }
692
693 /* Most of the helpers work on an array of bits */
694 assert(comps[c]->num_components == 1);
695 unsigned bits[1] = { chan->size };
696
697 switch (chan->type) {
698 case UTIL_FORMAT_TYPE_VOID:
699 comps[c] = nir_imm_int(b, 0);
700 break;
701
702 case UTIL_FORMAT_TYPE_UNSIGNED:
703 if (chan->normalized) {
704 comps[c] = nir_format_float_to_unorm(b, comps[c], bits);
705 } else if (chan->pure_integer) {
706 comps[c] = nir_format_clamp_uint(b, comps[c], bits);
707 } else {
708 comps[c] = nir_format_float_to_uscaled(b, comps[c], bits);
709 }
710 break;
711
712 case UTIL_FORMAT_TYPE_SIGNED:
713 if (chan->normalized) {
714 comps[c] = nir_format_float_to_snorm(b, comps[c], bits);
715 } else if (chan->pure_integer) {
716 comps[c] = nir_format_clamp_sint(b, comps[c], bits);
717 } else {
718 comps[c] = nir_format_float_to_sscaled(b, comps[c], bits);
719 }
720 /* We don't want sign bits ending up in other channels */
721 comps[c] = nir_format_mask_uvec(b, comps[c], bits);
722 break;
723
724 case UTIL_FORMAT_TYPE_FIXED:
725 unreachable("Fixed formats not supported");
726
727 case UTIL_FORMAT_TYPE_FLOAT:
728 switch (chan->size) {
729 case 16:
730 comps[c] = nir_format_float_to_half(b, comps[c]);
731 break;
732
733 case 32:
734 /* Nothing to do */
735 break;
736
737 default:
738 unreachable("Unknown number of float bits");
739 }
740 break;
741
742 default:
743 unreachable("Unknown format channel type");
744 }
745 }
746 nir_def *encoded = nir_vec(b, comps, desc->nr_channels);
747
748 if (desc->block.bits <= 32) {
749 unsigned bits[4] = { 0, };
750 for (uint32_t c = 0; c < desc->nr_channels; c++) {
751 if (c != 0) {
752 assert(desc->channel[c].shift ==
753 desc->channel[c - 1].shift + desc->channel[c - 1].size);
754 }
755 bits[c] = desc->channel[c].size;
756 }
757 return nir_format_pack_uint_unmasked(b, encoded, bits, desc->nr_channels);
758 } else {
759 unsigned bits = desc->channel[0].size;
760 for (uint32_t c = 1; c < desc->nr_channels; c++)
761 assert(desc->channel[c].size == bits);
762 return nir_format_bitcast_uvec_unmasked(b, encoded, bits, 32);
763 }
764 }
765