Графика (C++ AMP)

C++ AMP содержит несколько API в Concurrency::graphics пространстве имен, которые можно использовать для доступа к поддержке текстур в GPU. Ниже описываются наиболее типичные сценарии применения:

  • Класс можно использовать texture в качестве контейнера данных для вычислений и использовать пространственное расположение кэша текстур и макетов оборудования GPU. Пространственная локальность — это свойство элементов данных, заключающееся в их близком физическом расположении друг к другу;

  • среда выполнения обеспечивает эффективное взаимодействие с невычислительными шейдерами. Шейдеры пикселей, вершин, тесселяции и поверхностей часто используют или создают текстуры, которые можно использовать в вычислениях C++ AMP;

  • графические API в C++ AMP предоставляет альтернативные способы доступа к буферам, упакованным в подслова. Текстуры, имеющие форматы, представляющие тексели (элементы текстуры), состоящие из 8-разрядных или 16-разрядных скаляр, позволяют получить доступ к такому упакованном хранилищу данных.

Примечание.

Заголовки C++ AMP устарели начиная с Visual Studio 2022 версии 17.0. Включение всех заголовков AMP приведет к возникновению ошибок сборки. Определите _SILENCE_AMP_DEPRECATION_WARNINGS перед включением всех заголовков AMP, чтобы замолчать предупреждения.

Типы norm и unorm

И normunorm типы — скалярные типы, ограничивающие диапазон значений float . Это называется зажатием. Эти типы могут быть созданы из других скалярных типов явным образом. При приведение значение сначала приведение float , а затем зажато в соответствующем регионе, разрешенном norm [-1.0, 1.0] или unorm [0.0, 1.0]. Приведение из +/- бесконечности возвращает +/-1. Приведение из NaN не определено. Может norm быть неявно создано из неявного unorm и нет потери данных. Оператор неявного преобразования float определяется для этих типов. Двоичные операторы определяются между этими типами и другими встроенными скалярными типами, такими как floatintи : +-, ><=<==>=*/!=. Операторы составного назначения также поддерживаются: +=, -=, *=. /= Унарный оператор отрицания (-) определен для norm типов.

Библиотека коротких векторов

Библиотека коротких векторов предоставляет некоторые функции типа вектора, определенного в HLSL, и обычно используется для определения текселей. Короткий вектор — это структура данных, которая содержит от одного до четырех значений одного типа. Поддерживаемые типы: double, float, int, normи uintunorm. Имена типов показаны в следующей таблице. Для каждого типа также имеется соответствующий typedef знак подчеркивания в имени. Типы, имеющие знаки подчеркивания, находятся в пространстве имен параллелизма::graphics. Типы, которые не имеют подчеркивания, находятся в пространстве имен concurrency::graphics::d irect3d Namespace , чтобы они четко отделялись от аналогичных именованных фундаментальных типов, таких как __int8 и __int16.

Тип Длина 2 Длина 3 Длина 4
двойной точности double_2

double2
double_3

double3
double_4

double4
с плавающей запятой float_2

float2
float_3

float3
float_4

float4
INT int_2

int2
int_3

int3
int_4

int4
norm norm_2

norm2
norm_3

norm3
norm_4

norm4
uint uint_2

uint2
uint_3

uint3
uint_4

uint4
unorm unorm_2

unorm2
unorm_3

unorm3
unorm_4

unorm4

Операторы

Если оператор определен между двумя короткими векторами, то он также определен между коротким вектором и скаляром. Кроме того, должно выполняться одно из следующих утверждений:

  • Тип скалярного объекта должен совпадать с типом элемента короткого вектора.

  • Тип скалярного объекта можно неявно преобразовать в тип элемента вектора с помощью только одного пользовательского преобразования.

Операция выполняется покомпонентно между каждым компонентом короткого вектора и скаляром. Ниже приведены допустимые операторы.

Тип оператора Допустимые типы
Бинарные операторы Допустимо для всех типов: +, -, *, /

Допустимо для целых типов: %, ^, |, &<<>>

Два вектора должны иметь одинаковый размер, а результат будет вектором такого же размера.
Реляционные операторы Допустимо для всех типов: ==!=
Составной оператор присваивания Допустимый для всех типов: +=, -=, *=/=

