Blender V5.0
vk_data_conversion.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "BLI_color.hh"
12#include "BLI_math_half.hh"
13
14namespace blender::gpu {
15
16/* -------------------------------------------------------------------- */
19
78
80 const TextureFormat device_format)
81{
82 if (host_format != device_format) {
83 if (host_format == TextureFormat::SFLOAT_16_16_16 &&
84 device_format == TextureFormat::SFLOAT_16_16_16_16)
85 {
87 }
88 if (host_format == TextureFormat::SFLOAT_32_32_32 &&
89 device_format == TextureFormat::SFLOAT_32_32_32_32)
90 {
92 }
93
95 }
96
97 switch (device_format) {
98 case TextureFormat::SFLOAT_32_32_32_32:
99 case TextureFormat::SFLOAT_32_32:
100 case TextureFormat::SFLOAT_32:
101 case TextureFormat::SFLOAT_32_DEPTH:
103
104 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
106
107 case TextureFormat::SFLOAT_16_16_16_16:
108 case TextureFormat::SFLOAT_16_16:
109 case TextureFormat::SFLOAT_16:
110 case TextureFormat::SFLOAT_16_16_16:
112
113 case TextureFormat::SRGBA_8_8_8_8:
114 case TextureFormat::UNORM_8_8_8_8:
115 case TextureFormat::UNORM_8_8:
116 case TextureFormat::UNORM_8:
118
119 case TextureFormat::SNORM_8_8_8_8:
120 case TextureFormat::SNORM_8_8_8:
121 case TextureFormat::SNORM_8_8:
122 case TextureFormat::SNORM_8:
124
125 case TextureFormat::UNORM_16_16_16_16:
126 case TextureFormat::UNORM_16_16:
127 case TextureFormat::UNORM_16:
129
130 case TextureFormat::SNORM_16_16_16_16:
131 case TextureFormat::SNORM_16_16_16:
132 case TextureFormat::SNORM_16_16:
133 case TextureFormat::SNORM_16:
135
136 case TextureFormat::UFLOAT_11_11_10:
138
139 case TextureFormat::SRGB_DXT1:
140 case TextureFormat::SRGB_DXT3:
141 case TextureFormat::SRGB_DXT5:
142 case TextureFormat::SNORM_DXT1:
143 case TextureFormat::SNORM_DXT3:
144 case TextureFormat::SNORM_DXT5:
145 /* Not an actual "conversion", but compressed texture upload code
146 * pretends that host data is a float. It is actually raw BCn bits. */
148
149 /* #TextureFormat::SFLOAT_32_32_32 Not supported by vendors. */
150 case TextureFormat::SFLOAT_32_32_32:
151
152 case TextureFormat::UINT_8_8_8_8:
153 case TextureFormat::SINT_8_8_8_8:
154 case TextureFormat::UINT_16_16_16_16:
155 case TextureFormat::SINT_16_16_16_16:
156 case TextureFormat::UINT_32_32_32_32:
157 case TextureFormat::SINT_32_32_32_32:
158 case TextureFormat::UINT_8_8:
159 case TextureFormat::SINT_8_8:
160 case TextureFormat::UINT_16_16:
161 case TextureFormat::SINT_16_16:
162 case TextureFormat::UINT_32_32:
163 case TextureFormat::SINT_32_32:
164 case TextureFormat::UINT_8:
165 case TextureFormat::SINT_8:
166 case TextureFormat::UINT_16:
167 case TextureFormat::SINT_16:
168 case TextureFormat::UINT_32:
169 case TextureFormat::SINT_32:
170 case TextureFormat::UNORM_10_10_10_2:
171 case TextureFormat::UINT_10_10_10_2:
172 case TextureFormat::UINT_8_8_8:
173 case TextureFormat::SINT_8_8_8:
174 case TextureFormat::UNORM_8_8_8:
175 case TextureFormat::UINT_16_16_16:
176 case TextureFormat::SINT_16_16_16:
177 case TextureFormat::UNORM_16_16_16:
178 case TextureFormat::UINT_32_32_32:
179 case TextureFormat::SINT_32_32_32:
180 case TextureFormat::SRGBA_8_8_8:
181 case TextureFormat::UFLOAT_9_9_9_EXP_5:
182 case TextureFormat::UNORM_16_DEPTH:
184
187 break;
188 }
190}
191
193{
194 switch (device_format) {
195 case TextureFormat::SINT_32_32_32_32:
196 case TextureFormat::SINT_32_32:
197 case TextureFormat::SINT_32:
199
200 case TextureFormat::SINT_16_16_16_16:
201 case TextureFormat::SINT_16_16:
202 case TextureFormat::SINT_16:
204
205 case TextureFormat::SINT_8_8_8_8:
206 case TextureFormat::SINT_8_8:
207 case TextureFormat::SINT_8:
209
210 case TextureFormat::UINT_8_8_8_8:
211 case TextureFormat::UNORM_8_8_8_8:
212 case TextureFormat::UINT_16_16_16_16:
213 case TextureFormat::SFLOAT_16_16_16_16:
214 case TextureFormat::UNORM_16_16_16_16:
215 case TextureFormat::UINT_32_32_32_32:
216 case TextureFormat::SFLOAT_32_32_32_32:
217 case TextureFormat::UINT_8_8:
218 case TextureFormat::UNORM_8_8:
219 case TextureFormat::UINT_16_16:
220 case TextureFormat::SFLOAT_16_16:
221 case TextureFormat::UINT_32_32:
222 case TextureFormat::SFLOAT_32_32:
223 case TextureFormat::UNORM_16_16:
224 case TextureFormat::UINT_8:
225 case TextureFormat::UNORM_8:
226 case TextureFormat::UINT_16:
227 case TextureFormat::SFLOAT_16:
228 case TextureFormat::UNORM_16:
229 case TextureFormat::UINT_32:
230 case TextureFormat::SFLOAT_32:
231 case TextureFormat::UNORM_10_10_10_2:
232 case TextureFormat::UINT_10_10_10_2:
233 case TextureFormat::UFLOAT_11_11_10:
234 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
235 case TextureFormat::SRGBA_8_8_8_8:
236 case TextureFormat::SNORM_8_8_8_8:
237 case TextureFormat::SNORM_16_16_16_16:
238 case TextureFormat::UINT_8_8_8:
239 case TextureFormat::SINT_8_8_8:
240 case TextureFormat::UNORM_8_8_8:
241 case TextureFormat::SNORM_8_8_8:
242 case TextureFormat::UINT_16_16_16:
243 case TextureFormat::SINT_16_16_16:
244 case TextureFormat::SFLOAT_16_16_16:
245 case TextureFormat::UNORM_16_16_16:
246 case TextureFormat::SNORM_16_16_16:
247 case TextureFormat::UINT_32_32_32:
248 case TextureFormat::SINT_32_32_32:
249 case TextureFormat::SFLOAT_32_32_32:
250 case TextureFormat::SNORM_8_8:
251 case TextureFormat::SNORM_16_16:
252 case TextureFormat::SNORM_8:
253 case TextureFormat::SNORM_16:
254 case TextureFormat::SRGB_DXT1:
255 case TextureFormat::SRGB_DXT3:
256 case TextureFormat::SRGB_DXT5:
257 case TextureFormat::SNORM_DXT1:
258 case TextureFormat::SNORM_DXT3:
259 case TextureFormat::SNORM_DXT5:
260 case TextureFormat::SRGBA_8_8_8:
261 case TextureFormat::UFLOAT_9_9_9_EXP_5:
262 case TextureFormat::SFLOAT_32_DEPTH:
263 case TextureFormat::UNORM_16_DEPTH:
265
268 break;
269 }
271}
272
274{
275 switch (device_format) {
276 case TextureFormat::UINT_32_32_32_32:
277 case TextureFormat::UINT_32_32:
278 case TextureFormat::UINT_32:
280
281 case TextureFormat::UINT_16_16_16_16:
282 case TextureFormat::UINT_16_16:
283 case TextureFormat::UINT_16:
284 case TextureFormat::UINT_16_16_16:
286
287 case TextureFormat::UINT_8_8_8_8:
288 case TextureFormat::UINT_8_8:
289 case TextureFormat::UINT_8:
291
292 case TextureFormat::SFLOAT_32_DEPTH:
293 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
295
296 case TextureFormat::SINT_8_8_8_8:
297 case TextureFormat::UNORM_8_8_8_8:
298 case TextureFormat::SINT_16_16_16_16:
299 case TextureFormat::SFLOAT_16_16_16_16:
300 case TextureFormat::UNORM_16_16_16_16:
301 case TextureFormat::SINT_32_32_32_32:
302 case TextureFormat::SFLOAT_32_32_32_32:
303 case TextureFormat::SINT_8_8:
304 case TextureFormat::UNORM_8_8:
305 case TextureFormat::SINT_16_16:
306 case TextureFormat::SFLOAT_16_16:
307 case TextureFormat::UNORM_16_16:
308 case TextureFormat::SINT_32_32:
309 case TextureFormat::SFLOAT_32_32:
310 case TextureFormat::SINT_8:
311 case TextureFormat::UNORM_8:
312 case TextureFormat::SINT_16:
313 case TextureFormat::SFLOAT_16:
314 case TextureFormat::UNORM_16:
315 case TextureFormat::SINT_32:
316 case TextureFormat::SFLOAT_32:
317 case TextureFormat::UNORM_10_10_10_2:
318 case TextureFormat::UINT_10_10_10_2:
319 case TextureFormat::UFLOAT_11_11_10:
320 case TextureFormat::SRGBA_8_8_8_8:
321 case TextureFormat::SNORM_8_8_8_8:
322 case TextureFormat::SNORM_16_16_16_16:
323 case TextureFormat::UINT_8_8_8:
324 case TextureFormat::SINT_8_8_8:
325 case TextureFormat::UNORM_8_8_8:
326 case TextureFormat::SNORM_8_8_8:
327 case TextureFormat::SINT_16_16_16:
328 case TextureFormat::SFLOAT_16_16_16:
329 case TextureFormat::UNORM_16_16_16:
330 case TextureFormat::SNORM_16_16_16:
331 case TextureFormat::UINT_32_32_32:
332 case TextureFormat::SINT_32_32_32:
333 case TextureFormat::SFLOAT_32_32_32:
334 case TextureFormat::SNORM_8_8:
335 case TextureFormat::SNORM_16_16:
336 case TextureFormat::SNORM_8:
337 case TextureFormat::SNORM_16:
338 case TextureFormat::SRGB_DXT1:
339 case TextureFormat::SRGB_DXT3:
340 case TextureFormat::SRGB_DXT5:
341 case TextureFormat::SNORM_DXT1:
342 case TextureFormat::SNORM_DXT3:
343 case TextureFormat::SNORM_DXT5:
344 case TextureFormat::SRGBA_8_8_8:
345 case TextureFormat::UFLOAT_9_9_9_EXP_5:
346 case TextureFormat::UNORM_16_DEPTH:
348
351 break;
352 }
354}
355
357{
358 switch (device_format) {
359 case TextureFormat::SFLOAT_16_16_16_16:
360 case TextureFormat::SFLOAT_16_16:
361 case TextureFormat::SFLOAT_16:
363
364 case TextureFormat::UINT_8_8_8_8:
365 case TextureFormat::SINT_8_8_8_8:
366 case TextureFormat::UNORM_8_8_8_8:
367 case TextureFormat::UINT_16_16_16_16:
368 case TextureFormat::SINT_16_16_16_16:
369 case TextureFormat::UNORM_16_16_16_16:
370 case TextureFormat::UINT_32_32_32_32:
371 case TextureFormat::SINT_32_32_32_32:
372 case TextureFormat::SFLOAT_32_32_32_32:
373 case TextureFormat::UINT_8_8:
374 case TextureFormat::SINT_8_8:
375 case TextureFormat::UNORM_8_8:
376 case TextureFormat::UINT_16_16:
377 case TextureFormat::SINT_16_16:
378 case TextureFormat::UNORM_16_16:
379 case TextureFormat::UINT_32_32:
380 case TextureFormat::SINT_32_32:
381 case TextureFormat::SFLOAT_32_32:
382 case TextureFormat::UINT_8:
383 case TextureFormat::SINT_8:
384 case TextureFormat::UNORM_8:
385 case TextureFormat::UINT_16:
386 case TextureFormat::SINT_16:
387 case TextureFormat::UNORM_16:
388 case TextureFormat::UINT_32:
389 case TextureFormat::SINT_32:
390 case TextureFormat::SFLOAT_32:
391 case TextureFormat::UNORM_10_10_10_2:
392 case TextureFormat::UINT_10_10_10_2:
393 case TextureFormat::UFLOAT_11_11_10:
394 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
395 case TextureFormat::SRGBA_8_8_8_8:
396 case TextureFormat::SNORM_8_8_8_8:
397 case TextureFormat::SNORM_16_16_16_16:
398 case TextureFormat::UINT_8_8_8:
399 case TextureFormat::SINT_8_8_8:
400 case TextureFormat::UNORM_8_8_8:
401 case TextureFormat::SNORM_8_8_8:
402 case TextureFormat::UINT_16_16_16:
403 case TextureFormat::SINT_16_16_16:
404 case TextureFormat::SFLOAT_16_16_16:
405 case TextureFormat::UNORM_16_16_16:
406 case TextureFormat::SNORM_16_16_16:
407 case TextureFormat::UINT_32_32_32:
408 case TextureFormat::SINT_32_32_32:
409 case TextureFormat::SFLOAT_32_32_32:
410 case TextureFormat::SNORM_8_8:
411 case TextureFormat::SNORM_16_16:
412 case TextureFormat::SNORM_8:
413 case TextureFormat::SNORM_16:
414 case TextureFormat::SRGB_DXT1:
415 case TextureFormat::SRGB_DXT3:
416 case TextureFormat::SRGB_DXT5:
417 case TextureFormat::SNORM_DXT1:
418 case TextureFormat::SNORM_DXT3:
419 case TextureFormat::SNORM_DXT5:
420 case TextureFormat::SRGBA_8_8_8:
421 case TextureFormat::UFLOAT_9_9_9_EXP_5:
422 case TextureFormat::SFLOAT_32_DEPTH:
423 case TextureFormat::UNORM_16_DEPTH:
425
428 break;
429 }
431}
432
434{
435 switch (device_format) {
436 case TextureFormat::UINT_8_8_8_8:
437 case TextureFormat::UNORM_8_8_8_8:
438 case TextureFormat::UINT_8_8:
439 case TextureFormat::UNORM_8_8:
440 case TextureFormat::UINT_8:
441 case TextureFormat::UNORM_8:
442 case TextureFormat::SRGBA_8_8_8_8:
444
445 case TextureFormat::SFLOAT_16_16_16_16:
446 case TextureFormat::SFLOAT_16_16:
447 case TextureFormat::SFLOAT_16:
449
450 case TextureFormat::SINT_8_8_8_8:
451 case TextureFormat::UINT_16_16_16_16:
452 case TextureFormat::SINT_16_16_16_16:
453 case TextureFormat::UNORM_16_16_16_16:
454 case TextureFormat::UINT_32_32_32_32:
455 case TextureFormat::SINT_32_32_32_32:
456 case TextureFormat::SFLOAT_32_32_32_32:
457 case TextureFormat::SINT_8_8:
458 case TextureFormat::UINT_16_16:
459 case TextureFormat::SINT_16_16:
460 case TextureFormat::UNORM_16_16:
461 case TextureFormat::UINT_32_32:
462 case TextureFormat::SINT_32_32:
463 case TextureFormat::SFLOAT_32_32:
464 case TextureFormat::SINT_8:
465 case TextureFormat::UINT_16:
466 case TextureFormat::SINT_16:
467 case TextureFormat::UNORM_16:
468 case TextureFormat::UINT_32:
469 case TextureFormat::SINT_32:
470 case TextureFormat::SFLOAT_32:
471 case TextureFormat::UNORM_10_10_10_2:
472 case TextureFormat::UINT_10_10_10_2:
473 case TextureFormat::UFLOAT_11_11_10:
474 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
475 case TextureFormat::SNORM_8_8_8_8:
476 case TextureFormat::SNORM_16_16_16_16:
477 case TextureFormat::UINT_8_8_8:
478 case TextureFormat::SINT_8_8_8:
479 case TextureFormat::UNORM_8_8_8:
480 case TextureFormat::SNORM_8_8_8:
481 case TextureFormat::UINT_16_16_16:
482 case TextureFormat::SINT_16_16_16:
483 case TextureFormat::SFLOAT_16_16_16:
484 case TextureFormat::UNORM_16_16_16:
485 case TextureFormat::SNORM_16_16_16:
486 case TextureFormat::UINT_32_32_32:
487 case TextureFormat::SINT_32_32_32:
488 case TextureFormat::SFLOAT_32_32_32:
489 case TextureFormat::SNORM_8_8:
490 case TextureFormat::SNORM_16_16:
491 case TextureFormat::SNORM_8:
492 case TextureFormat::SNORM_16:
493 case TextureFormat::SRGB_DXT1:
494 case TextureFormat::SRGB_DXT3:
495 case TextureFormat::SRGB_DXT5:
496 case TextureFormat::SNORM_DXT1:
497 case TextureFormat::SNORM_DXT3:
498 case TextureFormat::SNORM_DXT5:
499 case TextureFormat::SRGBA_8_8_8:
500 case TextureFormat::UFLOAT_9_9_9_EXP_5:
501 case TextureFormat::SFLOAT_32_DEPTH:
502 case TextureFormat::UNORM_16_DEPTH:
504
507 break;
508 }
510}
511
513{
514 switch (device_format) {
515 case TextureFormat::SFLOAT_32_DEPTH_UINT_8:
517
518 case TextureFormat::SFLOAT_32_32_32_32:
519 case TextureFormat::SFLOAT_32_32:
520 case TextureFormat::SFLOAT_32:
521 case TextureFormat::SFLOAT_16_16_16_16:
522 case TextureFormat::SFLOAT_16_16:
523 case TextureFormat::SFLOAT_16:
524 case TextureFormat::SFLOAT_16_16_16:
525 case TextureFormat::UNORM_8_8_8_8:
526 case TextureFormat::UNORM_8_8:
527 case TextureFormat::UNORM_8:
528 case TextureFormat::SNORM_8_8_8_8:
529 case TextureFormat::SNORM_8_8_8:
530 case TextureFormat::SNORM_8_8:
531 case TextureFormat::SNORM_8:
532 case TextureFormat::UNORM_16_16_16_16:
533 case TextureFormat::UNORM_16_16:
534 case TextureFormat::UNORM_16:
535 case TextureFormat::SNORM_16_16_16_16:
536 case TextureFormat::SNORM_16_16_16:
537 case TextureFormat::SNORM_16_16:
538 case TextureFormat::SNORM_16:
539 case TextureFormat::SRGBA_8_8_8_8:
540 case TextureFormat::SFLOAT_32_DEPTH:
541 case TextureFormat::UFLOAT_11_11_10:
542 case TextureFormat::SRGB_DXT1:
543 case TextureFormat::SRGB_DXT3:
544 case TextureFormat::SRGB_DXT5:
545 case TextureFormat::SNORM_DXT1:
546 case TextureFormat::SNORM_DXT3:
547 case TextureFormat::SNORM_DXT5:
548
549 /* #TextureFormat::SFLOAT_32_32_32 Not supported by vendors. */
550 case TextureFormat::SFLOAT_32_32_32:
551
552 case TextureFormat::UINT_8_8_8_8:
553 case TextureFormat::SINT_8_8_8_8:
554 case TextureFormat::UINT_16_16_16_16:
555 case TextureFormat::SINT_16_16_16_16:
556 case TextureFormat::UINT_32_32_32_32:
557 case TextureFormat::SINT_32_32_32_32:
558 case TextureFormat::UINT_8_8:
559 case TextureFormat::SINT_8_8:
560 case TextureFormat::UINT_16_16:
561 case TextureFormat::SINT_16_16:
562 case TextureFormat::UINT_32_32:
563 case TextureFormat::SINT_32_32:
564 case TextureFormat::UINT_8:
565 case TextureFormat::SINT_8:
566 case TextureFormat::UINT_16:
567 case TextureFormat::SINT_16:
568 case TextureFormat::UINT_32:
569 case TextureFormat::SINT_32:
570 case TextureFormat::UNORM_10_10_10_2:
571 case TextureFormat::UINT_10_10_10_2:
572 case TextureFormat::UINT_8_8_8:
573 case TextureFormat::SINT_8_8_8:
574 case TextureFormat::UNORM_8_8_8:
575 case TextureFormat::UINT_16_16_16:
576 case TextureFormat::SINT_16_16_16:
577 case TextureFormat::UNORM_16_16_16:
578 case TextureFormat::UINT_32_32_32:
579 case TextureFormat::SINT_32_32_32:
580 case TextureFormat::SRGBA_8_8_8:
581 case TextureFormat::UFLOAT_9_9_9_EXP_5:
582 case TextureFormat::UNORM_16_DEPTH:
584
587 break;
588 }
590}
591
593{
594 if (device_format == TextureFormat::UFLOAT_11_11_10) {
596 }
598}
599
601{
602 if (ELEM(device_format, TextureFormat::UNORM_10_10_10_2, TextureFormat::UINT_10_10_10_2)) {
604 }
606}
607
609 const TextureFormat host_texture_format,
610 const TextureFormat device_format)
611{
612 switch (host_format) {
613 case GPU_DATA_FLOAT:
614 return type_of_conversion_float(host_texture_format, device_format);
615 case GPU_DATA_UINT:
616 return type_of_conversion_uint(device_format);
617 case GPU_DATA_INT:
618 return type_of_conversion_int(device_format);
620 return type_of_conversion_half(device_format);
621 case GPU_DATA_UBYTE:
622 return type_of_conversion_ubyte(device_format);
624 return type_of_conversion_r11g11b10(device_format);
626 return type_of_conversion_r10g10b10a2(device_format);
628 return type_of_conversion_uint248(device_format);
629 }
630
632}
633
635{
636#define CASE_SINGLE(a, b) \
637 case ConversionType::a##_TO_##b: \
638 return ConversionType::b##_TO_##a;
639
640#define CASE_PAIR(a, b) \
641 CASE_SINGLE(a, b) \
642 CASE_SINGLE(b, a)
643
644 switch (type) {
649
650 CASE_PAIR(FLOAT, UNORM8)
651 CASE_PAIR(FLOAT, SNORM8)
652 CASE_PAIR(FLOAT, UNORM16)
653 CASE_PAIR(FLOAT, SNORM16)
654 CASE_PAIR(FLOAT, UNORM32)
660 CASE_PAIR(FLOAT, B10F_G11F_R11F)
663 CASE_PAIR(UINT, DEPTH32F_STENCIL8)
665
668 }
669
670#undef CASE_PAIR
671#undef CASE_SINGLE
672
674}
675
677
678/* -------------------------------------------------------------------- */
681
682static uint32_t float_to_uint32_t(float value)
683{
684 union {
685 float fl;
686 uint32_t u;
687 } float_to_bits;
688 float_to_bits.fl = value;
689 return float_to_bits.u;
690}
691
692static float uint32_t_to_float(uint32_t value)
693{
694 union {
695 float fl;
696 uint32_t u;
697 } float_to_bits;
698 float_to_bits.u = value;
699 return float_to_bits.fl;
700}
701
702template<typename InnerType> struct ComponentValue {
703 InnerType value;
704};
705template<typename InnerType> struct PixelValue {
706 InnerType value;
707};
708
719/* NOTE: Vulkan stores R11_G11_B10 in reverse component order. */
720class B10F_G11G_R11F : public PixelValue<uint32_t> {};
721
722class HALF4 : public PixelValue<uint64_t> {
723 public:
724 uint32_t get_r() const
725 {
726 return value & 0xffff;
727 }
728
729 void set_r(uint64_t new_value)
730 {
731 value = (value & 0xffffffffffff0000) | (new_value & 0xffff);
732 }
734 {
735 return (value >> 16) & 0xffff;
736 }
737
738 void set_g(uint64_t new_value)
739 {
740 value = (value & 0xffffffff0000ffff) | ((new_value & 0xffff) << 16);
741 }
743 {
744 return (value >> 32) & 0xffff;
745 }
746
747 void set_b(uint64_t new_value)
748 {
749 value = (value & 0xffff0000ffffffff) | ((new_value & 0xffff) << 32);
750 }
751
752 void set_a(uint64_t new_value)
753 {
754 value = (value & 0xffffffffffff) | ((new_value & 0xffff) << 48);
755 }
756};
757
758/* Use a float as we only have the depth aspect in the staging buffers. */
760
761template<typename InnerType> struct SignedNormalized {
762 static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>());
763 InnerType value;
764
765 static constexpr int32_t scalar()
766 {
767 return (1 << (sizeof(InnerType) * 8 - 1));
768 }
769
770 static constexpr int32_t delta()
771 {
772 return (1 << (sizeof(InnerType) * 8 - 1)) - 1;
773 }
774
775 static constexpr int32_t max()
776 {
777 return ((1 << (sizeof(InnerType) * 8)) - 1);
778 }
779};
780
781template<typename InnerType> struct UnsignedNormalized {
782 static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>() ||
783 std::is_same<InnerType, uint32_t>());
784 InnerType value;
785
786 static constexpr size_t used_byte_size()
787 {
788 return sizeof(InnerType);
789 }
790
791 static constexpr uint32_t scalar()
792 {
793 return std::numeric_limits<InnerType>::max();
794 }
795
796 static constexpr uint32_t max()
797 {
798 return std::numeric_limits<InnerType>::max();
799 }
800};
801
802template<typename StorageType> void convert(SignedNormalized<StorageType> &dst, const F32 &src)
803{
804 static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
805 static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
807 dst.value = clamp_i((src.value * scalar + delta), 0, max);
808}
809
810template<typename StorageType> void convert(F32 &dst, const SignedNormalized<StorageType> &src)
811{
812 static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
813 static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
814 dst.value = float(int32_t(src.value) - delta) / scalar;
815}
816
817template<typename StorageType> void convert(UnsignedNormalized<StorageType> &dst, const F32 &src)
818{
819 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
820 static constexpr uint32_t max = scalar;
821 /* When converting a DEPTH32F to DEPTH24 the scalar gets to large where 1.0 will wrap around and
822 * become 0. Make sure that depth 1.0 will not wrap around. Without this gpu_select_pick will
823 * fail as all depth 1.0 will occlude previous depths. */
824 dst.value = src.value >= 1.0f ? max : max_ff(src.value * float(scalar), 0.0);
825}
826
827template<typename StorageType> void convert(F32 &dst, const UnsignedNormalized<StorageType> &src)
828{
829 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
830 dst.value = float(uint32_t(src.value & scalar)) / float(scalar);
831}
832
833template<typename StorageType>
834void convert(UnsignedNormalized<StorageType> & /*dst*/, const UI32 & /*src*/)
835{
837}
838
839template<typename StorageType> void convert(UI32 &dst, const UnsignedNormalized<StorageType> &src)
840{
841 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
842 dst.value = uint32_t(src.value) & scalar;
843}
844
845/* Copy the contents of src to dst with out performing any actual conversion. */
846template<typename DestinationType, typename SourceType>
847void convert(DestinationType &dst, const SourceType &src)
848{
849 static_assert(std::is_same<DestinationType, UI8>() || std::is_same<DestinationType, UI16>() ||
850 std::is_same<DestinationType, UI32>() || std::is_same<DestinationType, I8>() ||
851 std::is_same<DestinationType, I16>() || std::is_same<DestinationType, I32>());
852 static_assert(std::is_same<SourceType, UI8>() || std::is_same<SourceType, UI16>() ||
853 std::is_same<SourceType, UI32>() || std::is_same<SourceType, I8>() ||
854 std::is_same<SourceType, I16>() || std::is_same<SourceType, I32>());
855 static_assert(!std::is_same<DestinationType, SourceType>());
856 dst.value = src.value;
857}
858
859static void convert(FLOAT3 &dst, const HALF4 &src)
860{
861 dst.value.x = math::half_to_float(src.get_r());
862 dst.value.y = math::half_to_float(src.get_g());
863 dst.value.z = math::half_to_float(src.get_b());
864}
865
866static void convert(HALF4 &dst, const FLOAT3 &src)
867{
868 dst.set_r(math::float_to_half(src.value.x));
869 dst.set_g(math::float_to_half(src.value.y));
870 dst.set_b(math::float_to_half(src.value.z));
871 dst.set_a(0x3c00); /* FP16 1.0 */
872}
873
874static void convert(FLOAT3 &dst, const FLOAT4 &src)
875{
876 dst.value.x = src.value.r;
877 dst.value.y = src.value.g;
878 dst.value.z = src.value.b;
879}
880
881static void convert(FLOAT4 &dst, const FLOAT3 &src)
882{
883 dst.value.r = src.value.x;
884 dst.value.g = src.value.y;
885 dst.value.b = src.value.z;
886 dst.value.a = 1.0f;
887}
888
889static void convert(F16 &dst, const UI8 &src)
890{
892 un8.value = src.value;
893 F32 f32;
894 convert(f32, un8);
896}
897
898static void convert(UI8 &dst, const F16 &src)
899{
900 F32 f32;
903 convert(un8, f32);
904 dst.value = un8.value;
905}
906
907constexpr uint32_t MASK_10_BITS = 0b1111111111;
908constexpr uint32_t MASK_11_BITS = 0b11111111111;
909constexpr uint8_t SHIFT_B = 22;
910constexpr uint8_t SHIFT_G = 11;
911constexpr uint8_t SHIFT_R = 0;
912
922
930
932
933static void convert(UI32 &dst, const Depth32fStencil8 &src)
934{
935 uint32_t depth = uint32_t(src.value * 0xFFFFFF);
936 dst.value = (depth << 8);
937}
938
939static void convert(Depth32fStencil8 &dst, const UI32 &src)
940{
941 uint32_t depth = (src.value >> 8) & 0xFFFFFF;
942 dst.value = float(depth) * 0xFFFFFF;
943}
944
945template<typename DestinationType, typename SourceType>
947{
948 BLI_assert(src.size() == dst.size());
949 for (int64_t index : IndexRange(src.size())) {
950 convert(dst[index], src[index]);
951 }
952}
953
954template<typename DestinationType, typename SourceType>
955void convert_per_component(void *dst_memory,
956 const void *src_memory,
957 size_t buffer_size,
958 TextureFormat device_format)
959{
960 size_t total_components = to_component_len(device_format) * buffer_size;
961 Span<SourceType> src = Span<SourceType>(static_cast<const SourceType *>(src_memory),
962 total_components);
964 static_cast<DestinationType *>(dst_memory), total_components);
966}
967
968template<typename DestinationType, typename SourceType>
969void convert_per_pixel(void *dst_memory, const void *src_memory, size_t buffer_size)
970{
971 Span<SourceType> src = Span<SourceType>(static_cast<const SourceType *>(src_memory),
972 buffer_size);
974 static_cast<DestinationType *>(dst_memory), buffer_size);
976}
977
978static void convert_buffer(void *dst_memory,
979 const void *src_memory,
980 size_t buffer_size,
981 TextureFormat device_format,
982 ConversionType type)
983{
984 switch (type) {
986 return;
987
989 memcpy(dst_memory, src_memory, buffer_size * to_bytesize(device_format));
990 return;
991
993 memcpy(dst_memory, src_memory, buffer_size * to_bytesize(TextureFormat::SFLOAT_32_DEPTH));
994 return;
995
997 convert_per_component<UI16, UI32>(dst_memory, src_memory, buffer_size, device_format);
998 break;
999
1001 convert_per_component<UI32, UI16>(dst_memory, src_memory, buffer_size, device_format);
1002 break;
1003
1005 convert_per_component<UI8, UI32>(dst_memory, src_memory, buffer_size, device_format);
1006 break;
1007
1009 convert_per_component<UI32, UI8>(dst_memory, src_memory, buffer_size, device_format);
1010 break;
1011
1013 convert_per_component<I16, I32>(dst_memory, src_memory, buffer_size, device_format);
1014 break;
1015
1017 convert_per_component<I32, I16>(dst_memory, src_memory, buffer_size, device_format);
1018 break;
1019
1021 convert_per_component<I8, I32>(dst_memory, src_memory, buffer_size, device_format);
1022 break;
1023
1025 convert_per_component<I32, I8>(dst_memory, src_memory, buffer_size, device_format);
1026 break;
1027
1030 dst_memory, src_memory, buffer_size, device_format);
1031 break;
1034 dst_memory, src_memory, buffer_size, device_format);
1035 break;
1036
1039 dst_memory, src_memory, buffer_size, device_format);
1040 break;
1043 dst_memory, src_memory, buffer_size, device_format);
1044 break;
1045
1048 dst_memory, src_memory, buffer_size, device_format);
1049 break;
1052 dst_memory, src_memory, buffer_size, device_format);
1053 break;
1054
1057 dst_memory, src_memory, buffer_size, device_format);
1058 break;
1061 dst_memory, src_memory, buffer_size, device_format);
1062 break;
1063
1066 dst_memory, src_memory, buffer_size, device_format);
1067 break;
1070 dst_memory, src_memory, buffer_size, device_format);
1071 break;
1072
1074 convert_per_component<F16, UI8>(dst_memory, src_memory, buffer_size, device_format);
1075 break;
1077 convert_per_component<UI8, F16>(dst_memory, src_memory, buffer_size, device_format);
1078 break;
1079
1081 size_t element_len = to_component_len(device_format) * buffer_size;
1082 Span<float> src(static_cast<const float *>(src_memory), element_len);
1083 MutableSpan<uint16_t> dst(static_cast<uint16_t *>(dst_memory), element_len);
1084
1085 constexpr int64_t chunk_size = 4 * 1024 * 1024;
1086
1087 threading::parallel_for(IndexRange(element_len), chunk_size, [&](const IndexRange range) {
1088 /* Doing float to half conversion manually to avoid implementation specific behavior
1089 * regarding Inf and NaNs. Use make finite version to avoid unexpected black pixels on
1090 * certain implementation. For platform parity we clamp these infinite values to finite
1091 * values. */
1093 src.slice(range).data(), dst.slice(range).data(), range.size());
1094 });
1095 break;
1096 }
1098 blender::math::half_to_float_array(static_cast<const uint16_t *>(src_memory),
1099 static_cast<float *>(dst_memory),
1100 to_component_len(device_format) * buffer_size);
1101 break;
1102
1104 convert_per_pixel<B10F_G11G_R11F, FLOAT3>(dst_memory, src_memory, buffer_size);
1105 break;
1106
1108 convert_per_pixel<UI32, Depth32fStencil8>(dst_memory, src_memory, buffer_size);
1109 break;
1111 convert_per_pixel<Depth32fStencil8, UI32>(dst_memory, src_memory, buffer_size);
1112 break;
1113
1115 convert_per_pixel<FLOAT3, B10F_G11G_R11F>(dst_memory, src_memory, buffer_size);
1116 break;
1117
1119 convert_per_pixel<HALF4, FLOAT3>(dst_memory, src_memory, buffer_size);
1120 break;
1122 convert_per_pixel<FLOAT3, HALF4>(dst_memory, src_memory, buffer_size);
1123 break;
1124
1126 convert_per_pixel<FLOAT4, FLOAT3>(dst_memory, src_memory, buffer_size);
1127 break;
1129 convert_per_pixel<FLOAT3, FLOAT4>(dst_memory, src_memory, buffer_size);
1130 break;
1131 }
1132}
1133
1134/* -------------------------------------------------------------------- */
1137
1138void convert_host_to_device(void *dst_buffer,
1139 const void *src_buffer,
1140 size_t buffer_size,
1141 eGPUDataFormat host_format,
1142 TextureFormat host_texture_format,
1143 TextureFormat device_format)
1144{
1145 ConversionType conversion_type = host_to_device(host_format, host_texture_format, device_format);
1146 BLI_assert(conversion_type != ConversionType::UNSUPPORTED);
1147 convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
1148}
1149
1150void convert_device_to_host(void *dst_buffer,
1151 const void *src_buffer,
1152 size_t buffer_size,
1153 eGPUDataFormat host_format,
1154 TextureFormat host_texture_format,
1155 TextureFormat device_format)
1156{
1157 ConversionType conversion_type = reversed(
1158 host_to_device(host_format, host_texture_format, device_format));
1160 "Data conversion between host_format and device_format isn't supported (yet).");
1161 convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
1162}
1163
1165
1166} // namespace blender::gpu
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE float max_ff(float a, float b)
MINLINE int clamp_i(int value, int min, int max)
#define ELEM(...)
eGPUDataFormat
@ GPU_DATA_HALF_FLOAT
@ GPU_DATA_INT
@ GPU_DATA_10_11_11_REV
@ GPU_DATA_UBYTE
@ GPU_DATA_UINT
@ GPU_DATA_UINT_24_8_DEPRECATED
@ GPU_DATA_2_10_10_10_REV
@ GPU_DATA_FLOAT
long long int int64_t
unsigned long long int uint64_t
ChannelStorageType r
ChannelStorageType g
ChannelStorageType b
ChannelStorageType a
constexpr int64_t size() const
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
Definition BLI_span.hh:573
constexpr T * data() const
Definition BLI_span.hh:539
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr int64_t size() const
Definition BLI_span.hh:252
void set_g(uint64_t new_value)
void set_r(uint64_t new_value)
void set_a(uint64_t new_value)
void set_b(uint64_t new_value)
nullptr FLOAT
nullptr float
@ HALF
ComponentValue< int16_t > I16
ComponentValue< uint16_t > F16
ComponentValue< uint8_t > UI8
constexpr uint32_t MASK_10_BITS
void convert_per_component(void *dst_memory, const void *src_memory, size_t buffer_size, TextureFormat device_format)
ComponentValue< uint32_t > UI32
constexpr uint8_t SHIFT_B
static ConversionType reversed(ConversionType type)
static ConversionType host_to_device(const eGPUDataFormat host_format, const TextureFormat host_texture_format, const TextureFormat device_format)
static ConversionType type_of_conversion_uint(TextureFormat device_format)
static uint32_t float_to_uint32_t(float value)
void convert(SignedNormalized< StorageType > &dst, const F32 &src)
ComponentValue< uint16_t > UI16
constexpr uint8_t SHIFT_R
static ConversionType type_of_conversion_float(const TextureFormat host_format, const TextureFormat device_format)
constexpr uint8_t SHIFT_G
PixelValue< float3 > FLOAT3
static ConversionType type_of_conversion_uint248(const TextureFormat device_format)
int to_bytesize(const DataFormat format)
static ConversionType type_of_conversion_ubyte(TextureFormat device_format)
ComponentValue< float > F32
void convert_host_to_device(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, TextureFormat host_texture_format, TextureFormat device_format)
ComponentValue< int32_t > I32
PixelValue< ColorSceneLinear4f< eAlpha::Premultiplied > > FLOAT4
ComponentValue< int8_t > I8
static ConversionType type_of_conversion_r10g10b10a2(TextureFormat device_format)
static void convert_buffer(void *dst_memory, const void *src_memory, size_t buffer_size, TextureFormat device_format, ConversionType type)
int to_component_len(TextureFormat format)
static ConversionType type_of_conversion_r11g11b10(TextureFormat device_format)
uint32_t convert_float_formats(uint32_t value)
static float uint32_t_to_float(uint32_t value)
void convert_per_pixel(void *dst_memory, const void *src_memory, size_t buffer_size)
static ConversionType type_of_conversion_half(TextureFormat device_format)
void convert_device_to_host(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, TextureFormat host_texture_format, TextureFormat device_format)
constexpr uint32_t MASK_11_BITS
static ConversionType type_of_conversion_int(TextureFormat device_format)
uint16_t float_to_half(float v)
Definition math_half.cc:27
void half_to_float_array(const uint16_t *src, float *dst, size_t length)
Definition math_half.cc:368
void float_to_half_make_finite_array(const float *src, uint16_t *dst, size_t length)
Definition math_half.cc:274
float half_to_float(uint16_t v)
Definition math_half.cc:108
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
#define CASE_PAIR(value_src, value_dst)
static constexpr int32_t scalar()
static constexpr int32_t delta()
static constexpr int32_t max()
static constexpr uint32_t max()
static constexpr size_t used_byte_size()
static constexpr uint32_t scalar()
max
Definition text_draw.cc:251