1 //
2 // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // angle_loadimage.cpp: Defines image loading functions.
8
9 #include "image_util/loadimage.h"
10
11 #include "common/mathutil.h"
12 #include "common/platform.h"
13 #include "image_util/imageformats.h"
14
15 namespace angle
16 {
17 ImageLoadContext::ImageLoadContext() = default;
18 ImageLoadContext::~ImageLoadContext() = default;
19 ImageLoadContext::ImageLoadContext(const ImageLoadContext &other) = default;
20
LoadA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)21 void LoadA8ToRGBA8(const ImageLoadContext &context,
22 size_t width,
23 size_t height,
24 size_t depth,
25 const uint8_t *input,
26 size_t inputRowPitch,
27 size_t inputDepthPitch,
28 uint8_t *output,
29 size_t outputRowPitch,
30 size_t outputDepthPitch)
31 {
32 #if defined(ANGLE_USE_SSE)
33 if (gl::supportsSSE2())
34 {
35 __m128i zeroWide = _mm_setzero_si128();
36
37 for (size_t z = 0; z < depth; z++)
38 {
39 for (size_t y = 0; y < height; y++)
40 {
41 const uint8_t *source =
42 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
43 uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch,
44 outputDepthPitch);
45
46 size_t x = 0;
47
48 // Make output writes aligned
49 for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++)
50 {
51 dest[x] = static_cast<uint32_t>(source[x]) << 24;
52 }
53
54 for (; x + 7 < width; x += 8)
55 {
56 __m128i sourceData =
57 _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&source[x]));
58 // Interleave each byte to 16bit, make the lower byte to zero
59 sourceData = _mm_unpacklo_epi8(zeroWide, sourceData);
60 // Interleave each 16bit to 32bit, make the lower 16bit to zero
61 __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData);
62 __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData);
63
64 _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), lo);
65 _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x + 4]), hi);
66 }
67
68 // Handle the remainder
69 for (; x < width; x++)
70 {
71 dest[x] = static_cast<uint32_t>(source[x]) << 24;
72 }
73 }
74 }
75
76 return;
77 }
78 #endif
79
80 for (size_t z = 0; z < depth; z++)
81 {
82 for (size_t y = 0; y < height; y++)
83 {
84 const uint8_t *source =
85 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
86 uint32_t *dest =
87 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
88 for (size_t x = 0; x < width; x++)
89 {
90 dest[x] = static_cast<uint32_t>(source[x]) << 24;
91 }
92 }
93 }
94 }
95
LoadA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)96 void LoadA8ToBGRA8(const ImageLoadContext &context,
97 size_t width,
98 size_t height,
99 size_t depth,
100 const uint8_t *input,
101 size_t inputRowPitch,
102 size_t inputDepthPitch,
103 uint8_t *output,
104 size_t outputRowPitch,
105 size_t outputDepthPitch)
106 {
107 // Same as loading to RGBA
108 LoadA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
109 outputRowPitch, outputDepthPitch);
110 }
111
LoadA32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)112 void LoadA32FToRGBA32F(const ImageLoadContext &context,
113 size_t width,
114 size_t height,
115 size_t depth,
116 const uint8_t *input,
117 size_t inputRowPitch,
118 size_t inputDepthPitch,
119 uint8_t *output,
120 size_t outputRowPitch,
121 size_t outputDepthPitch)
122 {
123 for (size_t z = 0; z < depth; z++)
124 {
125 for (size_t y = 0; y < height; y++)
126 {
127 const float *source =
128 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
129 float *dest =
130 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
131 for (size_t x = 0; x < width; x++)
132 {
133 dest[4 * x + 0] = 0.0f;
134 dest[4 * x + 1] = 0.0f;
135 dest[4 * x + 2] = 0.0f;
136 dest[4 * x + 3] = source[x];
137 }
138 }
139 }
140 }
141
LoadA16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)142 void LoadA16FToRGBA16F(const ImageLoadContext &context,
143 size_t width,
144 size_t height,
145 size_t depth,
146 const uint8_t *input,
147 size_t inputRowPitch,
148 size_t inputDepthPitch,
149 uint8_t *output,
150 size_t outputRowPitch,
151 size_t outputDepthPitch)
152 {
153 for (size_t z = 0; z < depth; z++)
154 {
155 for (size_t y = 0; y < height; y++)
156 {
157 const uint16_t *source =
158 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
159 uint16_t *dest =
160 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
161 for (size_t x = 0; x < width; x++)
162 {
163 dest[4 * x + 0] = 0;
164 dest[4 * x + 1] = 0;
165 dest[4 * x + 2] = 0;
166 dest[4 * x + 3] = source[x];
167 }
168 }
169 }
170 }
171
LoadL8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)172 void LoadL8ToRGBA8(const ImageLoadContext &context,
173 size_t width,
174 size_t height,
175 size_t depth,
176 const uint8_t *input,
177 size_t inputRowPitch,
178 size_t inputDepthPitch,
179 uint8_t *output,
180 size_t outputRowPitch,
181 size_t outputDepthPitch)
182 {
183 for (size_t z = 0; z < depth; z++)
184 {
185 for (size_t y = 0; y < height; y++)
186 {
187 const uint8_t *source =
188 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
189 uint8_t *dest =
190 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
191 for (size_t x = 0; x < width; x++)
192 {
193 uint8_t sourceVal = source[x];
194 dest[4 * x + 0] = sourceVal;
195 dest[4 * x + 1] = sourceVal;
196 dest[4 * x + 2] = sourceVal;
197 dest[4 * x + 3] = 0xFF;
198 }
199 }
200 }
201 }
202
LoadL8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)203 void LoadL8ToBGRA8(const ImageLoadContext &context,
204 size_t width,
205 size_t height,
206 size_t depth,
207 const uint8_t *input,
208 size_t inputRowPitch,
209 size_t inputDepthPitch,
210 uint8_t *output,
211 size_t outputRowPitch,
212 size_t outputDepthPitch)
213 {
214 // Same as loading to RGBA
215 LoadL8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
216 outputRowPitch, outputDepthPitch);
217 }
218
LoadL32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)219 void LoadL32FToRGBA32F(const ImageLoadContext &context,
220 size_t width,
221 size_t height,
222 size_t depth,
223 const uint8_t *input,
224 size_t inputRowPitch,
225 size_t inputDepthPitch,
226 uint8_t *output,
227 size_t outputRowPitch,
228 size_t outputDepthPitch)
229 {
230 for (size_t z = 0; z < depth; z++)
231 {
232 for (size_t y = 0; y < height; y++)
233 {
234 const float *source =
235 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
236 float *dest =
237 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
238 for (size_t x = 0; x < width; x++)
239 {
240 dest[4 * x + 0] = source[x];
241 dest[4 * x + 1] = source[x];
242 dest[4 * x + 2] = source[x];
243 dest[4 * x + 3] = 1.0f;
244 }
245 }
246 }
247 }
248
LoadL16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)249 void LoadL16FToRGBA16F(const ImageLoadContext &context,
250 size_t width,
251 size_t height,
252 size_t depth,
253 const uint8_t *input,
254 size_t inputRowPitch,
255 size_t inputDepthPitch,
256 uint8_t *output,
257 size_t outputRowPitch,
258 size_t outputDepthPitch)
259 {
260 for (size_t z = 0; z < depth; z++)
261 {
262 for (size_t y = 0; y < height; y++)
263 {
264 const uint16_t *source =
265 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
266 uint16_t *dest =
267 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
268 for (size_t x = 0; x < width; x++)
269 {
270 dest[4 * x + 0] = source[x];
271 dest[4 * x + 1] = source[x];
272 dest[4 * x + 2] = source[x];
273 dest[4 * x + 3] = gl::Float16One;
274 }
275 }
276 }
277 }
278
LoadLA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)279 void LoadLA8ToRGBA8(const ImageLoadContext &context,
280 size_t width,
281 size_t height,
282 size_t depth,
283 const uint8_t *input,
284 size_t inputRowPitch,
285 size_t inputDepthPitch,
286 uint8_t *output,
287 size_t outputRowPitch,
288 size_t outputDepthPitch)
289 {
290 for (size_t z = 0; z < depth; z++)
291 {
292 for (size_t y = 0; y < height; y++)
293 {
294 const uint8_t *source =
295 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
296 uint8_t *dest =
297 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
298 for (size_t x = 0; x < width; x++)
299 {
300 dest[4 * x + 0] = source[2 * x + 0];
301 dest[4 * x + 1] = source[2 * x + 0];
302 dest[4 * x + 2] = source[2 * x + 0];
303 dest[4 * x + 3] = source[2 * x + 1];
304 }
305 }
306 }
307 }
308
LoadLA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)309 void LoadLA8ToBGRA8(const ImageLoadContext &context,
310 size_t width,
311 size_t height,
312 size_t depth,
313 const uint8_t *input,
314 size_t inputRowPitch,
315 size_t inputDepthPitch,
316 uint8_t *output,
317 size_t outputRowPitch,
318 size_t outputDepthPitch)
319 {
320 // Same as loading to RGBA
321 LoadLA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
322 outputRowPitch, outputDepthPitch);
323 }
324
LoadLA32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)325 void LoadLA32FToRGBA32F(const ImageLoadContext &context,
326 size_t width,
327 size_t height,
328 size_t depth,
329 const uint8_t *input,
330 size_t inputRowPitch,
331 size_t inputDepthPitch,
332 uint8_t *output,
333 size_t outputRowPitch,
334 size_t outputDepthPitch)
335 {
336 for (size_t z = 0; z < depth; z++)
337 {
338 for (size_t y = 0; y < height; y++)
339 {
340 const float *source =
341 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
342 float *dest =
343 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
344 for (size_t x = 0; x < width; x++)
345 {
346 dest[4 * x + 0] = source[2 * x + 0];
347 dest[4 * x + 1] = source[2 * x + 0];
348 dest[4 * x + 2] = source[2 * x + 0];
349 dest[4 * x + 3] = source[2 * x + 1];
350 }
351 }
352 }
353 }
354
LoadLA16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)355 void LoadLA16FToRGBA16F(const ImageLoadContext &context,
356 size_t width,
357 size_t height,
358 size_t depth,
359 const uint8_t *input,
360 size_t inputRowPitch,
361 size_t inputDepthPitch,
362 uint8_t *output,
363 size_t outputRowPitch,
364 size_t outputDepthPitch)
365 {
366 for (size_t z = 0; z < depth; z++)
367 {
368 for (size_t y = 0; y < height; y++)
369 {
370 const uint16_t *source =
371 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
372 uint16_t *dest =
373 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
374 for (size_t x = 0; x < width; x++)
375 {
376 dest[4 * x + 0] = source[2 * x + 0];
377 dest[4 * x + 1] = source[2 * x + 0];
378 dest[4 * x + 2] = source[2 * x + 0];
379 dest[4 * x + 3] = source[2 * x + 1];
380 }
381 }
382 }
383 }
384
LoadRGB8ToBGR565(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)385 void LoadRGB8ToBGR565(const ImageLoadContext &context,
386 size_t width,
387 size_t height,
388 size_t depth,
389 const uint8_t *input,
390 size_t inputRowPitch,
391 size_t inputDepthPitch,
392 uint8_t *output,
393 size_t outputRowPitch,
394 size_t outputDepthPitch)
395 {
396 for (size_t z = 0; z < depth; z++)
397 {
398 for (size_t y = 0; y < height; y++)
399 {
400 const uint8_t *source =
401 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
402 uint16_t *dest =
403 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
404 for (size_t x = 0; x < width; x++)
405 {
406 uint8_t r8 = source[x * 3 + 0];
407 uint8_t g8 = source[x * 3 + 1];
408 uint8_t b8 = source[x * 3 + 2];
409 auto r5 = static_cast<uint16_t>(r8 >> 3);
410 auto g6 = static_cast<uint16_t>(g8 >> 2);
411 auto b5 = static_cast<uint16_t>(b8 >> 3);
412 dest[x] = (r5 << 11) | (g6 << 5) | b5;
413 }
414 }
415 }
416 }
417
LoadRGB565ToBGR565(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)418 void LoadRGB565ToBGR565(const ImageLoadContext &context,
419 size_t width,
420 size_t height,
421 size_t depth,
422 const uint8_t *input,
423 size_t inputRowPitch,
424 size_t inputDepthPitch,
425 uint8_t *output,
426 size_t outputRowPitch,
427 size_t outputDepthPitch)
428 {
429 for (size_t z = 0; z < depth; z++)
430 {
431 for (size_t y = 0; y < height; y++)
432 {
433 const uint16_t *source =
434 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
435 uint16_t *dest =
436 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
437 for (size_t x = 0; x < width; x++)
438 {
439 // The GL type RGB is packed with with red in the MSB, while the D3D11 type BGR
440 // is packed with red in the LSB
441 auto rgb = source[x];
442 uint16_t r5 = gl::getShiftedData<5, 11>(rgb);
443 uint16_t g6 = gl::getShiftedData<6, 5>(rgb);
444 uint16_t b5 = gl::getShiftedData<5, 0>(rgb);
445 dest[x] = (r5 << 11) | (g6 << 5) | b5;
446 }
447 }
448 }
449 }
450
LoadRGB8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)451 void LoadRGB8ToBGRX8(const ImageLoadContext &context,
452 size_t width,
453 size_t height,
454 size_t depth,
455 const uint8_t *input,
456 size_t inputRowPitch,
457 size_t inputDepthPitch,
458 uint8_t *output,
459 size_t outputRowPitch,
460 size_t outputDepthPitch)
461 {
462 for (size_t z = 0; z < depth; z++)
463 {
464 for (size_t y = 0; y < height; y++)
465 {
466 const uint8_t *source =
467 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
468 uint8_t *dest =
469 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
470 for (size_t x = 0; x < width; x++)
471 {
472 dest[4 * x + 0] = source[x * 3 + 2];
473 dest[4 * x + 1] = source[x * 3 + 1];
474 dest[4 * x + 2] = source[x * 3 + 0];
475 dest[4 * x + 3] = 0xFF;
476 }
477 }
478 }
479 }
480
LoadRG8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)481 void LoadRG8ToBGRX8(const ImageLoadContext &context,
482 size_t width,
483 size_t height,
484 size_t depth,
485 const uint8_t *input,
486 size_t inputRowPitch,
487 size_t inputDepthPitch,
488 uint8_t *output,
489 size_t outputRowPitch,
490 size_t outputDepthPitch)
491 {
492 for (size_t z = 0; z < depth; z++)
493 {
494 for (size_t y = 0; y < height; y++)
495 {
496 const uint8_t *source =
497 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
498 uint8_t *dest =
499 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
500 for (size_t x = 0; x < width; x++)
501 {
502 dest[4 * x + 0] = 0x00;
503 dest[4 * x + 1] = source[x * 2 + 1];
504 dest[4 * x + 2] = source[x * 2 + 0];
505 dest[4 * x + 3] = 0xFF;
506 }
507 }
508 }
509 }
510
LoadR8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)511 void LoadR8ToBGRX8(const ImageLoadContext &context,
512 size_t width,
513 size_t height,
514 size_t depth,
515 const uint8_t *input,
516 size_t inputRowPitch,
517 size_t inputDepthPitch,
518 uint8_t *output,
519 size_t outputRowPitch,
520 size_t outputDepthPitch)
521 {
522 for (size_t z = 0; z < depth; z++)
523 {
524 for (size_t y = 0; y < height; y++)
525 {
526 const uint8_t *source =
527 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
528 uint8_t *dest =
529 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
530 for (size_t x = 0; x < width; x++)
531 {
532 dest[4 * x + 0] = 0x00;
533 dest[4 * x + 1] = 0x00;
534 dest[4 * x + 2] = source[x];
535 dest[4 * x + 3] = 0xFF;
536 }
537 }
538 }
539 }
540
LoadR5G6B5ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)541 void LoadR5G6B5ToBGRA8(const ImageLoadContext &context,
542 size_t width,
543 size_t height,
544 size_t depth,
545 const uint8_t *input,
546 size_t inputRowPitch,
547 size_t inputDepthPitch,
548 uint8_t *output,
549 size_t outputRowPitch,
550 size_t outputDepthPitch)
551 {
552 for (size_t z = 0; z < depth; z++)
553 {
554 for (size_t y = 0; y < height; y++)
555 {
556 const uint16_t *source =
557 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
558 uint8_t *dest =
559 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
560 for (size_t x = 0; x < width; x++)
561 {
562 uint16_t rgb = source[x];
563 dest[4 * x + 0] =
564 static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2));
565 dest[4 * x + 1] =
566 static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9));
567 dest[4 * x + 2] =
568 static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13));
569 dest[4 * x + 3] = 0xFF;
570 }
571 }
572 }
573 }
574
LoadR5G6B5ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)575 void LoadR5G6B5ToRGBA8(const ImageLoadContext &context,
576 size_t width,
577 size_t height,
578 size_t depth,
579 const uint8_t *input,
580 size_t inputRowPitch,
581 size_t inputDepthPitch,
582 uint8_t *output,
583 size_t outputRowPitch,
584 size_t outputDepthPitch)
585 {
586 for (size_t z = 0; z < depth; z++)
587 {
588 for (size_t y = 0; y < height; y++)
589 {
590 const uint16_t *source =
591 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
592 uint8_t *dest =
593 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
594 for (size_t x = 0; x < width; x++)
595 {
596 uint16_t rgb = source[x];
597 dest[4 * x + 0] =
598 static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13));
599 dest[4 * x + 1] =
600 static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9));
601 dest[4 * x + 2] =
602 static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2));
603 dest[4 * x + 3] = 0xFF;
604 }
605 }
606 }
607 }
608
LoadRGBA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)609 void LoadRGBA8ToBGRA8(const ImageLoadContext &context,
610 size_t width,
611 size_t height,
612 size_t depth,
613 const uint8_t *input,
614 size_t inputRowPitch,
615 size_t inputDepthPitch,
616 uint8_t *output,
617 size_t outputRowPitch,
618 size_t outputDepthPitch)
619 {
620 #if defined(ANGLE_USE_SSE)
621 if (gl::supportsSSE2())
622 {
623 __m128i brMask = _mm_set1_epi32(0x00ff00ff);
624
625 for (size_t z = 0; z < depth; z++)
626 {
627 for (size_t y = 0; y < height; y++)
628 {
629 const uint32_t *source =
630 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
631 uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch,
632 outputDepthPitch);
633
634 size_t x = 0;
635
636 // Make output writes aligned
637 for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
638 {
639 uint32_t rgba = source[x];
640 dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
641 }
642
643 for (; x + 3 < width; x += 4)
644 {
645 __m128i sourceData =
646 _mm_loadu_si128(reinterpret_cast<const __m128i *>(&source[x]));
647 // Mask out g and a, which don't change
648 __m128i gaComponents = _mm_andnot_si128(brMask, sourceData);
649 // Mask out b and r
650 __m128i brComponents = _mm_and_si128(sourceData, brMask);
651 // Swap b and r
652 __m128i brSwapped = _mm_shufflehi_epi16(
653 _mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)),
654 _MM_SHUFFLE(2, 3, 0, 1));
655 __m128i result = _mm_or_si128(gaComponents, brSwapped);
656 _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), result);
657 }
658
659 // Perform leftover writes
660 for (; x < width; x++)
661 {
662 uint32_t rgba = source[x];
663 dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
664 }
665 }
666 }
667
668 return;
669 }
670 #endif
671
672 for (size_t z = 0; z < depth; z++)
673 {
674 for (size_t y = 0; y < height; y++)
675 {
676 const uint32_t *source =
677 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
678 uint32_t *dest =
679 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
680 for (size_t x = 0; x < width; x++)
681 {
682 uint32_t rgba = source[x];
683 dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
684 }
685 }
686 }
687 }
688
LoadRGBA8ToBGRA4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)689 void LoadRGBA8ToBGRA4(const ImageLoadContext &context,
690 size_t width,
691 size_t height,
692 size_t depth,
693 const uint8_t *input,
694 size_t inputRowPitch,
695 size_t inputDepthPitch,
696 uint8_t *output,
697 size_t outputRowPitch,
698 size_t outputDepthPitch)
699 {
700 for (size_t z = 0; z < depth; z++)
701 {
702 for (size_t y = 0; y < height; y++)
703 {
704 const uint32_t *source =
705 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
706 uint16_t *dest =
707 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
708 for (size_t x = 0; x < width; x++)
709 {
710 uint32_t rgba8 = source[x];
711 auto r4 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4);
712 auto g4 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12);
713 auto b4 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20);
714 auto a4 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28);
715 dest[x] = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4;
716 }
717 }
718 }
719 }
720
LoadRGBA8ToRGBA4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)721 void LoadRGBA8ToRGBA4(const ImageLoadContext &context,
722 size_t width,
723 size_t height,
724 size_t depth,
725 const uint8_t *input,
726 size_t inputRowPitch,
727 size_t inputDepthPitch,
728 uint8_t *output,
729 size_t outputRowPitch,
730 size_t outputDepthPitch)
731 {
732 for (size_t z = 0; z < depth; z++)
733 {
734 for (size_t y = 0; y < height; y++)
735 {
736 const uint32_t *source =
737 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
738 uint16_t *dest =
739 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
740 for (size_t x = 0; x < width; x++)
741 {
742 uint32_t rgba8 = source[x];
743 auto r4 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4);
744 auto g4 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12);
745 auto b4 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20);
746 auto a4 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28);
747 dest[x] = (r4 << 12) | (g4 << 8) | (b4 << 4) | a4;
748 }
749 }
750 }
751 }
752
LoadRGBA4ToARGB4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)753 void LoadRGBA4ToARGB4(const ImageLoadContext &context,
754 size_t width,
755 size_t height,
756 size_t depth,
757 const uint8_t *input,
758 size_t inputRowPitch,
759 size_t inputDepthPitch,
760 uint8_t *output,
761 size_t outputRowPitch,
762 size_t outputDepthPitch)
763 {
764 for (size_t z = 0; z < depth; z++)
765 {
766 for (size_t y = 0; y < height; y++)
767 {
768 const uint16_t *source =
769 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
770 uint16_t *dest =
771 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
772 for (size_t x = 0; x < width; x++)
773 {
774 dest[x] = ANGLE_ROTR16(source[x], 4);
775 }
776 }
777 }
778 }
779
LoadRGBA4ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)780 void LoadRGBA4ToBGRA8(const ImageLoadContext &context,
781 size_t width,
782 size_t height,
783 size_t depth,
784 const uint8_t *input,
785 size_t inputRowPitch,
786 size_t inputDepthPitch,
787 uint8_t *output,
788 size_t outputRowPitch,
789 size_t outputDepthPitch)
790 {
791 for (size_t z = 0; z < depth; z++)
792 {
793 for (size_t y = 0; y < height; y++)
794 {
795 const uint16_t *source =
796 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
797 uint8_t *dest =
798 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
799 for (size_t x = 0; x < width; x++)
800 {
801 uint16_t rgba = source[x];
802 dest[4 * x + 0] =
803 static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4));
804 dest[4 * x + 1] =
805 static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8));
806 dest[4 * x + 2] =
807 static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12));
808 dest[4 * x + 3] =
809 static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0));
810 }
811 }
812 }
813 }
814
LoadRGBA4ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)815 void LoadRGBA4ToRGBA8(const ImageLoadContext &context,
816 size_t width,
817 size_t height,
818 size_t depth,
819 const uint8_t *input,
820 size_t inputRowPitch,
821 size_t inputDepthPitch,
822 uint8_t *output,
823 size_t outputRowPitch,
824 size_t outputDepthPitch)
825 {
826 for (size_t z = 0; z < depth; z++)
827 {
828 for (size_t y = 0; y < height; y++)
829 {
830 const uint16_t *source =
831 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
832 uint8_t *dest =
833 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
834 for (size_t x = 0; x < width; x++)
835 {
836 uint16_t rgba = source[x];
837 dest[4 * x + 0] =
838 static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12));
839 dest[4 * x + 1] =
840 static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8));
841 dest[4 * x + 2] =
842 static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4));
843 dest[4 * x + 3] =
844 static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0));
845 }
846 }
847 }
848 }
849
LoadBGRA4ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)850 void LoadBGRA4ToBGRA8(const ImageLoadContext &context,
851 size_t width,
852 size_t height,
853 size_t depth,
854 const uint8_t *input,
855 size_t inputRowPitch,
856 size_t inputDepthPitch,
857 uint8_t *output,
858 size_t outputRowPitch,
859 size_t outputDepthPitch)
860 {
861 for (size_t z = 0; z < depth; z++)
862 {
863 for (size_t y = 0; y < height; y++)
864 {
865 const uint16_t *source =
866 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
867 uint8_t *dest =
868 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
869 for (size_t x = 0; x < width; x++)
870 {
871 uint16_t bgra = source[x];
872 dest[4 * x + 0] =
873 static_cast<uint8_t>(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12));
874 dest[4 * x + 1] =
875 static_cast<uint8_t>(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8));
876 dest[4 * x + 2] =
877 static_cast<uint8_t>(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4));
878 dest[4 * x + 3] =
879 static_cast<uint8_t>(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0));
880 }
881 }
882 }
883 }
884
LoadRGBA8ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)885 void LoadRGBA8ToBGR5A1(const ImageLoadContext &context,
886 size_t width,
887 size_t height,
888 size_t depth,
889 const uint8_t *input,
890 size_t inputRowPitch,
891 size_t inputDepthPitch,
892 uint8_t *output,
893 size_t outputRowPitch,
894 size_t outputDepthPitch)
895 {
896 for (size_t z = 0; z < depth; z++)
897 {
898 for (size_t y = 0; y < height; y++)
899 {
900 const uint32_t *source =
901 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
902 uint16_t *dest =
903 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
904 for (size_t x = 0; x < width; x++)
905 {
906 uint32_t rgba8 = source[x];
907 auto r5 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3);
908 auto g5 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11);
909 auto b5 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19);
910 auto a1 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31);
911 dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5;
912 }
913 }
914 }
915 }
916
LoadRGBA8ToRGB5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)917 void LoadRGBA8ToRGB5A1(const ImageLoadContext &context,
918 size_t width,
919 size_t height,
920 size_t depth,
921 const uint8_t *input,
922 size_t inputRowPitch,
923 size_t inputDepthPitch,
924 uint8_t *output,
925 size_t outputRowPitch,
926 size_t outputDepthPitch)
927 {
928 for (size_t z = 0; z < depth; z++)
929 {
930 for (size_t y = 0; y < height; y++)
931 {
932 const uint32_t *source =
933 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
934 uint16_t *dest =
935 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
936 for (size_t x = 0; x < width; x++)
937 {
938 uint32_t rgba8 = source[x];
939 auto r5 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3);
940 auto g5 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11);
941 auto b5 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19);
942 auto a1 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31);
943 dest[x] = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
944 }
945 }
946 }
947 }
948
LoadRGB10A2ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)949 void LoadRGB10A2ToBGR5A1(const ImageLoadContext &context,
950 size_t width,
951 size_t height,
952 size_t depth,
953 const uint8_t *input,
954 size_t inputRowPitch,
955 size_t inputDepthPitch,
956 uint8_t *output,
957 size_t outputRowPitch,
958 size_t outputDepthPitch)
959 {
960 for (size_t z = 0; z < depth; z++)
961 {
962 for (size_t y = 0; y < height; y++)
963 {
964 const R10G10B10A2 *source =
965 priv::OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch);
966 uint16_t *dest =
967 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
968 for (size_t x = 0; x < width; x++)
969 {
970 R10G10B10A2 rgb10a2 = source[x];
971
972 uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u);
973 uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u);
974 uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u);
975 uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u);
976
977 dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5;
978 }
979 }
980 }
981 }
982
LoadRGB10A2ToRGB5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)983 void LoadRGB10A2ToRGB5A1(const ImageLoadContext &context,
984 size_t width,
985 size_t height,
986 size_t depth,
987 const uint8_t *input,
988 size_t inputRowPitch,
989 size_t inputDepthPitch,
990 uint8_t *output,
991 size_t outputRowPitch,
992 size_t outputDepthPitch)
993 {
994 for (size_t z = 0; z < depth; z++)
995 {
996 for (size_t y = 0; y < height; y++)
997 {
998 const R10G10B10A2 *source =
999 priv::OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch);
1000 uint16_t *dest =
1001 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1002 for (size_t x = 0; x < width; x++)
1003 {
1004 R10G10B10A2 rgb10a2 = source[x];
1005
1006 uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u);
1007 uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u);
1008 uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u);
1009 uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u);
1010
1011 dest[x] = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
1012 }
1013 }
1014 }
1015 }
1016
LoadRGB5A1ToA1RGB5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1017 void LoadRGB5A1ToA1RGB5(const ImageLoadContext &context,
1018 size_t width,
1019 size_t height,
1020 size_t depth,
1021 const uint8_t *input,
1022 size_t inputRowPitch,
1023 size_t inputDepthPitch,
1024 uint8_t *output,
1025 size_t outputRowPitch,
1026 size_t outputDepthPitch)
1027 {
1028 for (size_t z = 0; z < depth; z++)
1029 {
1030 for (size_t y = 0; y < height; y++)
1031 {
1032 const uint16_t *source =
1033 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1034 uint16_t *dest =
1035 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1036 for (size_t x = 0; x < width; x++)
1037 {
1038 dest[x] = ANGLE_ROTR16(source[x], 1);
1039 }
1040 }
1041 }
1042 }
1043
LoadRGB5A1ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1044 void LoadRGB5A1ToBGR5A1(const ImageLoadContext &context,
1045 size_t width,
1046 size_t height,
1047 size_t depth,
1048 const uint8_t *input,
1049 size_t inputRowPitch,
1050 size_t inputDepthPitch,
1051 uint8_t *output,
1052 size_t outputRowPitch,
1053 size_t outputDepthPitch)
1054 {
1055 for (size_t z = 0; z < depth; z++)
1056 {
1057 for (size_t y = 0; y < height; y++)
1058 {
1059 const uint16_t *source =
1060 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1061 uint16_t *dest =
1062 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1063 for (size_t x = 0; x < width; x++)
1064 {
1065 uint16_t rgba = source[x];
1066 auto r5 = static_cast<uint16_t>((rgba & 0xF800) >> 11);
1067 auto g5 = static_cast<uint16_t>((rgba & 0x07c0) >> 6);
1068 auto b5 = static_cast<uint16_t>((rgba & 0x003e) >> 1);
1069 auto a1 = static_cast<uint16_t>((rgba & 0x0001));
1070 dest[x] = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
1071 }
1072 }
1073 }
1074 }
1075
LoadRGB5A1ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1076 void LoadRGB5A1ToBGRA8(const ImageLoadContext &context,
1077 size_t width,
1078 size_t height,
1079 size_t depth,
1080 const uint8_t *input,
1081 size_t inputRowPitch,
1082 size_t inputDepthPitch,
1083 uint8_t *output,
1084 size_t outputRowPitch,
1085 size_t outputDepthPitch)
1086 {
1087 for (size_t z = 0; z < depth; z++)
1088 {
1089 for (size_t y = 0; y < height; y++)
1090 {
1091 const uint16_t *source =
1092 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1093 uint8_t *dest =
1094 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1095 for (size_t x = 0; x < width; x++)
1096 {
1097 uint16_t rgba = source[x];
1098 dest[4 * x + 0] =
1099 static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3));
1100 dest[4 * x + 1] =
1101 static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8));
1102 dest[4 * x + 2] =
1103 static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13));
1104 dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0);
1105 }
1106 }
1107 }
1108 }
1109
LoadRGB5A1ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1110 void LoadRGB5A1ToRGBA8(const ImageLoadContext &context,
1111 size_t width,
1112 size_t height,
1113 size_t depth,
1114 const uint8_t *input,
1115 size_t inputRowPitch,
1116 size_t inputDepthPitch,
1117 uint8_t *output,
1118 size_t outputRowPitch,
1119 size_t outputDepthPitch)
1120 {
1121 for (size_t z = 0; z < depth; z++)
1122 {
1123 for (size_t y = 0; y < height; y++)
1124 {
1125 const uint16_t *source =
1126 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1127 uint8_t *dest =
1128 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1129 for (size_t x = 0; x < width; x++)
1130 {
1131 uint16_t rgba = source[x];
1132 dest[4 * x + 0] =
1133 static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13));
1134 dest[4 * x + 1] =
1135 static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8));
1136 dest[4 * x + 2] =
1137 static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3));
1138 dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0);
1139 }
1140 }
1141 }
1142 }
1143
LoadBGR5A1ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1144 void LoadBGR5A1ToBGRA8(const ImageLoadContext &context,
1145 size_t width,
1146 size_t height,
1147 size_t depth,
1148 const uint8_t *input,
1149 size_t inputRowPitch,
1150 size_t inputDepthPitch,
1151 uint8_t *output,
1152 size_t outputRowPitch,
1153 size_t outputDepthPitch)
1154 {
1155 for (size_t z = 0; z < depth; z++)
1156 {
1157 for (size_t y = 0; y < height; y++)
1158 {
1159 const uint16_t *source =
1160 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1161 uint8_t *dest =
1162 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1163 for (size_t x = 0; x < width; x++)
1164 {
1165 uint16_t bgra = source[x];
1166 dest[4 * x + 0] =
1167 static_cast<uint8_t>(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13));
1168 dest[4 * x + 1] =
1169 static_cast<uint8_t>(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8));
1170 dest[4 * x + 2] =
1171 static_cast<uint8_t>(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3));
1172 dest[4 * x + 3] = static_cast<uint8_t>((bgra & 0x0001) ? 0xFF : 0);
1173 }
1174 }
1175 }
1176 }
1177
LoadRGB10A2ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1178 void LoadRGB10A2ToRGBA8(const ImageLoadContext &context,
1179 size_t width,
1180 size_t height,
1181 size_t depth,
1182 const uint8_t *input,
1183 size_t inputRowPitch,
1184 size_t inputDepthPitch,
1185 uint8_t *output,
1186 size_t outputRowPitch,
1187 size_t outputDepthPitch)
1188 {
1189 for (size_t z = 0; z < depth; z++)
1190 {
1191 for (size_t y = 0; y < height; y++)
1192 {
1193 const uint32_t *source =
1194 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1195 uint8_t *dest =
1196 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1197 for (size_t x = 0; x < width; x++)
1198 {
1199 uint32_t rgba = source[x];
1200 dest[4 * x + 0] = static_cast<uint8_t>((rgba & 0x000003FF) >> 2);
1201 dest[4 * x + 1] = static_cast<uint8_t>((rgba & 0x000FFC00) >> 12);
1202 dest[4 * x + 2] = static_cast<uint8_t>((rgba & 0x3FF00000) >> 22);
1203 dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0xC0000000) >> 30) * 0x55);
1204 }
1205 }
1206 }
1207 }
1208
LoadRGB10A2ToRGB10X2(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1209 void LoadRGB10A2ToRGB10X2(const ImageLoadContext &context,
1210 size_t width,
1211 size_t height,
1212 size_t depth,
1213 const uint8_t *input,
1214 size_t inputRowPitch,
1215 size_t inputDepthPitch,
1216 uint8_t *output,
1217 size_t outputRowPitch,
1218 size_t outputDepthPitch)
1219 {
1220 for (size_t z = 0; z < depth; z++)
1221 {
1222 for (size_t y = 0; y < height; y++)
1223 {
1224 const uint32_t *source =
1225 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1226 uint32_t *dest =
1227 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1228 for (size_t x = 0; x < width; x++)
1229 {
1230 dest[x] = source[x] | 0xC0000000;
1231 }
1232 }
1233 }
1234 }
1235
LoadRGB16FToRGB9E5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1236 void LoadRGB16FToRGB9E5(const ImageLoadContext &context,
1237 size_t width,
1238 size_t height,
1239 size_t depth,
1240 const uint8_t *input,
1241 size_t inputRowPitch,
1242 size_t inputDepthPitch,
1243 uint8_t *output,
1244 size_t outputRowPitch,
1245 size_t outputDepthPitch)
1246 {
1247 for (size_t z = 0; z < depth; z++)
1248 {
1249 for (size_t y = 0; y < height; y++)
1250 {
1251 const uint16_t *source =
1252 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1253 uint32_t *dest =
1254 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1255 for (size_t x = 0; x < width; x++)
1256 {
1257 dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]),
1258 gl::float16ToFloat32(source[x * 3 + 1]),
1259 gl::float16ToFloat32(source[x * 3 + 2]));
1260 }
1261 }
1262 }
1263 }
1264
LoadRGB32FToRGB9E5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1265 void LoadRGB32FToRGB9E5(const ImageLoadContext &context,
1266 size_t width,
1267 size_t height,
1268 size_t depth,
1269 const uint8_t *input,
1270 size_t inputRowPitch,
1271 size_t inputDepthPitch,
1272 uint8_t *output,
1273 size_t outputRowPitch,
1274 size_t outputDepthPitch)
1275 {
1276 for (size_t z = 0; z < depth; z++)
1277 {
1278 for (size_t y = 0; y < height; y++)
1279 {
1280 const float *source =
1281 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1282 uint32_t *dest =
1283 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1284 for (size_t x = 0; x < width; x++)
1285 {
1286 dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1],
1287 source[x * 3 + 2]);
1288 }
1289 }
1290 }
1291 }
1292
LoadRGB16FToRG11B10F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1293 void LoadRGB16FToRG11B10F(const ImageLoadContext &context,
1294 size_t width,
1295 size_t height,
1296 size_t depth,
1297 const uint8_t *input,
1298 size_t inputRowPitch,
1299 size_t inputDepthPitch,
1300 uint8_t *output,
1301 size_t outputRowPitch,
1302 size_t outputDepthPitch)
1303 {
1304 for (size_t z = 0; z < depth; z++)
1305 {
1306 for (size_t y = 0; y < height; y++)
1307 {
1308 const uint16_t *source =
1309 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1310 uint32_t *dest =
1311 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1312 for (size_t x = 0; x < width; x++)
1313 {
1314 dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) |
1315 (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) |
1316 (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22);
1317 }
1318 }
1319 }
1320 }
1321
LoadRGB32FToRG11B10F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1322 void LoadRGB32FToRG11B10F(const ImageLoadContext &context,
1323 size_t width,
1324 size_t height,
1325 size_t depth,
1326 const uint8_t *input,
1327 size_t inputRowPitch,
1328 size_t inputDepthPitch,
1329 uint8_t *output,
1330 size_t outputRowPitch,
1331 size_t outputDepthPitch)
1332 {
1333 for (size_t z = 0; z < depth; z++)
1334 {
1335 for (size_t y = 0; y < height; y++)
1336 {
1337 const float *source =
1338 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1339 uint32_t *dest =
1340 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1341 for (size_t x = 0; x < width; x++)
1342 {
1343 dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) |
1344 (gl::float32ToFloat11(source[x * 3 + 1]) << 11) |
1345 (gl::float32ToFloat10(source[x * 3 + 2]) << 22);
1346 }
1347 }
1348 }
1349 }
1350
LoadD24S8ToS8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1351 void LoadD24S8ToS8D24(const ImageLoadContext &context,
1352 size_t width,
1353 size_t height,
1354 size_t depth,
1355 const uint8_t *input,
1356 size_t inputRowPitch,
1357 size_t inputDepthPitch,
1358 uint8_t *output,
1359 size_t outputRowPitch,
1360 size_t outputDepthPitch)
1361 {
1362 for (size_t z = 0; z < depth; z++)
1363 {
1364 for (size_t y = 0; y < height; y++)
1365 {
1366 const uint32_t *source =
1367 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1368 uint32_t *dest =
1369 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1370 for (size_t x = 0; x < width; x++)
1371 {
1372 dest[x] = ANGLE_ROTL(source[x], 24);
1373 }
1374 }
1375 }
1376 }
1377
LoadD24S8ToD32FS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1378 void LoadD24S8ToD32FS8X24(const ImageLoadContext &context,
1379 size_t width,
1380 size_t height,
1381 size_t depth,
1382 const uint8_t *input,
1383 size_t inputRowPitch,
1384 size_t inputDepthPitch,
1385 uint8_t *output,
1386 size_t outputRowPitch,
1387 size_t outputDepthPitch)
1388 {
1389 for (size_t z = 0; z < depth; z++)
1390 {
1391 for (size_t y = 0; y < height; y++)
1392 {
1393 const uint32_t *source =
1394 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1395 float *destDepth =
1396 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1397 uint32_t *destStencil =
1398 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch) +
1399 1;
1400 for (size_t x = 0; x < width; x++)
1401 {
1402 destDepth[x * 2] = (source[x] >> 8) / static_cast<float>(0xFFFFFF);
1403 destStencil[x * 2] = source[x] & 0xFF;
1404 }
1405 }
1406 }
1407 }
1408
LoadD24S8ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1409 void LoadD24S8ToD32F(const ImageLoadContext &context,
1410 size_t width,
1411 size_t height,
1412 size_t depth,
1413 const uint8_t *input,
1414 size_t inputRowPitch,
1415 size_t inputDepthPitch,
1416 uint8_t *output,
1417 size_t outputRowPitch,
1418 size_t outputDepthPitch)
1419 {
1420 for (size_t z = 0; z < depth; z++)
1421 {
1422 for (size_t y = 0; y < height; y++)
1423 {
1424 const uint32_t *source =
1425 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1426 float *destDepth =
1427 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1428 for (size_t x = 0; x < width; x++)
1429 {
1430 destDepth[x] = (source[x] >> 8) / static_cast<float>(0xFFFFFF);
1431 }
1432 }
1433 }
1434 }
1435
LoadD32ToD32FX32(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1436 void LoadD32ToD32FX32(const ImageLoadContext &context,
1437 size_t width,
1438 size_t height,
1439 size_t depth,
1440 const uint8_t *input,
1441 size_t inputRowPitch,
1442 size_t inputDepthPitch,
1443 uint8_t *output,
1444 size_t outputRowPitch,
1445 size_t outputDepthPitch)
1446 {
1447 for (size_t z = 0; z < depth; z++)
1448 {
1449 for (size_t y = 0; y < height; y++)
1450 {
1451 const uint32_t *source =
1452 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1453 float *destDepth =
1454 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1455 for (size_t x = 0; x < width; x++)
1456 {
1457 destDepth[x * 2] = source[x] / static_cast<float>(0xFFFFFFFF);
1458 }
1459 }
1460 }
1461 }
1462
LoadD32ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1463 void LoadD32ToD32F(const ImageLoadContext &context,
1464 size_t width,
1465 size_t height,
1466 size_t depth,
1467 const uint8_t *input,
1468 size_t inputRowPitch,
1469 size_t inputDepthPitch,
1470 uint8_t *output,
1471 size_t outputRowPitch,
1472 size_t outputDepthPitch)
1473 {
1474 for (size_t z = 0; z < depth; z++)
1475 {
1476 for (size_t y = 0; y < height; y++)
1477 {
1478 const uint32_t *source =
1479 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1480 float *destDepth =
1481 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1482 for (size_t x = 0; x < width; x++)
1483 {
1484 uint32_t sourcePixel = source[x];
1485 destDepth[x] = sourcePixel / static_cast<float>(0xFFFFFFFF);
1486 }
1487 }
1488 }
1489 }
1490
LoadD32FToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1491 void LoadD32FToD32F(const ImageLoadContext &context,
1492 size_t width,
1493 size_t height,
1494 size_t depth,
1495 const uint8_t *input,
1496 size_t inputRowPitch,
1497 size_t inputDepthPitch,
1498 uint8_t *output,
1499 size_t outputRowPitch,
1500 size_t outputDepthPitch)
1501 {
1502 for (size_t z = 0; z < depth; z++)
1503 {
1504 for (size_t y = 0; y < height; y++)
1505 {
1506 const float *source =
1507 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1508 float *dest =
1509 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1510 for (size_t x = 0; x < width; x++)
1511 {
1512 dest[x] = gl::clamp01(source[x]);
1513 }
1514 }
1515 }
1516 }
1517
LoadD32FS8X24ToS8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1518 void LoadD32FS8X24ToS8D24(const ImageLoadContext &context,
1519 size_t width,
1520 size_t height,
1521 size_t depth,
1522 const uint8_t *input,
1523 size_t inputRowPitch,
1524 size_t inputDepthPitch,
1525 uint8_t *output,
1526 size_t outputRowPitch,
1527 size_t outputDepthPitch)
1528 {
1529 for (size_t z = 0; z < depth; z++)
1530 {
1531 for (size_t y = 0; y < height; y++)
1532 {
1533 const float *sourceDepth =
1534 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1535 const uint32_t *sourceStencil =
1536 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch) + 1;
1537 uint32_t *dest =
1538 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1539 for (size_t x = 0; x < width; x++)
1540 {
1541 uint32_t d = static_cast<uint32_t>(gl::clamp01(sourceDepth[x * 2]) * 0xFFFFFF);
1542 uint32_t s = sourceStencil[x * 2] << 24;
1543 dest[x] = d | s;
1544 }
1545 }
1546 }
1547 }
1548
LoadX24S8ToS8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1549 void LoadX24S8ToS8(const ImageLoadContext &context,
1550 size_t width,
1551 size_t height,
1552 size_t depth,
1553 const uint8_t *input,
1554 size_t inputRowPitch,
1555 size_t inputDepthPitch,
1556 uint8_t *output,
1557 size_t outputRowPitch,
1558 size_t outputDepthPitch)
1559 {
1560 for (size_t z = 0; z < depth; z++)
1561 {
1562 for (size_t y = 0; y < height; y++)
1563 {
1564 const uint32_t *source = reinterpret_cast<const uint32_t *>(
1565 input + (y * inputRowPitch) + (z * inputDepthPitch));
1566 uint8_t *destStencil =
1567 reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
1568 for (size_t x = 0; x < width; x++)
1569 {
1570 destStencil[x] = (source[x] & 0xFF);
1571 }
1572 }
1573 }
1574 }
1575
LoadX32S8ToS8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1576 void LoadX32S8ToS8(const ImageLoadContext &context,
1577 size_t width,
1578 size_t height,
1579 size_t depth,
1580 const uint8_t *input,
1581 size_t inputRowPitch,
1582 size_t inputDepthPitch,
1583 uint8_t *output,
1584 size_t outputRowPitch,
1585 size_t outputDepthPitch)
1586 {
1587 for (size_t z = 0; z < depth; z++)
1588 {
1589 for (size_t y = 0; y < height; y++)
1590 {
1591 const uint32_t *source = reinterpret_cast<const uint32_t *>(
1592 input + (y * inputRowPitch) + (z * inputDepthPitch));
1593 uint8_t *destStencil =
1594 reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
1595 for (size_t x = 0; x < width; x++)
1596 {
1597 destStencil[x] = (source[(x * 2) + 1] & 0xFF);
1598 }
1599 }
1600 }
1601 }
1602
LoadD32FS8X24ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1603 void LoadD32FS8X24ToD32F(const ImageLoadContext &context,
1604 size_t width,
1605 size_t height,
1606 size_t depth,
1607 const uint8_t *input,
1608 size_t inputRowPitch,
1609 size_t inputDepthPitch,
1610 uint8_t *output,
1611 size_t outputRowPitch,
1612 size_t outputDepthPitch)
1613 {
1614 for (size_t z = 0; z < depth; z++)
1615 {
1616 for (size_t y = 0; y < height; y++)
1617 {
1618 const float *sourceDepth =
1619 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1620 float *destDepth =
1621 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1622 for (size_t x = 0; x < width; x++)
1623 {
1624 destDepth[x] = gl::clamp01(sourceDepth[x * 2]);
1625 }
1626 }
1627 }
1628 }
1629
LoadD32FS8X24ToD32FS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1630 void LoadD32FS8X24ToD32FS8X24(const ImageLoadContext &context,
1631 size_t width,
1632 size_t height,
1633 size_t depth,
1634 const uint8_t *input,
1635 size_t inputRowPitch,
1636 size_t inputDepthPitch,
1637 uint8_t *output,
1638 size_t outputRowPitch,
1639 size_t outputDepthPitch)
1640 {
1641 for (size_t z = 0; z < depth; z++)
1642 {
1643 for (size_t y = 0; y < height; y++)
1644 {
1645 const float *sourceDepth =
1646 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1647 const uint32_t *sourceStencil =
1648 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch) + 1;
1649 float *destDepth =
1650 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1651 uint32_t *destStencil =
1652 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch) +
1653 1;
1654 for (size_t x = 0; x < width; x++)
1655 {
1656 destDepth[x * 2] = gl::clamp01(sourceDepth[x * 2]);
1657 destStencil[x * 2] = sourceStencil[x * 2] & 0xFF;
1658 }
1659 }
1660 }
1661 }
1662
LoadRGB32FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1663 void LoadRGB32FToRGBA16F(const ImageLoadContext &context,
1664 size_t width,
1665 size_t height,
1666 size_t depth,
1667 const uint8_t *input,
1668 size_t inputRowPitch,
1669 size_t inputDepthPitch,
1670 uint8_t *output,
1671 size_t outputRowPitch,
1672 size_t outputDepthPitch)
1673 {
1674 for (size_t z = 0; z < depth; z++)
1675 {
1676 for (size_t y = 0; y < height; y++)
1677 {
1678 const float *source =
1679 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1680 uint16_t *dest =
1681 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1682 for (size_t x = 0; x < width; x++)
1683 {
1684 dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
1685 dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
1686 dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
1687 dest[x * 4 + 3] = gl::Float16One;
1688 }
1689 }
1690 }
1691 }
1692
LoadRGB32FToRGB16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1693 void LoadRGB32FToRGB16F(const ImageLoadContext &context,
1694 size_t width,
1695 size_t height,
1696 size_t depth,
1697 const uint8_t *input,
1698 size_t inputRowPitch,
1699 size_t inputDepthPitch,
1700 uint8_t *output,
1701 size_t outputRowPitch,
1702 size_t outputDepthPitch)
1703 {
1704 for (size_t z = 0; z < depth; z++)
1705 {
1706 for (size_t y = 0; y < height; y++)
1707 {
1708 const float *source =
1709 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1710 uint16_t *dest =
1711 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1712 for (size_t x = 0; x < width; x++)
1713 {
1714 dest[x * 3 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
1715 dest[x * 3 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
1716 dest[x * 3 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
1717 }
1718 }
1719 }
1720 }
1721
LoadR32ToR16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1722 void LoadR32ToR16(const ImageLoadContext &context,
1723 size_t width,
1724 size_t height,
1725 size_t depth,
1726 const uint8_t *input,
1727 size_t inputRowPitch,
1728 size_t inputDepthPitch,
1729 uint8_t *output,
1730 size_t outputRowPitch,
1731 size_t outputDepthPitch)
1732 {
1733 for (size_t z = 0; z < depth; z++)
1734 {
1735 for (size_t y = 0; y < height; y++)
1736 {
1737 const uint32_t *source =
1738 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1739 uint16_t *dest =
1740 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1741 for (size_t x = 0; x < width; x++)
1742 {
1743 dest[x] = source[x] >> 16;
1744 }
1745 }
1746 }
1747 }
1748
LoadD32ToX8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1749 void LoadD32ToX8D24(const ImageLoadContext &context,
1750 size_t width,
1751 size_t height,
1752 size_t depth,
1753 const uint8_t *input,
1754 size_t inputRowPitch,
1755 size_t inputDepthPitch,
1756 uint8_t *output,
1757 size_t outputRowPitch,
1758 size_t outputDepthPitch)
1759 {
1760 for (size_t z = 0; z < depth; z++)
1761 {
1762 for (size_t y = 0; y < height; y++)
1763 {
1764 const uint32_t *source =
1765 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1766 uint32_t *dest =
1767 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1768
1769 for (size_t x = 0; x < width; x++)
1770 {
1771 dest[x] = source[x] >> 8;
1772 }
1773 }
1774 }
1775 }
1776
1777 // This conversion was added to support using a 32F depth buffer
1778 // as emulation for 16unorm depth buffer in Metal.
1779 // See https://anglebug.com/6597
LoadD16ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1780 void LoadD16ToD32F(const ImageLoadContext &context,
1781 size_t width,
1782 size_t height,
1783 size_t depth,
1784 const uint8_t *input,
1785 size_t inputRowPitch,
1786 size_t inputDepthPitch,
1787 uint8_t *output,
1788 size_t outputRowPitch,
1789 size_t outputDepthPitch)
1790 {
1791 for (size_t z = 0; z < depth; z++)
1792 {
1793 for (size_t y = 0; y < height; y++)
1794 {
1795 const uint16_t *source =
1796 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1797 float *dest =
1798 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1799 for (size_t x = 0; x < width; x++)
1800 {
1801 dest[x] = static_cast<float>(source[x]) / 0xFFFF;
1802 }
1803 }
1804 }
1805 }
1806
LoadS8ToS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1807 void LoadS8ToS8X24(const ImageLoadContext &context,
1808 size_t width,
1809 size_t height,
1810 size_t depth,
1811 const uint8_t *input,
1812 size_t inputRowPitch,
1813 size_t inputDepthPitch,
1814 uint8_t *output,
1815 size_t outputRowPitch,
1816 size_t outputDepthPitch)
1817 {
1818 for (size_t z = 0; z < depth; z++)
1819 {
1820 for (size_t y = 0; y < height; y++)
1821 {
1822 const uint8_t *source =
1823 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
1824 uint32_t *destStencil =
1825 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1826
1827 for (size_t x = 0; x < width; x++)
1828 {
1829 destStencil[x] = source[x] << 24;
1830 }
1831 }
1832 }
1833 }
1834
LoadYuvToNative(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1835 void LoadYuvToNative(const ImageLoadContext &context,
1836 size_t width,
1837 size_t height,
1838 size_t depth,
1839 const uint8_t *input,
1840 size_t inputRowPitch,
1841 size_t inputDepthPitch,
1842 uint8_t *output,
1843 size_t outputRowPitch,
1844 size_t outputDepthPitch)
1845 {
1846 // For YUV formats it is assumed that source has tightly packed data.
1847 memcpy(output, input, inputDepthPitch);
1848 }
1849
1850 } // namespace angle
1851