Поделиться через


Преобразование типов данных

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

Терминология типов данных

Следующий набор терминов впоследствии используется для описания различных преобразований формата.

Термин Определение
SNORM Подписанное нормализованное целое число, что означает, что для числа дополнения n-бита 2 максимальное значение означает 1,0f (например, 5-разрядное значение 01111 сопоставляется с 1,0f), а минимальное значение означает -1,0f (например, 5-разрядное значение 1000 сопоставляется с -1,0f). Кроме того, второй минимальный номер сопоставляется с -1,0f (например, 5-разрядное значение 10001 сопоставляется с -1,0f). Таким образом, существует два целых представления для -1.0f. Существует одно представление для 0.0f и одно представление для 1.0f. Это приводит к набору целых представлений для равномерно разделенных значений с плавающей запятой в диапазоне (-1,0f... 0,0f), а также дополнительный набор представлений для чисел в диапазоне (0,0f... 1.0f)
UNORM Без знака нормализованное целое число, что означает, что для n-разрядного числа все 0,0f означает 0,0f, а все 1.0f — 1,0f. Представлена последовательность равномерно разделенных значений с плавающей запятой от 0,0f до 1.0f. Например, 2-разрядный UNORM представляет 0,0f, 1/3, 2/3 и 1.0f.
SINT Целое число со знаком. Целое число 2. например, 3-разрядный SINT представляет целочисленные значения -4, -3, -2, -1, 0, 1, 2, 3.
UINT Целое число без знака. Например, 3-разрядная UINT представляет целочисленные значения 0, 1, 2, 3, 4, 5, 6, 7.
FLOAT Значение с плавающей запятой в любом из представлений, определенных Direct3D.
SRGB Аналогично UNORM, в том, что для n-битного числа все 0,0f и все 1 означает 1,0f. Однако в отличие от UNORM, с SRGB последовательность без знака целых чисел между всеми 0 до всех 1 представляют нелинейное прогрессирование в интерпретации с плавающей запятой чисел от 0,0f до 1,0f. Примерно, если эта нелинейная прогрессия, SRGB, отображается как последовательность цветов, она будет отображаться как линейная пандус уровней светимости для "среднего" наблюдателя, в условиях "среднего" просмотра, на "среднем" дисплее. Полные сведения см. в стандарте цвета SRGB, IEC 61996-2-1, в IEC (Международная электротехническая комиссия).

 

Приведенные выше термины часто используются как "Модификаторы имени формата", где описываются как данные в памяти, так и то, что преобразование для выполнения в пути транспорта (потенциально включая фильтрацию) из памяти в единицу конвейера или из единицы конвейера, например шейдера.

