3#include <QtGui/private/qrhi_p.h>
4#include <Gfx/Graph/RowOrder.hpp>
5#include <avnd/concepts/gfx.hpp>
6#include <Crousti/TextureFormat.hpp>
15inline void toRGB(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
17 const int N = width * height;
20 case QRhiTexture::RGBA8:
24 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
27 for(
int i = 0; i < N; i++)
29 data[write_i + 0] = data[read_i + 0];
30 data[write_i + 1] = data[read_i + 1];
31 data[write_i + 2] = data[read_i + 2];
40 case QRhiTexture::BGRA8:
44 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
47 for(
int i = 0; i < N; i++)
49 data[write_i + 0] = data[read_i + 2];
50 data[write_i + 1] = data[read_i + 1];
51 data[write_i + 2] = data[read_i + 0];
60 case QRhiTexture::RED_OR_ALPHA8:
65 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
69#if QT_VERSION > QT_VERSION_CHECK(6,8,0)
70 buf.resizeForOverwrite(N * 3);
74 for(
int i = N - 1; i >= 0; i--)
77 data[i * 3 + 0] = gray;
78 data[i * 3 + 1] = gray;
79 data[i * 3 + 2] = gray;
84 case QRhiTexture::R16:
88 QByteArray rgb(N*3, Qt::Uninitialized);
90 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
91 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
93 for(
int i = 0; i < N; i++)
95 uint8_t gray = (uint32_t(src[i]) * 255) / 65535;
97 dst[i * 3 + 0] = gray;
98 dst[i * 3 + 1] = gray;
99 dst[i * 3 + 2] = gray;
105 case QRhiTexture::RGBA16F:
109 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
110 unsigned char* data = (
unsigned char*)buf.data();
113 for(
int i = 0; i < N; i++)
115 data[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
116 data[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
117 data[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
124 case QRhiTexture::RGBA32F:
128 auto src =
reinterpret_cast<const float*
>(buf.constData());
129 unsigned char* data = (
unsigned char*)buf.data();
132 for(
int i = 0; i < N; i++)
134 data[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
135 data[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
136 data[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
143 case QRhiTexture::R16F:
148 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
149 unsigned char* dst = (
unsigned char*)buf.data();
150 for(
int i = N - 1; i >= 0; i--)
152 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
153 dst[i * 3 + 0] = gray;
154 dst[i * 3 + 1] = gray;
155 dst[i * 3 + 2] = gray;
159 case QRhiTexture::R32F:
163 auto src =
reinterpret_cast<const float*
>(buf.constData());
164 unsigned char* dst = (
unsigned char*)buf.data();
166 for(
int i = 0; i < N; i++)
168 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
169 dst[write_i + 0] = gray;
170 dst[write_i + 1] = gray;
171 dst[write_i + 2] = gray;
178#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
179 case QRhiTexture::R8UI:
183 unsigned char* data = (
unsigned char*)buf.data();
184 for(
int i = N - 1; i >= 0; i--)
187 data[i * 3 + 0] = gray;
188 data[i * 3 + 1] = gray;
189 data[i * 3 + 2] = gray;
193 case QRhiTexture::R32UI:
197 QByteArray rgb(N * 3, Qt::Uninitialized);
198 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
199 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
200 for(
int i = 0; i < N; i++)
202 uint8_t gray = (uint64_t(src[i]) * 255) / 4294967295UL;
203 dst[i * 3 + 0] = gray;
204 dst[i * 3 + 1] = gray;
205 dst[i * 3 + 2] = gray;
210 case QRhiTexture::RGBA32UI:
214 QByteArray rgb(N * 3, Qt::Uninitialized);
215 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
216 auto dst =
reinterpret_cast<uint8_t*
>(rgb.data());
219 for(
int i = 0; i < N; i++)
222 dst[write_i + 0] = src[read_i + 0] > 255 ? 255 : src[read_i + 0];
223 dst[write_i + 1] = src[read_i + 1] > 255 ? 255 : src[read_i + 1];
224 dst[write_i + 2] = src[read_i + 2] > 255 ? 255 : src[read_i + 2];
234 if(buf.size() < N * 3)
240inline void toRGBA(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
242 const int N = width * height;
245 case QRhiTexture::RGBA8:
248 case QRhiTexture::BGRA8:
251 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
252 for(
int i = 0; i < N; i++)
254 std::swap(data[i * 4 + 0], data[i * 4 + 2]);
259 case QRhiTexture::RED_OR_ALPHA8:
260 case QRhiTexture::R8:
262#if QT_VERSION > QT_VERSION_CHECK(6,8,0)
263 buf.resizeForOverwrite(N * 4);
267 uint8_t* data =
reinterpret_cast<uint8_t*
>(buf.data());
268 for(
int i = N - 1; i >= 0; i--)
271 data[i * 4 + 0] = gray;
272 data[i * 4 + 1] = gray;
273 data[i * 4 + 2] = gray;
274 data[i * 4 + 3] = 255;
279 case QRhiTexture::R16:
283 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
284 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
285 for(
int i = N - 1; i >= 0; i--)
287 uint8_t gray = (uint32_t(src[i]) * 255) / 65535;
288 dst[i * 4 + 0] = gray;
289 dst[i * 4 + 1] = gray;
290 dst[i * 4 + 2] = gray;
291 dst[i * 4 + 3] = 255;
296 case QRhiTexture::RGBA16F:
299 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
300 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
303 for(
int i = 0; i < N; i++)
305 dst[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
306 dst[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
307 dst[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
308 dst[write_i + 3] = qBound(0,
int(src[read_i + 3] * 255.0f), 255);
316 case QRhiTexture::RGBA32F:
319 auto src =
reinterpret_cast<const float*
>(buf.constData());
320 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
323 for(
int i = 0; i < N; i++)
325 dst[write_i + 0] = qBound(0,
int(src[read_i + 0] * 255.0f), 255);
326 dst[write_i + 1] = qBound(0,
int(src[read_i + 1] * 255.0f), 255);
327 dst[write_i + 2] = qBound(0,
int(src[read_i + 2] * 255.0f), 255);
328 dst[write_i + 3] = qBound(0,
int(src[read_i + 3] * 255.0f), 255);
336 case QRhiTexture::R16F:
340 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
341 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
342 for(
int i = N - 1; i >= 0; i--)
344 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
345 dst[i * 4 + 0] = gray;
346 dst[i * 4 + 1] = gray;
347 dst[i * 4 + 2] = gray;
348 dst[i * 4 + 3] = 255;
353 case QRhiTexture::R32F:
356 auto src =
reinterpret_cast<const float*
>(buf.constData());
357 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
358 for(
int i = 0; i < N; i++)
360 uint8_t gray = qBound(0,
int(src[i] * 255.0f), 255);
361 dst[i * 4 + 0] = gray;
362 dst[i * 4 + 1] = gray;
363 dst[i * 4 + 2] = gray;
364 dst[i * 4 + 3] = 255;
370#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
371 case QRhiTexture::R8UI:
375 auto data =
reinterpret_cast<uint8_t*
>(buf.data());
376 for(
int i = N - 1; i >= 0; i--)
379 data[i * 4 + 0] = gray;
380 data[i * 4 + 1] = gray;
381 data[i * 4 + 2] = gray;
382 data[i * 4 + 3] = 255;
387 case QRhiTexture::R32UI:
390 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
391 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
392 for(
int i = 0; i < N; i++)
394 uint8_t gray = (uint64_t(src[i]) * 255) / 4294967295UL;
395 dst[i * 4 + 0] = gray;
396 dst[i * 4 + 1] = gray;
397 dst[i * 4 + 2] = gray;
398 dst[i * 4 + 3] = 255;
404 case QRhiTexture::RGBA32UI:
407 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
408 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
411 for(
int i = 0; i < N; i++)
413 dst[write_i + 0] = src[read_i + 0] > 255 ? 255 : src[read_i + 0];
414 dst[write_i + 1] = src[read_i + 1] > 255 ? 255 : src[read_i + 1];
415 dst[write_i + 2] = src[read_i + 2] > 255 ? 255 : src[read_i + 2];
416 dst[write_i + 3] = src[read_i + 3] > 255 ? 255 : src[read_i + 3];
426 if(buf.size() < N * 4)
432inline void toR8(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
434 const int N = width * height;
437 case QRhiTexture::R8:
438 case QRhiTexture::RED_OR_ALPHA8:
439#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
440 case QRhiTexture::R8UI:
444 case QRhiTexture::RGBA8:
447 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
448 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
449 for(
int i = 0; i < N; i++)
451 dst[i] = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
460 case QRhiTexture::BGRA8:
463 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
464 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
465 for(
int i = 0; i < N; i++)
467 dst[i] = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
473 case QRhiTexture::R16:
476 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
477 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
478 for(
int i = 0; i < N; i++)
480 dst[i] = (uint32_t(src[i]) * 255) / 65535;
486 case QRhiTexture::RGBA16F:
489 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
490 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
491 for(
int i = 0; i < N; i++)
493 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
494 dst[i] = qBound(0,
int(gray * 255.0f), 255);
500 case QRhiTexture::RGBA32F:
503 auto src =
reinterpret_cast<const float*
>(buf.constData());
504 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
505 for(
int i = 0; i < N; i++)
507 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
508 dst[i] = qBound(0,
int(gray * 255.0f), 255);
514 case QRhiTexture::R16F:
517 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
518 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
519 for(
int i = 0; i < N; i++)
521 dst[i] = qBound(0,
int(src[i] * 255.0f), 255);
527 case QRhiTexture::R32F:
530 auto src =
reinterpret_cast<const float*
>(buf.constData());
531 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
532 for(
int i = 0; i < N; i++)
534 dst[i] = qBound(0,
int(src[i] * 255.0f), 255);
540#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
541 case QRhiTexture::R32UI:
544 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
545 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
546 for(
int i = 0; i < N; i++)
548 dst[i] = (uint64_t(src[i]) * 255) / 4294967295UL;
554 case QRhiTexture::RGBA32UI:
557 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
558 auto dst =
reinterpret_cast<uint8_t*
>(buf.data());
559 for(
int i = 0; i < N; i++)
561 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
562 dst[i] = gray > 255 ? 255 : gray;
575inline void toRGBA32F(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
577 const int N = width * height;
580 case QRhiTexture::RGBA32F:
583 case QRhiTexture::RGBA8:
587 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
588 auto dst =
reinterpret_cast<float*
>(buf.data());
589 for(
int i = N - 1; i >= 0; i--)
591 dst[i * 4 + 0] = src[i * 4 + 0] / 255.0f;
592 dst[i * 4 + 1] = src[i * 4 + 1] / 255.0f;
593 dst[i * 4 + 2] = src[i * 4 + 2] / 255.0f;
594 dst[i * 4 + 3] = src[i * 4 + 3] / 255.0f;
599 case QRhiTexture::BGRA8:
603 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
604 auto dst =
reinterpret_cast<float*
>(buf.data());
605 for(
int i = N - 1; i >= 0; i--)
607 dst[i * 4 + 0] = src[i * 4 + 2] / 255.0f;
608 dst[i * 4 + 1] = src[i * 4 + 1] / 255.0f;
609 dst[i * 4 + 2] = src[i * 4 + 0] / 255.0f;
610 dst[i * 4 + 3] = src[i * 4 + 3] / 255.0f;
615 case QRhiTexture::RED_OR_ALPHA8:
616 case QRhiTexture::R8:
620 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
621 auto dst =
reinterpret_cast<float*
>(buf.data());
622 for(
int i = N - 1; i >= 0; i--)
624 float gray = src[i] / 255.0f;
625 dst[i * 4 + 0] = gray;
626 dst[i * 4 + 1] = gray;
627 dst[i * 4 + 2] = gray;
628 dst[i * 4 + 3] = 1.0f;
633 case QRhiTexture::R16:
637 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
638 auto dst =
reinterpret_cast<float*
>(buf.data());
639 for(
int i = N - 1; i >= 0; i--)
641 float gray = src[i] / 65535.0f;
642 dst[i * 4 + 0] = gray;
643 dst[i * 4 + 1] = gray;
644 dst[i * 4 + 2] = gray;
645 dst[i * 4 + 3] = 1.0f;
650 case QRhiTexture::RGBA16F:
654 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
655 auto dst =
reinterpret_cast<float*
>(buf.data());
656 for(
int i = N - 1; i >= 0; i--)
658 dst[i * 4 + 0] = src[i * 4 + 0];
659 dst[i * 4 + 1] = src[i * 4 + 1];
660 dst[i * 4 + 2] = src[i * 4 + 2];
661 dst[i * 4 + 3] = src[i * 4 + 3];
666 case QRhiTexture::R16F:
670 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
671 auto dst =
reinterpret_cast<float*
>(buf.data());
672 for(
int i = N - 1; i >= 0; i--)
675 dst[i * 4 + 0] = gray;
676 dst[i * 4 + 1] = gray;
677 dst[i * 4 + 2] = gray;
678 dst[i * 4 + 3] = 1.0f;
683 case QRhiTexture::R32F:
687 auto src =
reinterpret_cast<const float*
>(buf.constData());
688 auto dst =
reinterpret_cast<float*
>(buf.data());
689 for(
int i = N - 1; i >= 0; i--)
692 dst[i * 4 + 0] = gray;
693 dst[i * 4 + 1] = gray;
694 dst[i * 4 + 2] = gray;
695 dst[i * 4 + 3] = 1.0f;
700#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
701 case QRhiTexture::R8UI:
705 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
706 auto dst =
reinterpret_cast<float*
>(buf.data());
707 for(
int i = N - 1; i >= 0; i--)
709 float gray = src[i] / 255.0f;
710 dst[i * 4 + 0] = gray;
711 dst[i * 4 + 1] = gray;
712 dst[i * 4 + 2] = gray;
713 dst[i * 4 + 3] = 1.0f;
718 case QRhiTexture::R32UI:
722 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
723 auto dst =
reinterpret_cast<float*
>(buf.data());
724 for(
int i = N - 1; i >= 0; i--)
726 float gray = src[i] / 4294967295.0f;
727 dst[i * 4 + 0] = gray;
728 dst[i * 4 + 1] = gray;
729 dst[i * 4 + 2] = gray;
730 dst[i * 4 + 3] = 1.0f;
735 case QRhiTexture::RGBA32UI:
738 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
739 auto dst =
reinterpret_cast<float*
>(buf.data());
740 for(
int i = 0; i < N; i++)
742 dst[i * 4 + 0] = src[i * 4 + 0] / 4294967295.0f;
743 dst[i * 4 + 1] = src[i * 4 + 1] / 4294967295.0f;
744 dst[i * 4 + 2] = src[i * 4 + 2] / 4294967295.0f;
745 dst[i * 4 + 3] = src[i * 4 + 3] / 4294967295.0f;
752 if(buf.size() < N * 16)
757inline void toR16(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
759 const int N = width * height;
762 case QRhiTexture::R16:
765 case QRhiTexture::RGBA8:
768 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
769 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
770 for(
int i = 0; i < N; i++)
773 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
774 dst[i] = (gray * 65535) / 255;
780 case QRhiTexture::BGRA8:
783 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
784 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
785 for(
int i = 0; i < N; i++)
787 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
788 dst[i] = (gray * 65535) / 255;
794 case QRhiTexture::RED_OR_ALPHA8:
795 case QRhiTexture::R8:
799 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
800 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
801 for(
int i = N - 1; i >= 0; i--)
803 dst[i] = (src[i] * 65535) / 255;
808 case QRhiTexture::RGBA16F:
811 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
812 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
813 for(
int i = 0; i < N; i++)
815 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
816 dst[i] = qBound(0,
int(gray * 65535.0f), 65535);
822 case QRhiTexture::RGBA32F:
825 auto src =
reinterpret_cast<const float*
>(buf.constData());
826 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
827 for(
int i = 0; i < N; i++)
830 float gray = (src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f);
831 dst[i] = qBound(0,
int(gray * 65535.0f), 65535);
837 case QRhiTexture::R16F:
840 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
841 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
842 for(
int i = 0; i < N; i++)
844 dst[i] = qBound(0,
int(src[i] * 65535.0f), 65535);
849 case QRhiTexture::R32F:
852 auto src =
reinterpret_cast<const float*
>(buf.constData());
853 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
854 for(
int i = 0; i < N; i++)
856 dst[i] = qBound(0,
int(src[i] * 65535.0f), 65535);
862#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
863 case QRhiTexture::R8UI:
867 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
868 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
869 for(
int i = N - 1; i >= 0; i--)
871 dst[i] = (src[i] * 65535) / 255;
876 case QRhiTexture::R32UI:
879 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
880 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
881 for(
int i = 0; i < N; i++)
883 dst[i] = (uint64_t(src[i]) * 65535) / 4294967295UL;
889 case QRhiTexture::RGBA32UI:
892 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
893 auto dst =
reinterpret_cast<uint16_t*
>(buf.data());
894 for(
int i = 0; i < N; i++)
896 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;
897 dst[i] = gray > 65535 ? 65535 : gray;
905 if(buf.size() != N * 2)
910inline void toR32F(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
912 const int N = width * height;
915 case QRhiTexture::R32F:
918 case QRhiTexture::RGBA8:
921 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
922 auto dst =
reinterpret_cast<float*
>(buf.data());
923 for(
int i = 0; i < N; i++)
925 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
926 dst[i] = gray / 255.0f;
931 case QRhiTexture::BGRA8:
934 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
935 auto dst =
reinterpret_cast<float*
>(buf.data());
936 for(
int i = 0; i < N; i++)
939 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
940 dst[i] = gray / 255.0f;
945 case QRhiTexture::RED_OR_ALPHA8:
946 case QRhiTexture::R8:
950 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
951 auto dst =
reinterpret_cast<float*
>(buf.data());
952 for(
int i = N - 1; i >= 0; i--)
954 dst[i] = src[i] / 255.0f;
959 case QRhiTexture::R16:
963 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
964 auto dst =
reinterpret_cast<float*
>(buf.data());
965 for(
int i = N - 1; i >= 0; i--)
967 dst[i] = src[i] / 65535.0f;
972 case QRhiTexture::RGBA16F:
975 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
976 auto dst =
reinterpret_cast<float*
>(buf.data());
977 for(
int i = 0; i < N; i++)
979 dst[i] = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
985 case QRhiTexture::RGBA32F:
988 auto src =
reinterpret_cast<const float*
>(buf.constData());
989 auto dst =
reinterpret_cast<float*
>(buf.data());
990 for(
int i = 0; i < N; i++)
993 dst[i] = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
999 case QRhiTexture::R16F:
1003 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1004 auto dst =
reinterpret_cast<float*
>(buf.data());
1005 for(
int i = N - 1; i >= 0; i--)
1012#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1013 case QRhiTexture::R8UI:
1017 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1018 auto dst =
reinterpret_cast<float*
>(buf.data());
1019 for(
int i = N - 1; i >= 0; i--)
1021 dst[i] = src[i] / 255.0f;
1026 case QRhiTexture::R32UI:
1029 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1030 auto dst =
reinterpret_cast<float*
>(buf.data());
1031 for(
int i = 0; i < N; i++)
1033 dst[i] = src[i] / 4294967295.0f;
1038 case QRhiTexture::RGBA32UI:
1041 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1042 auto dst =
reinterpret_cast<float*
>(buf.data());
1043 for(
int i = 0; i < N; i++)
1045 float gray = (src[i * 4 + 0] / 4294967295.0f) * 0.299f +
1046 (src[i * 4 + 1] / 4294967295.0f) * 0.587f +
1047 (src[i * 4 + 2] / 4294967295.0f) * 0.114f;
1056 if(buf.size() != N * 4)
1061inline void toR32UI(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1063 const int N = width * height;
1066#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1067 case QRhiTexture::R32UI:
1071 case QRhiTexture::RGBA8:
1074 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1075 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1076 for(
int i = 0; i < N; i++)
1078 uint32_t gray = (src[i * 4 + 0] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 2] * 114) / 1000;
1079 dst[i] = (gray * 4294967295UL) / 255;
1084 case QRhiTexture::BGRA8:
1087 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1088 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1089 for(
int i = 0; i < N; i++)
1091 uint32_t gray = (src[i * 4 + 2] * 299 + src[i * 4 + 1] * 587 + src[i * 4 + 0] * 114) / 1000;
1092 dst[i] = (gray * 4294967295UL) / 255;
1097 case QRhiTexture::RED_OR_ALPHA8:
1098 case QRhiTexture::R8:
1102 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1103 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1104 for(
int i = N - 1; i >= 0; i--)
1106 dst[i] = (src[i] * 4294967295UL) / 255;
1111 case QRhiTexture::R16:
1115 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
1116 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1117 for(
int i = N - 1; i >= 0; i--)
1119 dst[i] = (uint64_t(src[i]) * 4294967295UL) / 65535;
1124 case QRhiTexture::RGBA16F:
1127 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1128 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1129 for(
int i = 0; i < N; i++)
1132 float gray = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
1133 dst[i] = qBound(0.0f, gray * 4294967295.0f, 4294967295.0f);
1139 case QRhiTexture::RGBA32F:
1142 auto src =
reinterpret_cast<const float*
>(buf.constData());
1143 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1144 for(
int i = 0; i < N; i++)
1147 float gray = src[i * 4 + 0] * 0.299f + src[i * 4 + 1] * 0.587f + src[i * 4 + 2] * 0.114f;
1148 dst[i] = qBound(0.0f, gray * 4294967295.0f, 4294967295.0f);
1154 case QRhiTexture::R16F:
1158 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1159 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1160 for(
int i = N - 1; i >= 0; i--)
1162 float val = float(src[i]);
1163 dst[i] = qBound(0.0f, val * 4294967295.0f, 4294967295.0f);
1168 case QRhiTexture::R32F:
1171 auto src =
reinterpret_cast<const float*
>(buf.constData());
1172 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1173 for(
int i = 0; i < N; i++)
1175 dst[i] = qBound(0.0f, src[i] * 4294967295.0f, 4294967295.0f);
1180#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1181 case QRhiTexture::R8UI:
1185 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1186 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1187 for(
int i = N - 1; i >= 0; i--)
1189 dst[i] = (src[i] * 4294967295UL) / 255;
1194 case QRhiTexture::RGBA32UI:
1197 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1198 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1199 for(
int i = 0; i < N; i++)
1201 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;
1202 dst[i] = gray > 4294967295UL ? 4294967295UL : gray;
1210 if(buf.size() != N * 4)
1215inline void toRGBA32UI(QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1217 const int N = width * height;
1220#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1221 case QRhiTexture::RGBA32UI:
1225 case QRhiTexture::RGBA8:
1229 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1230 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1231 for(
int i = N - 1; i >= 0; i--)
1233 dst[i * 4 + 0] = (src[i * 4 + 0] * 4294967295UL) / 255;
1234 dst[i * 4 + 1] = (src[i * 4 + 1] * 4294967295UL) / 255;
1235 dst[i * 4 + 2] = (src[i * 4 + 2] * 4294967295UL) / 255;
1236 dst[i * 4 + 3] = (src[i * 4 + 3] * 4294967295UL) / 255;
1241 case QRhiTexture::BGRA8:
1245 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1246 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1247 for(
int i = N - 1; i >= 0; i--)
1249 dst[i * 4 + 0] = (src[i * 4 + 2] * 4294967295UL) / 255;
1250 dst[i * 4 + 1] = (src[i * 4 + 1] * 4294967295UL) / 255;
1251 dst[i * 4 + 2] = (src[i * 4 + 0] * 4294967295UL) / 255;
1252 dst[i * 4 + 3] = (src[i * 4 + 3] * 4294967295UL) / 255;
1257 case QRhiTexture::RED_OR_ALPHA8:
1258 case QRhiTexture::R8:
1262 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1263 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1264 for(
int i = N - 1; i >= 0; i--)
1266 uint32_t gray = (src[i] * 4294967295UL) / 255;
1267 dst[i * 4 + 0] = gray;
1268 dst[i * 4 + 1] = gray;
1269 dst[i * 4 + 2] = gray;
1270 dst[i * 4 + 3] = 4294967295UL;
1275 case QRhiTexture::R16:
1279 auto src =
reinterpret_cast<const uint16_t*
>(buf.constData());
1280 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1281 for(
int i = N - 1; i >= 0; i--)
1283 uint32_t gray = (uint64_t(src[i]) * 4294967295UL) / 65535;
1284 dst[i * 4 + 0] = gray;
1285 dst[i * 4 + 1] = gray;
1286 dst[i * 4 + 2] = gray;
1287 dst[i * 4 + 3] = 4294967295UL;
1292 case QRhiTexture::RGBA16F:
1296 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1297 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1298 for(
int i = N - 1; i >= 0; i--)
1300 dst[i * 4 + 0] = qBound(0.0f,
float(src[i * 4 + 0]) * 4294967295.0f, 4294967295.0f);
1301 dst[i * 4 + 1] = qBound(0.0f,
float(src[i * 4 + 1]) * 4294967295.0f, 4294967295.0f);
1302 dst[i * 4 + 2] = qBound(0.0f,
float(src[i * 4 + 2]) * 4294967295.0f, 4294967295.0f);
1303 dst[i * 4 + 3] = qBound(0.0f,
float(src[i * 4 + 3]) * 4294967295.0f, 4294967295.0f);
1308 case QRhiTexture::RGBA32F:
1311 auto src =
reinterpret_cast<const float*
>(buf.constData());
1312 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1313 for(
int i = 0; i < N; i++)
1315 dst[i * 4 + 0] = qBound(0.0f, src[i * 4 + 0] * 4294967295.0f, 4294967295.0f);
1316 dst[i * 4 + 1] = qBound(0.0f, src[i * 4 + 1] * 4294967295.0f, 4294967295.0f);
1317 dst[i * 4 + 2] = qBound(0.0f, src[i * 4 + 2] * 4294967295.0f, 4294967295.0f);
1318 dst[i * 4 + 3] = qBound(0.0f, src[i * 4 + 3] * 4294967295.0f, 4294967295.0f);
1323 case QRhiTexture::R16F:
1327 auto src =
reinterpret_cast<const qfloat16*
>(buf.constData());
1328 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1329 for(
int i = N - 1; i >= 0; i--)
1331 uint32_t gray = qBound(0.0f,
float(src[i]) * 4294967295.0f, 4294967295.0f);
1332 dst[i * 4 + 0] = gray;
1333 dst[i * 4 + 1] = gray;
1334 dst[i * 4 + 2] = gray;
1335 dst[i * 4 + 3] = 4294967295UL;
1340 case QRhiTexture::R32F:
1344 auto src =
reinterpret_cast<const float*
>(buf.constData());
1345 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1346 for(
int i = N - 1; i >= 0; i--)
1348 uint32_t gray = qBound(0.0f, src[i] * 4294967295.0f, 4294967295.0f);
1349 dst[i * 4 + 0] = gray;
1350 dst[i * 4 + 1] = gray;
1351 dst[i * 4 + 2] = gray;
1352 dst[i * 4 + 3] = 4294967295UL;
1357#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1358 case QRhiTexture::R8UI:
1362 auto src =
reinterpret_cast<const uint8_t*
>(buf.constData());
1363 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1364 for(
int i = N - 1; i >= 0; i--)
1366 uint32_t gray = (src[i] * 4294967295UL) / 255;
1367 dst[i * 4 + 0] = gray;
1368 dst[i * 4 + 1] = gray;
1369 dst[i * 4 + 2] = gray;
1370 dst[i * 4 + 3] = 4294967295UL;
1375 case QRhiTexture::R32UI:
1379 auto src =
reinterpret_cast<const uint32_t*
>(buf.constData());
1380 auto dst =
reinterpret_cast<uint32_t*
>(buf.data());
1381 for(
int i = N - 1; i >= 0; i--)
1383 uint32_t gray = src[i];
1384 dst[i * 4 + 0] = gray;
1385 dst[i * 4 + 1] = gray;
1386 dst[i * 4 + 2] = gray;
1387 dst[i * 4 + 3] = 4294967295UL;
1394 if(buf.size() < N * 16)
1399inline void unpremultiply(QRhiTexture::Format format, QByteArray& buf,
int width,
int height)
1401 const qsizetype N = qsizetype(width) * height;
1406 case QRhiTexture::RGBA8:
1407 case QRhiTexture::BGRA8:
1409 if(buf.size() < N * 4)
1411 auto* px =
reinterpret_cast<uint8_t*
>(buf.data());
1412 for(qsizetype i = 0; i < N; i++, px += 4)
1414 const int a = px[3];
1419 px[0] = px[1] = px[2] = 0;
1422 for(
int c = 0; c < 3; c++)
1423 px[c] = uint8_t(std::min(255, (px[c] * 255 + a / 2) / a));
1427 case QRhiTexture::RGBA16F:
1429 if(buf.size() < N * 8)
1431 auto* px =
reinterpret_cast<qfloat16*
>(buf.data());
1432 for(qsizetype i = 0; i < N; i++, px += 4)
1434 const float a = px[3];
1436 px[0] = px[1] = px[2] = qfloat16(0.f);
1438 for(
int c = 0; c < 3; c++)
1439 px[c] = qfloat16(
float(px[c]) / a);
1443 case QRhiTexture::RGBA32F:
1445 if(buf.size() < N * 16)
1447 auto* px =
reinterpret_cast<float*
>(buf.data());
1448 for(qsizetype i = 0; i < N; i++, px += 4)
1450 const float a = px[3];
1452 px[0] = px[1] = px[2] = 0.f;
1454 for(
int c = 0; c < 3; c++)
1464inline void convertTexture(QRhiTexture::Format out_format, QRhiTexture::Format in_format, QByteArray& buf,
int width,
int height)
1468 case QRhiTexture::BGRA8:
1469 case QRhiTexture::RGBA8:
1470 return toRGBA(in_format, buf, width, height);
1472 case QRhiTexture::RED_OR_ALPHA8:
1473 case QRhiTexture::R8:
1474#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1475 case QRhiTexture::R8UI:
1477#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
1478 case QRhiTexture::R8SI:
1480 return toR8(in_format, buf, width, height);
1482 case QRhiTexture::R16:
1483 return toR16(in_format, buf, width, height);
1485 case QRhiTexture::RGBA32F:
1486 return toRGBA32F(in_format, buf, width, height);
1488 case QRhiTexture::R32F:
1489 return toR32F(in_format, buf, width, height);
1491#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1492 case QRhiTexture::R32UI:
1493 return toR32UI(in_format, buf, width, height);
1495 case QRhiTexture::RGBA32UI:
1496 return toRGBA32UI(in_format, buf, width, height);
1499 case QRhiTexture::RG16:
1500 case QRhiTexture::RGBA16F:
1501 case QRhiTexture::RG8:
1502 case QRhiTexture::R16F:
1503#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
1504 case QRhiTexture::RGB10A2:
1506#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1507 case QRhiTexture::RG32UI:
1509 case QRhiTexture::D16:
1510 case QRhiTexture::D24:
1511 case QRhiTexture::D24S8:
1512 case QRhiTexture::D32F:
1513#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
1514 case QRhiTexture::D32FS8:
1516 case QRhiTexture::UnknownFormat:
1517 case QRhiTexture::BC1:
1518 case QRhiTexture::BC2:
1519 case QRhiTexture::BC3:
1520 case QRhiTexture::BC4:
1521 case QRhiTexture::BC5:
1522 case QRhiTexture::BC6H:
1523 case QRhiTexture::BC7:
1524 case QRhiTexture::ETC2_RGB8:
1525 case QRhiTexture::ETC2_RGB8A1:
1526 case QRhiTexture::ETC2_RGBA8:
1527 case QRhiTexture::ASTC_4x4:
1528 case QRhiTexture::ASTC_5x4:
1529 case QRhiTexture::ASTC_5x5:
1530 case QRhiTexture::ASTC_6x5:
1531 case QRhiTexture::ASTC_6x6:
1532 case QRhiTexture::ASTC_8x5:
1533 case QRhiTexture::ASTC_8x6:
1534 case QRhiTexture::ASTC_8x8:
1535 case QRhiTexture::ASTC_10x5:
1536 case QRhiTexture::ASTC_10x6:
1537 case QRhiTexture::ASTC_10x8:
1538 case QRhiTexture::ASTC_10x10:
1539 case QRhiTexture::ASTC_12x10:
1540 case QRhiTexture::ASTC_12x12:
1550inplaceMirror(
unsigned char* bytes,
int width,
int height,
int bytes_per_pixel)
1552 if(width < 1 || height <= 1)
1554 const size_t row_size = width * bytes_per_pixel;
1556 auto temp_row = (
unsigned char*)alloca(row_size);
1558 auto bottom = bytes + (height - 1) * row_size;
1562 memcpy(temp_row, top, row_size);
1563 memcpy(top, bottom, row_size);
1564 memcpy(bottom, temp_row, row_size);
1571template <avnd::cpu_texture Tex>
1572void loadInputTexture(QRhi& rhi,
auto& m_readbacks, Tex& cpu_tex,
int k)
1574 auto& rb = m_readbacks[k];
1575 auto& buf = rb.data;
1576 qsizetype bytesize{};
1577 if_possible(bytesize = cpu_tex.bytesize())
1578 else if_possible(bytesize = cpu_tex.bytesize)
1581 if(buf.size() < bytesize)
1585 cpu_tex.bytes =
nullptr;
1586 cpu_tex.changed =
false;
1591 if constexpr(
requires { std::string_view{Tex::format()}; })
1593 constexpr std::string_view fmt = Tex::format();
1595 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1599 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1600 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1603 else if constexpr(
requires { Tex::RGB; })
1605 if constexpr(avnd::cpu_dynamic_format_texture<Tex>){
1606 if(cpu_tex.format == Tex::RGB)
1607 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1610 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1611 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1616 gpp::qrhi::toRGB(rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1621 const auto dstFormat = gpp::qrhi::textureFormat(cpu_tex);
1622 gpp::qrhi::convertTexture(dstFormat, rb.format, buf, rb.pixelSize.width(), rb.pixelSize.height());
1625 using components_type = std::decay_t<
decltype(cpu_tex.bytes)>;
1626 cpu_tex.bytes =
reinterpret_cast<components_type
>(buf.data());
1631 if(cpu_tex.width * cpu_tex.height > 0)
1634 if constexpr(
requires { cpu_tex.bytes_per_pixel(); })
1635 bpp = cpu_tex.bytes_per_pixel();
1637 bpp = cpu_tex.bytes_per_pixel;
1640 reinterpret_cast<unsigned char*
>(cpu_tex.bytes), cpu_tex.width,
1641 cpu_tex.height, bpp);
1644 cpu_tex.changed =
true;
Definition Controls.hpp:30
bool uploadReversesRows(const QRhi &rhi) noexcept
Definition RowOrder.hpp:29