Допустимо для целых типов: %=, ^=, |=, &=<<=>>=
Операторы инкремента и декремента Допустимо для всех типов: ++, --

Как префиксная, так и постфиксная формы являются допустимыми.
Побитовый оператор NOT (~) Допустим для целочисленных типов.
Унарный - оператор Допустим для всех типов, за исключением unorm и uint.

Группирующие выражения

Библиотека коротких векторов поддерживает конструкции метода доступа вида vector_type.identifier для обращения к компонентам короткого вектора. Выражение identifier, которое называется вращающееся выражением, указывает компоненты вектора. Выражение может быть l-значением или r-значением. Отдельные символы в идентификаторе могут быть: x, y, z и w; или r, g, b и a. "x" и "r" означает нулевой компонент, "y" и "g" означает первый компонент и т. д. (Обратите внимание, что "x" и "r" нельзя использовать в одном идентификаторе.) Поэтому "rgba" и "xyzw" возвращают тот же результат. Методы доступа из одного компонента, такие как "x" и "y", являются скалярными типами значений. Многокомпонентные методы доступа — типы короткого вектора. Например, если есть вектор int_4 с именем fourInts и значениями 2, 4, 6 и 8, то fourInts.y возвращает целое число 4, а fourInts.rg — объект int_2 со значениями 2 и 4.

Классы текстуры

Многие графические процессоры имеют аппаратные компоненты и кэши, оптимизированные для получения пикселов и текселей и визуализации изображений и текстур. Класс texture<T,N> , являющийся классом контейнера для объектов texel, предоставляет функциональные возможности текстур этих GPU. Тексель может быть:

  • , int, uintnormfloatdoubleunorm или скалярный.

  • коротким вектором, который содержит 2 или 4 компонента. Единственное исключение — тип double_4, который не разрешен.

Объект texture может иметь ранг 1, 2 или 3. Объект texture может быть перехвачен только по ссылке в лямбда-выражении в вызове метода parallel_for_each. Текстура хранится в GPU в виде объектов текстуры Direct3D. Дополнительные сведения о текстурах и текселях в Direct3D см. в статье "Общие сведения о текстурах в Direct3D 11".

В качестве типа текселя можно использовать одним из множества различных форматов текстур, которые используются при программировании графики. Например, формат RGBA может использовать 32 бита, по 8 бит на каждый из скалярных элементов R, G, B и A. Текстурные компоненты видеокарты могут обращаться к отдельным элементам текстуры в зависимости от формата. Например, если используется формат RGBA, то текстурные компоненты могут извлекать каждый 8-битный элемент в 32-битное представление. В C++ AMP можно задать количество бит на один скалярный элемент текселя, что позволяет автоматически обращаться к отдельным скалярным элементам в коде без использования битовых сдвигов.

Создание объектов текстуры

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

#include <amp.h>
#include <amp_graphics.h>
using namespace concurrency;
using namespace concurrency::graphics;

void declareTextures() {
    // Create a 16-texel texture of int.
    texture<int, 1> intTexture1(16);
    texture<int, 1> intTexture2(extent<1>(16));

    // Create a 16 x 32 texture of float_2.
    texture<float_2, 2> floatTexture1(16, 32);
    texture<float_2, 2> floatTexture2(extent<2>(16, 32));

    // Create a 2 x 4 x 8 texture of uint_4.
    texture<uint_4, 3> uintTexture1(2, 4, 8);
    texture<uint_4, 3> uintTexture2(extent<3>(2, 4, 8));
}

Кроме того, для объявления и инициализации объектов texture можно использовать конструкторы. В следующем примере кода создается объект texture из вектора объектов float_4. Количество битов на один скалярный элемент установлено по умолчанию. Нельзя использовать этот конструктор с norm, unorm или с короткими векторами norm и unorm, поскольку они не имеют количества бит по умолчанию на один скалярный элемент.

#include <amp.h>
#include <amp_graphics.h>
#include <vector>
using namespace concurrency;
using namespace concurrency::graphics;

void initializeTexture() {
    std::vector<int_4> texels;
    for (int i = 0; i < 768 * 1024; i++) {
        int_4 i4(i, i, i, i);
        texels.push_back(i4);
    }

    texture<int_4, 2> aTexture(768, 1024, texels.begin(), texels.end());
}

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