Преобразование с плавающей запятой

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

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

  • Циклический к нулю используется во время преобразования в другой формат с плавающей запятой. Если целевой объект является целым или фиксированным форматом точек, используется округление до ближайшего, если преобразование не задокументировано явным образом, как использование другого поведения округления, например округления к ближайшему для FLOAT к SNORM, FLOAT в UNORM или FLOAT в SRGB. Другими исключениями являются инструкции по шейдеру ftoi и ftou, которые используют циклический к нулю. Наконец, преобразования с плавающей запятой, используемые образцом текстуры и растеризатором, имеют указанную допустимость, измеряемую в Unit-Last-Place из бесконечно точного идеала.
  • Для исходных значений, превышающих динамический диапазон целевого формата нижнего диапазона (например, большое 32-разрядное значение с плавающей запятой записывается в 16-разрядное значение Float RenderTarget), максимальное представление (соответствующее подписанное) значение, не включая подписанный бесконечность (из-за округления до нуля, описанного выше).
  • NaN в более высоком формате диапазона преобразуется в представление NaN в нижнем диапазоне, если представление NaN существует в нижнем формате. Если нижний формат не имеет представления NaN, результат будет 0.
  • INF в более высоком формате диапазона будет преобразован в INF в формате нижнего диапазона, если он доступен. Если нижний формат не имеет представления INF, он будет преобразован в максимальное значение, представляющее значение. Знак будет сохранен, если он доступен в целевом формате.
  • Денорм в формате более высокого диапазона будет преобразован в представление Denorm в нижнем диапазоне, если оно доступно в нижнем диапазоне, и преобразование возможно, в противном случае результат равен 0. Бит подписи будет сохранен, если он доступен в целевом формате.

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

  • NaN в нижнем формате диапазона будет преобразован в представление NaN в формате более высокого диапазона, если оно доступно в более высоком формате. Если формат более высокого диапазона не имеет представления NaN, он будет преобразован в 0.
  • INF в нижнем формате диапазона будет преобразовано в представление INF в формате с более высоким диапазоном, если оно доступно в более высоком формате. Если более высокий формат не имеет представления INF, он будет преобразован в максимальное значение, представляющее (MAX_FLOAT в этом формате). Знак будет сохранен, если он доступен в целевом формате.
  • Денорм в нижнем диапазоне будет преобразован в нормализованное представление в формате более высокого диапазона, если это возможно, или в представление Denorm в более высоком формате, если представление Denorm существует. Если формат более высокого диапазона не имеет представления Denorm, он будет преобразован в 0. Знак будет сохранен, если он доступен в целевом формате. Обратите внимание, что 32-разрядные числа с плавающей запятой считаются форматом без представления Denorm (так как Денормс в операциях с 32-разрядными плавающими с плавающей запятой, чтобы подписать сохраненный 0).

Преобразование целых чисел

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

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

Тип исходных данных Тип данных назначения Правило преобразования
SNORM FLOAT

Учитывая n-битовое целое значение, представляющее подписанный диапазон [-1.0f до 1.0f], преобразование в плавающую точку выглядит следующим образом.

  • Наиболее отрицательное значение сопоставляется с -1,0f. Например, 5-разрядное значение 10000 сопоставляется с -1,0f.
  • Каждое другое значение преобразуется в плавающее значение (вызывает его c), а затем результат = c * (1,0f / (2⁽ⁿ⁻️⁾-1)). Например, 5-разрядное значение 10001 преобразуется в -15,0f, а затем делится на 15,0f, предоставляя -1,0f.
FLOAT SNORM

Учитывая число с плавающей запятой, преобразование в n-битовое целочисленное значение, представляющее подписанный диапазон [-1.0f до 1.0f], выглядит следующим образом.

  • Давайте представим начальное значение.
  • Если c имеет значение NaN, результат равен 0.
  • Если значение c > 1.0f, включая INF, оно зажато до 1,0f.
  • Если c < -1.0f, включая -INF, он зажат до -1.0f.
  • Преобразование из плавающей шкалы в целочисленный масштаб: c = c * (2ⁿ⁻️-1).
  • Преобразуйте в целочисленное число следующим образом.
    • Если c = 0, то c >= c + 0,5f, в противном случае c = c - 0,5f.
    • Удалите десятичную дробь, а оставшееся значение с плавающей запятой (целочисленное) преобразуется непосредственно в целое число.

Это преобразование допускает допустимость D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place Unit-Last-Place (на целочисленной стороне). Это означает, что после преобразования из плавающего в целочисленное масштабирование любое значение в D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place значения представления целевого формата разрешено сопоставить с этим значением. Дополнительное требование к инвертируемости данных гарантирует, что преобразование не создается в диапазоне и все выходные значения доступны. (В константы, показанные здесь, xx следует заменить версией Direct3D, например 10, 11 или 12.)

UNORM FLOAT

Начальное n-разрядное значение преобразуется в float (0,0f, 1.0f, 2.0f и т. д.), а затем делится на (2ⁿ-1).

FLOAT UNORM

