3#include <QtGui/private/qrhi_p.h>
4#include <avnd/concepts/gfx.hpp>
5#include <Crousti/TextureFormat.hpp>
12inline void toRGB(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
14 const int N = width * height;
17 case QRhiTexture::RGBA8:
21 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
24 for(
int i = 0; i < N; i++)
26 data[write_i + 0] = data[read_i + 0];
27 data[write_i + 1] = data[read_i + 1];
28 data[write_i + 2] = data[read_i + 2];
37 case QRhiTexture::BGRA8:
41 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
44 for(
int i = 0; i < N; i++)
46 data[write_i + 0] = data[read_i + 2];
47 data[write_i + 1] = data[read_i + 1];
48 data[write_i + 2] = data[read_i + 0];
57 case QRhiTexture::RED_OR_ALPHA8:
62 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
66#if QT_VERSION > QT_VERSION_CHECK(6,8,0)
67 buf.resizeForOverwrite(N * 3);
71 for(
int i = N - 1; i >= 0; i--)
74 data[i * 3 + 0] = gray;
75 data[i * 3 + 1] = gray;
76 data[i * 3 + 2] = gray;
81 case QRhiTexture::R16:
85 QByteArray rgb(N*3, Qt::Uninitialized);
87 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
88 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
90 for(
int i = 0; i < N; i++)
92 uint8_t gray = (uint32_t(src[i]) * 255) / 65535;
94 dst[i * 3 + 0] = gray;
95 dst[i * 3 + 1] = gray;
96 dst[i * 3 + 2] = gray;
102 case QRhiTexture::RGBA16F:
106 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
107 unsigned char* data = (
unsigned char*)buf.data();
110 for(
int i = 0; i < N; i++)
112 data[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
113 data[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
114 data[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
121 case QRhiTexture::RGBA32F:
125 auto src =
reinterpret_cast<const float*
>(buf.constData());
126 unsigned char* data = (
unsigned char*)buf.data();
129 for(
int i = 0; i < N; i++)
131 data[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
132 data[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
133 data[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
140 case QRhiTexture::R16F:
145 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
146 unsigned char* dst = (
unsigned char*)buf.data();
147 for(
int i = N - 1; i >= 0; i--)
149 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
150 dst[i * 3 + 0] = gray;
151 dst[i * 3 + 1] = gray;
152 dst[i * 3 + 2] = gray;
156 case QRhiTexture::R32F:
160 auto src =
reinterpret_cast<const float*
>(buf.constData());
161 unsigned char* dst = (
unsigned char*)buf.data();
163 for(
int i = 0; i < N; i++)
165 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
166 dst[write_i + 0] = gray;
167 dst[write_i + 1] = gray;
168 dst[write_i + 2] = gray;
175#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
176 case QRhiTexture::R8UI:
180 unsigned char* data = (
unsigned char*)buf.data();
181 for(
int i = N - 1; i >= 0; i--)
184 data[i * 3 + 0] = gray;
185 data[i * 3 + 1] = gray;
186 data[i * 3 + 2] = gray;
190 case QRhiTexture::R32UI:
194 QByteArray rgb(N * 3, Qt::Uninitialized);
195 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
196 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
197 for(
int i = 0; i < N; i++)
199 uint8_t gray = (uint64_t(src[i]) * 255) / 4294967295UL;
200 dst[i * 3 + 0] = gray;
201 dst[i * 3 + 1] = gray;
202 dst[i * 3 + 2] = gray;
207 case QRhiTexture::RGBA32UI:
211 QByteArray rgb(N * 3, Qt::Uninitialized);
212 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
213 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
216 for(
int i = 0; i < N; i++)
219 dst[write_i + 0] = src[read_i + 0] > 255 ? 255 : src[read_i + 0];
220 dst[write_i + 1] = src[read_i + 1] > 255 ? 255 : src[read_i + 1];
221 dst[write_i + 2] = src[read_i + 2] > 255 ? 255 : src[read_i + 2];
231 if(buf.size() < N * 3)
237inline void toRGBA(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
239 const int N = width * height;
242 case QRhiTexture::RGBA8:
245 case QRhiTexture::BGRA8:
248 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
249 for(
int i = 0; i < N; i++)
251 std::swap(data[i * 4 + 0], data[i * 4 + 2]);
256 case QRhiTexture::RED_OR_ALPHA8:
257 case QRhiTexture::R8:
259#if QT_VERSION > QT_VERSION_CHECK(6,8,0)
260 buf.resizeForOverwrite(N * 4);
264 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
265 for(
int i = N - 1; i >= 0; i--)
268 data[i * 4 + 0] = gray;
269 data[i * 4 + 1] = gray;
270 data[i * 4 + 2] = gray;
271 data[i * 4 + 3] = 255;
276 case QRhiTexture::R16:
280 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
281 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
282 for(
int i = N - 1; i >= 0; i--)
284 uint8_t gray = (uint32_t(src[i]) * 255) / 65535;
285 dst[i * 4 + 0] = gray;
286 dst[i * 4 + 1] = gray;
287 dst[i * 4 + 2] = gray;
288 dst[i * 4 + 3] = 255;
293 case QRhiTexture::RGBA16F:
296 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
297 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
300 for(
int i = 0; i < N; i++)
302 dst[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
303 dst[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
304 dst[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
305 dst[write_i + 3] = qBound(0,
int(src[read_i + 3] * 255.0f), 255);
313 case QRhiTexture::RGBA32F:
316 auto src =
reinterpret_cast<const float*
>(buf.constData());
317 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
320 for(
int i = 0; i < N; i++)
322 dst[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
323 dst[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
324 dst[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
325 dst[write_i + 3] = qBound(0,
int(src[read_i + 3] * 255.0f), 255);
333 case QRhiTexture::R16F:
337 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
338 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
339 for(
int i = N - 1; i >= 0; i--)
341 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
342 dst[i * 4 + 0] = gray;
343 dst[i * 4 + 1] = gray;
344 dst[i * 4 + 2] = gray;
345 dst[i * 4 + 3] = 255;
350 case QRhiTexture::R32F:
353 auto src =
reinterpret_cast<const float*
>(buf.constData());
354 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
355 for(
int i = 0; i < N; i++)
357 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
358 dst[i * 4 + 0] = gray;
359 dst[i * 4 + 1] = gray;
360 dst[i * 4 + 2] = gray;
361 dst[i * 4 + 3] = 255;
367#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
368 case QRhiTexture::R8UI:
372 auto data =
reinterpret_cast<uint8_t*
>(buf.data());
373 for(
int i = N - 1; i >= 0; i--)
376 data[i * 4 + 0] = gray;
377 data[i * 4 + 1] = gray;
378 data[i * 4 + 2] = gray;
379 data[i * 4 + 3] = 255;
384 case QRhiTexture::R32UI:
387 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
388 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
389 for(
int i = 0; i < N; i++)
391 uint8_t gray = (uint64_t(src[i]) * 255) / 4294967295UL;
392 dst[i * 4 + 0] = gray;
393 dst[i * 4 + 1] = gray;
394 dst[i * 4 + 2] = gray;
395 dst[i * 4 + 3] = 255;
401 case QRhiTexture::RGBA32UI:
404 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
405 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
408 for(
int i = 0; i < N; i++)
410 dst[write_i + 0] = src[read_i + 0] > 255 ? 255 : src[read_i + 0];
411 dst[write_i + 1] = src[read_i + 1] > 255 ? 255 : src[read_i + 1];
412 dst[write_i + 2] = src[read_i + 2] > 255 ? 255 : src[read_i + 2];
413 dst[write_i + 3] = src[read_i + 3] > 255 ? 255 : src[read_i + 3];
423 if(buf.size() < N * 4)
429inline void toR8(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
431 const int N = width * height;
434 case QRhiTexture::R8:
435 case QRhiTexture::RED_OR_ALPHA8:
436#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
437 case QRhiTexture::R8UI:
441 case QRhiTexture::RGBA8:
444 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
445 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
446 for(
int i = 0; i < N; i++)
448 dst[i] = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
457 case QRhiTexture::BGRA8:
460 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
461 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
462 for(
int i = 0; i < N; i++)
464 dst[i] = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
470 case QRhiTexture::R16:
473 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
474 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
475 for(
int i = 0; i < N; i++)
477 dst[i] = (uint32_t(src[i]) * 255) / 65535;
483 case QRhiTexture::RGBA16F:
486 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
487 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
488 for(
int i = 0; i < N; i++)
490 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
491 dst[i] = qBound(0,
int(gray * 255.0f), 255);
497 case QRhiTexture::RGBA32F:
500 auto src =
reinterpret_cast<const float*
>(buf.constData());
501 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
502 for(
int i = 0; i < N; i++)
504 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
505 dst[i] = qBound(0,
int(gray * 255.0f), 255);
511 case QRhiTexture::R16F:
514 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
515 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
516 for(
int i = 0; i < N; i++)
518 dst[i] = qBound(0,
int(src[i] * 255.0f), 255);
524 case QRhiTexture::R32F:
527 auto src =
reinterpret_cast<const float*
>(buf.constData());
528 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
529 for(
int i = 0; i < N; i++)
531 dst[i] = qBound(0,
int(src[i] * 255.0f), 255);
537#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
538 case QRhiTexture::R32UI:
541 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
542 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
543 for(
int i = 0; i < N; i++)
545 dst[i] = (uint64_t(src[i]) * 255) / 4294967295UL;
551 case QRhiTexture::RGBA32UI:
554 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
555 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
556 for(
int i = 0; i < N; i++)
558 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
559 dst[i] = gray > 255 ? 255 : gray;
572inline void toRGBA32F(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
574 const int N = width * height;
577 case QRhiTexture::RGBA32F:
580 case QRhiTexture::RGBA8:
584 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
585 auto dst =
reinterpret_cast<float*
>(buf.data());
586 for(
int i = N - 1; i >= 0; i--)
588 dst[i * 4 + 0] = src[i * 4 + 0] / 255.0f;
589 dst[i * 4 + 1] = src[i * 4 + 1] / 255.0f;
590 dst[i * 4 + 2] = src[i * 4 + 2] / 255.0f;
591 dst[i * 4 + 3] = src[i * 4 + 3] / 255.0f;
596 case QRhiTexture::BGRA8:
600 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
601 auto dst =
reinterpret_cast<float*
>(buf.data());
602 for(
int i = N - 1; i >= 0; i--)
604 dst[i * 4 + 0] = src[i * 4 + 2] / 255.0f;
605 dst[i * 4 + 1] = src[i * 4 + 1] / 255.0f;
606 dst[i * 4 + 2] = src[i * 4 + 0] / 255.0f;
607 dst[i * 4 + 3] = src[i * 4 + 3] / 255.0f;
612 case QRhiTexture::RED_OR_ALPHA8:
613 case QRhiTexture::R8:
617 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
618 auto dst =
reinterpret_cast<float*
>(buf.data());
619 for(
int i = N - 1; i >= 0; i--)
621 float gray = src[i] / 255.0f;
622 dst[i * 4 + 0] = gray;
623 dst[i * 4 + 1] = gray;
624 dst[i * 4 + 2] = gray;
625 dst[i * 4 + 3] = 1.0f;
630 case QRhiTexture::R16:
634 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
635 auto dst =
reinterpret_cast<float*
>(buf.data());
636 for(
int i = N - 1; i >= 0; i--)
638 float gray = src[i] / 65535.0f;
639 dst[i * 4 + 0] = gray;
640 dst[i * 4 + 1] = gray;
641 dst[i * 4 + 2] = gray;
642 dst[i * 4 + 3] = 1.0f;
647 case QRhiTexture::RGBA16F:
651 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
652 auto dst =
reinterpret_cast<float*
>(buf.data());
653 for(
int i = N - 1; i >= 0; i--)
655 dst[i * 4 + 0] = src[i * 4 + 0];
656 dst[i * 4 + 1] = src[i * 4 + 1];
657 dst[i * 4 + 2] = src[i * 4 + 2];
658 dst[i * 4 + 3] = src[i * 4 + 3];
663 case QRhiTexture::R16F:
667 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
668 auto dst =
reinterpret_cast<float*
>(buf.data());
669 for(
int i = N - 1; i >= 0; i--)
672 dst[i * 4 + 0] = gray;
673 dst[i * 4 + 1] = gray;
674 dst[i * 4 + 2] = gray;
675 dst[i * 4 + 3] = 1.0f;
680 case QRhiTexture::R32F:
684 auto src =
reinterpret_cast<const float*
>(buf.constData());
685 auto dst =
reinterpret_cast<float*
>(buf.data());
686 for(
int i = N - 1; i >= 0; i--)
689 dst[i * 4 + 0] = gray;
690 dst[i * 4 + 1] = gray;
691 dst[i * 4 + 2] = gray;
692 dst[i * 4 + 3] = 1.0f;
697#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
698 case QRhiTexture::R8UI:
702 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
703 auto dst =
reinterpret_cast<float*
>(buf.data());
704 for(
int i = N - 1; i >= 0; i--)
706 float gray = src[i] / 255.0f;
707 dst[i * 4 + 0] = gray;
708 dst[i * 4 + 1] = gray;
709 dst[i * 4 + 2] = gray;
710 dst[i * 4 + 3] = 1.0f;
715 case QRhiTexture::R32UI:
719 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
720 auto dst =
reinterpret_cast<float*
>(buf.data());
721 for(
int i = N - 1; i >= 0; i--)
723 float gray = src[i] / 4294967295.0f;
724 dst[i * 4 + 0] = gray;
725 dst[i * 4 + 1] = gray;
726 dst[i * 4 + 2] = gray;
727 dst[i * 4 + 3] = 1.0f;
732 case QRhiTexture::RGBA32UI:
735 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
736 auto dst =
reinterpret_cast<float*
>(buf.data());
737 for(
int i = 0; i < N; i++)
739 dst[i * 4 + 0] = src[i * 4 + 0] / 4294967295.0f;
740 dst[i * 4 + 1] = src[i * 4 + 1] / 4294967295.0f;
741 dst[i * 4 + 2] = src[i * 4 + 2] / 4294967295.0f;
742 dst[i * 4 + 3] = src[i * 4 + 3] / 4294967295.0f;
749 if(buf.size() < N * 16)
754inline void toR16(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
756 const int N = width * height;
759 case QRhiTexture::R16:
762 case QRhiTexture::RGBA8:
765 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
766 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
767 for(
int i = 0; i < N; i++)
770 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
771 dst[i] = (gray * 65535) / 255;
777 case QRhiTexture::BGRA8:
780 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
781 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
782 for(
int i = 0; i < N; i++)
784 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
785 dst[i] = (gray * 65535) / 255;
791 case QRhiTexture::RED_OR_ALPHA8:
792 case QRhiTexture::R8:
796 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
797 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
798 for(
int i = N - 1; i >= 0; i--)
800 dst[i] = (src[i] * 65535) / 255;
805 case QRhiTexture::RGBA16F:
808 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
809 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
810 for(
int i = 0; i < N; i++)
812 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
813 dst[i] = qBound(0,
int(gray * 65535.0f), 65535);
819 case QRhiTexture::RGBA32F:
822 auto src =
reinterpret_cast<const float*
>(buf.constData());
823 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
824 for(
int i = 0; i < N; i++)
827 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
828 dst[i] = qBound(0,
int(gray * 65535.0f), 65535);
834 case QRhiTexture::R16F:
837 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
838 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
839 for(
int i = 0; i < N; i++)
841 dst[i] = qBound(0,
int(src[i] * 65535.0f), 65535);
846 case QRhiTexture::R32F:
849 auto src =
reinterpret_cast<const float*
>(buf.constData());
850 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
851 for(
int i = 0; i < N; i++)
853 dst[i] = qBound(0,
int(src[i] * 65535.0f), 65535);
859#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
860 case QRhiTexture::R8UI:
864 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
865 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
866 for(
int i = N - 1; i >= 0; i--)
868 dst[i] = (src[i] * 65535) / 255;
873 case QRhiTexture::R32UI:
876 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
877 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
878 for(
int i = 0; i < N; i++)
880 dst[i] = (uint64_t(src[i]) * 65535) / 4294967295UL;
886 case QRhiTexture::RGBA32UI:
889 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
890 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
891 for(
int i = 0; i < N; i++)
893 uint64_t gray = (uint64_t(src[i * 4 + 0]) * 299 + uint64_t(src[i * 4 + 1]) * 587 + uint64_t(src[i * 4 + 2]) * 114) / 1000;
894 dst[i] = gray > 65535 ? 65535 : gray;
902 if(buf.size() != N * 2)
907inline void toR32F(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
909 const int N = width * height;
912 case QRhiTexture::R32F:
915 case QRhiTexture::RGBA8:
918 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
919 auto dst =
reinterpret_cast<float*
>(buf.data());
920 for(
int i = 0; i < N; i++)
922 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
923 dst[i] = gray / 255.0f;
928 case QRhiTexture::BGRA8:
931 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
932 auto dst =
reinterpret_cast<float*
>(buf.data());
933 for(
int i = 0; i < N; i++)
936 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
937 dst[i] = gray / 255.0f;
942 case QRhiTexture::RED_OR_ALPHA8:
943 case QRhiTexture::R8:
947 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
948 auto dst =
reinterpret_cast<float*
>(buf.data());
949 for(
int i = N - 1; i >= 0; i--)
951 dst[i] = src[i] / 255.0f;
956 case QRhiTexture::R16:
960 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
961 auto dst =
reinterpret_cast<float*
>(buf.data());
962 for(
int i = N - 1; i >= 0; i--)
964 dst[i] = src[i] / 65535.0f;
969 case QRhiTexture::RGBA16F:
972 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
973 auto dst =
reinterpret_cast<float*
>(buf.data());
974 for(
int i = 0; i < N; i++)
976 dst[i] = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
982 case QRhiTexture::RGBA32F:
985 auto src =
reinterpret_cast<const float*
>(buf.constData());
986 auto dst =
reinterpret_cast<float*
>(buf.data());
987 for(
int i = 0; i < N; i++)
990 dst[i] = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
996 case QRhiTexture::R16F:
1000 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1001 auto dst =
reinterpret_cast<float*
>(buf.data());
1002 for(
int i = N - 1; i >= 0; i--)
1009#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1010 case QRhiTexture::R8UI:
1014 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1015 auto dst =
reinterpret_cast<float*
>(buf.data());
1016 for(
int i = N - 1; i >= 0; i--)
1018 dst[i] = src[i] / 255.0f;
1023 case QRhiTexture::R32UI:
1026 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1027 auto dst =
reinterpret_cast<float*
>(buf.data());
1028 for(
int i = 0; i < N; i++)
1030 dst[i] = src[i] / 4294967295.0f;
1035 case QRhiTexture::RGBA32UI:
1038 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1039 auto dst =
reinterpret_cast<float*
>(buf.data());
1040 for(
int i = 0; i < N; i++)
1042 float gray = (src[i * 4 + 0] / 4294967295.0f) * 0.299f +
1043 (src[i * 4 + 1] / 4294967295.0f) * 0.587f +
1044 (src[i * 4 + 2] / 4294967295.0f) * 0.114f;
1053 if(buf.size() != N * 4)
1058inline void toR32UI(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1060 const int N = width * height;
1063#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1064 case QRhiTexture::R32UI:
1068 case QRhiTexture::RGBA8:
1071 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1072 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1073 for(
int i = 0; i < N; i++)
1075 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
1076 dst[i] = (gray * 4294967295UL) / 255;
1081 case QRhiTexture::BGRA8:
1084 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1085 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1086 for(
int i = 0; i < N; i++)
1088 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
1089 dst[i] = (gray * 4294967295UL) / 255;
1094 case QRhiTexture::RED_OR_ALPHA8:
1095 case QRhiTexture::R8:
1099 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1100 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1101 for(
int i = N - 1; i >= 0; i--)
1103 dst[i] = (src[i] * 4294967295UL) / 255;
1108 case QRhiTexture::R16:
1112 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
1113 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1114 for(
int i = N - 1; i >= 0; i--)
1116 dst[i] = (uint64_t(src[i]) * 4294967295UL) / 65535;
1121 case QRhiTexture::RGBA16F:
1124 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1125 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1126 for(
int i = 0; i < N; i++)
1129 float gray = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
1130 dst[i] = qBound(0.0f, gray * 4294967295.0f, 4294967295.0f);
1136 case QRhiTexture::RGBA32F:
1139 auto src =
reinterpret_cast<const float*
>(buf.constData());
1140 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1141 for(
int i = 0; i < N; i++)
1144 float gray = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
1145 dst[i] = qBound(0.0f, gray * 4294967295.0f, 4294967295.0f);
1151 case QRhiTexture::R16F:
1155 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1156 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1157 for(
int i = N - 1; i >= 0; i--)
1159 float val = float(src[i]);
1160 dst[i] = qBound(0.0f, val * 4294967295.0f, 4294967295.0f);
1165 case QRhiTexture::R32F:
1168 auto src =
reinterpret_cast<const float*
>(buf.constData());
1169 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1170 for(
int i = 0; i < N; i++)
1172 dst[i] = qBound(0.0f, src[i] * 4294967295.0f, 4294967295.0f);
1177#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1178 case QRhiTexture::R8UI:
1182 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1183 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1184 for(
int i = N - 1; i >= 0; i--)
1186 dst[i] = (src[i] * 4294967295UL) / 255;
1191 case QRhiTexture::RGBA32UI:
1194 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1195 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1196 for(
int i = 0; i < N; i++)
1198 uint64_t gray = (uint64_t(src[i * 4 + 0]) * 299 + uint64_t(src[i * 4 + 1]) * 587 + uint64_t(src[i * 4 + 2]) * 114) / 1000;
1199 dst[i] = gray > 4294967295UL ? 4294967295UL : gray;
1207 if(buf.size() != N * 4)
1212inline void toRGBA32UI(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1214 const int N = width * height;
1217#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1218 case QRhiTexture::RGBA32UI:
1222 case QRhiTexture::RGBA8:
1226 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1227 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1228 for(
int i = N - 1; i >= 0; i--)
1230 dst[i * 4 + 0] = (src[i * 4 + 0] * 4294967295UL) / 255;
1231 dst[i * 4 + 1] = (src[i * 4 + 1] * 4294967295UL) / 255;
1232 dst[i * 4 + 2] = (src[i * 4 + 2] * 4294967295UL) / 255;
1233 dst[i * 4 + 3] = (src[i * 4 + 3] * 4294967295UL) / 255;
1238 case QRhiTexture::BGRA8:
1242 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1243 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1244 for(
int i = N - 1; i >= 0; i--)
1246 dst[i * 4 + 0] = (src[i * 4 + 2] * 4294967295UL) / 255;
1247 dst[i * 4 + 1] = (src[i * 4 + 1] * 4294967295UL) / 255;
1248 dst[i * 4 + 2] = (src[i * 4 + 0] * 4294967295UL) / 255;
1249 dst[i * 4 + 3] = (src[i * 4 + 3] * 4294967295UL) / 255;
1254 case QRhiTexture::RED_OR_ALPHA8:
1255 case QRhiTexture::R8:
1259 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1260 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1261 for(
int i = N - 1; i >= 0; i--)
1263 uint32_t gray = (src[i] * 4294967295UL) / 255;
1264 dst[i * 4 + 0] = gray;
1265 dst[i * 4 + 1] = gray;
1266 dst[i * 4 + 2] = gray;
1267 dst[i * 4 + 3] = 4294967295UL;
1272 case QRhiTexture::R16:
1276 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
1277 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1278 for(
int i = N - 1; i >= 0; i--)
1280 uint32_t gray = (uint64_t(src[i]) * 4294967295UL) / 65535;
1281 dst[i * 4 + 0] = gray;
1282 dst[i * 4 + 1] = gray;
1283 dst[i * 4 + 2] = gray;
1284 dst[i * 4 + 3] = 4294967295UL;
1289 case QRhiTexture::RGBA16F:
1293 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1294 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1295 for(
int i = N - 1; i >= 0; i--)
1297 dst[i * 4 + 0] = qBound(0.0f,
float(src[i * 4 + 0]) * 4294967295.0f, 4294967295.0f);
1298 dst[i * 4 + 1] = qBound(0.0f,
float(src[i * 4 + 1]) * 4294967295.0f, 4294967295.0f);
1299 dst[i * 4 + 2] = qBound(0.0f,
float(src[i * 4 + 2]) * 4294967295.0f, 4294967295.0f);
1300 dst[i * 4 + 3] = qBound(0.0f,
float(src[i * 4 + 3]) * 4294967295.0f, 4294967295.0f);
1305 case QRhiTexture::RGBA32F:
1308 auto src =
reinterpret_cast<const float*
>(buf.constData());
1309 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1310 for(
int i = 0; i < N; i++)
1312 dst[i * 4 + 0] = qBound(0.0f, src[i * 4 + 0] * 4294967295.0f, 4294967295.0f);
1313 dst[i * 4 + 1] = qBound(0.0f, src[i * 4 + 1] * 4294967295.0f, 4294967295.0f);
1314 dst[i * 4 + 2] = qBound(0.0f, src[i * 4 + 2] * 4294967295.0f, 4294967295.0f);
1315 dst[i * 4 + 3] = qBound(0.0f, src[i * 4 + 3] * 4294967295.0f, 4294967295.0f);
1320 case QRhiTexture::R16F:
1324 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1325 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1326 for(
int i = N - 1; i >= 0; i--)
1328 uint32_t gray = qBound(0.0f,
float(src[i]) * 4294967295.0f, 4294967295.0f);
1329 dst[i * 4 + 0] = gray;
1330 dst[i * 4 + 1] = gray;
1331 dst[i * 4 + 2] = gray;
1332 dst[i * 4 + 3] = 4294967295UL;
1337 case QRhiTexture::R32F:
1341 auto src =
reinterpret_cast<const float*
>(buf.constData());
1342 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1343 for(
int i = N - 1; i >= 0; i--)
1345 uint32_t gray = qBound(0.0f, src[i] * 4294967295.0f, 4294967295.0f);
1346 dst[i * 4 + 0] = gray;
1347 dst[i * 4 + 1] = gray;
1348 dst[i * 4 + 2] = gray;
1349 dst[i * 4 + 3] = 4294967295UL;
1354#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1355 case QRhiTexture::R8UI:
1359 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1360 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1361 for(
int i = N - 1; i >= 0; i--)
1363 uint32_t gray = (src[i] * 4294967295UL) / 255;
1364 dst[i * 4 + 0] = gray;
1365 dst[i * 4 + 1] = gray;
1366 dst[i * 4 + 2] = gray;
1367 dst[i * 4 + 3] = 4294967295UL;
1372 case QRhiTexture::R32UI:
1376 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1377 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1378 for(
int i = N - 1; i >= 0; i--)
1380 uint32_t gray = src[i];
1381 dst[i * 4 + 0] = gray;
1382 dst[i * 4 + 1] = gray;
1383 dst[i * 4 + 2] = gray;
1384 dst[i * 4 + 3] = 4294967295UL;
1391 if(buf.size() < N * 16)
1396inline void convertTexture(QRhiTexture::Format out_format, QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1400 case QRhiTexture::BGRA8:
1401 case QRhiTexture::RGBA8:
1402 return toRGBA(in_format, buf, width, height);
1404 case QRhiTexture::RED_OR_ALPHA8:
1405 case QRhiTexture::R8:
1406#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1407 case QRhiTexture::R8UI:
1409 return toR8(in_format, buf, width, height);
1411 case QRhiTexture::R16:
1412 return toR16(in_format, buf, width, height);
1414 case QRhiTexture::RGBA32F:
1415 return toRGBA32F(in_format, buf, width, height);
1417 case QRhiTexture::R32F:
1418 return toR32F(in_format, buf, width, height);
1420#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1421 case QRhiTexture::R32UI:
1422 return toR32UI(in_format, buf, width, height);
1424 case QRhiTexture::RGBA32UI:
1425 return toRGBA32UI(in_format, buf, width, height);
1428 case QRhiTexture::RG16:
1429 case QRhiTexture::RGBA16F:
1430 case QRhiTexture::RG8:
1431 case QRhiTexture::R16F:
1432#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
1433 case QRhiTexture::RGB10A2:
1435#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1436 case QRhiTexture::RG32UI:
1438 case QRhiTexture::D16:
1439 case QRhiTexture::D24:
1440 case QRhiTexture::D24S8:
1441 case QRhiTexture::D32F:
1442#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1443 case QRhiTexture::D32FS8:
1445 case QRhiTexture::UnknownFormat:
1446 case QRhiTexture::BC1:
1447 case QRhiTexture::BC2:
1448 case QRhiTexture::BC3:
1449 case QRhiTexture::BC4:
1450 case QRhiTexture::BC5:
1451 case QRhiTexture::BC6H:
1452 case QRhiTexture::BC7:
1453 case QRhiTexture::ETC2_RGB8:
1454 case QRhiTexture::ETC2_RGB8A1:
1455 case QRhiTexture::ETC2_RGBA8:
1456 case QRhiTexture::ASTC_4x4:
1457 case QRhiTexture::ASTC_5x4:
1458 case QRhiTexture::ASTC_5x5:
1459 case QRhiTexture::ASTC_6x5:
1460 case QRhiTexture::ASTC_6x6:
1461 case QRhiTexture::ASTC_8x5:
1462 case QRhiTexture::ASTC_8x6:
1463 case QRhiTexture::ASTC_8x8:
1464 case QRhiTexture::ASTC_10x5:
1465 case QRhiTexture::ASTC_10x6:
1466 case QRhiTexture::ASTC_10x8:
1467 case QRhiTexture::ASTC_10x10:
1468 case QRhiTexture::ASTC_12x10:
1469 case QRhiTexture::ASTC_12x12:
1479inplaceMirror(
unsigned char* bytes,
int width,
int height,
int bytes_per_pixel)
1481 if(width < 1 || height <= 1)
1483 const size_t row_size = width * bytes_per_pixel;
1485 auto temp_row = (
unsigned char*)alloca(row_size);
1487 auto bottom = bytes + (height - 1) * row_size;
1491 memcpy(temp_row, top, row_size);
1492 memcpy(top, bottom, row_size);
1493 memcpy(bottom, temp_row, row_size);
1500template <avnd::cpu_texture Tex>
1501void loadInputTexture(QRhi& rhi,
auto& m_readbacks, Tex& cpu_tex,
int k)
1503 auto& rb = m_readbacks[k];
1504 auto& buf = rb.data;
1505 qsizetype bytesize{};
1506 if_possible(bytesize = cpu_tex.bytesize())
1507 else if_possible(bytesize = cpu_tex.bytesize)
1510 if(buf.size() < bytesize)
1512 cpu_tex.bytes =
nullptr;
1517 if constexpr(
requires { std::string_view{Tex::format()}; })
1519 constexpr std::string_view fmt = Tex::format();
1521 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1525 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1526 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1529 else if constexpr(
requires { Tex::RGB; })
1531 if constexpr(avnd::cpu_dynamic_format_texture<Tex>){
1532 if(cpu_tex.format == Tex::RGB)
1533 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1536 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1537 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1542 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1547 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1548 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1551 using components_type = std::decay_t<
decltype(cpu_tex.bytes)>;
1552 cpu_tex.bytes =
reinterpret_cast<components_type
>(buf.data());
1554 if(rhi.isYUpInNDC())
1555 if(cpu_tex.width * cpu_tex.height > 0)
1557 reinterpret_cast<unsigned char*
>(cpu_tex.bytes), cpu_tex.width,
1558 cpu_tex.height, cpu_tex.bytes_per_pixel);
1560 cpu_tex.changed =
true;
Definition Factories.hpp:19