void createTextureWithBPC() { // Create the source data.
    float source[1024* 2];
    for (int i = 0; i <1024* 2; i++) {
        source[i] = (float)i;
    }
    // Initialize the texture by using the size of source in bytes // and bits per scalar element.
    texture<float_2, 1> floatTexture(1024, source, (unsigned int)sizeof(source), 32U);
}

Текстуры в этих примерах созданы в представлении по умолчанию ускорителя по умолчанию. Можно использовать другие перегрузки конструктора, если нужно определить объект accelerator_view. Объект текстуры нельзя создать в ускорителе ЦП.

Существуют ограничения на размер каждого измерения объекта texture, показанные в следующей таблице. Если пределы превышены, то возникает ошибка времени выполнения.

Текстура Ограничение размера на измерение
текстура<T,1> 16384
текстура<T,2> 16384
текстура<T,3> 2048

Чтение из объектов текстуры

Считывать из texture объекта можно с помощью метода texture:::operator[], texture::operator() или texture::get. Два оператора возвращают значение, а не ссылку. Поэтому нельзя осуществлять запись в объект texture с помощью texture::operator\[\].

void readTexture() {
    std::vector<int_2> src;
    for (int i = 0; i <16 *32; i++) {
        int_2 i2(i, i);

        src.push_back(i2);
    }

    std::vector<int_2> dst(16* 32);

    array_view<int_2, 2> arr(16, 32, dst);

    arr.discard_data();

    const texture<int_2, 2> tex9(16, 32, src.begin(), src.end());

    parallel_for_each(tex9.extent, [=, &tex9] (index<2> idx) restrict(amp) { // Use the subscript operator.
        arr[idx].x += tex9[idx].x; // Use the function () operator.
        arr[idx].x += tex9(idx).x; // Use the get method.
        arr[idx].y += tex9.get(idx).y; // Use the function () operator.
        arr[idx].y += tex9(idx[0], idx[1]).y;
    });

    arr.synchronize();
}

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

void UseBitsPerScalarElement() { // Create the image data. // Each unsigned int (32-bit) represents four 8-bit scalar elements(r,g,b,a values).
    const int image_height = 16;
    const int image_width = 16;
    std::vector<unsigned int> image(image_height* image_width);

    extent<2> image_extent(image_height, image_width);

    // By using uint_4 and 8 bits per channel, each 8-bit channel in the data source is // stored in one 32-bit component of a uint_4.
    texture<uint_4, 2> image_texture(image_extent, image.data(), image_extent.size()* 4U,  8U);

    // Use can access the RGBA values of the source data by using swizzling expressions of the uint_4.
    parallel_for_each(image_extent,
        [&image_texture](index<2> idx) restrict(amp)
        { // 4 bytes are automatically extracted when reading.
            uint_4 color = image_texture[idx];
            unsigned int r = color.r;
            unsigned int g = color.g;
            unsigned int b = color.b;
            unsigned int a = color.a;
        });
}

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

Тип данных текстуры Допустимое количество бит на скалярный элемент
int, int_2, int_4

uint, uint_2, uint_4
8, 16, 32
int_3, uint_3 32
float, float_2, float_4 16, 32
float_3 32
double, double_2 64
norm, norm_2, norm_4

unorm, unorm_2, unorm_4
8, 16

Запись в объекты текстуры

Используйте метод текстуры::set для записи в texture объекты. Объект текстуры может быть доступен только для чтения или для чтения и записи. Для объекта текстуры, который должен быть доступен для чтения и записи, должны выполняться следующие условия:

  • T имеет только один скалярный компонент. (Нельзя использовать короткие векторы);

  • T не doubleявляется , normили unorm.

  • значение свойства texture::bits_per_scalar_element — 32.

Если все три условия не выполняются, то объект texture будет доступен только для чтения. Первые два условия проверяются во время компиляции. Ошибка компиляции генерируется, если имеется код, который пытается писать в readonly-объект текстуры. Условие для texture::bits_per_scalar_element обнаружения во время выполнения и среда выполнения создает исключение unsupported_feature при попытке записи в объект readonly texture .

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

void writeTexture() {
    texture<int, 1> tex1(16);

    parallel_for_each(tex1.extent, [&tex1] (index<1> idx) restrict(amp) {
        tex1.set(idx, 0);
    });
}

