> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DirectStorage 隨機排列格式

> DirectStorage 隨機排列格式

從 March 2024 GDK 開始，XBOX DirectStorage API 中的 swizzle 模式參數提供了數個額外選項。這些選項的設計目的是在搭配 BCPACK 或 ZLib 型壓縮使用時，進一步節省壓縮後的大小。

這些隨機排列格式各自描述資料儲存在磁碟上時的重新排列方式，搭配預期的 BCn 格式使用時，可改善壓縮後的大小。DirectStorage 中的 swizzle 模式選項會在將資料寫出至記憶體時重新排列資料，以準備進行最終修正。計算著色器會對資料執行最終修正，以還原正確的位元組順序。

下方提供的參考程式碼示範如何準備資料在磁碟上的格式。可執行資料最終「修正」的範例著色器可應要求提供。如果您想要取得這些著色器的複本，請連絡您的 Microsoft 代表。

<Note>
  雖然下文所述的功能適用於任何符合對齊需求的資料，但其設計用途是搭配離線 swizzle 處理的內容，而且在此情況下最有效。
</Note>

## 內容

* [DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_8K](#DSTORAGE_SWIZZLE_MODE_4K_4K_8K)
* [DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_4K\_8K](#DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K)
* [DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_24K](#DSTORAGE_SWIZZLE_MODE_4K_4K_24K)
* [DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_12K](#DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K)

<a id="DSTORAGE_SWIZZLE_MODE_4K_4K_8K" />

## DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_8K

此模式適用於 BC1 編碼的內容。未壓縮內容的大小必須是 16KB 的倍數。此模式假設來源資料依串流 (亦即端點和索引) 分組，以改善可壓縮性。來源資料也必須使用 Zlib 或 BCPack 進行壓縮。當為 DSTORAGE\_REQUEST\_OPTIONS::SwizzleMode 選項提供 DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_8K 時，DirectStorage 會從分組內容中的對應資料擷取，將記憶體中未壓縮的內容重新排列為大小 16KB 的交錯群組。每個 16KB 群組都包含原始 BC1 內容的所有資料，但仍保持分組。可以使用計算著色器從 16KB 群組就地完整重建原始內容。

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_4K_8K.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=4606a1ab5e5e6125e4b694f615c808fb" alt="DSTORAGE_SWIZZLE_MODE_4K_4K_8K 轉換的圖表" width="1069" height="340" data-path="images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_4K_8K.png" />

```C++ theme={null}
// This algorithm will rearrange a source buffer into the disk layout that works 
// with the DSTORAGE_SWIZZLE_MODE_4K_4K_8K swizzle mode.  The comments refer
// to an assumption that the source buffer is BC1 formatted data.
auto shuffle_224 = [](uint8_t* dest, const uint8_t* src, size_t size) {
    uint8_t* d1 = dest;            // e0
    uint8_t* d2 = dest + size / 4; // e1
    uint8_t* d3 = dest + size / 2; // indexes

    do {
        *d1++ = *src++; *d1++ = *src++; // e0 (2B)
        *d2++ = *src++; *d2++ = *src++; // e1 (2B)
        *d3++ = *src++; *d3++ = *src++; // ind (4B)
        *d3++ = *src++; *d3++ = *src++;
    } while (size -= 8);
};
```

<a id="DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K" />

## DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_4K\_8K

此模式適用於 BC3 編碼的內容。未壓縮內容的大小必須是 32KB 的倍數。此模式假設來源資料依串流 (亦即端點和索引) 分組，以改善可壓縮性。來源資料也必須使用 Zlib 或 BCPack 進行壓縮。當為 DSTORAGE\_REQUEST\_OPTIONS::SwizzleMode 選項提供 DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_4K\_8K 時，DirectStorage 會從分組內容中的對應資料擷取，將記憶體中未壓縮的內容重新排列為大小 32KB 的交錯群組。每個 32KB 群組都包含原始 BC3 內容的所有資料，但仍保持分組。可以使用計算著色器從 32KB 群組就地完整重建原始內容。

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=efdec5bc6b9b346b4d3827fa2bab6243" alt="DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K 轉換的圖表" width="1079" height="384" data-path="images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K.png" />

```C++ theme={null}
// This algorithm will rearrange a source buffer into the disk layout that works 
// with the DSTORAGE_SWIZZLE_MODE_4K_12K_4K_4K_8K swizzle mode.  The comments refer
// to an assumption that the source buffer is BC3 formatted data.
//
// NOTE: A0/A1 are interleaved 2K/2K in each 4KB range of that stream
auto shuffle_26_224 = [](uint8_t* dest, const uint8_t* src, size_t size) {
    uint8_t* d1 = dest, *d2 = dest + 2048;      // a0, a1 interleaved 2k/2k
    uint8_t* d3 = dest + size / 8;              // aind
    uint8_t* d4 = dest + size / 2;              // e0
    uint8_t *d5 = dest + size / 2 + size / 8;   // e1
    uint8_t* d6 = dest + size / 2 + size / 4;   // eind

    do {
        *d1++ = *src++;                                 // a0 (1B)
        *d2++ = *src++;                                 // a1 (1B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++; // aind (6B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++;
        *d4++ = *src++; *d4++ = *src++;                 // e0 (2B)
        *d5++ = *src++; *d5++ = *src++;                 // e1 (2B)
        *d6++ = *src++; *d6++ = *src++;                 // eind (4B)
        *d6++ = *src++; *d6++ = *src++;

        // every 2K tiles, we need to advance the interleave
        if ((size-16) % (2048*16) == 0)
        {
            d1 += 2048;
            d2 += 2048;
        }
    } while (size -= 16);
};
```

<a id="DSTORAGE_SWIZZLE_MODE_4K_4K_24K" />

## DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_24K

此模式適用於 BC4 編碼的內容。未壓縮內容的大小必須是 32KB 的倍數。此模式假設來源資料依串流 (亦即端點和索引) 分組，以改善可壓縮性。來源資料也必須使用 Zlib 或 BCPack 進行壓縮。當為 DSTORAGE\_REQUEST\_OPTIONS::SwizzleMode 選項提供 DSTORAGE\_SWIZZLE\_MODE\_4K\_4K\_24K 時，DirectStorage 會從分組內容中的對應資料擷取，將記憶體中未壓縮的內容重新排列為大小 32KB 的交錯群組。每個 32KB 群組都包含原始 BC4 內容的所有資料，但仍保持分組。可以使用計算著色器從 32KB 群組就地完整重建原始內容。

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_4K_24K.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=8239b0cdffc7aeb42e213cd3fb74b96f" alt="DSTORAGE_SWIZZLE_MODE_4K_4K_24K 轉換的圖表" width="1065" height="351" data-path="images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_4K_24K.png" />

```C++ theme={null}
// This algorithm will rearrange a source buffer into the disk layout that works 
// with the DSTORAGE_SWIZZLE_MODE_4K_4K_24K swizzle mode.  The comments refer
// to an assumption that the source buffer is BC4 formatted data.
auto shuffle_116 = [](uint8_t* dest, const uint8_t* src, size_t size) {
    uint8_t* d1 = dest, *d2 = dest + size / 8;          // r0, r1
    uint8_t* d3 = dest + size / 4;                      // ind

    do {
        *d1++ = *src++;                                 // r0 (1B)
        *d2++ = *src++;                                 // r1 (1B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++; // ind (6B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++;
    } while (size -= 8);
};
```

<a id="DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K" />

## DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_12K

此模式適用於 BC5 編碼的內容。未壓縮內容的大小必須是 32KB 的倍數。此模式假設來源資料依串流 (亦即端點和索引) 分組，以改善可壓縮性。來源資料也必須使用 Zlib 或 BCPack 進行壓縮。當為 DSTORAGE\_REQUEST\_OPTIONS::SwizzleMode 選項提供 DSTORAGE\_SWIZZLE\_MODE\_4K\_12K\_4K\_12K 時，DirectStorage 會從分組內容中的對應資料擷取，將記憶體中未壓縮的內容重新排列為大小 32KB 的交錯群組。每個 32KB 群組都包含原始 BC5 內容的所有資料，但仍保持分組。可以使用計算著色器從 32KB 群組就地完整重建原始內容。

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=9e172d069d0ef63e8924b71e5a26d975" alt="DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K 轉換的圖表" width="1111" height="421" data-path="images/gdk/features/console/DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K.png" />

```C++ theme={null}
// This algorithm will rearrange a source buffer into the disk layout that works 
// with the DSTORAGE_SWIZZLE_MODE_4K_12K_4K_12K swizzle mode.  The comments refer
// to an assumption that the source buffer is BC5 formatted data.
//
// NOTE: R0/R1 and G0/G1 are interleaved 2K/2K in each 4KB range of those streams
auto shuffle_26_26 = [](uint8_t* dest, const uint8_t* src, size_t size) {
    uint8_t* d1 = dest, *d2 = dest + 2048;                       // r0, r1 interleaved 2K/2K
    uint8_t* d3 = dest + size / 8;                               // rind
    uint8_t* d4 = dest + size / 2, *d5 = dest + size / 2 + 2048; // g0, g1 interleaved 2K/2K
    uint8_t* d6 = dest + size / 2 + size / 8;                    // gind

    do {
        *d1++ = *src++;                                 // r0 (1B)
        *d2++ = *src++;                                 // r1 (1B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++; // rind (6B)
        *d3++ = *src++; *d3++ = *src++; *d3++ = *src++;
        *d4++ = *src++;                                 // g0 (1B)
        *d5++ = *src++;                                 // g1 (1B)
        *d6++ = *src++; *d6++ = *src++; *d6++ = *src++; // gind (6B)
        *d6++ = *src++; *d6++ = *src++; *d6++ = *src++;

        // every 2K tiles, we need to advance the interleave
        if ((size - 16) % (2048 * 16) == 0)
        {
            d1 += 2048;
            d2 += 2048;
            d4 += 2048;
            d5 += 2048;
        }
    } while (size -= 16);
};
```

## 另請參閱

[DirectStorage](/zh-TW/build/console-features/storage/directstorage-toc)

[DirectStorage 使用方式與內部細節](/zh-TW/build/console-features/storage/directstorage/directstorage-white-paper)

[分析 DirectStorage 效能](/zh-TW/tools/tools-console/pix/pix-directstorage)

[GDK 範例清單](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/development-downloads/gdk-samples-list)


## Related topics

- [DirectStorage](/zh-CN/build/console-features/storage/directstorage-toc.md)
- [DirectStorage 概述](/zh-CN/build/console-features/storage/directstorage/directstorage-overview.md)
- [DirectStorage Overview](/build/console-features/storage/directstorage/directstorage-overview.md)
- [DirectStorage 개요](/ko/build/console-features/storage/directstorage/directstorage-overview.md)
- [DirectStorage の概要](/ja-jp/build/console-features/storage/directstorage/directstorage-overview.md)
