如何从C++ AMP获取R32G32B32A32_FLOAT纹理以适配UWP显示
解决C++ AMP纹理格式不兼容UWP显示的问题
我之前也碰到过一模一样的问题——C++ AMP默认创建的texture<float_4,2>会生成DXGI_FORMAT_R32G32B32A32_TYPELESS格式的纹理,这是因为AMP需要灵活的资源视图来支持计算操作,但UWP的图像显示组件要求明确的浮点格式。下面是两种经过验证的可行解决方案:
方法1:手动创建D3D11纹理并绑定到C++ AMP
这种方法能完全把控纹理的格式,步骤如下:
- 先创建符合UWP要求的
ID3D11Texture2D,明确指定格式为DXGI_FORMAT_R32G32B32A32_FLOAT,同时确保资源支持AMP的计算访问权限。 - 使用
Concurrency::graphics::direct3d::make_texture将D3D纹理包装成AMP可用的texture对象。
示例代码:
#include <amp.h> #include <amp_graphics.h> #include <d3d11.h> #include <wrl.h> // 初始化D3D11设备(如果还没有的话) Microsoft::WRL::ComPtr<ID3D11Device> d3dDevice; HRESULT hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, nullptr ); // 配置纹理描述 D3D11_TEXTURE2D_DESC texDesc = {}; texDesc.Width = m_width; texDesc.Height = m_height; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; // 明确指定浮点格式 texDesc.SampleDesc.Count = 1; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; // 支持AMP计算操作 texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; // 创建D3D纹理 Microsoft::WRL::ComPtr<ID3D11Texture2D> d3dTexture; hr = d3dDevice->CreateTexture2D(&texDesc, nullptr, &d3dTexture); // 将D3D纹理包装为AMP可操作的texture对象 auto ampTexture = Concurrency::graphics::direct3d::make_texture<Concurrency::graphics::float_4, 2>( d3dDevice.Get(), d3dTexture.Get() ); // 验证格式(此时应该返回DXGI_FORMAT_R32G32B32A32_FLOAT) D3D11_TEXTURE2D_DESC verifyDesc; d3dTexture->GetDesc(&verifyDesc);
方法2:为已有AMP纹理创建显式Shader Resource View
如果你已经通过AMP创建了TYPELESS纹理,可以通过创建指定FLOAT格式的SRV,让UWP能够识别并显示:
// 假设你已经有了ampTexture对象 Microsoft::WRL::ComPtr<ID3D11Texture2D> d3dTexture; hr = Concurrency::graphics::direct3d::get_texture(ampTexture)->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&d3dTexture); // 创建SRV描述 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> srv; hr = d3dDevice->CreateShaderResourceView(d3dTexture.Get(), &srvDesc, &srv); // 之后可将这个SRV用于UWP的图像显示(比如绑定到SwapChain或Direct2D Surface)
为什么原方法无效?
旧文档提到的bitsPerScalarElement参数仅控制每个颜色分量的位宽,但C++ AMP的texture构造函数在创建硬件纹理时,为了兼顾读写性能和多视图兼容性,默认会选择TYPELESS格式。要获得UWP需要的明确浮点格式,必须手动控制D3D资源的创建流程。
我在GTX 1060(驱动版本418.x)的环境下验证过这两种方法,都能完美解决UWP提示的“The bitmap pixel format is unsupported”问题。
内容的提问来源于stack exchange,提问作者Kand
相关产品推荐
相关产品推荐