Копирование объектов текстуры

Можно скопировать между объектами текстуры с помощью функции копирования или функции copy_async , как показано в следующем примере кода.

void copyHostArrayToTexture() { // Copy from source array to texture object by using the copy function.
    float floatSource[1024* 2];
    for (int i = 0; i <1024* 2; i++) {
        floatSource[i] = (float)i;
    }
    texture<float_2, 1> floatTexture(1024);

    copy(floatSource, (unsigned int)sizeof(floatSource), floatTexture);

    // Copy from source array to texture object by using the copy function.
    char charSource[16* 16];
    for (int i = 0; i <16* 16; i++) {
        charSource[i] = (char)i;
    }
    texture<int, 2> charTexture(16, 16, 8U);

    copy(charSource, (unsigned int)sizeof(charSource), charTexture);
    // Copy from texture object to source array by using the copy function.
    copy(charTexture, charSource, (unsigned int)sizeof(charSource));
}

Можно также скопировать из одной текстуры в другую с помощью метода texture::copy_to . Две текстуры могут находиться на разных объектах accelerator_view. При копировании в объект writeonly_texture_view данные копируются в нижележащий объект texture. Количество бит на один скалярный элемент и размер должны быть одинаковыми на объектах texture источника и назначения. Если эти требования не выполнены, то генерируется исключение.

Классы представления текстуры

C++ AMP представляет класс texture_view в Visual Studio 2013. Представления текстур поддерживают те же типы текселя и ранги, что и класс текстур, но в отличие от текстур, они обеспечивают доступ к дополнительным аппаратным функциям, таким как выборка текстур и mipmap. Представления текстуры поддерживают доступ только для чтения, только для записи и для чтения и записи к соответствующим данным текстуры.

  • Доступ только для чтения предоставляется специализацией шаблона texture_view<const T, N>, которая поддерживает элементы с 1, 2 или 4 компонентами, дискретизацию текстур и динамический доступ к диапазону уровней MIP-карты, определяемых при создании экземпляра представления.

  • Доступ только для записи предоставляется неспециализированным классом шаблона texture_view<T, N>, который поддерживает элементы с 2 или 4 компонентами и позволяет обращаться к одному уровню MIP-карты, определяемому при создании экземпляра представления. Оно не поддерживает дискретизацию.

  • Доступ для чтения и записи предоставляется неспециализированным классом шаблона texture_view<T, N>, который, как и текстуры, поддерживает элементы только с одним компонентом; представление может обращаться к одному уровню MIP-карты, определяемому при создании экземпляра этого представления. Оно не поддерживает дискретизацию.

Представления текстур аналогичны представлениям массива, но не предоставляют функции автоматического управления данными и перемещения, предоставляемые классом array_view по классу массива. К texture_view можно обращаться только в представлении ускорителя, в котором находятся соответствующие данные текстуры.

Использовать класс writeonly_texture_view не рекомендуется

Для Visual Studio 2013 C++ AMP предоставляет лучшую поддержку функций текстур оборудования, таких как выборка и mIP-карты, которые не поддерживаются классом writeonly_texture_view. Новый класс texture_view поддерживает надмножество функций в writeonly_texture_view; поэтому использовать writeonly_texture_view больше не рекомендуется.

Рекомендуется (по крайней мере в новом коде) использовать texture_view для доступа к функциям, которые раньше реализовывались с помощью writeonly_texture_view. Сравните следующие два примера кода, в которых осуществляется запись в объект текстуры, состоящий из двух компонентов (int_2). Обратите внимание, что в обоих случаях представление wo_tv4 должно захватываться по значению в лямбда-выражении. Ниже приведен пример, в котором используется новый класс texture_view:

void write2ComponentTexture() {
    texture<int_2, 1> tex4(16);

    texture_view<int_2, 1> wo_tv4(tex4);

    parallel_for_each(extent<1>(16), [=] (index<1> idx) restrict(amp) {
        wo_tv4.set(idx, int_2(1, 1));
    });
}

А здесь показан нерекомендуемый класс writeonly_texture_view:

void write2ComponentTexture() {
    texture<int_2, 1> tex4(16);

    writeonly_texture_view<int_2, 1> wo_tv4(tex4);

    parallel_for_each(extent<1>(16), [=] (index<1> idx) restrict(amp) {
        wo_tv4.set(idx, int_2(1, 1));
    });
}

