UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
RHISurfaceDataConversion.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 RHISurfaceDataConversion.h: RHI surface data conversions.
5=============================================================================*/
6
7#pragma once
8
9#include "Math/Float16Color.h"
10#include "Math/PackedVector.h"
11#include "Math/Plane.h"
13#include "RHI.h"
14#include "RHITypes.h"
15
16namespace
17{
18
20struct FRHIR10G10B10A2
21{
22 uint32 R : 10;
23 uint32 G : 10;
24 uint32 B : 10;
25 uint32 A : 2;
26};
27
29struct FRHIRGBA16
30{
31 uint16 R;
32 uint16 G;
33 uint16 B;
34 uint16 A;
35};
36
38struct FRHIRG16
39{
40 uint16 R;
41 uint16 G;
42};
43
44
45inline void ConvertRawR16DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
46{
47 // e.g. shadow maps
48 for (uint32 Y = 0; Y < Height; Y++)
49 {
50 uint16* SrcPtr = (uint16*)(In + Y * SrcPitch);
51 FColor* DestPtr = Out + Y * Width;
52
53 for (uint32 X = 0; X < Width; X++)
54 {
57
59 ++SrcPtr;
60 ++DestPtr;
61 }
62 }
63}
64
65inline void ConvertRawR8G8B8A8DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
66{
67 for (uint32 Y = 0; Y < Height; Y++)
68 {
69 FColor* SrcPtr = (FColor*)(In + Y * SrcPitch);
70 FColor* DestPtr = Out + Y * Width;
71 for (uint32 X = 0; X < Width; X++)
72 {
73 *DestPtr = FColor(SrcPtr->B, SrcPtr->G, SrcPtr->R, SrcPtr->A);
74 ++SrcPtr;
75 ++DestPtr;
76 }
77 }
78}
79
80inline void ConvertRawB8G8R8A8DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
81{
82 const uint32 DstPitch = Width * sizeof(FColor);
83
84 // If source & dest pitch matches, perform a single memcpy.
85 if (DstPitch == SrcPitch)
86 {
87 FPlatformMemory::Memcpy(Out, In, Width * Height * sizeof(FColor));
88 }
89 else
90 {
92
93 // Need to copy row wise since the Pitch does not match the Width.
94 for (uint32 Y = 0; Y < Height; Y++)
95 {
96 FColor* SrcPtr = (FColor*)(In + Y * SrcPitch);
97 FColor* DestPtr = Out + Y * Width;
99 }
100 }
101}
102
104{
105 const uint32 DstPitch = Width * sizeof(FFloat16Color);
106
107 // If source & dest pitch matches, perform a single memcpy.
108 if (DstPitch == SrcPitch)
109 {
110 FPlatformMemory::Memcpy(Out, In, Width * Height * sizeof(FFloat16Color));
111 }
112 else
113 {
115
116 // Need to copy row wise since the Pitch does not match the Width.
117 for (uint32 Y = 0; Y < Height; Y++)
118 {
120 FFloat16Color* DestPtr = Out + Y * Width;
122 }
123 }
124}
125
126inline void ConvertRawR10G10B10A2DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
127{
128 for (uint32 Y = 0; Y < Height; Y++)
129 {
130 FRHIR10G10B10A2* SrcPtr = (FRHIR10G10B10A2*)(In + Y * SrcPitch);
131 FColor* DestPtr = Out + Y * Width;
132 for (uint32 X = 0; X < Width; X++)
133 {
135 SrcPtr->R,
136 SrcPtr->G,
137 SrcPtr->B,
138 SrcPtr->A
139 );
140 ++SrcPtr;
141 ++DestPtr;
142 }
143 }
144}
145
146inline void ConvertRawB10G10R10A2DataToFColor(uint32 Width, uint32 Height, uint8* In, uint32 SrcPitch, FColor* Out)
147{
148 for (uint32 Y = 0; Y < Height; Y++)
149 {
150 FRHIR10G10B10A2* SrcPtr = (FRHIR10G10B10A2*)(In + Y * SrcPitch);
151 FColor* DestPtr = Out + Y * Width;
152 for (uint32 X = 0; X < Width; X++)
153 {
155 SrcPtr->B,
156 SrcPtr->G,
157 SrcPtr->R,
158 SrcPtr->A
159 );
160 ++SrcPtr;
161 ++DestPtr;
162 }
163 }
164}
165
167{
168 FPlane MinValue(0.0f, 0.0f, 0.0f, 0.0f),
169 MaxValue(1.0f, 1.0f, 1.0f, 1.0f);
170
171 check(sizeof(FFloat16) == sizeof(uint16));
172
173 for (uint32 Y = 0; Y < Height; Y++)
174 {
175 FFloat16* SrcPtr = (FFloat16*)(In + Y * SrcPitch);
176
177 for (uint32 X = 0; X < Width; X++)
178 {
179 MinValue.X = FMath::Min<float>(SrcPtr[0], MinValue.X);
180 MinValue.Y = FMath::Min<float>(SrcPtr[1], MinValue.Y);
181 MinValue.Z = FMath::Min<float>(SrcPtr[2], MinValue.Z);
182 MinValue.W = FMath::Min<float>(SrcPtr[3], MinValue.W);
183 MaxValue.X = FMath::Max<float>(SrcPtr[0], MaxValue.X);
184 MaxValue.Y = FMath::Max<float>(SrcPtr[1], MaxValue.Y);
185 MaxValue.Z = FMath::Max<float>(SrcPtr[2], MaxValue.Z);
186 MaxValue.W = FMath::Max<float>(SrcPtr[3], MaxValue.W);
187 SrcPtr += 4;
188 }
189 }
190
191 for (uint32 Y = 0; Y < Height; Y++)
192 {
193 FFloat16* SrcPtr = (FFloat16*)(In + Y * SrcPitch);
194 FColor* DestPtr = Out + Y * Width;
195
196 for (uint32 X = 0; X < Width; X++)
197 {
198 *DestPtr =
200 (SrcPtr[0] - MinValue.X) / (MaxValue.X - MinValue.X),
201 (SrcPtr[1] - MinValue.Y) / (MaxValue.Y - MinValue.Y),
202 (SrcPtr[2] - MinValue.Z) / (MaxValue.Z - MinValue.Z),
203 (SrcPtr[3] - MinValue.W) / (MaxValue.W - MinValue.W)
205 SrcPtr += 4;
206 ++DestPtr;
207 }
208 }
209}
210
211inline void ConvertRawR11G11B10DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out, bool LinearToGamma)
212{
213 check(sizeof(FFloat3Packed) == sizeof(uint32));
214
215 for (uint32 Y = 0; Y < Height; Y++)
216 {
218 FColor* DestPtr = Out + Y * Width;
219
220 for (uint32 X = 0; X < Width; X++)
221 {
222 FLinearColor Value = (*SrcPtr).ToLinearColor();
223
225 ++SrcPtr;
226 ++DestPtr;
227 }
228 }
229}
230
231inline void ConvertRawR9G9B9E5DataToFColor(uint32 Width, uint32 Height, uint8* In, uint32 SrcPitch, FColor* Out, bool LinearToGamma)
232{
233 check(sizeof(FFloat3PackedSE) == sizeof(uint32));
234
235 for (uint32 Y = 0; Y < Height; Y++)
236 {
238 FColor* DestPtr = Out + Y * Width;
239
240 for (uint32 X = 0; X < Width; X++)
241 {
242 FLinearColor Value = (*SrcPtr).ToLinearColor();
243
245 ++SrcPtr;
246 ++DestPtr;
247 }
248 }
249}
250
251inline void ConvertRawR32G32B32A32DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out, bool LinearToGamma)
252{
253 FPlane MinValue(0.0f, 0.0f, 0.0f, 0.0f);
254 FPlane MaxValue(1.0f, 1.0f, 1.0f, 1.0f);
255
256 for (uint32 Y = 0; Y < Height; Y++)
257 {
258 float* SrcPtr = (float*)(In + Y * SrcPitch);
259
260 for (uint32 X = 0; X < Width; X++)
261 {
262 MinValue.X = FMath::Min<float>(SrcPtr[0], MinValue.X);
263 MinValue.Y = FMath::Min<float>(SrcPtr[1], MinValue.Y);
264 MinValue.Z = FMath::Min<float>(SrcPtr[2], MinValue.Z);
265 MinValue.W = FMath::Min<float>(SrcPtr[3], MinValue.W);
266 MaxValue.X = FMath::Max<float>(SrcPtr[0], MaxValue.X);
267 MaxValue.Y = FMath::Max<float>(SrcPtr[1], MaxValue.Y);
268 MaxValue.Z = FMath::Max<float>(SrcPtr[2], MaxValue.Z);
269 MaxValue.W = FMath::Max<float>(SrcPtr[3], MaxValue.W);
270 SrcPtr += 4;
271 }
272 }
273
274 for (uint32 Y = 0; Y < Height; Y++)
275 {
276 float* SrcPtr = (float*)(In + Y * SrcPitch);
277 FColor* DestPtr = Out + Y * Width;
278
279 for (uint32 X = 0; X < Width; X++)
280 {
281 *DestPtr =
283 (SrcPtr[0] - MinValue.X) / (MaxValue.X - MinValue.X),
284 (SrcPtr[1] - MinValue.Y) / (MaxValue.Y - MinValue.Y),
285 (SrcPtr[2] - MinValue.Z) / (MaxValue.Z - MinValue.Z),
286 (SrcPtr[3] - MinValue.W) / (MaxValue.W - MinValue.W)
288 SrcPtr += 4;
289 ++DestPtr;
290 }
291 }
292}
293
294
296{
297 bool bLinearToGamma = InFlags.GetLinearToGamma();
298 // Depth stencil
299 for (uint32 Y = 0; Y < Height; Y++)
300 {
301 uint32* SrcPtr = (uint32 *)In;
302 FColor* DestPtr = Out + Y * Width;
303
304 for (uint32 X = 0; X < Width; X++)
305 {
307 if (InFlags.GetOutputStencil())
308 {
309 uint8 DeviceStencil = (*SrcPtr & 0xFF000000) >> 24;
311 }
312 else
313 {
314 float DeviceZ = (*SrcPtr & 0xffffff) / (float)(1 << 24);
315 float LinearValue = FMath::Min(InFlags.ComputeNormalizedDepth(DeviceZ), 1.0f);
317 }
318
320 ++SrcPtr;
321 ++DestPtr;
322 }
323 }
324}
325
327{
328 bool bLinearToGamma = InFlags.GetLinearToGamma();
329 for (uint32 Y = 0; Y < Height; Y++)
330 {
331 float* SrcPtr = (float *)(In + Y * SrcPitch);
332 FColor* DestPtr = Out + Y * Width;
333
334 for (uint32 X = 0; X < Width; X++)
335 {
336 float DeviceZ = (*SrcPtr);
337
338 float LinearValue = FMath::Min(InFlags.ComputeNormalizedDepth(DeviceZ), 1.0f);
339
341 SrcPtr += 1; // todo: copies only depth, need to check how this format is read
342 ++DestPtr;
343 UE_LOG(LogRHI, Warning, TEXT("CPU read of R32G8X24 is not tested and may not function."));
344 }
345 }
346}
347
348inline void ConvertRawR16G16B16A16DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out, bool bLinearToGamma = false)
349{
350 for (uint32 Y = 0; Y < Height; Y++)
351 {
352 FRHIRGBA16* SrcPtr = (FRHIRGBA16*)(In + Y * SrcPitch);
353 FColor* DestPtr = Out + Y * Width;
354 for (uint32 X = 0; X < Width; X++)
355 {
361 ).ToFColor(bLinearToGamma);
362 ++SrcPtr;
363 ++DestPtr;
364 }
365 }
366}
367
368inline void ConvertRawR16G16DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
369{
370 for (uint32 Y = 0; Y < Height; Y++)
371 {
372 FRHIRG16* SrcPtr = (FRHIRG16*)(In + Y * SrcPitch);
373 FColor* DestPtr = Out + Y * Width;
374 for (uint32 X = 0; X < Width; X++)
375 {
376 *DestPtr = FColor(
379 0);
380 ++SrcPtr;
381 ++DestPtr;
382 }
383 }
384}
385
386inline void ConvertRawR8DataToFColor(uint32 Width, uint32 Height, uint8 *In, uint32 SrcPitch, FColor* Out)
387{
388 for (uint32 Y = 0; Y < Height; Y++)
389 {
390 uint8* SrcPtr = (uint8*)(In + Y * SrcPitch);
391 FColor* DestPtr = Out + Y * Width;
392 for (uint32 X = 0; X < Width; X++)
393 {
395 ++SrcPtr;
396 ++DestPtr;
397 }
398 }
399}
400
401inline void ConvertRawR8G8DataToFColor(uint32 Width, uint32 Height, uint8* In, uint32 SrcPitch, FColor* Out)
402{
403 for (uint32 Y = 0; Y < Height; Y++)
404 {
405 uint8* SrcPtr = (uint8*)(In + Y * SrcPitch);
406 FColor* DestPtr = Out + Y * Width;
407 for (uint32 X = 0; X < Width; X++)
408 {
409 *DestPtr = FColor(*SrcPtr, *(SrcPtr + 1), 0);
410 SrcPtr += 2;
411 ++DestPtr;
412 }
413 }
414}
415
417{
418 bool bLinearToGamma = InFlags.GetLinearToGamma();
419 // Depth
420 if (!InFlags.GetOutputStencil())
421 {
422 for (uint32 Y = 0; Y < Height; Y++)
423 {
424 uint32* SrcPtr = (uint32*)(In + Y * SrcPitch);
425 FColor* DestPtr = Out + Y * Width;
426
427 for (uint32 X = 0; X < Width; X++)
428 {
429 float DeviceZ = *SrcPtr;
430 float LinearValue = FMath::Min(InFlags.ComputeNormalizedDepth(DeviceZ), 1.0f);
432
433 ++DestPtr;
434 ++SrcPtr;
435 }
436 }
437 }
438 // Stencil
439 else
440 {
441 // Depth stencil
442 for (uint32 Y = 0; Y < Height; Y++)
443 {
444 uint8* SrcPtr = (uint8*)(In + Y * SrcPitch);
445 FColor* DestPtr = Out + Y * Width;
446
447 for (uint32 X = 0; X < Width; X++)
448 {
451
452 ++SrcPtr;
453 ++DestPtr;
454 }
455 }
456 }
457}
458
459// Linear functions
460
462{
463 // e.g. shadow maps
464 for (uint32 Y = 0; Y < Height; Y++)
465 {
466 uint16* SrcPtr = (uint16*)(In + Y * SrcPitch);
467 FLinearColor* DestPtr = Out + Y * Width;
468
469 for (uint32 X = 0; X < Width; X++)
470 {
472 float Value = Value16 * (1.f/0xffff);
473
475 ++SrcPtr;
476 ++DestPtr;
477 }
478 }
479}
480
482{
483 // e.g. shadow maps
484 for (uint32 Y = 0; Y < Height; Y++)
485 {
486 FFloat16 * SrcPtr = (FFloat16 *)(In + Y * SrcPitch);
487 FLinearColor* DestPtr = Out + Y * Width;
488
489 for (uint32 X = 0; X < Width; X++)
490 {
491 float Value = SrcPtr->GetFloat();
492
494 ++SrcPtr;
495 ++DestPtr;
496 }
497 }
498}
499
501{
502 // Read the data out of the buffer, converting it from ABGR to ARGB.
503 for (uint32 Y = 0; Y < Height; Y++)
504 {
505 FColor* SrcPtr = (FColor*)(In + Y * SrcPitch);
506 FLinearColor* DestPtr = Out + Y * Width;
507 for (uint32 X = 0; X < Width; X++)
508 {
509 FColor sRGBColor = FColor(SrcPtr->B, SrcPtr->G, SrcPtr->R, SrcPtr->A); // swap RB
510 // FLinearColor(FColor) does SRGB -> Linear
512 ++SrcPtr;
513 ++DestPtr;
514 }
515 }
516}
517
519{
520 for (uint32 Y = 0; Y < Height; Y++)
521 {
522 FColor* SrcPtr = (FColor*)(In + Y * SrcPitch);
523 FLinearColor* DestPtr = Out + Y * Width;
524 for (uint32 X = 0; X < Width; X++)
525 {
526 // FLinearColor(FColor) does SRGB -> Linear
528 ++SrcPtr;
529 ++DestPtr;
530 }
531 }
532}
533
535{
536 // Read the data out of the buffer, converting it from R10G10B10A2 to FLinearColor.
537 for (uint32 Y = 0; Y < Height; Y++)
538 {
539 FRHIR10G10B10A2* SrcPtr = (FRHIR10G10B10A2*)(In + Y * SrcPitch);
540 FLinearColor* DestPtr = Out + Y * Width;
541 for (uint32 X = 0; X < Width; X++)
542 {
544 (float)SrcPtr->R / 1023.0f,
545 (float)SrcPtr->G / 1023.0f,
546 (float)SrcPtr->B / 1023.0f,
547 (float)SrcPtr->A / 3.0f
548 );
549 ++SrcPtr;
550 ++DestPtr;
551 }
552 }
553}
554
556{
557 if (InFlags.GetCompressionMode() == RCM_MinMax)
558 {
559 for (uint32 Y = 0; Y < Height; Y++)
560 {
561 FFloat16* SrcPtr = (FFloat16*)(In + Y * SrcPitch);
562 FLinearColor* DestPtr = Out + Y * Width;
563
564 for (uint32 X = 0; X < Width; X++)
565 {
566 *DestPtr = FLinearColor((float)SrcPtr[0], (float)SrcPtr[1], (float)SrcPtr[2], (float)SrcPtr[3]);
567 ++DestPtr;
568 SrcPtr += 4;
569 }
570 }
571 }
572 else
573 {
574 FPlane MinValue(0.0f, 0.0f, 0.0f, 0.0f);
575 FPlane MaxValue(1.0f, 1.0f, 1.0f, 1.0f);
576
577 check(sizeof(FFloat16) == sizeof(uint16));
578
579 for (uint32 Y = 0; Y < Height; Y++)
580 {
581 FFloat16* SrcPtr = (FFloat16*)(In + Y * SrcPitch);
582
583 for (uint32 X = 0; X < Width; X++)
584 {
585 MinValue.X = FMath::Min<float>(SrcPtr[0], MinValue.X);
586 MinValue.Y = FMath::Min<float>(SrcPtr[1], MinValue.Y);
587 MinValue.Z = FMath::Min<float>(SrcPtr[2], MinValue.Z);
588 MinValue.W = FMath::Min<float>(SrcPtr[3], MinValue.W);
589 MaxValue.X = FMath::Max<float>(SrcPtr[0], MaxValue.X);
590 MaxValue.Y = FMath::Max<float>(SrcPtr[1], MaxValue.Y);
591 MaxValue.Z = FMath::Max<float>(SrcPtr[2], MaxValue.Z);
592 MaxValue.W = FMath::Max<float>(SrcPtr[3], MaxValue.W);
593 SrcPtr += 4;
594 }
595 }
596
597 for (uint32 Y = 0; Y < Height; Y++)
598 {
599 FFloat16* SrcPtr = (FFloat16*)(In + Y * SrcPitch);
600 FLinearColor* DestPtr = Out + Y * Width;
601
602 for (uint32 X = 0; X < Width; X++)
603 {
605 (SrcPtr[0] - MinValue.X) / (MaxValue.X - MinValue.X),
606 (SrcPtr[1] - MinValue.Y) / (MaxValue.Y - MinValue.Y),
607 (SrcPtr[2] - MinValue.Z) / (MaxValue.Z - MinValue.Z),
608 (SrcPtr[3] - MinValue.W) / (MaxValue.W - MinValue.W)
609 );
610 ++DestPtr;
611 SrcPtr += 4;
612 }
613 }
614 }
615}
616
617
619{
620 check(sizeof(FFloat3Packed) == sizeof(uint32));
621
622 for (uint32 Y = 0; Y < Height; Y++)
623 {
625 FLinearColor* DestPtr = Out + Y * Width;
626
627 for (uint32 X = 0; X < Width; X++)
628 {
629 *DestPtr = (*SrcPtr).ToLinearColor();
630 ++DestPtr;
631 ++SrcPtr;
632 }
633 }
634}
635
637{
638 if (InFlags.GetCompressionMode() == RCM_MinMax)
639 {
640 // Copy data directly, respecting existing min-max values
643 const int32 ImageSize = sizeof(FLinearColor) * Height * Width;
644
645 FMemory::Memcpy(DestPtr, SrcPtr, ImageSize);
646 }
647 else
648 {
649 // Normalize data
650 FPlane MinValue(0.0f, 0.0f, 0.0f, 0.0f);
651 FPlane MaxValue(1.0f, 1.0f, 1.0f, 1.0f);
652
653 for (uint32 Y = 0; Y < Height; Y++)
654 {
655 float* SrcPtr = (float*)(In + Y * SrcPitch);
656
657 for (uint32 X = 0; X < Width; X++)
658 {
659 MinValue.X = FMath::Min<float>(SrcPtr[0], MinValue.X);
660 MinValue.Y = FMath::Min<float>(SrcPtr[1], MinValue.Y);
661 MinValue.Z = FMath::Min<float>(SrcPtr[2], MinValue.Z);
662 MinValue.W = FMath::Min<float>(SrcPtr[3], MinValue.W);
663 MaxValue.X = FMath::Max<float>(SrcPtr[0], MaxValue.X);
664 MaxValue.Y = FMath::Max<float>(SrcPtr[1], MaxValue.Y);
665 MaxValue.Z = FMath::Max<float>(SrcPtr[2], MaxValue.Z);
666 MaxValue.W = FMath::Max<float>(SrcPtr[3], MaxValue.W);
667 SrcPtr += 4;
668 }
669 }
670
671 float* SrcPtr = (float*)In;
672
673 for (uint32 Y = 0; Y < Height; Y++)
674 {
675 FLinearColor* DestPtr = Out + Y * Width;
676
677 for (uint32 X = 0; X < Width; X++)
678 {
680 (SrcPtr[0] - MinValue.X) / (MaxValue.X - MinValue.X),
681 (SrcPtr[1] - MinValue.Y) / (MaxValue.Y - MinValue.Y),
682 (SrcPtr[2] - MinValue.Z) / (MaxValue.Z - MinValue.Z),
683 (SrcPtr[3] - MinValue.W) / (MaxValue.W - MinValue.W)
684 );
685 ++DestPtr;
686 SrcPtr += 4;
687 }
688 }
689 }
690}
691
693{
694 // Depth stencil
695 for (uint32 Y = 0; Y < Height; Y++)
696 {
697 uint32* SrcPtr = (uint32 *)In;
698 FLinearColor* DestPtr = Out + Y * Width;
699
700 for (uint32 X = 0; X < Width; X++)
701 {
702 float DeviceStencil = 0.0f;
703 DeviceStencil = (float)((*SrcPtr & 0xFF000000) >> 24) / 255.0f;
704 float DeviceZ = (*SrcPtr & 0xffffff) / (float)(1 << 24);
705 float LinearValue = FMath::Min(InFlags.ComputeNormalizedDepth(DeviceZ), 1.0f);
707 ++DestPtr;
708 ++SrcPtr;
709 }
710 }
711}
712
714{
715 // Depth stencil
716 for (uint32 Y = 0; Y < Height; Y++)
717 {
718 uint8* SrcStart = (uint8 *)(In + Y * SrcPitch);
719 FLinearColor* DestPtr = Out + Y * Width;
720
721 for (uint32 X = 0; X < Width; X++)
722 {
723 float DeviceZ = *((float *)(SrcStart));
724 float LinearValue = FMath::Min(InFlags.ComputeNormalizedDepth(DeviceZ), 1.0f);
725 float DeviceStencil = (float)(*(SrcStart + 4)) / 255.0f;
727 SrcStart += 8; //64 bit format with the last 24 bit ignore
728 ++DestPtr;
729 }
730 }
731}
732
734{
735 // Read the data out of the buffer, converting it to FLinearColor.
736 for (uint32 Y = 0; Y < Height; Y++)
737 {
738 FRHIRGBA16* SrcPtr = (FRHIRGBA16*)(In + Y * SrcPitch);
739 FLinearColor* DestPtr = Out + Y * Width;
740 for (uint32 X = 0; X < Width; X++)
741 {
743 (float)SrcPtr->R / 65535.0f,
744 (float)SrcPtr->G / 65535.0f,
745 (float)SrcPtr->B / 65535.0f,
746 (float)SrcPtr->A / 65535.0f
747 );
748 ++SrcPtr;
749 ++DestPtr;
750 }
751 }
752}
753
755{
756 // Read the data out of the buffer, converting it to FLinearColor.
757 for (uint32 Y = 0; Y < Height; Y++)
758 {
759 FRHIRG16* SrcPtr = (FRHIRG16*)(In + Y * SrcPitch);
760 FLinearColor* DestPtr = Out + Y * Width;
761 for (uint32 X = 0; X < Width; X++)
762 {
764 (float)SrcPtr->R / 65535.0f,
765 (float)SrcPtr->G / 65535.0f,
766 0);
767 ++SrcPtr;
768 ++DestPtr;
769 }
770 }
771}
772
774{
775 // InFlags.GetLinearToGamma() is ignored by the FLinearColor reader
776
777 // Flags RCM_MinMax means pass the values out unchanged
778 // default flags RCM_UNorm rescales them to [0,1] if they were outside that range
779
780 if (Format == PF_G16 || Format == PF_R16_UINT )
781 {
782 ConvertRawR16UDataToFLinearColor(Width, Height, In, SrcPitch, Out);
783 return true;
784 }
785 else if (Format == PF_R16F || Format == PF_R16F_FILTER)
786 {
787 ConvertRawR16FDataToFLinearColor(Width, Height, In, SrcPitch, Out);
788 return true;
789 }
790 else if (Format == PF_R8G8B8A8)
791 {
792 ConvertRawR8G8B8A8DataToFLinearColor(Width, Height, In, SrcPitch, Out);
793 return true;
794 }
795 else if (Format == PF_B8G8R8A8)
796 {
797 ConvertRawB8G8R8A8DataToFLinearColor(Width, Height, In, SrcPitch, Out);
798 return true;
799 }
800 else if (Format == PF_A2B10G10R10)
801 {
802 ConvertRawA2B10G10R10DataToFLinearColor(Width, Height, In, SrcPitch, Out);
803 return true;
804 }
805 else if (Format == PF_FloatRGBA)
806 {
808 return true;
809 }
810 else if (Format == PF_FloatRGB || Format == PF_FloatR11G11B10)
811 {
812 // assume FloatRGB == PF_FloatR11G11B10 always here
813 check( GPixelFormats[Format].BlockBytes == 4 );
814 ConvertRawR11G11B10FDataToFLinearColor(Width, Height, In, SrcPitch, Out);
815 return true;
816 }
817 else if (Format == PF_A32B32G32R32F)
818 {
820 return true;
821 }
822 else if ( Format == PF_D24 ||
823 ( (Format == PF_X24_G8 || Format == PF_DepthStencil ) && GPixelFormats[Format].BlockBytes == 4 )
824 )
825 {
826 // see CVarD3D11UseD24/CVarD3D12UseD24
827 ConvertRawR24G8DataToFLinearColor(Width, Height, In, SrcPitch, Out, InFlags);
828 return true;
829 }
830 else if ( (Format == PF_X24_G8 || Format == PF_DepthStencil ) && GPixelFormats[Format].BlockBytes > 4 )
831 {
832 // @@ D3D 11/12 different?
833
847 return true;
848 }
849 else if (Format == PF_A16B16G16R16)
850 {
851 ConvertRawR16G16B16A16DataToFLinearColor(Width, Height, In, SrcPitch, Out);
852 return true;
853 }
854 else if (Format == PF_G16R16)
855 {
856 ConvertRawR16G16DataToFLinearColor(Width, Height, In, SrcPitch, Out);
857 return true;
858 }
859 else if (Format == PF_G16R16F)
860 {
861 // Read the data out of the buffer, converting it to FLinearColor.
862 for (uint32 Y = 0; Y < Height; Y++)
863 {
864 FFloat16 * SrcPtr = (FFloat16*)(In + Y * SrcPitch);
865 FLinearColor* DestPtr = Out + Y * Width;
866 for (uint32 X = 0; X < Width; X++)
867 {
868 *DestPtr = FLinearColor( SrcPtr[0].GetFloat(), SrcPtr[1].GetFloat(), 0.f,1.f);
869 SrcPtr += 2;
870 ++DestPtr;
871 }
872 }
873 return true;
874 }
875 else if (Format == PF_G32R32F)
876 {
877 // not doing MinMax/Unorm remap here
878
879 // Read the data out of the buffer, converting it to FLinearColor.
880 for (uint32 Y = 0; Y < Height; Y++)
881 {
882 float * SrcPtr = (float *)(In + Y * SrcPitch);
883 FLinearColor* DestPtr = Out + Y * Width;
884 for (uint32 X = 0; X < Width; X++)
885 {
886 *DestPtr = FLinearColor( SrcPtr[0], SrcPtr[1], 0.f, 1.f );
887 SrcPtr += 2;
888 ++DestPtr;
889 }
890 }
891 return true;
892 }
893 else if (Format == PF_R32_FLOAT)
894 {
895 // not doing MinMax/Unorm remap here
896
897 // Read the data out of the buffer, converting it to FLinearColor.
898 for (uint32 Y = 0; Y < Height; Y++)
899 {
900 float * SrcPtr = (float *)(In + Y * SrcPitch);
901 FLinearColor* DestPtr = Out + Y * Width;
902 for (uint32 X = 0; X < Width; X++)
903 {
904 *DestPtr = FLinearColor( SrcPtr[0], 0.f, 0.f, 1.f );
905 ++SrcPtr;
906 ++DestPtr;
907 }
908 }
909 return true;
910 }
911 else
912 {
913 // not supported yet
914 check(0);
915 return false;
916 }
917}
918
920{
921 bool bLinearToGamma = InFlags.GetLinearToGamma();
922
923 if (Format == PF_G16 || Format == PF_R16_UINT)
924 {
925 ConvertRawR16DataToFColor(Width, Height, In, SrcPitch, Out);
926 return true;
927 }
928 else if (Format == PF_R8G8B8A8)
929 {
930 ConvertRawR8G8B8A8DataToFColor(Width, Height, In, SrcPitch, Out);
931 return true;
932 }
933 else if (Format == PF_B8G8R8A8)
934 {
935 ConvertRawB8G8R8A8DataToFColor(Width, Height, In, SrcPitch, Out);
936 return true;
937 }
938 else if (Format == PF_A2B10G10R10)
939 {
940 ConvertRawR10G10B10A2DataToFColor(Width, Height, In, SrcPitch, Out);
941 return true;
942 }
943 else if (Format == PF_FloatRGBA)
944 {
945 ConvertRawR16G16B16A16FDataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
946 return true;
947 }
948 else if (Format == PF_FloatRGB || Format == PF_FloatR11G11B10)
949 {
950 ConvertRawR11G11B10DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
951 return true;
952 }
953 else if (Format == PF_A32B32G32R32F)
954 {
955 ConvertRawR32G32B32A32DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
956 return true;
957 }
958 else if (Format == PF_D24 || ((Format == PF_X24_G8 || Format == PF_DepthStencil) && GPixelFormats[Format].BlockBytes == 4))
959 {
960 ConvertRawR24G8DataToFColor(Width, Height, In, SrcPitch, Out, InFlags);
961 return true;
962 }
963 else if (Format == PF_A16B16G16R16)
964 {
965 ConvertRawR16G16B16A16DataToFColor(Width, Height, In, SrcPitch, Out);
966 return true;
967 }
968 else if (Format == PF_G16R16)
969 {
970 ConvertRawR16G16DataToFColor(Width, Height, In, SrcPitch, Out);
971 return true;
972 }
973 else
974 {
975 // not supported yet
976 check(0);
977 return false;
978 }
979}
980
981#if defined(DXGI_FORMAT_DEFINED) && DXGI_FORMAT_DEFINED
982
983// switching on platform format
984// could switch on EPixelFormat instead and make this more generic
985// have to be a little careful with that as the mapping is not one to one
986
989{
990 // todo : use a helper to map all the typeless to unorm before switching here ; see DXGIUtilities
991
992 bool bLinearToGamma = InFlags.GetLinearToGamma();
993 switch (Format)
994 {
997 ConvertRawR16DataToFColor(Width, Height, In, SrcPitch, Out);
998 return true;
1002 ConvertRawR8G8B8A8DataToFColor(Width, Height, In, SrcPitch, Out);
1003 return true;
1007 ConvertRawB8G8R8A8DataToFColor(Width, Height, In, SrcPitch, Out);
1008 return true;
1010 ConvertRawR10G10B10A2DataToFColor(Width, Height, In, SrcPitch, Out);
1011 return true;
1013 ConvertRawR16G16B16A16FDataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
1014 return true;
1016 ConvertRawR11G11B10DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
1017 return true;
1019 ConvertRawR9G9B9E5DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
1020 return true;
1022 ConvertRawR32G32B32A32DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
1023 return true;
1025 ConvertRawR24G8DataToFColor(Width, Height, In, SrcPitch, Out, InFlags);
1026 return true;
1028 ConvertRawDepthStencil64DataToFColor(Width, Height, In, SrcPitch, Out, InFlags);
1029 return true;
1031 ConvertRawR16G16B16A16DataToFColor(Width, Height, In, SrcPitch, Out, bLinearToGamma);
1032 return true;
1034 ConvertRawR16G16DataToFColor(Width, Height, In, SrcPitch, Out);
1035 return true;
1037 ConvertRawR8DataToFColor(Width, Height, In, SrcPitch, Out);
1038 return true;
1040 ConvertRawR8G8DataToFColor(Width, Height, In, SrcPitch, Out);
1041 return true;
1042 default:
1043 return false;
1044 }
1045}
1046
1047#endif // DXGI_FORMAT_DEFINED
1048
1049}; // namespace
#define check(expr)
Definition AssertionMacros.h:314
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
FPixelFormatInfo GPixelFormats[PF_MAX]
Definition PixelFormat.cpp:31
EPixelFormat
Definition PixelFormat.h:16
@ PF_FloatRGBA
Definition PixelFormat.h:27
@ PF_G32R32F
Definition PixelFormat.h:34
@ PF_FloatR11G11B10
Definition PixelFormat.h:43
@ PF_R16F
Definition PixelFormat.h:38
@ PF_DepthStencil
Definition PixelFormat.h:28
@ PF_FloatRGB
Definition PixelFormat.h:26
@ PF_G16R16F
Definition PixelFormat.h:32
@ PF_G16
Definition PixelFormat.h:21
@ PF_R32_FLOAT
Definition PixelFormat.h:30
@ PF_A2B10G10R10
Definition PixelFormat.h:35
@ PF_A32B32G32R32F
Definition PixelFormat.h:18
@ PF_R16F_FILTER
Definition PixelFormat.h:39
@ PF_D24
Definition PixelFormat.h:37
@ PF_A16B16G16R16
Definition PixelFormat.h:36
@ PF_R16_UINT
Definition PixelFormat.h:49
@ PF_B8G8R8A8
Definition PixelFormat.h:19
@ PF_R8G8B8A8
Definition PixelFormat.h:54
@ PF_X24_G8
Definition PixelFormat.h:61
@ PF_G16R16
Definition PixelFormat.h:31
@ RCM_MinMax
Definition RHIDefinitions.h:805
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Float16Color.h:13
Definition Float16.h:34
Definition PackedVector.h:69
Definition PackedVector.h:16
Definition RHITypes.h:16
const TCHAR * B(bool b)
Definition SkinnedMeshComponent.cpp:386
constexpr int32 MaxValue
Definition LandscapeDataAccess.h:26
constexpr double MinValue(bool OnlyInside)
Definition Geometry.cpp:53
Definition Color.h:486
static FColor MakeRequantizeFrom1010102(int R, int G, int B, int A)
Definition Color.h:654
static float DequantizeUNorm16ToFloat(int Value16)
Definition Color.h:617
static uint8 Requantize16to8(int Value16)
Definition Color.h:638
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition GenericPlatformMemory.h:591
Definition Color.h:48
FColor ToFColor(const bool bSRGB) const
Definition Color.h:810
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160