The main issue is that your are trying to access a non-32 bit texture
. If you run this code through the debugger it actually throws on the .set()
instruction.
Neither MSDN not the AMP team's blog explain this very well but the solution appears to be to declare the input texture as containing a const
type. I'm assuming you're using VS 2013, if not then let me know and I'll post the code for 2012.
Here's the whole program. it appears to behave as expected for me.
#include "opencv2/highgui/highgui.hpp"
#include <amp.h>
#include <amp_graphics.h>
#include <amp_short_vectors.h>
using namespace concurrency;
using namespace std;
int main( int argc, const char** argv )
{
cv::Mat image(480, 640, CV_16UC1);
cv::Mat image2(480, 640, CV_16UC1);
// create a gradient, just to see something meaningful
for (int i = 0; i < 480; i++)
{
for (int j = 0; j < 640; j++)
{
/*int gradientInY = (i / 480.f) * 65535;
image.at<uint16_t>(i, j) = gradientInY;*/
int gradientInX = (j / 640.f) * (i / 480.f) * 65535;
image.at<uint16_t>(i, j) = gradientInX;
image2.at<uint16_t>(i, j) = 65535 / 2;
}
}
cv::imshow("image", image);
cv::waitKey(50);
concurrency::extent<2> imageSize(480, 640);
int bits = 16;
const unsigned int nBytes = imageSize.size() * bits / 8; // 614400
// Source Data
graphics::texture<unsigned int, 2> texDataS(imageSize, image.data, nBytes, bits);
graphics::texture_view<const unsigned int, 2> texS(texDataS);
// Result data
graphics::texture<unsigned int, 2> texDataD(imageSize, 16);
graphics::texture_view<unsigned int, 2> texD(texDataD);
parallel_for_each(imageSize, [=, &texDataS](concurrency::index<2> idx) restrict(amp)
{
int val = texS(idx);
// Do your image processing work here.
int result = val;
texD.set(idx, result);
});
// Don't copy async here as you need the result immediately.
concurrency::graphics::copy(texDataD, image2.data, imageSize.size() * bits / 8);
cv::imshow("result", image2);
cv::waitKey(50);
return 0;
}