Давайте представим начальное значение.

  • Если c имеет значение NaN, результат равен 0.
  • Если значение c > 1.0f, включая INF, оно зажато до 1,0f.
  • Если значение c < 0.0f, включая -INF, оно зажато до 0,0f.
  • Преобразование из плавающего масштаба в целочисленный масштаб: c = c * (2ⁿ-1).
  • Преобразование в целое число.
    • c = c + 0,5f.
    • Десятичная дробь удаляется, а оставшееся значение с плавающей запятой (целочисленное) преобразуется непосредственно в целое число.

Это преобразование допускает допустимость D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (на стороне целочисленного числа). Это означает, что после преобразования из плавающего в целочисленное масштабирование любое значение в D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place значения представления целевого формата разрешено сопоставить с этим значением. Дополнительное требование к инвертируемости данных гарантирует, что преобразование не создается в диапазоне и все выходные значения доступны.

SRGB FLOAT

Ниже приведено идеальное преобразование SRGB в FLOAT.

  • Возьмите начальное n-разрядное значение, преобразуйте его с плавающей запятой (0,0f, 1.0f, 2.0f и т. д.); вызовите этот c.
  • c = c * (1.0f / (2ⁿ-1))
  • If (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) затем: result = c / D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_1, else: result = ((c + D3Dxx_SRGB_TO_FLOAT_OFFSET)/D3D xx_SRGB_TO_FLOAT_DENOMINATOR_2)D3D xx_SRGB_TO_FLOAT_EXPONENT

Это преобразование допускает допустимость D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (на стороне SRGB).

FLOAT SRGB

Ниже приведено идеальное преобразование FLOAT -> SRGB.

Если целевой компонент цвета SRGB имеет n битов:

  • Предположим, что начальное значение равно c.
  • Если c имеет значение NaN, результат равен 0.
  • Если значение c > 1.0f, включая INF, зацепляется до 1,0f.
  • Если значение c < 0.0f, включая -INF, оно зажато до 0,0f.
  • If (c <= D3D xx_FLOAT_TO_SRGB_THRESHOLD) затем: c = D3D xx_FLOAT_TO_SRGB_SCALE_1 * c, else: c = D3Dxx_FLOAT_TO_SRGB_SCALE_2 * c(D3Dxx_FLOAT_TO_SRGB_EXPONENT_NUMERATOR/D3D xx_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR) - D3Dxx_FLOAT_TO_SRGB_OFFSET
  • Преобразование из плавающего масштаба в целочисленный масштаб: c = c * (2ⁿ-1).
  • Преобразование в целое число:
    • c = c + 0,5f.
    • Десятичная дробь удаляется, а оставшееся значение с плавающей запятой (целочисленное) преобразуется непосредственно в целое число.

Это преобразование допускает допустимость D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (на стороне целочисленного числа). Это означает, что после преобразования из плавающего в целочисленное масштабирование любое значение в D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place значения представления целевого формата разрешено сопоставить с этим значением. Дополнительное требование к инвертируемости данных гарантирует, что преобразование не создается в диапазоне и все выходные значения доступны.

SINT SINT с дополнительными битами

Чтобы преобразовать из SINT в SINT с большим количеством битов, самый значительный бит (MSB) начального номера является "расширенным для входа" в дополнительные биты, доступные в целевом формате.

UINT SINT с дополнительными битами

Для преобразования из UINT в SINT с большим количеством битов число копируется в наименьшие биты целевого формата (LSB), а дополнительные MSB заполняются 0.

SINT UINT с дополнительными битами

Для преобразования из SINT в UINT с большим числом битов: если отрицательное значение зажато до 0. В противном случае число копируется в LSB целевого формата, а дополнительные объекты MSB заполняются 0.

UINT UINT с дополнительными битами

Для преобразования из UINT в UINT с дополнительными битами число копируется в LSB целевого формата, а дополнительные msB заполняются 0.

