Blender V4.5
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
90
92 const eGPUTextureFormat device_format)
93{
94 if (host_format != device_format) {
95 if (host_format == GPU_RGB16F && device_format == GPU_RGBA16F) {
97 }
98 if (host_format == GPU_RGB32F && device_format == GPU_RGBA32F) {
100 }
101 if (host_format == GPU_DEPTH_COMPONENT24 && device_format == GPU_DEPTH_COMPONENT32F) {
103 }
104 if (host_format == GPU_DEPTH24_STENCIL8 && device_format == GPU_DEPTH32F_STENCIL8) {
106 }
107
109 }
110
111 switch (device_format) {
112 case GPU_RGBA32F:
113 case GPU_RG32F:
114 case GPU_R32F:
117
120
121 case GPU_RGBA16F:
122 case GPU_RG16F:
123 case GPU_R16F:
124 case GPU_RGB16F:
126
127 case GPU_RGBA8:
128 case GPU_RG8:
129 case GPU_R8:
131
132 case GPU_RGBA8_SNORM:
133 case GPU_RGB8_SNORM:
134 case GPU_RG8_SNORM:
135 case GPU_R8_SNORM:
137
138 case GPU_RGBA16:
139 case GPU_RG16:
140 case GPU_R16:
142
143 case GPU_RGBA16_SNORM:
144 case GPU_RGB16_SNORM:
145 case GPU_RG16_SNORM:
146 case GPU_R16_SNORM:
148
149 case GPU_SRGB8_A8:
151
155
158
162 case GPU_RGBA8_DXT1:
163 case GPU_RGBA8_DXT3:
164 case GPU_RGBA8_DXT5:
165 /* Not an actual "conversion", but compressed texture upload code
166 * pretends that host data is a float. It is actually raw BCn bits. */
168
169 case GPU_RGB32F: /* GPU_RGB32F Not supported by vendors. */
170 case GPU_RGBA8UI:
171 case GPU_RGBA8I:
172 case GPU_RGBA16UI:
173 case GPU_RGBA16I:
174 case GPU_RGBA32UI:
175 case GPU_RGBA32I:
176 case GPU_RG8UI:
177 case GPU_RG8I:
178 case GPU_RG16UI:
179 case GPU_RG16I:
180 case GPU_RG32UI:
181 case GPU_RG32I:
182 case GPU_R8UI:
183 case GPU_R8I:
184 case GPU_R16UI:
185 case GPU_R16I:
186 case GPU_R32UI:
187 case GPU_R32I:
188 case GPU_RGB10_A2:
189 case GPU_RGB10_A2UI:
190 case GPU_RGB8UI:
191 case GPU_RGB8I:
192 case GPU_RGB8:
193 case GPU_RGB16UI:
194 case GPU_RGB16I:
195 case GPU_RGB16:
196 case GPU_RGB32UI:
197 case GPU_RGB32I:
198 case GPU_SRGB8:
199 case GPU_RGB9_E5:
202 }
204}
205
207{
208 switch (device_format) {
209 case GPU_RGBA32I:
210 case GPU_RG32I:
211 case GPU_R32I:
213
214 case GPU_RGBA16I:
215 case GPU_RG16I:
216 case GPU_R16I:
218
219 case GPU_RGBA8I:
220 case GPU_RG8I:
221 case GPU_R8I:
223
224 case GPU_RGBA8UI:
225 case GPU_RGBA8:
226 case GPU_RGBA16UI:
227 case GPU_RGBA16F:
228 case GPU_RGBA16:
229 case GPU_RGBA32UI:
230 case GPU_RGBA32F:
231 case GPU_RG8UI:
232 case GPU_RG8:
233 case GPU_RG16UI:
234 case GPU_RG16F:
235 case GPU_RG32UI:
236 case GPU_RG32F:
237 case GPU_RG16:
238 case GPU_R8UI:
239 case GPU_R8:
240 case GPU_R16UI:
241 case GPU_R16F:
242 case GPU_R16:
243 case GPU_R32UI:
244 case GPU_R32F:
245 case GPU_RGB10_A2:
246 case GPU_RGB10_A2UI:
250 case GPU_SRGB8_A8:
251 case GPU_RGBA8_SNORM:
252 case GPU_RGBA16_SNORM:
253 case GPU_RGB8UI:
254 case GPU_RGB8I:
255 case GPU_RGB8:
256 case GPU_RGB8_SNORM:
257 case GPU_RGB16UI:
258 case GPU_RGB16I:
259 case GPU_RGB16F:
260 case GPU_RGB16:
261 case GPU_RGB16_SNORM:
262 case GPU_RGB32UI:
263 case GPU_RGB32I:
264 case GPU_RGB32F:
265 case GPU_RG8_SNORM:
266 case GPU_RG16_SNORM:
267 case GPU_R8_SNORM:
268 case GPU_R16_SNORM:
272 case GPU_RGBA8_DXT1:
273 case GPU_RGBA8_DXT3:
274 case GPU_RGBA8_DXT5:
275 case GPU_SRGB8:
276 case GPU_RGB9_E5:
281 }
283}
284
286{
287 switch (device_format) {
288 case GPU_RGBA32UI:
289 case GPU_RG32UI:
290 case GPU_R32UI:
293
294 case GPU_RGBA16UI:
295 case GPU_RG16UI:
296 case GPU_R16UI:
297 case GPU_RGB16UI:
299
300 case GPU_RGBA8UI:
301 case GPU_RG8UI:
302 case GPU_R8UI:
304
310
311 case GPU_RGBA8I:
312 case GPU_RGBA8:
313 case GPU_RGBA16I:
314 case GPU_RGBA16F:
315 case GPU_RGBA16:
316 case GPU_RGBA32I:
317 case GPU_RGBA32F:
318 case GPU_RG8I:
319 case GPU_RG8:
320 case GPU_RG16I:
321 case GPU_RG16F:
322 case GPU_RG16:
323 case GPU_RG32I:
324 case GPU_RG32F:
325 case GPU_R8I:
326 case GPU_R8:
327 case GPU_R16I:
328 case GPU_R16F:
329 case GPU_R16:
330 case GPU_R32I:
331 case GPU_R32F:
332 case GPU_RGB10_A2:
333 case GPU_RGB10_A2UI:
335 case GPU_SRGB8_A8:
336 case GPU_RGBA8_SNORM:
337 case GPU_RGBA16_SNORM:
338 case GPU_RGB8UI:
339 case GPU_RGB8I:
340 case GPU_RGB8:
341 case GPU_RGB8_SNORM:
342 case GPU_RGB16I:
343 case GPU_RGB16F:
344 case GPU_RGB16:
345 case GPU_RGB16_SNORM:
346 case GPU_RGB32UI:
347 case GPU_RGB32I:
348 case GPU_RGB32F:
349 case GPU_RG8_SNORM:
350 case GPU_RG16_SNORM:
351 case GPU_R8_SNORM:
352 case GPU_R16_SNORM:
356 case GPU_RGBA8_DXT1:
357 case GPU_RGBA8_DXT3:
358 case GPU_RGBA8_DXT5:
359 case GPU_SRGB8:
360 case GPU_RGB9_E5:
363 }
365}
366
368{
369 switch (device_format) {
370 case GPU_RGBA16F:
371 case GPU_RG16F:
372 case GPU_R16F:
374
375 case GPU_RGBA8UI:
376 case GPU_RGBA8I:
377 case GPU_RGBA8:
378 case GPU_RGBA16UI:
379 case GPU_RGBA16I:
380 case GPU_RGBA16:
381 case GPU_RGBA32UI:
382 case GPU_RGBA32I:
383 case GPU_RGBA32F:
384 case GPU_RG8UI:
385 case GPU_RG8I:
386 case GPU_RG8:
387 case GPU_RG16UI:
388 case GPU_RG16I:
389 case GPU_RG16:
390 case GPU_RG32UI:
391 case GPU_RG32I:
392 case GPU_RG32F:
393 case GPU_R8UI:
394 case GPU_R8I:
395 case GPU_R8:
396 case GPU_R16UI:
397 case GPU_R16I:
398 case GPU_R16:
399 case GPU_R32UI:
400 case GPU_R32I:
401 case GPU_R32F:
402 case GPU_RGB10_A2:
403 case GPU_RGB10_A2UI:
407 case GPU_SRGB8_A8:
408 case GPU_RGBA8_SNORM:
409 case GPU_RGBA16_SNORM:
410 case GPU_RGB8UI:
411 case GPU_RGB8I:
412 case GPU_RGB8:
413 case GPU_RGB8_SNORM:
414 case GPU_RGB16UI:
415 case GPU_RGB16I:
416 case GPU_RGB16F:
417 case GPU_RGB16:
418 case GPU_RGB16_SNORM:
419 case GPU_RGB32UI:
420 case GPU_RGB32I:
421 case GPU_RGB32F:
422 case GPU_RG8_SNORM:
423 case GPU_RG16_SNORM:
424 case GPU_R8_SNORM:
425 case GPU_R16_SNORM:
429 case GPU_RGBA8_DXT1:
430 case GPU_RGBA8_DXT3:
431 case GPU_RGBA8_DXT5:
432 case GPU_SRGB8:
433 case GPU_RGB9_E5:
438 }
440}
441
443{
444 switch (device_format) {
445 case GPU_RGBA8UI:
446 case GPU_RGBA8:
447 case GPU_RG8UI:
448 case GPU_RG8:
449 case GPU_R8UI:
450 case GPU_R8:
451 case GPU_SRGB8_A8:
453
454 case GPU_RGBA16F:
455 case GPU_RG16F:
456 case GPU_R16F:
458
459 case GPU_RGBA8I:
460 case GPU_RGBA16UI:
461 case GPU_RGBA16I:
462 case GPU_RGBA16:
463 case GPU_RGBA32UI:
464 case GPU_RGBA32I:
465 case GPU_RGBA32F:
466 case GPU_RG8I:
467 case GPU_RG16UI:
468 case GPU_RG16I:
469 case GPU_RG16:
470 case GPU_RG32UI:
471 case GPU_RG32I:
472 case GPU_RG32F:
473 case GPU_R8I:
474 case GPU_R16UI:
475 case GPU_R16I:
476 case GPU_R16:
477 case GPU_R32UI:
478 case GPU_R32I:
479 case GPU_R32F:
480 case GPU_RGB10_A2:
481 case GPU_RGB10_A2UI:
485 case GPU_RGBA8_SNORM:
486 case GPU_RGBA16_SNORM:
487 case GPU_RGB8UI:
488 case GPU_RGB8I:
489 case GPU_RGB8:
490 case GPU_RGB8_SNORM:
491 case GPU_RGB16UI:
492 case GPU_RGB16I:
493 case GPU_RGB16F:
494 case GPU_RGB16:
495 case GPU_RGB16_SNORM:
496 case GPU_RGB32UI:
497 case GPU_RGB32I:
498 case GPU_RGB32F:
499 case GPU_RG8_SNORM:
500 case GPU_RG16_SNORM:
501 case GPU_R8_SNORM:
502 case GPU_R16_SNORM:
506 case GPU_RGBA8_DXT1:
507 case GPU_RGBA8_DXT3:
508 case GPU_RGBA8_DXT5:
509 case GPU_SRGB8:
510 case GPU_RGB9_E5:
515 }
517}
518
520{
521 switch (device_format) {
524
527
528 case GPU_RGBA32F:
529 case GPU_RG32F:
530 case GPU_R32F:
531 case GPU_RGBA16F:
532 case GPU_RG16F:
533 case GPU_R16F:
534 case GPU_RGB16F:
535 case GPU_RGBA8:
536 case GPU_RG8:
537 case GPU_R8:
538 case GPU_RGBA8_SNORM:
539 case GPU_RGB8_SNORM:
540 case GPU_RG8_SNORM:
541 case GPU_R8_SNORM:
542 case GPU_RGBA16:
543 case GPU_RG16:
544 case GPU_R16:
545 case GPU_RGBA16_SNORM:
546 case GPU_RGB16_SNORM:
547 case GPU_RG16_SNORM:
548 case GPU_R16_SNORM:
549 case GPU_SRGB8_A8:
556 case GPU_RGBA8_DXT1:
557 case GPU_RGBA8_DXT3:
558 case GPU_RGBA8_DXT5:
559
560 case GPU_RGB32F: /* GPU_RGB32F Not supported by vendors. */
561 case GPU_RGBA8UI:
562 case GPU_RGBA8I:
563 case GPU_RGBA16UI:
564 case GPU_RGBA16I:
565 case GPU_RGBA32UI:
566 case GPU_RGBA32I:
567 case GPU_RG8UI:
568 case GPU_RG8I:
569 case GPU_RG16UI:
570 case GPU_RG16I:
571 case GPU_RG32UI:
572 case GPU_RG32I:
573 case GPU_R8UI:
574 case GPU_R8I:
575 case GPU_R16UI:
576 case GPU_R16I:
577 case GPU_R32UI:
578 case GPU_R32I:
579 case GPU_RGB10_A2:
580 case GPU_RGB10_A2UI:
581 case GPU_RGB8UI:
582 case GPU_RGB8I:
583 case GPU_RGB8:
584 case GPU_RGB16UI:
585 case GPU_RGB16I:
586 case GPU_RGB16:
587 case GPU_RGB32UI:
588 case GPU_RGB32I:
589 case GPU_SRGB8:
590 case GPU_RGB9_E5:
593 }
595}
596
598{
599 if (device_format == GPU_R11F_G11F_B10F) {
601 }
603}
604
612
614 const eGPUTextureFormat host_texture_format,
615 const eGPUTextureFormat device_format)
616{
617 switch (host_format) {
618 case GPU_DATA_FLOAT:
619 return type_of_conversion_float(host_texture_format, device_format);
620 case GPU_DATA_UINT:
621 return type_of_conversion_uint(device_format);
622 case GPU_DATA_INT:
623 return type_of_conversion_int(device_format);
625 return type_of_conversion_half(device_format);
626 case GPU_DATA_UBYTE:
627 return type_of_conversion_ubyte(device_format);
629 return type_of_conversion_r11g11b10(device_format);
631 return type_of_conversion_r10g10b10a2(device_format);
633 return type_of_conversion_uint248(device_format);
634 }
635
637}
638
640{
641#define CASE_SINGLE(a, b) \
642 case ConversionType::a##_TO_##b: \
643 return ConversionType::b##_TO_##a;
644
645#define CASE_PAIR(a, b) \
646 CASE_SINGLE(a, b) \
647 CASE_SINGLE(b, a)
648
649 switch (type) {
654
655 CASE_PAIR(FLOAT, UNORM8)
656 CASE_PAIR(FLOAT, SNORM8)
657 CASE_PAIR(FLOAT, UNORM16)
658 CASE_PAIR(FLOAT, SNORM16)
659 CASE_PAIR(FLOAT, UNORM32)
666 CASE_PAIR(FLOAT, DEPTH_COMPONENT24)
667 CASE_PAIR(UINT, DEPTH_COMPONENT24)
668 CASE_PAIR(FLOAT, B10F_G11F_R11F)
671 CASE_PAIR(UINT, DEPTH24_STENCIL8)
672 CASE_PAIR(UINT, DEPTH32F_STENCIL8)
674
677 }
678
679#undef CASE_PAIR
680#undef CASE_SINGLE
681
683}
684
685/* \} */
686
687/* -------------------------------------------------------------------- */
690
691static uint32_t float_to_uint32_t(float value)
692{
693 union {
694 float fl;
695 uint32_t u;
696 } float_to_bits;
697 float_to_bits.fl = value;
698 return float_to_bits.u;
699}
700
701static float uint32_t_to_float(uint32_t value)
702{
703 union {
704 float fl;
705 uint32_t u;
706 } float_to_bits;
707 float_to_bits.u = value;
708 return float_to_bits.fl;
709}
710
711template<typename InnerType> struct ComponentValue {
712 InnerType value;
713};
714template<typename InnerType> struct PixelValue {
715 InnerType value;
716};
717
729/* NOTE: Vulkan stores R11_G11_B10 in reverse component order. */
730class B10F_G11G_R11F : public PixelValue<uint32_t> {};
731
732class HALF4 : public PixelValue<uint64_t> {
733 public:
734 uint32_t get_r() const
735 {
736 return value & 0xffff;
737 }
738
739 void set_r(uint64_t new_value)
740 {
741 value = (value & 0xffffffffffff0000) | (new_value & 0xffff);
742 }
744 {
745 return (value >> 16) & 0xffff;
746 }
747
748 void set_g(uint64_t new_value)
749 {
750 value = (value & 0xffffffff0000ffff) | ((new_value & 0xffff) << 16);
751 }
753 {
754 return (value >> 32) & 0xffff;
755 }
756
757 void set_b(uint64_t new_value)
758 {
759 value = (value & 0xffff0000ffffffff) | ((new_value & 0xffff) << 32);
760 }
761
762 void set_a(uint64_t new_value)
763 {
764 value = (value & 0xffffffffffff) | ((new_value & 0xffff) << 48);
765 }
766};
767
768class DepthComponent24 : public ComponentValue<uint32_t> {
769 public:
770 operator uint32_t() const
771 {
772 return value;
773 }
774
775 DepthComponent24 &operator=(uint32_t new_value)
776 {
777 value = new_value;
778 return *this;
779 }
780
781 /* Depth component24 are 4 bytes, but 1 isn't used. */
782 static constexpr size_t used_byte_size()
783 {
784 return 3;
785 }
786};
787
788struct Depth24Stencil8 : ComponentValue<uint32_t> {};
789/* Use a float as we only have the depth aspect in the staging buffers. */
791
792template<typename InnerType> struct SignedNormalized {
793 static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>());
794 InnerType value;
795
796 static constexpr int32_t scalar()
797 {
798 return (1 << (sizeof(InnerType) * 8 - 1));
799 }
800
801 static constexpr int32_t delta()
802 {
803 return (1 << (sizeof(InnerType) * 8 - 1)) - 1;
804 }
805
806 static constexpr int32_t max()
807 {
808 return ((1 << (sizeof(InnerType) * 8)) - 1);
809 }
810};
811
812template<typename InnerType> struct UnsignedNormalized {
813 static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>() ||
814 std::is_same<InnerType, uint32_t>() ||
815 std::is_same<InnerType, DepthComponent24>());
816 InnerType value;
817
818 static constexpr size_t used_byte_size()
819 {
820 if constexpr (std::is_same<InnerType, DepthComponent24>()) {
821 return InnerType::used_byte_size();
822 }
823 else {
824 return sizeof(InnerType);
825 }
826 }
827
828 static constexpr uint32_t scalar()
829 {
830 if constexpr (std::is_same<InnerType, DepthComponent24>()) {
831 return (1 << (used_byte_size() * 8)) - 1;
832 }
833 else {
834 return std::numeric_limits<InnerType>::max();
835 }
836 }
837
838 static constexpr uint32_t max()
839 {
840 if constexpr (std::is_same<InnerType, DepthComponent24>()) {
841 return (1 << (used_byte_size() * 8)) - 1;
842 }
843 else {
844 return std::numeric_limits<InnerType>::max();
845 }
846 }
847};
848
849template<typename StorageType> void convert(SignedNormalized<StorageType> &dst, const F32 &src)
850{
851 static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
852 static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
854 dst.value = clamp_i((src.value * scalar + delta), 0, max);
855}
856
857template<typename StorageType> void convert(F32 &dst, const SignedNormalized<StorageType> &src)
858{
859 static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
860 static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
861 dst.value = float(int32_t(src.value) - delta) / scalar;
862}
863
864template<typename StorageType> void convert(UnsignedNormalized<StorageType> &dst, const F32 &src)
865{
866 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
867 static constexpr uint32_t max = scalar;
868 /* When converting a DEPTH32F to DEPTH24 the scalar gets to large where 1.0 will wrap around and
869 * become 0. Make sure that depth 1.0 will not wrap around. Without this gpu_select_pick will
870 * fail as all depth 1.0 will occlude previous depths. */
871 dst.value = src.value >= 1.0f ? max : max_ff(src.value * float(scalar), 0.0);
872}
873
874template<typename StorageType> void convert(F32 &dst, const UnsignedNormalized<StorageType> &src)
875{
876 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
877 dst.value = float(uint32_t(src.value & scalar)) / float(scalar);
878}
879
880template<typename StorageType>
881void convert(UnsignedNormalized<StorageType> & /*dst*/, const UI32 & /*src*/)
882{
884}
885
886template<typename StorageType> void convert(UI32 &dst, const UnsignedNormalized<StorageType> &src)
887{
888 static constexpr uint32_t scalar = UnsignedNormalized<StorageType>::scalar();
889 dst.value = uint32_t(src.value) & scalar;
890}
891
892/* Copy the contents of src to dst with out performing any actual conversion. */
893template<typename DestinationType, typename SourceType>
894void convert(DestinationType &dst, const SourceType &src)
895{
896 static_assert(std::is_same<DestinationType, UI8>() || std::is_same<DestinationType, UI16>() ||
897 std::is_same<DestinationType, UI32>() || std::is_same<DestinationType, I8>() ||
898 std::is_same<DestinationType, I16>() || std::is_same<DestinationType, I32>());
899 static_assert(std::is_same<SourceType, UI8>() || std::is_same<SourceType, UI16>() ||
900 std::is_same<SourceType, UI32>() || std::is_same<SourceType, I8>() ||
901 std::is_same<SourceType, I16>() || std::is_same<SourceType, I32>());
902 static_assert(!std::is_same<DestinationType, SourceType>());
903 dst.value = src.value;
904}
905
906static void convert(SRGBA8 &dst, const FLOAT4 &src)
907{
908 dst.value = src.value.encode();
909}
910
911static void convert(FLOAT4 &dst, const SRGBA8 &src)
912{
913 dst.value = src.value.decode();
914}
915
916static void convert(FLOAT3 &dst, const HALF4 &src)
917{
918 dst.value.x = math::half_to_float(src.get_r());
919 dst.value.y = math::half_to_float(src.get_g());
920 dst.value.z = math::half_to_float(src.get_b());
921}
922
923static void convert(HALF4 &dst, const FLOAT3 &src)
924{
925 dst.set_r(math::float_to_half(src.value.x));
926 dst.set_g(math::float_to_half(src.value.y));
927 dst.set_b(math::float_to_half(src.value.z));
928 dst.set_a(0x3c00); /* FP16 1.0 */
929}
930
931static void convert(FLOAT3 &dst, const FLOAT4 &src)
932{
933 dst.value.x = src.value.r;
934 dst.value.y = src.value.g;
935 dst.value.z = src.value.b;
936}
937
938static void convert(FLOAT4 &dst, const FLOAT3 &src)
939{
940 dst.value.r = src.value.x;
941 dst.value.g = src.value.y;
942 dst.value.b = src.value.z;
943 dst.value.a = 1.0f;
944}
945
946static void convert(F16 &dst, const UI8 &src)
947{
949 un8.value = src.value;
950 F32 f32;
951 convert(f32, un8);
953}
954
955static void convert(UI8 &dst, const F16 &src)
956{
957 F32 f32;
960 convert(un8, f32);
961 dst.value = un8.value;
962}
963
964constexpr uint32_t MASK_10_BITS = 0b1111111111;
965constexpr uint32_t MASK_11_BITS = 0b11111111111;
966constexpr uint8_t SHIFT_B = 22;
967constexpr uint8_t SHIFT_G = 11;
968constexpr uint8_t SHIFT_R = 0;
969
979
987
988/* \} */
989
990/* Convert vulkan depth stencil to OpenGL depth stencil */
991static void convert(UI32 &dst, const Depth24Stencil8 &src)
992{
993 uint32_t stencil = (src.value & 0xFF000000) >> 24;
994 uint32_t depth = (src.value & 0xFFFFFF);
995 dst.value = (depth << 8) + stencil;
996}
997
998/* Convert OpenGL depth stencil to Vulkan depth stencil */
999static void convert(Depth24Stencil8 &dst, const UI32 &src)
1000{
1001 uint32_t stencil = (src.value & 0xFF);
1002 uint32_t depth = (src.value >> 8) & 0xFFFFFF;
1003 dst.value = depth + (stencil << 24);
1004}
1005
1006static void convert(UI32 &dst, const Depth32fStencil8 &src)
1007{
1008 uint32_t depth = uint32_t(src.value * 0xFFFFFF);
1009 dst.value = (depth << 8);
1010}
1011
1012static void convert(Depth32fStencil8 &dst, const UI32 &src)
1013{
1014 uint32_t depth = (src.value >> 8) & 0xFFFFFF;
1015 dst.value = float(depth) * 0xFFFFFF;
1016}
1017
1018template<typename DestinationType, typename SourceType>
1020{
1021 BLI_assert(src.size() == dst.size());
1022 for (int64_t index : IndexRange(src.size())) {
1023 convert(dst[index], src[index]);
1024 }
1025}
1026
1027template<typename DestinationType, typename SourceType>
1028void convert_per_component(void *dst_memory,
1029 const void *src_memory,
1030 size_t buffer_size,
1031 eGPUTextureFormat device_format)
1032{
1033 size_t total_components = to_component_len(device_format) * buffer_size;
1034 Span<SourceType> src = Span<SourceType>(static_cast<const SourceType *>(src_memory),
1035 total_components);
1037 static_cast<DestinationType *>(dst_memory), total_components);
1039}
1040
1041template<typename DestinationType, typename SourceType>
1042void convert_per_pixel(void *dst_memory, const void *src_memory, size_t buffer_size)
1043{
1044 Span<SourceType> src = Span<SourceType>(static_cast<const SourceType *>(src_memory),
1045 buffer_size);
1047 static_cast<DestinationType *>(dst_memory), buffer_size);
1049}
1050
1051static void convert_buffer(void *dst_memory,
1052 const void *src_memory,
1053 size_t buffer_size,
1054 eGPUTextureFormat device_format,
1055 ConversionType type)
1056{
1057 switch (type) {
1059 return;
1060
1063 memcpy(dst_memory, src_memory, buffer_size * to_bytesize(device_format));
1064 return;
1065
1067 memcpy(dst_memory, src_memory, buffer_size * to_bytesize(GPU_DEPTH_COMPONENT32F));
1068 return;
1069
1071 convert_per_component<UI16, UI32>(dst_memory, src_memory, buffer_size, device_format);
1072 break;
1073
1075 convert_per_component<UI32, UI16>(dst_memory, src_memory, buffer_size, device_format);
1076 break;
1077
1079 convert_per_component<UI8, UI32>(dst_memory, src_memory, buffer_size, device_format);
1080 break;
1081
1083 convert_per_component<UI32, UI8>(dst_memory, src_memory, buffer_size, device_format);
1084 break;
1085
1087 convert_per_component<I16, I32>(dst_memory, src_memory, buffer_size, device_format);
1088 break;
1089
1091 convert_per_component<I32, I16>(dst_memory, src_memory, buffer_size, device_format);
1092 break;
1093
1095 convert_per_component<I8, I32>(dst_memory, src_memory, buffer_size, device_format);
1096 break;
1097
1099 convert_per_component<I32, I8>(dst_memory, src_memory, buffer_size, device_format);
1100 break;
1101
1104 dst_memory, src_memory, buffer_size, device_format);
1105 break;
1108 dst_memory, src_memory, buffer_size, device_format);
1109 break;
1110
1113 dst_memory, src_memory, buffer_size, device_format);
1114 break;
1117 dst_memory, src_memory, buffer_size, device_format);
1118 break;
1119
1122 dst_memory, src_memory, buffer_size, device_format);
1123 break;
1126 dst_memory, src_memory, buffer_size, device_format);
1127 break;
1128
1131 dst_memory, src_memory, buffer_size, device_format);
1132 break;
1135 dst_memory, src_memory, buffer_size, device_format);
1136 break;
1137
1140 dst_memory, src_memory, buffer_size, device_format);
1141 break;
1144 dst_memory, src_memory, buffer_size, device_format);
1145 break;
1146
1148 convert_per_component<F16, UI8>(dst_memory, src_memory, buffer_size, device_format);
1149 break;
1151 convert_per_component<UI8, F16>(dst_memory, src_memory, buffer_size, device_format);
1152 break;
1153
1155 blender::math::float_to_half_array(static_cast<const float *>(src_memory),
1156 static_cast<uint16_t *>(dst_memory),
1157 to_component_len(device_format) * buffer_size);
1158 break;
1160 blender::math::half_to_float_array(static_cast<const uint16_t *>(src_memory),
1161 static_cast<float *>(dst_memory),
1162 to_component_len(device_format) * buffer_size);
1163 break;
1164
1166 convert_per_pixel<SRGBA8, FLOAT4>(dst_memory, src_memory, buffer_size);
1167 break;
1169 convert_per_pixel<FLOAT4, SRGBA8>(dst_memory, src_memory, buffer_size);
1170 break;
1171
1174 dst_memory, src_memory, buffer_size, device_format);
1175 break;
1178 dst_memory, src_memory, buffer_size, device_format);
1179 break;
1182 dst_memory, src_memory, buffer_size, device_format);
1183 break;
1185 convert_per_pixel<B10F_G11G_R11F, FLOAT3>(dst_memory, src_memory, buffer_size);
1186 break;
1187
1189 convert_per_pixel<UI32, Depth24Stencil8>(dst_memory, src_memory, buffer_size);
1190 break;
1192 convert_per_pixel<Depth24Stencil8, UI32>(dst_memory, src_memory, buffer_size);
1193 break;
1195 convert_per_pixel<UI32, Depth32fStencil8>(dst_memory, src_memory, buffer_size);
1196 break;
1198 convert_per_pixel<Depth32fStencil8, UI32>(dst_memory, src_memory, buffer_size);
1199 break;
1200
1202 convert_per_pixel<FLOAT3, B10F_G11G_R11F>(dst_memory, src_memory, buffer_size);
1203 break;
1204
1206 convert_per_pixel<HALF4, FLOAT3>(dst_memory, src_memory, buffer_size);
1207 break;
1209 convert_per_pixel<FLOAT3, HALF4>(dst_memory, src_memory, buffer_size);
1210 break;
1211
1213 convert_per_pixel<FLOAT4, FLOAT3>(dst_memory, src_memory, buffer_size);
1214 break;
1216 convert_per_pixel<FLOAT3, FLOAT4>(dst_memory, src_memory, buffer_size);
1217 break;
1218 }
1219}
1220
1221/* -------------------------------------------------------------------- */
1224
1225void convert_host_to_device(void *dst_buffer,
1226 const void *src_buffer,
1227 size_t buffer_size,
1228 eGPUDataFormat host_format,
1229 eGPUTextureFormat host_texture_format,
1230 eGPUTextureFormat device_format)
1231{
1232 ConversionType conversion_type = host_to_device(host_format, host_texture_format, device_format);
1233 BLI_assert(conversion_type != ConversionType::UNSUPPORTED);
1234 convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
1235}
1236
1237void convert_device_to_host(void *dst_buffer,
1238 const void *src_buffer,
1239 size_t buffer_size,
1240 eGPUDataFormat host_format,
1241 eGPUTextureFormat host_texture_format,
1242 eGPUTextureFormat device_format)
1243{
1244 ConversionType conversion_type = reversed(
1245 host_to_device(host_format, host_texture_format, device_format));
1247 "Data conversion between host_format and device_format isn't supported (yet).");
1248 convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
1249}
1250
1251/* \} */
1252
1253} // 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_UINT_24_8
@ GPU_DATA_INT
@ GPU_DATA_10_11_11_REV
@ GPU_DATA_UBYTE
@ GPU_DATA_UINT
@ GPU_DATA_2_10_10_10_REV
@ GPU_DATA_FLOAT
eGPUTextureFormat
@ GPU_RGB16
@ GPU_R16UI
@ GPU_RGB8
@ GPU_RG16F
@ GPU_DEPTH32F_STENCIL8
@ GPU_R32F
@ GPU_SRGB8
@ GPU_R16I
@ GPU_SRGB8_A8
@ GPU_RG8_SNORM
@ GPU_DEPTH24_STENCIL8
@ GPU_RGB10_A2
@ GPU_RGB8I
@ GPU_R32I
@ GPU_RGBA8_SNORM
@ GPU_RGB10_A2UI
@ GPU_RG8UI
@ GPU_R16F
@ GPU_RGB16I
@ GPU_RGBA16_SNORM
@ GPU_RGB9_E5
@ GPU_SRGB8_A8_DXT5
@ GPU_RG8I
@ GPU_RG16I
@ GPU_RG32UI
@ GPU_RGB32I
@ GPU_RGBA32F
@ GPU_RGBA16F
@ GPU_RG8
@ GPU_RG32I
@ GPU_SRGB8_A8_DXT1
@ GPU_RG16
@ GPU_RGBA32UI
@ GPU_R8I
@ GPU_R16
@ GPU_RG16UI
@ GPU_RGBA8I
@ GPU_RGBA8_DXT1
@ GPU_RGBA8UI
@ GPU_RGB32F
@ GPU_RGBA16UI
@ GPU_RGBA16I
@ GPU_R8UI
@ GPU_RGBA16
@ GPU_SRGB8_A8_DXT3
@ GPU_RGB8_SNORM
@ GPU_RGBA8_DXT3
@ GPU_RGB32UI
@ GPU_R8_SNORM
@ GPU_RG32F
@ GPU_R8
@ GPU_RGB16_SNORM
@ GPU_DEPTH_COMPONENT24
@ GPU_RG16_SNORM
@ GPU_RGB8UI
@ GPU_RGB16F
@ GPU_RGB16UI
@ GPU_R32UI
@ GPU_RGBA32I
@ GPU_RGBA8_DXT5
@ GPU_DEPTH_COMPONENT32F
@ GPU_R16_SNORM
@ GPU_DEPTH_COMPONENT16
@ GPU_R11F_G11F_B10F
@ GPU_RGBA8
long long int int64_t
unsigned long long int uint64_t
ChannelStorageType r
Definition BLI_color.hh:93
ChannelStorageType g
Definition BLI_color.hh:93
ChannelStorageType b
Definition BLI_color.hh:93
ChannelStorageType a
Definition BLI_color.hh:93
ColorSceneLinearByteEncoded4b< Alpha > encode() const
Definition BLI_color.hh:168
ColorSceneLinear4f< Alpha > decode() const
Definition BLI_color.hh:229
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr int64_t size() const
Definition BLI_span.hh:252
DepthComponent24 & operator=(uint32_t new_value)
static constexpr size_t used_byte_size()
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)
@ HALF
ComponentValue< int16_t > I16
ComponentValue< uint16_t > F16
ComponentValue< uint8_t > UI8
constexpr uint32_t MASK_10_BITS
PixelValue< ColorSceneLinearByteEncoded4b< eAlpha::Premultiplied > > SRGBA8
static ConversionType type_of_conversion_float(const eGPUTextureFormat host_format, const eGPUTextureFormat device_format)
ComponentValue< uint32_t > UI32
constexpr uint8_t SHIFT_B
static ConversionType type_of_conversion_ubyte(eGPUTextureFormat device_format)
static ConversionType reversed(ConversionType type)
static ConversionType type_of_conversion_half(eGPUTextureFormat device_format)
void convert_host_to_device(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, eGPUTextureFormat host_texture_format, eGPUTextureFormat device_format)
void convert_per_component(void *dst_memory, const void *src_memory, size_t buffer_size, eGPUTextureFormat device_format)
static ConversionType host_to_device(const eGPUDataFormat host_format, const eGPUTextureFormat host_texture_format, const eGPUTextureFormat 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
constexpr uint8_t SHIFT_G
void convert_device_to_host(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, eGPUTextureFormat host_texture_format, eGPUTextureFormat device_format)
PixelValue< float3 > FLOAT3
static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format)
static ConversionType type_of_conversion_uint248(const eGPUTextureFormat device_format)
int to_bytesize(const DataFormat format)
ComponentValue< float > F32
ComponentValue< int32_t > I32
PixelValue< ColorSceneLinear4f< eAlpha::Premultiplied > > FLOAT4
static ConversionType type_of_conversion_r10g10b10a2(eGPUTextureFormat device_format)
ComponentValue< int8_t > I8
static void convert_buffer(void *dst_memory, const void *src_memory, size_t buffer_size, eGPUTextureFormat device_format, ConversionType type)
int to_component_len(eGPUTextureFormat 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_r11g11b10(eGPUTextureFormat device_format)
static ConversionType type_of_conversion_int(eGPUTextureFormat device_format)
constexpr uint32_t MASK_11_BITS
void float_to_half_array(const float *src, uint16_t *dst, size_t length)
Definition math_half.cc:221
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:257
float half_to_float(uint16_t v)
Definition math_half.cc:91
@ FLOAT
#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