Először tekintsük át a szükséges változtatásokat az előző OpenCL programokhoz képest.
Az első dolog, amire oda kell figyelnünk a megfelelő méretű memória objektum létrehozása. Mivel RGB komponensű képet állítunk elő, ezért ennek megfelelően kell lefoglalnunk a memóriát.
bool CreateMemObjects(cl_context context, cl_mem memObjects[1])
{
memObjects[0] = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(unsigned char) * N * N * 3, NULL, NULL);
if (memObjects[0] == NULL )
{
std::cerr << "Error creating memory objects." << std::endl;
return false;
}
return true;
}
A következő változás az előzőekhez képest, hogy a lokális és globális mukacsoportokat két dimenziós indextartományon kell majd kezelni. Ehhez szükség van egy kerekítésre is, ami a lokális méretnek megfelelően alakítja a szükséges globális index tartományt.
size_t RoundUp(int groupSize, int globalSize)
{
int r = globalSize % groupSize;
if (r == 0)
{
return globalSize;
}
else
{
return globalSize + groupSize - r;
}
}
A main függvényben a munkacsoport méretét a következőképpen kell beállítani
size_t localWorkSize[2] = { 16, 16 };
size_t globalWorkSize[2] = { RoundUp(localWorkSize[0], N), RoundUp(localWorkSize[1], N) };
A kernelt is a két dimenzios tartományoknak megfelelően kell elhelyezni a parancssorban a manin függvényben.
errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
A kernel végrehajtása után az eredményt be kell tölteni a gazdagép memóriájába. Ehhez először le kell foglalni a megfelelő méretű memória területet, majd pedig az adott memória objektum tartalmát be kell tölteni a gazdagép memóriáába.
unsigned char* result = new unsigned char[N*N * 3];
errNum = clEnqueueReadBuffer(commandQueue, memObjects[0], CL_TRUE, 0, 3 * N * N * sizeof(char), result, 0, NULL, NULL);
A sikeres memória másolás után az eredményt kiírjuk egy png állományba. Az eredmény kiírására a következő szekcióban mutatunk két lehetséges megoldást a FreeImage függvénykönyvtár használatával.
writeRGBImageToFile("image.png", result, N, N);
A teljes forráskód letöltése itt.