我正在尝试自学 C++AMP,并且想从我所在领域的一个非常简单的任务开始,那就是图像处理。我想将每像素 24 位的 RGB 图像(位图)转换为每像素 8 位的灰度图像。图像数据以unsigned char
数组形式提供(从Bitmap::LockBits(...)
等处获得)
我知道 C++AMP 出于某种原因无法通过or处理char
orunsigned char
数据,因此我尝试根据该博客使用 s 。这里解释了如何写入 8bpp 纹理,尽管 VisualStudio 2013 告诉我已弃用。array
array_view
texture
writeonly_texture_view
我的代码抛出运行时异常,提示“无法调度内核”。异常的完整文本很长:
ID3D11DeviceContext::Dispatch:计算着色器单元插槽 0 中的无序访问视图 (UAV) 具有格式 (R8_UINT)。这种格式不支持像 UAV 一样从着色器中读取。如果着色器实际使用视图,则这种不匹配是无效的(例如,由于着色器代码分支,它没有被跳过)。不幸的是,不可能让所有硬件实现都支持将此格式作为 UAV 读取,尽管该格式可以作为 UAV 写入。如果着色器只需要对该资源执行读取而不是写入,请考虑使用着色器资源视图而不是 UAV。
到目前为止我使用的代码是这样的:
namespace gpu = concurrency;
gpu::extent<3> inputExtent(height, width, 3);
gpu::graphics::texture<unsigned int, 3> inputTexture(inputExtent, eight);
gpu::graphics::copy((void*)inputData24bpp, dataLength, inputTexture);
gpu::graphics::texture_view<unsigned int, 3> inputTexView(inputTexture);
gpu::graphics::texture<unsigned int, 2> outputTexture(width, height, eight);
gpu::graphics::writeonly_texture_view<unsigned int, 2> outputTexView(outputTexture);
gpu::parallel_for_each(outputTexture.extent,
[inputTexView, outputTexView](gpu::index<2> pix) restrict(amp) {
gpu::index<3> indR(pix[0], pix[1], 0);
gpu::index<3> indG(pix[0], pix[1], 1);
gpu::index<3> indB(pix[0], pix[1], 2);
unsigned int sum = inputTexView[indR] + inputTexView[indG] + inputTexView[indB];
outputTexView.set(pix, sum / 3);
});
gpu::graphics::copy(outputTexture, outputData8bpp);
这个异常的原因是什么,我可以做些什么来解决这个问题?