Типы данных
Эта глава детализирует типы данных для Металлического языка штриховки, включая типы, представляющие векторы и матрицы. Атомарные типы данных, буферы, текстуры, сэмплеры, массивы и определяемые пользователем структуры также обсуждены. Введите выравнивание, и преобразование типов также описаны.
Скалярные типы данных
Металл поддерживает скалярные типы, перечисленные в Таблице 2-1. Металл не поддерживает типы данных double
, long
, unsigned long
, long long
, unsigned long long
, и long double
.
Ввести | Описание |
---|---|
| Условный тип данных, имеющий значение также |
| Дополнительное 8-разрядное целое число two со знаком. |
| 8-разрядное целое число без знака. |
| Дополнительное 16-разрядное целое число two со знаком. |
| 16-разрядное целое число без знака. |
| Дополнительное 32-разрядное целое число two со знаком. |
| 32-разрядное целое число без знака. |
| 16-разрядное с плавающей точкой. Половина типа данных должна соответствовать формату хранения IEEE 754 binary16. |
| 32-разрядное с плавающей точкой. Тип данных float должен соответствовать формату хранения IEEE 754 одинарной точности. |
| Тип целого без знака результата |
| Тип целого числа со знаком, который является результатом вычитания двух указателей. Это - 64-разрядное целое число со знаком. |
| |
Векторные и матричные типы данных
Металлический язык штриховки поддерживает подмножество векторных и матричных типов данных, реализованных системной математической библиотекой вектора.
Поддерживаемые имена типа вектора:
booln
charn, shortn, intn, ucharn, ushortn, uintn
halfn
иfloatn
где n
2, 3, или 4 представления 2-, 3-или типа вектора с 4 компонентами.
Матричные поддерживаемые имена типов:
halfnxm
иfloatnxm
где n
и m
число столбцов и строк. n
и m
может быть 2, 3, или 4. Матрица составлена из нескольких векторов. Например, a floatnx3
матрица составлена из n
float3
векторы. Точно так же a halfnx4
матрица составлена из n
half4
векторы.
Доступ к векторным компонентам
К векторным компонентам можно получить доступ с помощью индекса массива. Индекс массива 0 относится к первому компоненту вектора, индекса 1 к второму компоненту, и т.д. Следующие примеры показывают различные способы получить доступ к компонентам массива:
pos = float4(1.0f, 2.0f, 3.0f, 4.0f); float x = pos[0]; // x = 1.0 float z = pos[2]; // z = 3.0 float4 vA = float4(1.0f, 2.0f, 3.0f, 4.0f); float4 vB; for (int i=0; i<4; i++) vB[i] = vA[i] * 2.0f // vB = (2.0, 4.0, 6.0, 8.0); |
Металлические поддержки с помощью периода (.) в качестве оператора выбора к компонентам вектора доступа, с помощью букв, которые могут указать координатные или цветные данные: <vector_data_type>.xyzw
или <vector_data_type>.rgba
.
В следующем коде, векторе test
инициализируется и затем к компонентам получают доступ с помощью .xyzw
или .rgba
синтаксис выбора:
int4 test = int4(0, 1, 2, 3); int a = test.x; // a = 0 int b = test.y; // b = 1 int c = test.z; // c = 2 int d = test.w; // d = 3 int e = test.r; // e = 0 int f = test.g; // f = 1 int g = test.b; // g = 2 int h = test.a; // h = 3 |
Синтаксис выбора компонента позволяет многократным компонентам быть выбранными.
float4 c; |
c.xyzw = float4(1.0f, 2.0f, 3.0f, 4.0f); |
c.z = 1.0f; |
c.xy = float2(3.0f, 4.0f); |
c.xyz = float3(3.0f, 4.0f, 5.0f); |
Синтаксис выбора компонента также позволяет компонентам быть переставленными или тиражированными.
float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); |
float4 swiz = pos.wzyx; // swiz = (4.0f, 3.0f, 2.0f, 1.0f) |
float4 dup = pos.xxyy; // dup = (1.0f, 1.0f, 2.0f, 2.0f) |
Нотация группы компонента может произойти на левой стороне выражения. Для формирования lvalue swizzling может быть применен. Получающийся lvalue может быть или скаляра или типа вектора, в зависимости от числа указанных компонентов. Каждый компонент должен быть поддерживаемым скалярным или типом вектора. Получающийся lvalue типа вектора не должен содержать двойные компоненты.
float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); // pos = (5.0, 2.0, 3.0, 6.0) pos.xw = float2(5.0f, 6.0f); // pos = (8.0, 2.0, 3.0, 7.0) pos.wx = float2(7.0f, 8.0f); // pos = (3.0, 5.0, 9.0, 7.0) pos.xyz = float3(3.0f, 5.0f, 9.0f); |
Следующие методы векторного доступа компонента не разрешены и результат в ошибке времени компиляции:
Доступ к компонентам вне объявленных для типа вектора является ошибкой. Двухкомпонентные векторные типы данных могут получить доступ только
.xy
или.rg
элементы. Трехкомпонентные векторные типы данных могут получить доступ только.xyz
или.rgb
элементы. Например:float2 pos;
pos.x = 1.0f; // is legal; so is y
pos.z = 1.0f; // is illegal; so is w
float3 pos;
pos.z = 1.0f; // is legal
pos.w = 1.0f; // is illegal
Доступ к тому же компоненту дважды на левой стороне неоднозначен. Например:
// illegal - 'x' used twice
pos.xx = float2(3.0f, 4.0f);
// illegal - mismatch between float2 and float4
pos.xy = float4(1.0f, 2.0f, 3.0f, 4.0f);
.rgba
и.xyzw
спецификаторы не могут быть смешаны в одиночном обращении. Например:float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); pos.x = 1.0f; // OK pos.g = 2.0f; // OK pos.xg = float2(3.0f, 4.0f); // illegal - mixed qualifiers used float3 coord = pos.ryz; // illegal - mixed qualifiers used
Swizzling не может использоваться с указателем или ссылкой. Например:
float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f);
my_func(&pos.xy); // illegal
sizeof
оператор на типе вектора возвращает размер вектора, данного как число компонентов * размер каждого компонента. Например, sizeof(float4)
возвраты 16 и sizeof(half4)
возвраты 8.
Доступ к матричным компонентам
floatnxm
и halfnxm
к матрицам можно получить доступ как массив n floatm
или n halfm
записи.
К компонентам матрицы можно получить доступ с помощью синтаксиса преобразования в нижний индекс массива. Применение единственного нижнего индекса к матрице обрабатывает матрицу как массив векторов столбца. Первый столбец является столбцом 0. Второй нижний индекс тогда воздействует на итоговый вектор, как определено ранее для векторов. Следовательно, два нижних индекса выбирают столбец и затем строку.
float4x4 m; |
// sets the 2nd column to all 2.0 |
m[1] = float4(2.0f); |
// sets the 1st element of the 1st column to 1.0 |
m[0][0] = 1.0f; |
// sets the 4th element of the 3rd column to 3.0 |
m[2][3] = 3.0f; |
Доступ к компоненту вне границ матрицы с непостоянным выражением приводит к неопределенному поведению. Доступ к матричному компоненту, который является вне границ матрицы с константным выражением, генерирует ошибку времени компиляции.
Векторные конструкторы
Конструкторы могут использоваться для создания векторов из ряда скаляров или векторов. Когда вектор инициализируется, его подпись параметра определяет, как он создается. Например, если вектор инициализируется с только единственным скалярным параметром, все компоненты созданного вектора установлены в то скалярное значение.
Если вектор создается из многократных скаляров, одного или более векторов или смеси их, компоненты вектора создаются в порядке от компонентов параметров. Параметры используются слева направо. Каждый параметр имеет все свои использованные компоненты в порядке, прежде чем будут использованы любые компоненты от следующего параметра.
Это - полный список конструкторов, которые доступны для float4
:
float4(float x); float4(float x, float y, float z, float w); float4(float2 a, float2 b); float4(float2 a, float b, float c); float4(float a, float b, float2 c); float4(float a, float2 b, float c); float4(float3 a, float b); float4(float a, float3 b); float4(float4 x); |
Это - полный список конструкторов, которые доступны для float3
:
float3(float x); |
float3(float x, float y, float z); |
float3(float a, float2 b); |
float3(float2 a, float b); |
float3(float3 x); |
Это - полный список конструкторов, которые доступны для float2
:
float2(float x); |
float2(float x, float y); |
float2(float2 x); |
Следующие примеры иллюстрируют использование конструкторов:
float x = 1.0f, y = 2.0f, z = 3.0f, w = 4.0f; float4 a = float4(0.0f); float4 b = float4(x, y, z, w); float2 c = float2(5.0f, 6.0f); float2 a = float2(x, y); float2 b = float2(z, w); float4 x = float4(a.xy, b.xy); |
Underinitializing векторный конструктор является ошибкой времени компиляции.
Матричные конструкторы
Конструкторы могут использоваться для создания матриц из ряда скаляров, векторов или матриц. Когда матрица инициализируется, ее подпись параметра определяет, как она создается. Например, если матрица инициализируется с только единственным скалярным параметром, результатом является матрица, содержащая тот скаляр для всех компонентов диагонали матрицы с остающимися компонентами, инициализированными к 0,0. Например, вызов к
float4x4(fval); |
где fval
скалярное значение с плавающей точкой, создает матрицу с этим начальным содержанием:
fval 0.0 0.0 0.0 |
0.0 fval 0.0 0.0 |
0.0 0.0 fval 0.0 |
0.0 0.0 0.0 fval |
Матрица может также быть создана из другой матрицы, имеющей тот же размер, т.е. имеющей то же число строк и столбцов. Например:
float3x4(float3x4); |
float3x4(half3x4); |
Матричные компоненты создаются и используются в порядке развертывания по столбцам. У матричного конструктора должно быть как раз достаточно значений, указанных в его параметрах для инициализации каждого компонента в созданном матричном объекте. Обеспечение большего количества параметров, чем необходимо результаты по ошибке. Underinitializing матричный конструктор также приводит к ошибке времени компиляции.
Матрица типа T
с n
столбцы и m
строки могут также быть созданы из n
векторы типа T
с m
компоненты. Следующими примерами являются юридические конструкторы:
float2x2(float2, float2); |
float3x3(float3, float3, float3); |
float3x2(float2, float2, float2); |
Следующее является примерами не поддерживающихся матричных конструкторов. Матрица не может быть создана из многократных скалярных значений, ни из комбинаций векторов и скаляров.
// both cases below are not supported |
float2x2(float a00, float a01, float a10, float a11); |
float2x3(float2 a, float b, float2 c, float d); |
Атомарные типы данных
Металлический атомарный тип данных ограничивается для использования атомарными функциями, реализованными Металлическим языком штриховки, как описано в Атомарных Функциях. Эти атомарные функции являются подмножеством C++ 11 атомарных и функции синхронизации. Металлические атомарные функции должны воздействовать на Металлические атомарные данные.
Металлические атомарные типы определяются как atomic_int
и atomic_uint
.
Буферы
Металл реализует буферы как указатель на встроенный или определяемый пользователем тип данных, описанный в device
или constant
адресное пространство. (Обратитесь к Спецификаторам Адресного пространства для Переменных и Параметрам за полное описание этих спецификаторов адреса.) Эти буферы могут быть объявлены в объеме программы или переданы как параметры функции.
Например:
device float4 *device_buffer; |
struct my_user_data { |
float4 a; |
float b; |
int2 c; |
}; |
constant my_user_data *user_data; |
Текстуры
Тип данных текстуры является дескриптором к одному - два - или трехмерные данные текстуры, соответствующие всем или части единственного уровня множественного отображения текстуры. Следующие шаблоны определяют определенные типы данных текстуры:
enum class access { sample, read, write }; texture1d<T, access a = access::sample> texture1d_array<T, access a = access::sample> texture2d<T, access a = access::sample> texture2d_array<T, access a = access::sample> texture3d<T, access a = access::sample> texturecube<T, access a = access::sample> texture2d_ms<T, access a = access::read> |
Текстуры с форматами глубины должны быть объявлены как один из следующих типов данных текстуры:
enum class depth_format { depth_float }; depth2d<T, access a = access::sample, depth_format d = depth_format::depth_float> depth2d_array<T, access a = access::sample, depth_format d = depth_format::depth_float> depthcube<T, access a = access::sample, depth_format d = depth_format::depth_float> depth2d_ms<T, access a = access::read, depth_format d = depth_format::depth_float> |
T
указывает, что тип цвета возвратился при чтении из текстуры, или тип цвета указал при записи в текстуру. Для типов текстуры (кроме глубины текстурируют типы), T
может быть half
, float
, short
, ushort
, int
, или uint
. Поскольку глубина текстурирует типы, T
должен быть float
.
access
спецификатор описывает, как к текстуре можно получить доступ. Поддерживаемые спецификаторы доступа:
sample
- Объект текстуры может быть выбран.sample
подразумевает возможность читать из текстуры с и без сэмплера.read
- Без сэмплера графика или функция ядра могут только считать объект текстуры.write
– Графика или функция ядра могут записать в объект текстуры.
depth_format
спецификатор описывает формат текстур глубины. Единственное поддерживаемое значение depth_format
.
Следующий пример использует эти спецификаторы доступа с параметрами объекта текстуры:
void foo (texture2d<float> imgA [[ texture(0) ]], |
texture2d<float, access::read> imgB [[ texture(1) ]], |
texture2d<float, access::write> imgC [[ texture(2) ]]) |
{ |
... |
} |
(См. Спецификаторы Атрибута для Определения местоположения Ресурсов для описания texture
спецификатор атрибута.)
Сэмплеры
На Металлическом языке штриховки, sampler
тип идентифицирует, как выбрать текстуру. Металлическая платформа позволяет Вам создавать соответствие MTLSamplerState
объект и передача это в параметре графике или функции ядра. A sampler
объект может также быть описан в источнике программы построения теней вместо в Металлической платформе. Источник программы построения теней позволяет указывать только подмножество состояния сэмплера: способ адресации, режим фильтра, нормализованные координаты и функция сравнения.
Таблица 2-2 описывает список поддерживаемых перечислений состояния сэмплера и их присваиваемых значений (и значения по умолчанию). Когда сэмплер инициализируется в источнике программы построения теней, эти состояния могут быть указаны.
Перечислимое имя | Допустимые значения | Описание |
---|---|---|
|
| Указывает, нормализованы ли координаты текстуры при выборке от текстуры или ненормализованные значения. |
|
| Устанавливает способ адресации для всех координат текстуры. |
|
| Устанавливает способ адресации для отдельной координаты текстуры. |
|
| Устанавливает увеличение и режимы фильтрации минификации для выборки текстуры. |
|
| Устанавливает режим фильтрации увеличения для выборки текстуры. |
|
| Устанавливает режимы фильтрации минификации для выборки текстуры. |
|
| Устанавливает режим фильтрации множественного отображения для выборки текстуры. Если |
|
| Сравнительное испытание наборов для использования с r координатой текстуры для схем затенения. |
Для способа адресации, clamp_to_zero
подобно способу адресации зажима к границе OpenGL, за исключением того, что значение цвета рамки всегда (0.0, 0.0, 0.0, 1.0) при выборке вне текстуры, не имеющей альфа-компонента, и это (0.0, 0.0, 0.0, 0.0) при выборке вне текстуры, имеющей альфа-компонент.
Типы перечисления, используемые типом данных сэмплера, как описано в Таблице 2-2, указаны следующим образом. (Если coord
установлен в pixel
, min_filter
и mag_filter
значения должны быть тем же, mip_filter
и compare_func
значения должны быть none
, и режимы адреса должны быть также clamp_to_zero
или clamp_to_edge
.)
enum class coord { normalized, pixel }; enum class filter { nearest, linear }; enum class min_filter { nearest, linear }; enum class mag_filter { nearest, linear }; enum class s_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat }; enum class t_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat }; enum class r_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat }; enum class address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat }; enum class mip_filter { none, nearest, linear }; // can only be used with depth_sampler enum class compare_func { none, less, less_equal, greater, greater_equal, equal, not_equal }; |
Металлический язык штриховки реализует объект сэмплера следующим образом:
struct sampler { |
public: |
// full version of sampler constructor |
template<typename... Ts> |
constexpr sampler(Ts... sampler_params){}; |
private: |
}; |
Ts
должны быть типы перечисления, упомянутые выше, который может использоваться типом данных сэмплера. Если тот же тип перечисления будет объявлен многократно в данном конструкторе сэмплера, то последнее перечисленное значение вступит в силу.
Следующий источник программы построения теней иллюстрирует несколько способов объявить сэмплеры. Спецификаторы атрибута (sampler(n)
, buffer(n)
, и texture(n)
) это появляется в коде ниже, объяснены в Спецификаторах Атрибута для Определения местоположения Ресурсов. Обратите внимание на то, что сэмплерам или постоянным буферам, объявленным в источнике программы построения теней, не нужны эти спецификаторы атрибута.
constexpr sampler s(coord::pixel, address::clamp_to_zero, filter::linear); constexpr sampler a(coord::normalized); constexpr sampler b(address::repeat); constexpr sampler s(address::clamp_to_zero, filter::linear, compare_func::less); kernel void my_kernel(device float4 *p [[ buffer(0) ]], texture2d<float4> img [[ texture(0) ]], sampler smp [[ sampler(3) ]], ...) { ... } |
Массивы и структуры
Массивы и структуры поддерживаются со следующими ограничениями:
Массивы текстуры и типов сэмплера не поддерживаются.
texture
иsampler
типы не могут быть объявлены в структуре.Параметры графике и функциям ядра, как могут объявлять, не имеют тип
size_t
,ptrdiff_t
, или структура и/или объединение, содержащее элементы, которые, как объявляют, были одним из этих встроенных скалярных типов.Элементы структуры должны принадлежать тому же адресному пространству.
Выравнивание и размер типов
Таблица 2-3 перечисляет выравнивание и размер скалярных и векторных типов данных.
Ввести | Выравнивание (в байтах) | Размер (в байтах) |
---|---|---|
| 1 | 1 |
| 1 | 1 |
| 2 | 2 |
| 4 | 4 |
| 4 | 4 |
| 2 | 2 |
| 4 | 4 |
| 8 | 8 |
| 8 | 8 |
| 4 | 4 |
| 8 | 8 |
| 16 | 16 |
| 16 | 16 |
| 2 | 2 |
| 4 | 4 |
| 8 | 8 |
| 8 | 8 |
| 4 | 4 |
| 8 | 8 |
| 16 | 16 |
| 16 | 16 |
Таблица 2-4 перечисляет выравнивание и размер матричных типов данных.
Ввести | Выравнивание (в байтах) | Размер (в байтах) |
---|---|---|
| 4 | 8 |
| 8 | 16 |
| 8 | 16 |
| 4 | 12 |
| 8 | 24 |
| 8 | 24 |
| 4 | 16 |
| 8 | 32 |
| 8 | 32 |
| 8 | 16 |
| 16 | 32 |
| 16 | 32 |
| 8 | 24 |
| 16 | 48 |
| 16 | 48 |
| 8 | 32 |
| 16 | 64 |
| 16 | 64 |
Так как матрица составлена из векторов, каждый столбец матрицы имеет выравнивание своего векторного компонента. Например, каждый столбец a floatnx3
матрица является a float3
вектор, который является выровненный на 16-байтовой границе, как показано в Таблице 2-3. Точно так же каждый столбец a halfnx2
матрица является a half2
вектор, который является выровненный на 4-байтовой границе.
alignas
спецификатор выравнивания может использоваться для указания требования выравнивания типа или объекта. alignas
спецификатор может быть применен к объявлению переменной или элементу данных структуры или класса. Это может также быть применено к объявлению структуры, класса или типа перечисления.
Металлический языковой компилятор штриховки ответственен за выравнивание элементов данных к надлежащему выравниванию, как требуется по условию вводят. Для параметров графике или функции ядра, которая, как объявляют, была указателем на тип данных, Металлический языковой компилятор штриховки может предположить, что данные, на которые ссылается указатель, всегда соответственно выровненные, как требуется по условию вводят.
Упакованные векторные типы данных
Векторные типы данных, описанные в Векторных и Матричных Типах данных, выровненные к размеру вектора. Существует много вариантов использования, где разработчики требуют, чтобы были плотно упакованы их векторные данные. Одним примером является структура вершины, которая может содержать позицию, нормальную, векторы касательной и координаты текстуры, плотно упакованные и переданные как буфер функции вершины.
Следующие упакованные имена типа вектора поддерживаются:
packed_charn
,packed_shortn
,packed_intn
,packed_ucharn
,packed_ushortn
,packed_uintn
,packed_halfn
, иpacked_floatn
где n
2, 3, или 4 представления 2-, 3-или типа вектора с 4 компонентами. ( packed_booln
имена типа вектора резервируются.)
Таблица 2-5 перечисляет выравнивание и размер упакованных векторных типов данных.
Упакованный тип вектора | Выравнивание (в байтах) | sizeof (в байтах) |
---|---|---|
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 4 |
| 2 | 6 |
| 2 | 8 |
| 4 | 8 |
| 4 | 12 |
| 4 | 16 |
| 2 | 4 |
| 2 | 6 |
| 2 | 8 |
| 4 | 8 |
| 4 | 12 |
| 4 | 16 |
Упакованные векторные типы данных обычно используются в качестве формата хранения данных. Металлическая загрузка поддержек и хранение от упакованного векторного типа данных до выровненного векторного типа данных и наоборот. Скопируйте конструкторов, и операторы присваивания также поддерживаются. Арифметика, логические, и операторы отношения также поддерживаются для упакованных векторных типов данных.
Пример:
device float4 *buffer; device packed_float4 *packed_buffer; int i; packed_float4 f ( buffer[i] ); pack_buffer[i] = buffer[i]; // operator to convert from packed_float4 to float4. buffer[i] = float4( packed_buffer[i] ); |
К компонентам упакованного векторного типа данных можно получить доступ с индексом массива. Однако к компонентам упакованного векторного типа данных нельзя получить доступ с .xyzw
или .rgba
синтаксис выбора.
Пример:
packed_float4 f; |
f[0] = 1.0f; // OK |
f.x = 1.0f; // Illegal - compilation error |
Неявные преобразования типов
Металл поддерживает неявные преобразования между скалярными встроенными типами (кроме void
). Когда неявное преобразование выполняется, это не просто реинтерпретация значения выражения, но и преобразование того значения к эквивалентной стоимости в новом типе. Например, целочисленное значение 5 преобразовывается в значение с плавающей точкой 5.0.
Все типы векторов, как полагают, имеют более высокий разряд преобразования, чем скалярные типы. Неявные преобразования от типа вектора до другого векторного или скалярного типа не разрешены, и ошибка компиляции заканчивается. Например, следующая попытка преобразовать от целочисленного вектора с 4 компонентами до вектора с плавающей точкой с 4 компонентами перестала работать:
int4 i; |
float4 f = i; // compile error |
Поддерживаются неявные преобразования от скаляра до типов векторов. Скалярное значение тиражировано в каждый элемент вектора. Скаляр может также подвергнуться обычному арифметическому преобразованию в тип элемента, используемый вектором или матрицей.
Например:
float4 f = 2.0f; // f = (2.0f, 2.0f, 2.0f, 2.0f) |
Неявные преобразования от скаляра до матричных типов и от вектора до матричных типов не поддерживаются, и ошибка компиляции заканчивается. Неявные преобразования от матричного типа до другой матрицы, векторный или скалярный тип не разрешен, и ошибка компиляции заканчивается.
Неявные преобразования для типов указателей соблюдают правила, описанные в C++ 11 Спецификаций [PDF].
Преобразования типов и данные иного толкования
Металл использует static_cast
оператор для преобразования от скалярного или типа вектора до другого скалярного или типа вектора без насыщенности и с режимом округления значения по умолчанию. В зависимости от округляющихся режимов, поддерживаемых GPU, преобразовывая до мая с плавающей точкой вокруг к нулю или к самому близкому четному числу по умолчанию. При преобразовании в целое число режим по умолчанию округляется к нулю. Если исходный тип является скалярной или векторной булевской переменной, значением false
преобразовывается в нуль и значение true
преобразовывается в одного.
Металлический язык штриховки добавляет as_type<type-id>
оператор для разрешения любого скалярного или векторного типа данных (который не является указателем) быть данным иное толкование как другой скалярный или векторный тип данных того же размера. Биты в операнде возвращаются непосредственно без модификации как новый тип. Обычное продвижение типа для аргументов функции не выполняется.
Например, as_type<float>(0x3f800000)
возвраты 1.0f, который является значением комбинации двоичных разрядов 0x3f800000
если просматривается как значение одинарной точности IEEE 754.
Это - ошибка использовать as_type<type-id>
оператор для иного толкования данным к типу, имеющему различное число байтов.
Вот некоторые примеры юридических и недопустимых преобразований с помощью as_type<type-id>
оператор:
float f = 1.0f; // Legal. Contains: 0x3f800000 uint u = as_type<uint>(f); // Legal. Contains: // (int4)(0x3f800000, 0x40000000, // 0x40400000, 0x40800000) float4 f = float4(1.0f, 2.0f, 3.0f, 4.0f); int4 i = as_type<int4>(f); int i; // Legal. short2 j = as_type<short2>(i); half4 f; // Error. Result and operand have different sizes float4 g = as_type<float4>(f); float4 f; // Legal. g.xyz will have same values as f.xyz. // g.w is undefined float3 g = as_type<float3>(f); |