Elementos gráficos (C++ AMP)
O C++ AMP contém várias APIs no namespace Concurrency::graphics que você pode usar para acessar o suporte de textura em GPUs. Alguns cenários comuns são:
Você pode usar a classe textura como um recipiente de dados para a computação e explorar a localidade espacial do cache de textura e os layouts de hardware da GPU. A localidade espacial é a propriedade dos elementos de dados que estão fisicamente perto uns dos outros.
O tempo em execução fornece uma interoperabilidade eficiente com shaders não computados. O pixel, o vértice, o tessellation e os shaders de casca frequentemente consomem ou geram texturas que você pode usar em suas cálculos de C++ AMP.
As APIs de elementos gráficos do C++ AMP fornecem maneiras alternativas para acessar buffers empacotados em sub-palavras. As texturas que possuem os formatos que representam texels (elementos de textura) que são compostos de escalares de 8 bits ou 16 bits permitem o acesso a um armazenamento de dados empacotado.
Os tipos norm e unorm
Os tipos norm e unorm são os tipos escalares que limitam o intervalo de valores float; isso é conhecido como compressão. Esses tipos podem ser explicitamente construídos de outros tipos escalares. Na conversão, o valor é inicialmente convertido para float e comprimido na região respectiva que é permitida por norm [-1,0…1,0] ou unorm [0,0…1,0]. Conversão de +/- infinito retorna +/-1. Conversão de NaN é indefinida. Uma norma pode ser implicitamente construída a partir de um unorm, e não há perda de dados. O operador de conversão implícita para flutuante é definido nesses tipos. Os operadores binários são definidos entre esses tipos e outros tipos internos escalares como float e int: +, -, *, /, ==, !=, >, <, >=, <=. Operadores de atribuição composta também são suportados: +=, -=, *=, /=. O operador unário de negação (-) é definido para tipos norm.
Biblioteca de vetor curto
A biblioteca de vetor curto fornece algumas das funcionalidades do Tipo vetorial que é definido em HLSL e é normalmente usado para definir texels. Um vetor curto é uma estrutura de dados que contém de um a quatro valores do mesmo tipo. Os tipos suportados são double, float, int, norm, uint, e unorm. Os nomes dos tipos são mostrados na tabela a seguir. Para cada tipo, há também um typedef correspondente que não tem um sublinhado no nome. Os tipos que têm sublinhados estão em Namespace Concurrency::graphics. Os tipos que não têm sublinhados estão em Namespace Concurrency::graphics::direct3d de modo que sejam claramente separados dos tipos fundamentais com nomes semelhantes, como __int8 e __int16.
Comprimento 2 |
Comprimento 3 |
Comprimento 4 |
|
---|---|---|---|
double |
double_2 double2 |
double_3 double3 |
double_4 double4 |
float |
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 |
Operadores
Se um operador for definido entre dois vetores curtos, então será definido também entre um vetor curto e um escalar. Além disso, um destes deve ser true:
O tipo de escalar deve ser o mesmo que o tipo de elemento curto do vetor.
O tipo de escalar pode ser convertido implicitamente para o tipo de elemento vetorial usando apenas uma conversão definida pelo usuário.
A operação é executada no componente inteiro entre cada componente do vetor curto e o escalar. Veja os operadores válidos:
Tipo de operador |
Tipos válidos |
---|---|
Operadores binários |
Válido em todos os tipos: +, -, *, /, Válido em tipos inteiros: %, ^, |, &, <<, >> Os dois vetores devem ter o mesmo tamanho, e o resultado é um vetor do mesmo tamanho. |
Operadores relacionais |
Válido em todos os tipos: == e != |
Operador de atribuição composta |
Válido em todos os tipos: +=, -=, *=, /= Válido em tipos inteiros: %=, ^=, |=, &=, <<=, >>= |
Operadores de incremento e de decremento |
Válido em todos os tipos: ++, -- O prefixo e o sufixo são válidos. |
Operador NOT de bit a bit (~) |
Válido em tipos inteiros. |
Operador unário |
Válido em todos os tipos exceto unorm e uint. |
Expressões de Swizzling
A biblioteca de vetor pequeno oferece suporte ao acessador de construção vector_type.identifier para acessar os componentes de um vetor curto. O identifier, que é conhecido como uma expressão swizzling, especifica os componentes do vetor. A expressão pode ser um valor l ou um valor r. Os caracteres individuais no identificador podem ser: x, y, z, e w; ou r, g, b, e a. “x” e “r” significam "componente zero", “y” e “g” significam "primeiro componente", e assim por diante. (“x” e “r” não podem ser usados no mesmo identificador.) Portanto, “rgba” e “xyzw" retornam o mesmo resultado. Assessores de um componente como “x” e “y” são tipos de valor escalar. Assessores de vários componentes são tipos de vetor curtos. Por exemplo, se você construir um vetor int_4 que é chamado fourInts e têm valores 2, 4, 6, e 8, então fourInts.y retorna o número inteiro 4 e fourInts.rg retorna um objeto int_2 que possui os valores 2 e 4.
Classes de textura
Muitas GPUs têm hardware e os caches que são otimizados para buscar pixels e texels e processar imagens e texturas. A classe textura<T,N>, que é uma classe recipiente para objetos de texel, expõe a funcionalidade de textura desses GPUs. Um texel pode ser:
Um escalar int, uint, float, double, norm ou unorm.
Um vetor curto que possui dois ou quatro componentes. A única exceção é double_4, que não é permitida.
O objeto texture pode ter uma classificação de 1, 2, ou 3. O objeto texture pode ser detectado somente por referência no método de uma chamada a parallel_for_each. A textura é armazenada em GPU, assim como os objetos de textura do Direct3D. Para obter mais informações sobre as texturas e texels em Direct3D, consulte Introdução às texturas em Direct3D 11.
O tipo de texel que você usa pode ser um dos muitos formatos de textura que são usados na programação de elementos gráficos. Por exemplo, um formato de RGBA pode usar 32 bits, com 8 bits para cada um dos elementos escalares R, G, B e A. O hardware de textura de uma placa gráfica pode acessar elementos baseados em formato. Por exemplo, se você estiver usando o formato de RGBA, o hardware de textura pode extrair cada elemento de 8 bits em um formulário de 32 bits. Em C++ AMP, você pode definir os bits por elemento escalar do seu texel para que você possa automaticamente acessar elementos individuais escalares no código sem usar o deslocamento de bits.
Criando uma instância de objetos de textura
Você pode declarar um objeto de textura sem inicialização. O exemplo de código declara vários objetos de textura.
#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));
}
Você também pode usar um construtor para declarar e inicializar um objeto texture. O exemplo de código a seguir cria uma instância de um objeto texture a partir de um vetor de objetos float_4. Os bits por elemento escalar são definidos como padrão. Você não pode usar esse construtor com norm, unorm, ou vetores curtos de norm e de unorm, porque eles não têm um padrão de bits por elemento escalar.
#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());
}
Você pode também declarar e inicializar um objeto texture usando uma sobrecarga do construtor que utiliza um ponteiro para os dados de origem, o tamanho dos dados de origem em bytes, e os bits por elemento escalar.
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);
}
As texturas nesses exemplos são criadas no modo de exibição padrão do acelerador padrão. Você pode usar outras sobrecargas do construtor se você desejar especificar um objeto accelerator_view. Você não pode criar um objeto de textura em um acelerador CPU.
Há um limite no tamanho de cada dimensão de objeto texture, conforme mostrado na tabela. Um erro em tempo de execução é gerado se você exceder os limites.
Textura |
Limite de tamanho |
---|---|
textura<T,1> |
16384 |
textura<T,2> |
16384 |
textura<T,2> |
2048 |
Ler de objetos de textura
Você pode ler a partir de um objeto texture usando Operador texture::operator[], Operador texture::operator() ou Método texture::get. Operador texture::operator[] e Operador texture::operator() retornam um valor, não uma referência. Portanto, você não pode gravar em um objeto texture usando Operador 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();
}
O exemplo de código a seguir demonstra como armazenar os canais de textura em um vetor curto e, em seguida, acessar os elementos individuais escalares como propriedades do vetor curto.
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;
});
}
A tabela a seguir lista os bits válidos por canal para cada tipo de vetor de classificação.
Tipo de dados de textura |
Bits válidos pelo elemento escalar |
---|---|
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 |
Gravando em objetos de textura
Use o método texture::set para gravar os objetos de texture. Um objeto de textura pode ser somente leitura ou de leitura/gravação. Para que um objeto de textura seja legível e gravável, as seguintes condições devem ser verdadeiras:
T tem apenas um componente escalar. (Vetores curtos não são permitidos.)
T não é double, norm, ou unorm.
A propriedade texture::bits_per_scalar_element é 32.
Se todos os três não forem verdadeiros, então o objeto texture é aleatório. As duas primeiras condições são verificadas durante a compilação. Um erro de compilação é gerado se você tem o código que tenta escrever em um objeto de textura readonly. A condição de texture::bits_per_scalar_element é detectada em tempo de execução, e o tempo de execução gera a exceção unsupported_feature se você tentar gravar em um objeto aleatório de texture.
O exemplo de código a seguir grava valores em um objeto de textura.
void writeTexture() {
texture<int, 1> tex1(16);
parallel_for_each(tex1.extent, [&tex1] (index<1> idx) restrict(amp) {
tex1.set(idx, 0);
});
}
Copiando objetos de textura
Você pode fazer copias entre objetos de textura usando as funções impressão ou copy_async, conforme mostrado no exemplo de código a seguir.
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));
}
Você também pode copiar de uma textura para outra usando o método texture::copy_to. As duas texturas podem estar em accelerator_views diferentes. Quando você copia para um objeto writeonly_texture_view, os dados são copiados para o objeto subjacente texture. Os bits por elemento escalar e a extensão devem ser os mesmos em objetos de origem e destino texture. Se os requisitos não forem atendidos, o tempo de execução gerará uma exceção.
Classes de exibição de textura
O C++ AMP introduz a Classe texture_view no Visual Studio 2013. As exibições de textura suportam os mesmos tipos e ordens que o Classe texture, mas diferentemente de texturas, eles fornece acesso aos recursos de hardware adicionais como amostragem e mipmaps de textura. As exibições de textura suportam somente leitura, somente gravação e de leitura-gravação para os dados subjacentes de textura.
O acesso somente leitura é fornecido pela especialização do modelo texture_view<const T, N>, que suporta elementos que têm 1, 2 ou 4 componentes, amostragem de textura, e acesso dinâmico a uma variedade de mipmaps que são determinados quando a exibição é instanciada.
O acesso de leitura gravação é fornecido pela classe de modelo não especializado texture_view<T, N>, que oferece suporte a elementos que tem 2 ou 4 componentes e pode acessar um nível de mipmap que é determinado quando a exibição é instanciada. Ela não dá suporte a amostragem.
O acesso de leitura-gravação é fornecido pela classe de modelo não especializado texture_view<T, N>, que, como as texturas, oferecem suporte a elementos que tem somente um componente; a exibição pode acessar um nível de mipmap que é determinado quando é instanciado. Ela não dá suporte a amostragem.
As exibições de textura são análogas a exibições de matriz, mas não fornecem a funcionalidade de gerenciamento e de mover dados automáticos que o Classe array_view fornece para as Classe array. Um texture_view só pode ser acessado no modo de exibição de acelerador onde os dados subjacentes de textura residem.
writeonly_texture_view preterido
Para o Visual Studio 2013, o C++ AMP apresenta melhor suporte para recursos de textura de hardware, como a amostragem e os mipmaps, que não podem ser suportados por Classe writeonly_texture_view. A classe recentemente introduzida de texture_view suporta um supraconjunto de funcionalidade em writeonly_texture_view; como resultado, writeonly_texture_view é substituído.
Recomendamos (pelo menos para o novo código) que você use texture_view para acessar a funcionalidade que foi fornecida anteriormente por writeonly_texture_view. Compare os seguintes exemplos de código que gravam em um objeto de textura que tem dois componentes (int_2). Observe que em ambos os casos, a exibição, wo_tv4, deve ser detectada pelo valor na expressão lambda. Veja um exemplo que usa a nova classe de 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));
});
}
Veja a classe writeonly_texture_view substituída:
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));
});
}
Como você pode ver, os dois exemplos de código são quase idênticos quando tudo o que você estiver fazendo for escrever o nível primário de mipmap. Se você usou writeonly_texture_view no código existente e você não estiver planejando aprimorar o código, não é necessário alterá-lo. Entretanto, se você está pensando em apresentar o código, sugerimos que você o reescreva para usar texture_view porque os aprimoramentos nele suportam os novos recursos de textura de hardware. Leia para obter mais informações sobre esses novos recursos.
Para obter mais informações sobre substituição de writeonly_texture_view, consulte Visão geral de design de exibição de textura no C++ AMP na programação paralela no blog de código nativo.
Criando uma instância de objetos de exibição de textura
Declarar uma texture_view é semelhante a declarar uma array_view que está associada a uma array. O código de exemplo declara vários objetos de texture e objetos texture_view que são associados a eles.
#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
}
Observe como um modo de exibição de textura cujo tipo de elemento é não const e tem um componente de leitura/gravação, mas um modo de exibição de textura cujo tipo de elemento é não const mas tem mais de um componente somente leitura. Exibições de textura de tipos de elemento const sempre são somente leitura, mas se o tipo de elemento é não const, então o número de componentes no elemento determina se é leitura-gravação (1 componente) ou somente gravação (vários componentes).
O tipo de elemento de um texture_view— seu característica const e o número dos componentes que ele tem - também tem uma função de determinar se a amostragem de textura do suporte de exibição e como os níveis de mipmap podem ser acessados:
Tipo |
Componentes |
Ler |
Write |
Preparação de exemplos |
Acesso de Mipmap |
---|---|---|---|---|---|
exibição da textura<const T, N> |
1, 2, 4 |
Sim |
Nº (1) |
Sim |
Sim, indexável. O intervalo é determinado na instanciação. |
Texture_view<T, N> |
1 2, 4 |
Sim Nº (2) |
Sim Sim |
Nº (1) Nº (1) |
Sim, um nível. O nível é determinado na instanciação. Sim, um nível. O nível é determinado na instanciação. |
Nesta tabela, você pode ver que as exibições somente leitura de textura suportam totalmente os novos recursos em troca de não serem capazes de gravar na exibição. As exibições de gravação de textura são limitadas e só podem acessar um nível mipmap. As exibições de leitura-gravação da textura são mais especializadas que as de gravação, porque adicionam os requisitos que o tipo de elemento de exibição da textura tem somente um componente. Observe que exemplo não é suportado para visualizações modificáveis de textura porque é uma operação orientada à leitura.
Ler de objetos de exibição de textura
Ler dados textura não provados em uma exibição de textura é como ler a partir da própria textura, com exceção das texturas que são capturadas por referência, enquanto as exibições de textura são capturadas por valor. Os seguintes exemplos de código a seguir demonstram; primeiro, usando somente 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));
});
}
Veja o mesmo exemplo, mas agora usando a classe 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));
});
}
As exibições de textura cujos elementos são baseados em tipos de ponto flutuante - por exemplo, float, float_2 ou float_4 - também pode estar pronto para usar a amostragem de textura para aproveitar o suporte de hardware para vários modos de filtragem e modos endereçando. O C++ AMP suporta os dois modos de filtragem que são mais comuns nos cenários de computação: filtragem de ponto (vizinho mais próximo) e filtragem linear (média ponderada), e quatro modos de endereçamento, encapsulado, espelhado, restrito e borda. Para obter mais informações sobre modos de filtragem, consulte Enumeração filter_mode; para obter mais informações sobre modos endereçando, consulte Enumeração address_mode.
Além dos modos que o C++ AMP oferece suporte direto, você pode acessar outros modos de filtragem e modos endereçando da plataforma subjacente usando APIs de interoperabilidade para adotar um demonstrador de textura que foi criado usando APIs de plataforma diretamente. Por exemplo, Direct3D suporta outros modos de filtragem, como filtro anisotrópico, e pode aplicar um modo de endereçamento diferente para cada dimensão de uma textura. É possível criar uma amostra de textura cujas coordenadas são envolvidas verticalmente, espelhadas horizontalmente e provadas com filtro anisotrópico usando APIs do Direct3D, em seguida, aproveitar a amostra do seu código de C++ AMP usando a API de interoperabilidade make_sampler. Para obter mais informações, consulte Amostragem de textura no C++ AMP no blog Programação paralela em código nativo.
As exibições de textura também dão suporte aos mipmaps de leitura. As exibições de textura somente leitura (que têm um tipo de elemento const) oferecem maior flexibilidade pois uma variedade de intervalos de níveis mip determinada na instanciação pode ser provada de forma dinâmica, e porque os elementos têm 1, 2 ou 4 componentes são suportados. As exibições de leitura-gravação da textura que tem elementos que têm um componente também dão suporte a mipmaps mas somente um dos níveis determinados na instanciação. Para obter mais informações, consulte Textura com Mipmaps no blog Programação paralela em código nativo.
Gravando em objetos de exibição de textura
Use Método texture_view::get para escrever no texture pelo objeto de texture_view. Um modo de exibição de textura pode ser somente leitura, leitura e gravação, ou somente gravação. Para que um modo de exibição de textura seja modificável ele deve ter um tipo de elemento não const; para que um modo de exibição de textura seja legível e modificável, o tipo de elemento também deve ter apenas um componente. Caso contrário, o modo de exibição de texto é somente leitura. É possível acessar somente um nível de mipmap de uma textura em uma hora com um modo de exibição de textura, e o nível é especificado quando o modo de exibição é instanciado.
Este exemplo mostra como escrever o segundo - mipmap mais detalhado em nível de uma textura que tem 4 níveis de mipmap. O nível mais detalhado de mipmap é o nível 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);
});
Interoperabilidade
O tempo de execução do C++ AMP oferece suporte à interoperabilidade entre texture<T,1> e a Interface ID3D11Texture1D, entre texture<T,2> e a ID3D11Texture2D e entre texture<T,3> e ID3D11Texture3D. O método get_texture utiliza um objeto texture e retorna uma interface IUnknown. O método make_texture usa uma interface IUnknown e um objeto accelerator_view e retorna um objeto texture.