SINT или UINT SINT или UINT с меньшим или равным битами

Чтобы преобразовать из SINT или UINT в SINT или UINT с меньшим или равным битами (и/или изменением в подписи), начальное значение просто зажато в диапазон целевого формата.

 

Преобразование целочисленных точек

Целые числа фиксированной точки — это просто целые числа некоторых битовых размеров, которые имеют неявную десятичную точку в фиксированном расположении.

Тип данных inbiquitous "integer" — это особый случай целого числа фиксированной точки с десятичным числом в конце числа.

Фиксированные представления чисел точек характеризуются следующим образом: i.f, где число целых битов и f — это количество дробных битов. Например, 16,8 означает 16 бит целое число, за которым следует 8 бит дробей. Целочисленная часть хранится в дополнение 2, по крайней мере как определено здесь (хотя оно может быть определено одинаково для целых чисел без знака, а также). Дробная часть хранится в форме без знака. Дробная часть всегда представляет положительную дробь между двумя ближайшими целыми значениями, начиная с самого отрицательного.

Операции сложения и вычитания с фиксированными числами точек выполняются просто с помощью арифметики стандартного целочисленного числа без каких-либо соображений, когда подразумеваемая десятичная точка лежит. Добавление 1 к 16,8 фиксированного числа точек просто означает добавление 256, так как десятичное значение равно 8 местам из наименьшего значительного конца числа. Другие операции, такие как умножение, можно выполнять, а также просто использовать целочисленную арифметику, при условии, что влияние на фиксированное десятичное значение учитывается. Например, умножение двух целых чисел 16,8 с помощью целочисленного умножения приводит к результату 32,16.

Целочисленные представления фиксированной точки используются двумя способами в Direct3D.

  • Позиции вершин после обрезки в растризаторе привязываются к фиксированной точке, чтобы равномерно распределять точность по области RenderTarget. Многие операции растеризатора, включая очистку лиц в качестве одного из примеров, происходят на позициях с привязкой к фиксированной точке, а другие операции, такие как настройка интерполятора атрибутов, используют позиции, которые были преобразованы обратно в плавающую точку с оснастки фиксированной точки.
  • Координаты текстур для операций выборки привязываются к фиксированной точке (после масштабирования по размеру текстуры), чтобы равномерно распределять точность между пространством текстуры при выборе расположений и весов фильтра. Значения веса преобразуются обратно в плавающую точку перед выполнением фактической арифметики фильтрации.
Тип исходных данных Тип данных назначения Правило преобразования
FLOAT Целое число фиксированной точки

Ниже приведена общая процедура преобразования числа с плавающей запятой n в целое число фиксированной точки i.f, где число целочисленных (подписанных) битов и f — количество дробных битов.

  • Compute FixedMin = -2⁽ⁱ⁻⁻ ⁾
  • Compute FixedMax = 2⁽ⁱ⁻⁾ - 2(-f)
  • Если n является naN, результат = 0; Значение , если n равно +Inf, результат = FixedMax*2f; если n равно -Inf, результат = FixedMin*2f
  • Если n = FixedMax, результат = Fixedmax*2 f; если n ><= FixedMin, результат = FixedMin*2f
  • Другие вычисления n*2f и преобразование в целочисленное число.

Реализации допускаются D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP допустимость единиц последнего места в целочисленном результате вместо бесконечно точного значения n*2f после последнего шага выше.

Целое число фиксированной точки FLOAT

Предположим, что определенное представление фиксированной точки, преобразованное в float, не содержит более 24 бит информации, не более 23 бит, из которых находится в дробном компоненте. Предположим, что заданный номер фиксированной точки, fxp, находится в форме i.f (i bits целое число, дробь битов). Преобразование в плавающее значение равно следующему псевдокоду.

float result = (float)(fxp >> f) + // extract integer

((float)(fxp & (2 f - 1)) / (2f)); // извлечение дроби

 

Приложения