Распаковка и упаковка DXGI_FORMAT для редактирования изображений In-Place

Файл D3DX_DXGIFormatConvert.inl содержит встроенные функции преобразования формата, которые можно использовать в вычислительном шейдере или пиксельном шейдере на оборудовании Direct3D 11. Эти функции можно использовать в приложении для одновременного чтения из текстуры и записи в нее. То есть можно выполнять редактирование изображения на месте. Чтобы использовать эти встроенные функции преобразования формата, включите в приложение файл D3DX_DXGIFormatConvert.inl.

Заголовок D3DX_DXGIFormatConvert.inl входит в состав устаревшего пакета SDK Для DirectX. Он также входит в пакет NuGet Microsoft.DXSDK.D3DX .

Неупорядоченное представление доступа (UAV) Direct3D 11 ресурса Texture1D, Texture2D или Texture3D поддерживает произвольный доступ для чтения и записи в память из вычислительного шейдера или пиксельного шейдера. Однако Direct3D 11 поддерживает одновременное чтение и запись только в формате текстуры DXGI_FORMAT_R32_UINT. Например, Direct3D 11 не поддерживает одновременное чтение и запись в другие, более полезные форматы, такие как DXGI_FORMAT_R8G8B8A8_UNORM. Вы можете использовать только UAV для произвольного доступа к записи в такие другие форматы или использовать только представление ресурсов шейдера (SRV) для произвольного доступа к чтению из таких других форматов. Оборудование преобразования форматов недоступно для одновременного чтения и записи из таких форматов.

Однако вы по-прежнему можете одновременно выполнять чтение и запись в других форматах, приведя текстуру к формату текстуры DXGI_FORMAT_R32_UINT при создании UAV, если исходный формат ресурса поддерживает приведение к DXGI_FORMAT_R32_UINT. Большинство 32-разрядных форматов на элемент поддерживают приведение к DXGI_FORMAT_R32_UINT. Приведение текстуры к формату текстуры DXGI_FORMAT_R32_UINT при создании БПЛА позволяет одновременно выполнять операции чтения и записи в текстуру при условии, что шейдер выполняет распаковку формата вручную при чтении и упаковке при записи.

Преимущество приведения текстуры к формату DXGI_FORMAT_R32_UINT текстуры заключается в том, что позже вы сможете использовать соответствующий формат (например, DXGI_FORMAT_R16G16_FLOAT) с другими представлениями на той же текстуре, такими как представления целевых объектов отрисовки (RTVs) или SRV. Таким образом, оборудование может выполнять стандартный автоматический формат распаковки и упаковки, может выполнять фильтрацию текстур и т. д., где нет аппаратных ограничений.

В следующем сценарии требуется, чтобы приложение выполнило следующую последовательность действий для редактирования изображения на месте.

Предположим, вы хотите создать текстуру, для которой можно использовать пиксельный шейдер или вычислительный шейдер для редактирования на месте, и хотите, чтобы данные текстуры хранились в формате, который является потомком одного из следующих форматов TYPELESS:

  • DXGI_FORMAT_R10G10B10A2_TYPELESS
  • DXGI_FORMAT_R8G8B8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8X8_TYPELESS
  • DXGI_FORMAT_R16G16_TYPELESS

Например, формат DXGI_FORMAT_R10G10B10A2_UNORM является потомком формата DXGI_FORMAT_R10G10B10A2_TYPELESS. Поэтому DXGI_FORMAT_R10G10B10A2_UNORM поддерживает шаблон использования, описанный в следующей последовательности. Форматы, которые происходят от DXGI_FORMAT_R32_TYPELESS, например DXGI_FORMAT_R32_FLOAT, поддерживаются тривиально без необходимости в помощи по преобразованию формата, описанной в следующей последовательности.

