Типы данных

Эта глава детализирует типы данных для Металлического языка штриховки, включая типы, представляющие векторы и матрицы. Атомарные типы данных, буферы, текстуры, сэмплеры, массивы и определяемые пользователем структуры также обсуждены. Введите выравнивание, и преобразование типов также описаны.

Скалярные типы данных

Металл поддерживает скалярные типы, перечисленные в Таблице 2-1. Металл не поддерживает типы данных double, long, unsigned long, long long, unsigned long long, и long double.

Табличный 2-1  металл скалярные типы данных

Ввести

Описание

bool

Условный тип данных, имеющий значение также true или false. Значение true расширяется до целочисленного постоянного 1 и значения false расширяется до целочисленного постоянного 0.

char

Дополнительное 8-разрядное целое число two со знаком.

unsigned char

uchar

8-разрядное целое число без знака.

short

Дополнительное 16-разрядное целое число two со знаком.

unsigned short

ushort

16-разрядное целое число без знака.

int

Дополнительное 32-разрядное целое число two со знаком.

unsigned int

uint

32-разрядное целое число без знака.

half

16-разрядное с плавающей точкой. Половина типа данных должна соответствовать формату хранения IEEE 754 binary16.

float

32-разрядное с плавающей точкой. Тип данных float должен соответствовать формату хранения IEEE 754 одинарной точности.

size_t

Тип целого без знака результата sizeof оператор. Это - 64-разрядное целое без знака.

ptrdiff_t

Тип целого числа со знаком, который является результатом вычитания двух указателей. Это - 64-разрядное целое число со знаком.

void

void введите, который включает пустое множество значений; это - неполный тип, который не может быть завершен.

Векторные и матричные типы данных

Металлический язык штриховки поддерживает подмножество векторных и матричных типов данных, реализованных системной математической библиотекой вектора.

Поддерживаемые имена типа вектора:

где n 2, 3, или 4 представления 2-, 3-или типа вектора с 4 компонентами.

Матричные поддерживаемые имена типов:

где 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 спецификатор описывает, как к текстуре можно получить доступ. Поддерживаемые спецификаторы доступа:

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 описывает список поддерживаемых перечислений состояния сэмплера и их присваиваемых значений (и значения по умолчанию). Когда сэмплер инициализируется в источнике программы построения теней, эти состояния могут быть указаны.

Табличные 2-2  перечислимые величины состояния сэмплера

Перечислимое имя

Допустимые значения

Описание

coord

normalized (значение по умолчанию)

pixel

Указывает, нормализованы ли координаты текстуры при выборке от текстуры или ненормализованные значения.

address

clamp_to_edge (значение по умолчанию)

clamp_to_zero

mirrored_repeat

repeat

Устанавливает способ адресации для всех координат текстуры.

s_address

t_address

r_address

clamp_to_edge (значение по умолчанию)

clamp_to_zero

mirrored_repeat

repeat

Устанавливает способ адресации для отдельной координаты текстуры.

filter

nearest (значение по умолчанию)

linear

Устанавливает увеличение и режимы фильтрации минификации для выборки текстуры.

mag_filter

nearest (значение по умолчанию)

linear

Устанавливает режим фильтрации увеличения для выборки текстуры.

min_filter

nearest (значение по умолчанию)

linear

Устанавливает режимы фильтрации минификации для выборки текстуры.

mip_filter

none (значение по умолчанию)

nearest

linear

Устанавливает режим фильтрации множественного отображения для выборки текстуры. Если none, тогда только один уровень детализации активен.

compare_func

none (значение по умолчанию)

less

less_equal

greater

greater_equal

equal

not_equal

Сравнительное испытание наборов для использования с r координатой текстуры для схем затенения.

compare_func может только быть указан для сэмплеров, объявленных в источнике программы построения теней.

Для способа адресации, 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) ]], 
          ...)
{
    ...
}

Массивы и структуры

Массивы и структуры поддерживаются со следующими ограничениями:

Выравнивание и размер типов

Таблица 2-3 перечисляет выравнивание и размер скалярных и векторных типов данных.

Табличное 2-3  выравнивание и размер скалярных и векторных типов данных

Ввести

Выравнивание (в байтах)

Размер (в байтах)

bool

1

1

char

uchar

1

1

char2

uchar2

2

2

char3

uchar3

4

4

char4

uchar4

4

4

short

ushort

2

2

short2

ushort2

4

4

short3

ushort3

8

8

short4

ushort4

8

8

int

uint

4

4

int2

uint2

8

8

int3

uint3

16

16

int4

uint4

16

16

half

2

2

half2

4

4

half3

8

8

half4

8

8

float

4

4

float2

8

8

float3

16

16

float4

16

16

Таблица 2-4 перечисляет выравнивание и размер матричных типов данных.

Табличное 2-4  выравнивание и размер матричных типов данных

Ввести

Выравнивание (в байтах)

Размер (в байтах)

half2x2

4

8

half2x3

8

16

half2x4

8

16

half3x2

4

12

half3x3

8

24

half3x4

8

24

half4x2

4

16

half4x3

8

32

half4x4

8

32

float2x2

8

16

float2x3

16

32

float2x4

16

32

float3x2

8

24

float3x3

16

48

float3x4

16

48

float4x2

8

32

float4x3

16

64

float4x4

16

64

Так как матрица составлена из векторов, каждый столбец матрицы имеет выравнивание своего векторного компонента. Например, каждый столбец a floatnx3 матрица является a float3 вектор, который является выровненный на 16-байтовой границе, как показано в Таблице 2-3. Точно так же каждый столбец a halfnx2 матрица является a half2 вектор, который является выровненный на 4-байтовой границе.

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

Металлический языковой компилятор штриховки ответственен за выравнивание элементов данных к надлежащему выравниванию, как требуется по условию вводят. Для параметров графике или функции ядра, которая, как объявляют, была указателем на тип данных, Металлический языковой компилятор штриховки может предположить, что данные, на которые ссылается указатель, всегда соответственно выровненные, как требуется по условию вводят.

Упакованные векторные типы данных

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

Следующие упакованные имена типа вектора поддерживаются:

где n 2, 3, или 4 представления 2-, 3-или типа вектора с 4 компонентами. ( packed_booln имена типа вектора резервируются.)

Таблица 2-5 перечисляет выравнивание и размер упакованных векторных типов данных.

Табличное 2-5  выравнивание и размер упакованных векторных типов данных

Упакованный тип вектора

Выравнивание (в байтах)

sizeof (в байтах)

packed_char2

packed_uchar2

1

2

packed_char3

packed_uchar3

1

3

packed_char4

packed_uchar4

1

4

packed_short2

packed_ushort2

2

4

packed_short3

packed_ushort3

2

6

packed_short4

packed_ushort4

2

8

packed_int2

packed_uint2

4

8

packed_int3

packed_uint3

4

12

packed_int4

packed_uint4

4

16

packed_half2

2

4

packed_half3

2

6

packed_half4

2

8

packed_float2

4

8

packed_float3

4

12

packed_float4

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);