@@ -24,7 +24,7 @@ namespace
24
24
#else
25
25
// N3864 - A constexpr bitwise operations library for C++
26
26
// https://github.com/fmatthew5876/stdcxx-bitops
27
- uint32_t deposit_bits (uint32_t val, int mask)
27
+ uint32_t deposit_bits (uint32_t val, int mask) noexcept
28
28
{
29
29
uint32_t res = 0 ;
30
30
for (uint32_t bb = 1 ; mask != 0 ; bb += bb)
@@ -38,7 +38,7 @@ namespace
38
38
return res;
39
39
}
40
40
41
- uint32_t extract_bits (uint32_t val, int mask)
41
+ uint32_t extract_bits (uint32_t val, int mask) noexcept
42
42
{
43
43
uint32_t res = 0 ;
44
44
for (uint32_t bb = 1 ; mask !=0 ; bb += bb)
@@ -61,6 +61,64 @@ namespace
61
61
constexpr size_t MAX_TEXTURE_SIZE = UINT32_MAX;
62
62
#endif
63
63
64
+ // Standard Swizzle is not defined for these formats.
65
+ bool IsExcludedFormat (DXGI_FORMAT fmt) noexcept
66
+ {
67
+ switch (static_cast <int >(fmt))
68
+ {
69
+ // 96bpp
70
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
71
+ case DXGI_FORMAT_R32G32B32_FLOAT:
72
+ case DXGI_FORMAT_R32G32B32_UINT:
73
+ case DXGI_FORMAT_R32G32B32_SINT:
74
+
75
+ // Depth/stencil
76
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
77
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
78
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
79
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
80
+ case DXGI_FORMAT_D32_FLOAT:
81
+ case DXGI_FORMAT_R24G8_TYPELESS:
82
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
83
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
84
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
85
+ case DXGI_FORMAT_D16_UNORM:
86
+ case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT:
87
+ case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
88
+ case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT:
89
+
90
+ // Monochrome
91
+ case DXGI_FORMAT_R1_UNORM:
92
+
93
+ // Packed
94
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
95
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
96
+ case DXGI_FORMAT_YUY2:
97
+ case DXGI_FORMAT_Y210:
98
+ case DXGI_FORMAT_Y216:
99
+
100
+ // Planar
101
+ case DXGI_FORMAT_NV12:
102
+ case DXGI_FORMAT_P010:
103
+ case DXGI_FORMAT_P016:
104
+ case DXGI_FORMAT_420_OPAQUE:
105
+ case DXGI_FORMAT_NV11:
106
+ case WIN10_DXGI_FORMAT_P208:
107
+ case WIN10_DXGI_FORMAT_V208:
108
+ case WIN10_DXGI_FORMAT_V408:
109
+
110
+ // Palettized
111
+ case DXGI_FORMAT_AI44:
112
+ case DXGI_FORMAT_IA44:
113
+ case DXGI_FORMAT_P8:
114
+ case DXGI_FORMAT_A8P8:
115
+ return true ;
116
+
117
+ default :
118
+ return false ;
119
+ }
120
+ }
121
+
64
122
// -------------------------------------------------------------------------------------
65
123
// 2D z-order curve
66
124
// -------------------------------------------------------------------------------------
@@ -218,40 +276,55 @@ namespace
218
276
constexpr uint16_t VOLUME_STANDARD_SWIZZLE_Z_64 = 0b0010010011000111 ;
219
277
constexpr uint16_t VOLUME_STANDARD_SWIZZLE_Z_128 = 0b0010010011001111 ;
220
278
221
- inline int GetSwizzleMask3D_X (size_t bytesPerPixel) noexcept
222
- {
223
- switch (bytesPerPixel)
224
- {
225
- case 1 : return VOLUME_STANDARD_SWIZZLE_X_8;
226
- case 2 : return VOLUME_STANDARD_SWIZZLE_X_16;
227
- case 8 : return VOLUME_STANDARD_SWIZZLE_X_64;
228
- case 16 : return VOLUME_STANDARD_SWIZZLE_X_128;
229
- default : return VOLUME_STANDARD_SWIZZLE_X_32;
230
- }
231
- }
279
+ // We rely on the fact that ScratchImage will put all slices in the same mip level
280
+ // in continous memory. We do not assume that is true of the source images.
232
281
233
- inline int GetSwizzleMask3D_Y (size_t bytesPerPixel) noexcept
282
+ // ---------------------------------------------------------------------------------
283
+ // row-major to z-order curve
284
+ // ---------------------------------------------------------------------------------
285
+ template <int xBytesMask, int yBytesMask, int zBytesMask, size_t bytesPerPixel>
286
+ HRESULT LinearToStandardSwizzle3D (
287
+ _In_reads_ (depth) const Image* srcImages,
288
+ const Image& destImage,
289
+ size_t depth,
290
+ bool isCompressed) noexcept
234
291
{
235
- switch (bytesPerPixel)
236
- {
237
- case 1 : return VOLUME_STANDARD_SWIZZLE_Y_8;
238
- case 2 : return VOLUME_STANDARD_SWIZZLE_Y_16;
239
- case 8 : return VOLUME_STANDARD_SWIZZLE_Y_64;
240
- case 16 : return VOLUME_STANDARD_SWIZZLE_Y_128;
241
- default : return VOLUME_STANDARD_SWIZZLE_Y_32;
242
- }
292
+ if (!srcImages || !depth)
293
+ return E_INVALIDARG;
294
+
295
+ uint8_t * dptr = destImage.pixels ;
296
+ if (!dptr)
297
+ return E_POINTER;
298
+
299
+ if (destImage.rowPitch > UINT32_MAX)
300
+ return HRESULT_E_ARITHMETIC_OVERFLOW;
301
+
302
+ // TODO: linear to swizzle x,y,z
303
+ return E_NOTIMPL;
243
304
}
244
305
245
- inline int GetSwizzleMask3D_Z (size_t bytesPerPixel) noexcept
306
+ // ---------------------------------------------------------------------------------
307
+ // z-order curve to row-major
308
+ // ---------------------------------------------------------------------------------
309
+ template <int xBytesMask, int yBytesMask, int zBytesMask, size_t bytesPerPixel>
310
+ HRESULT StandardSwizzleToLinear3D (
311
+ _In_reads_ (depth) const Image* srcImages,
312
+ const Image& destImage,
313
+ size_t depth,
314
+ bool isCompressed) noexcept
246
315
{
247
- switch (bytesPerPixel)
248
- {
249
- case 1 : return VOLUME_STANDARD_SWIZZLE_Z_8;
250
- case 2 : return VOLUME_STANDARD_SWIZZLE_Z_16;
251
- case 8 : return VOLUME_STANDARD_SWIZZLE_Z_64;
252
- case 16 : return VOLUME_STANDARD_SWIZZLE_Z_128;
253
- default : return VOLUME_STANDARD_SWIZZLE_Z_32;
254
- }
316
+ if (!srcImages || !depth)
317
+ return E_INVALIDARG;
318
+
319
+ uint8_t * dptr = destImage.pixels ;
320
+ if (!dptr)
321
+ return E_POINTER;
322
+
323
+ if (destImage.rowPitch > UINT32_MAX)
324
+ return HRESULT_E_ARITHMETIC_OVERFLOW;
325
+
326
+ // TODO: swizzle x,y,z to linear
327
+ return E_NOTIMPL;
255
328
}
256
329
}
257
330
@@ -273,7 +346,7 @@ HRESULT DirectX::StandardSwizzle(
273
346
return HRESULT_E_NOT_SUPPORTED;
274
347
}
275
348
276
- if (IsPlanar (srcImage.format ) || IsPalettized (srcImage. format ) || (srcImage. format == DXGI_FORMAT_R1_UNORM ))
349
+ if (IsExcludedFormat (srcImage.format ))
277
350
return HRESULT_E_NOT_SUPPORTED;
278
351
279
352
if (!srcImage.pixels )
@@ -368,7 +441,7 @@ HRESULT DirectX::StandardSwizzle(
368
441
return HRESULT_E_NOT_SUPPORTED;
369
442
}
370
443
371
- if (IsPlanar (metadata.format ) || IsPalettized (metadata. format ) || (metadata. format == DXGI_FORMAT_R1_UNORM ))
444
+ if (IsExcludedFormat (metadata.format ))
372
445
return HRESULT_E_NOT_SUPPORTED;
373
446
374
447
HRESULT hr = result.Initialize (metadata);
@@ -398,8 +471,104 @@ HRESULT DirectX::StandardSwizzle(
398
471
399
472
if (metadata.dimension == TEX_DIMENSION_TEXTURE3D)
400
473
{
401
- // TODO -
402
- return E_NOTIMPL;
474
+ size_t index = 0 ;
475
+ size_t depth = metadata.depth ;
476
+ for (size_t level = 0 ; level < metadata.mipLevels ; ++level)
477
+ {
478
+ const Image* srcBase = &srcImages[index ];
479
+ const Image& destBase = dest[index ];
480
+
481
+ for (size_t slice = 0 ; slice < depth; ++slice, ++index )
482
+ {
483
+ if (index >= nimages)
484
+ {
485
+ result.Release ();
486
+ return E_UNEXPECTED;
487
+ }
488
+
489
+ const Image& src = srcImages[index ];
490
+ if (!src.pixels )
491
+ {
492
+ result.Release ();
493
+ return E_POINTER;
494
+ }
495
+
496
+ if (src.format != metadata.format )
497
+ {
498
+ result.Release ();
499
+ return E_FAIL;
500
+ }
501
+
502
+ if ((src.width > MAX_TEXTURE_DIMENSION) || (src.height > MAX_TEXTURE_DIMENSION))
503
+ {
504
+ result.Release ();
505
+ return E_FAIL;
506
+ }
507
+
508
+ const Image& dst = dest[index ];
509
+ assert (dst.format == metadata.format );
510
+
511
+ if (src.width != dst.width || src.height != dst.height )
512
+ {
513
+ result.Release ();
514
+ return E_FAIL;
515
+ }
516
+ }
517
+
518
+ if (toSwizzle)
519
+ {
520
+ switch (bytesPerPixel)
521
+ {
522
+ case 1 :
523
+ hr = LinearToStandardSwizzle3D<VOLUME_STANDARD_SWIZZLE_X_8, VOLUME_STANDARD_SWIZZLE_Y_8, VOLUME_STANDARD_SWIZZLE_Z_8, 1 >(srcBase, destBase, depth, false );
524
+ break ;
525
+ case 2 :
526
+ hr = LinearToStandardSwizzle3D<VOLUME_STANDARD_SWIZZLE_X_16, VOLUME_STANDARD_SWIZZLE_Y_16, VOLUME_STANDARD_SWIZZLE_Z_16, 2 >(srcBase, destBase, depth, false );
527
+ break ;
528
+ case 8 :
529
+ hr = LinearToStandardSwizzle3D<VOLUME_STANDARD_SWIZZLE_X_64, VOLUME_STANDARD_SWIZZLE_Y_64, VOLUME_STANDARD_SWIZZLE_Z_64, 8 >(srcBase, destBase, depth, isCompressed);
530
+ break ;
531
+ case 16 :
532
+ hr = LinearToStandardSwizzle3D<VOLUME_STANDARD_SWIZZLE_X_128, VOLUME_STANDARD_SWIZZLE_Y_128, VOLUME_STANDARD_SWIZZLE_Z_128, 16 >(srcBase, destBase, depth, isCompressed);
533
+ break ;
534
+ default :
535
+ hr = LinearToStandardSwizzle3D<VOLUME_STANDARD_SWIZZLE_X_32, VOLUME_STANDARD_SWIZZLE_Y_32, VOLUME_STANDARD_SWIZZLE_Z_32, 4 >(srcBase, destBase, depth, false );
536
+ break ;
537
+ }
538
+ }
539
+ else
540
+ {
541
+ switch (bytesPerPixel)
542
+ {
543
+ case 1 :
544
+ hr = StandardSwizzleToLinear3D<VOLUME_STANDARD_SWIZZLE_X_8, VOLUME_STANDARD_SWIZZLE_Y_8, VOLUME_STANDARD_SWIZZLE_Z_8, 1 >(srcBase, destBase, depth, false );
545
+ break ;
546
+ case 2 :
547
+ hr = StandardSwizzleToLinear3D<VOLUME_STANDARD_SWIZZLE_X_16, VOLUME_STANDARD_SWIZZLE_Y_16, VOLUME_STANDARD_SWIZZLE_Z_16, 2 >(srcBase, destBase, depth, false );
548
+ break ;
549
+ case 8 :
550
+ hr = StandardSwizzleToLinear3D<VOLUME_STANDARD_SWIZZLE_X_64, VOLUME_STANDARD_SWIZZLE_Y_64, VOLUME_STANDARD_SWIZZLE_Z_64, 8 >(srcBase, destBase, depth, isCompressed);
551
+ break ;
552
+ case 16 :
553
+ hr = StandardSwizzleToLinear3D<VOLUME_STANDARD_SWIZZLE_X_128, VOLUME_STANDARD_SWIZZLE_Y_128, VOLUME_STANDARD_SWIZZLE_Z_128, 16 >(srcBase, destBase, depth, isCompressed);
554
+ break ;
555
+ default :
556
+ hr = StandardSwizzleToLinear3D<VOLUME_STANDARD_SWIZZLE_X_32, VOLUME_STANDARD_SWIZZLE_Y_32, VOLUME_STANDARD_SWIZZLE_Z_32, 4 >(srcBase, destBase, depth, false );
557
+ break ;
558
+ }
559
+ }
560
+
561
+ if (FAILED (hr))
562
+ {
563
+ result.Release ();
564
+ return hr;
565
+ }
566
+
567
+ if (depth > 1 )
568
+ depth >>= 1 ;
569
+ }
570
+
571
+ return S_OK;
403
572
}
404
573
else
405
574
{
@@ -484,43 +653,6 @@ HRESULT DirectX::StandardSwizzle(
484
653
485
654
486
655
#if 0
487
- // TODO: merging into main based on metadata
488
- _Use_decl_annotations_
489
- HRESULT DirectX::StandardSwizzle3D(
490
- const Image* srcImages,
491
- size_t depth,
492
- const TexMetadata& metadata,
493
- bool toSwizzle,
494
- ScratchImage& result) noexcept
495
- {
496
- if (!srcImages || !depth || (metadata.dimension != TEX_DIMENSION_TEXTURE3D))
497
- return E_INVALIDARG;
498
-
499
- if (IsPlanar(metadata.format) || IsPalettized(metadata.format) || (metadata.format == DXGI_FORMAT_R1_UNORM))
500
- return HRESULT_E_NOT_SUPPORTED;
501
-
502
- HRESULT hr = result.Initialize(metadata);
503
- if (FAILED(hr))
504
- return hr;
505
-
506
- if ((depth * metadata.mipLevels) != result.GetImageCount())
507
- {
508
- result.Release();
509
- return E_FAIL;
510
- }
511
-
512
- const bool isCompressed = IsCompressed(metadata.format);
513
- const size_t bytesPerPixel = isCompressed ? BytesPerBlock(metadata.format) : (BitsPerPixel(metadata.format) / 8);
514
- if (!bytesPerPixel)
515
- {
516
- result.Release();
517
- return E_FAIL;
518
- }
519
-
520
- const int xBytesMask = GetSwizzleMask3D_X(metadata.format);
521
- const int yBytesMask = GetSwizzleMask3D_Y(metadata.format);
522
- const int zBytesMask = GetSwizzleMask3D_Z(metadata.format);
523
-
524
656
if (toSwizzle)
525
657
{
526
658
// row-major to z-order curve
@@ -584,7 +716,4 @@ HRESULT DirectX::StandardSwizzle3D(
584
716
}
585
717
}
586
718
}
587
-
588
- return S_OK;
589
- }
590
719
#endif
0 commit comments