Выполнение редактирования изображения на месте

  1. Создайте текстуру с соответствующим форматом, зависящим от TYPELESS, который указан в предыдущем сценарии вместе с необходимыми флагами привязки, например D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE.

  2. Для редактирования изображений на месте создайте UAV в формате DXGI_FORMAT_R32_UINT. API Direct3D 11 обычно не разрешает приведение между "семействами" разных форматов. Однако API Direct3D 11 создает исключение в формате DXGI_FORMAT_R32_UINT.

  3. В шейдере вычислений или шейдере пикселей используйте соответствующий пакет встроенного формата и распакуйте функции, предоставляемые в файле D3DX_DXGIFormatConvert.inl. Например, предположим, что DXGI_FORMAT_R32_UINT UAV текстуры действительно содержит данные в формате DXGI_FORMAT_R10G10B10A2_UNORM. После того как приложение считывает uint из UAV в шейдер, оно должно вызвать следующую функцию для распаковки формата текстуры:

    XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
    

    Затем для записи в UAV в том же шейдере приложение вызывает следующую функцию для упаковки данных шейдера в uint, который приложение может записывать в UAV:

    UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
    
  4. Затем приложение может создавать другие представления, например srv, в требуемом формате. Например, приложение может создать SRV в формате DXGI_FORMAT_R10G10B10A2_UNORM, если ресурс был создан как DXGI_FORMAT_R10G10B10A2_TYPELESS. Когда шейдер обращается к SRV, оборудование может выполнять автоматическое преобразование типов, как обычно.

Примечание

Если шейдер должен записывать данные только в БПЛА или читать как SRV, эта работа по преобразованию не требуется, так как вы можете использовать полностью типизированные БПЛА или SRV. Функции преобразования формата, предоставляемые в D3DX_DXGIFormatConvert.inl, потенциально полезны, только если требуется выполнять одновременное чтение и запись в UAV текстуры.

 

Ниже приведен список функций преобразования формата, включенных в файл D3DX_DXGIFormatConvert.inl. Эти функции классифицируются по DXGI_FORMAT, которые они распаковывают и упаковывают. Каждый из поддерживаемых форматов происходит от одного из форматов TYPELESS, перечисленных в предыдущем сценарии, и поддерживает приведение к DXGI_FORMAT_R32_UINT в качестве UAV.

DXGI_FORMAT_R10G10B10A2_UNORM

XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R10G10B10A2_UINT

XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput)
UINT    D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_UNORM

XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_UNORM_SRGB

XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)

Примечание

Функция типа _inexact использует инструкции шейдера, которые не обладают достаточной точностью для получения точного ответа. Альтернативная функция использует таблицу подстановки, хранящуюся в шейдере, для точного преобразования SRGB-float>.

 

DXGI_FORMAT_R8G8B8A8_UINT

XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput)
XMUINT  D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_SNORM

XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_SINT

XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput)
UINT   D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput)

DXGI_FORMAT_B8G8R8A8_UNORM

XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_B8G8R8A8_UNORM_SRGB

XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)

Примечание

Функция типа _inexact использует инструкции шейдера, которые не обладают достаточной точностью для получения точного ответа. Альтернативная функция использует таблицу подстановки, хранящуюся в шейдере, для точного преобразования SRGB-float>.

 

DXGI_FORMAT_B8G8R8X8_UNORM

XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput)
UINT     D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput)

DXGI_FORMAT_B8G8R8X8_UNORM_SRGB

XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput) *
XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput)
UINT     D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput)

Примечание

Функция типа _inexact использует инструкции шейдера, которые не обладают достаточной точностью для получения точного ответа. Альтернативная функция использует таблицу подстановки, хранящуюся в шейдере, для точного преобразования SRGB-float>.

 

DXGI_FORMAT_R16G16_FLOAT

XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_UNORM

XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise FLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_UINT

XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput)
UINT    D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput)

DXGI_FORMAT_R16G16_SNORM

XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_SINT

XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput)
UINT   D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput)

Руководство по программированию для HLSL

Руководство по программированию для HLSL