Можно видеть, что оба примера кода практически идентичны, когда требуется выполнить запись в базовый уровень MIP-карты. Если в вашем коде используется класс writeonly_texture_view и вы не планируете улучшать его, код можно не менять. Если же вы думаете о расширении кода, рекомендуется переписать его с использованием класса texture_view, поскольку усовершенствования в нем поддерживают новые аппаратные возможности для работы с текстурами. Ниже эти новые возможности описаны более подробно.

Дополнительные сведения об устаревании writeonly_texture_viewсм. в разделе "Обзор конструктора представления текстур в C++ AMP " в блоге о параллельном программировании в машинном коде.

Создание экземпляров объектов представлений текстуры

texture_view Объявление аналогично объявлениюarray_view, связанному с массивом. В следующем примере кода объявляются несколько объектов texture и связанных с ними объектов texture_view.

#include <amp.h>
#include <amp_graphics.h>
using namespace concurrency;
using namespace concurrency::graphics;

void declareTextureViews()
{
    // Create a 16-texel texture of int, with associated texture_views.
    texture<int, 1> intTexture(16);
    texture_view<const int, 1> intTextureViewRO(intTexture);  // read-only
    texture_view<int, 1> intTextureViewRW(intTexture);        // read-write

    // Create a 16 x 32 texture of float_2, with associated texture_views.
    texture<float_2, 2> floatTexture(16, 32);
    texture_view<const float_2, 2> floatTextureViewRO(floatTexture);  // read-only
    texture_view<float_2, 2> floatTextureViewRO(floatTexture);        // write-only

    // Create a 2 x 4 x 8 texture of uint_4, with associated texture_views.
    texture<uint_4, 3> uintTexture(2, 4, 8);
    texture_view<const uint_4, 3> uintTextureViewRO(uintTexture);  // read-only
    texture_view<uint_4, 3> uintTextureViewWO(uintTexture);        // write-only
}

Обратите внимание, что представление текстуры, тип элемента которой не является константным и содержащее один компонент, доступно для чтения и записи, а представление текстуры, тип элемента которой не является константным, но содержащее более одного компонента, доступно только для записи. Представления текстуры с константными типами элемента всегда доступны только для чтения, но если тип элемента не является константным, число компонентов в этом элементе определяют режим доступа к текстуре — чтение и запись (один компонент) или только запись (несколько компонентов).

Тип элемента texture_view (его "константность" и количество компонентов в нем) также определяют, поддерживает ли представление дискретизацию текстуры и способ доступа к уровням MIP-карт.

Тип Компоненты Чтение Запись Образец Доступ к MIP-карте
<texture_view const T, N> 1, 2, 4 Да Нет (1) Да Да, индексируемый. Диапазон определяется при создании экземпляра.
<Texture_view T, N> 1

2, 4
Да

Нет (2)
Да

Да
Нет (1)

Нет (1)
Да, один уровень. Уровень определяется при создании экземпляра.

Да, один уровень. Уровень определяется при создании экземпляра.

Из этой таблицы можно увидеть, что представления текстур, доступные только для чтения, полностью поддерживают новые возможности в обмен на невозможность записи в в представление. Доступные для записи представления текстуры ограничены тем, что они поддерживают доступ только к одному уровню MIP-карт. Представления текстуры для чтения и записи являются более специализированным по сравнению с поддерживающими только запись, поскольку они содержат дополнительное требование о том, что тип элемента в таком представлении текстуры должен содержать только один компонент. Обратите внимание, что дискретизация не поддерживается для записываемых представлений текстур, поскольку эта операция предполагает чтение.

Чтение из объектов представления текстуры

Чтение недискретизированных данных текстуры через представление текстуры похоже на чтение из самой текстуры за тем исключением, что текстуры передаются по ссылке, а представления текстуры — по значению. В следующих двух примерах кода демонстрируется это. В первом — с использованием только texture:

void write2ComponentTexture() {
    texture<int_2, 1> text_data(16);

    parallel_for_each(extent<1>(16), [&] (index<1> idx) restrict(amp) {
        tex_data.set(idx, int_2(1, 1));
    });
}

А ниже приведен тот же пример, но с использованием класса texture_view:

void write2ComponentTexture() {
    texture<int_2, 1> tex_data(16);

    texture_view<int_2, 1> tex_view(tex_data);

    parallel_for_each(extent<1>(16), [=] (index<1> idx) restrict(amp) {
        tex_view.set(idx, int_2(1, 1));
    });
}

Представления текстур, элементы которых основаны на типах с плавающей запятой, например float, float_2 или float_4, также могут считываться с помощью дискретизации текстур, чтобы можно было использовать аппаратную поддержку различных режимов фильтрации и адресации. C++ AMP поддерживает два режима фильтрации, которые чаще всего используются в вычислениях — точечная фильтрация (ближайший сосед) и линейная фильтрации (средневзвешенный показатель), а также четыре режима адресации — с переносом, зеркальный, ограниченный и граничный. Дополнительные сведения о режимах адресации см. в разделе address_mode Перечисление.

Помимо режимов, поддерживаемых в C++ AMP напрямую, можно использовать другие режимы фильтрации и адресации базовой платформы через API взаимодействия, чтобы применять дискретизатор текстур, созданный непосредственно API. Например, Direct3D поддерживает другие режимы фильтрации, такие как анизотропная фильтрация, и может применять к каждому измерению текстуры свой режим адресации. С помощью API Direct3D можно создать дискретизатор текстур, координаты которого будут переноситься по вертикали, зеркально отражаться по горизонтали и дискретизироваться с помощью анизотропного фильтра, после чего использовать этот дискретизатор в коде C++ AMP с помощью API взаимодействия make_sampler. Дополнительные сведения см. в статье "Выборка текстур" в C++ AMP в блоге по параллельному программированию в машинном коде.

Представления текстуры также поддерживают чтение MIP-карт. Доступные только для чтения представления текстуры (имеющие константный тип элемента) обеспечивают наибольшую гибкость, поскольку диапазон MIP-уровней, определяемых при создании экземпляра, может дискретизироваться динамически и потому что поддерживаются элементы с 1, 2 или 4 компонентами. Представления текстуры для чтения и записи, содержащие элементы с одним компонентом, также поддерживают MIP-карты, но только один уровень определяется при создании экземпляра. Дополнительные сведения см. в разделе "Текстура" с MIP-картами в блоге по параллельному программированию в машинном коде.

Запись в объекты представлений текстуры

Используйте метод texture_view::get для записи в базовый texturetexture_view объект. Представление текстуры могут быть доступным только для чтения, для чтения и записи или только для записи. Чтобы представление текстуры было доступно для записи, оно должно иметь неконстантный тип элемента; чтобы представление текстуры было доступным для чтения и записи, его тип элемента должен также иметь только один компонент. В противном случае представление текстуры доступно только для чтения. Через представление текстуры одновременно можно обращаться только к одному уровню MIP-карты текстуры, и этот уровень задается при создании экземпляра представления.

В этом примере показано, как осуществлять запись во второй по детализации уровень текстуры, имеющей 4 уровня MIP-карт. Самый подробный уровень MIP-карт — уровень 0.

// Create a texture that has 4 mipmap levels : 16x16, 8x8, 4x4, 2x2
texture<int, 2> tex(extent<2>(16, 16), 16U, 4);

// Create a writable texture view to the second mipmap level :4x4
texture_view<int, 2> w_view(tex, 1);

parallel_for_each(w_view.extent, [=](index<2> idx) restrict(amp)
{
    w_view.set(idx, 123);
});

Совместимость

Среда выполнения C++ AMP поддерживает взаимодействие между texture<T,1> интерфейсом ID3D11Texture1D между texture<T,2> интерфейсом ID3D11Texture2D и между texture<T,3> интерфейсом ID3D11Texture3D. Метод get_texture принимает texture объект и возвращает IUnknown интерфейс. Метод make_texture принимает IUnknown интерфейс и accelerator_view объект и возвращает texture объект.

См. также

Класс double_2
Класс double_3
Класс double_4
Класс float_2
Класс float_3
Класс float_4
Класс int_2
Класс int_3
Класс int_4
Класс norm_2
Класс norm_3
Класс norm_4
Структура short_vector
Структура short_vector_traits
Класс uint_2
Класс uint_3
Класс uint_4
Класс unorm_2
Класс unorm_3
Класс unorm_4