protected virtual void Initialize(Context context, CommandQueue cq, int width, int height) { BitmapData bd; Bitmap = new Bitmap(width,height,PixelFormat.Format32bppArgb); bd = LockEntireBitmap( Bitmap, ImageLockMode.ReadOnly ); Image = context.CreateImage2D(MemFlags.COPY_HOST_PTR, OpenCLNet.ImageFormat.ARGB8U, width, height, bd.Stride, bd.Scan0); Context = context; CQ = cq; }
/// <summary> /// Test all versions of: /// /// EnqueueWriteImage /// EnqueueReadImage /// EnqueueCopyImage /// /// The test just copies the entirety of a buffer and checks if the result is equal to the original. /// An error indicates that one of the above functions failed and further manual analysis is required /// to pinpoint the error. /// </summary> /// <param name="c"></param> /// <param name="cq"></param> private void TestImageReadWriteCopyOps(Context c, CommandQueue cq) { if (!cq.Device.ImageSupport) { Output("Skipping image read/write/copy tests(not supported on this device)"); return; } Output("Testing image read/write/copy functions"); OpenCLNet.Image img0 = null; OpenCLNet.Image img1 = null; OpenCLNet.Image img2 = null; int imgWidth = 1024; int imgHeight = 1024; int bufLen = imgWidth*4*imgHeight; byte[] srcData = new byte[bufLen]; byte[] cmpData = new byte[bufLen]; Event event0; Event event1; Event event2; Event event3; Event event4; Event event5; for (int i = 0; i < srcData.Length; i++) srcData[i] = (byte)(i); Array.Clear(cmpData, 0, cmpData.Length); try { img0 = c.CreateImage2D(MemFlags.READ_WRITE, ImageFormat.RGBA8U, imgWidth, imgHeight); img1 = c.CreateImage2D(MemFlags.READ_WRITE, ImageFormat.RGBA8U, imgWidth, imgHeight); img2 = c.CreateImage2D(MemFlags.READ_WRITE, ImageFormat.RGBA8U, imgWidth, imgHeight); Array.Clear(cmpData, 0, cmpData.Length); fixed (byte* pSrc = srcData) { fixed (byte* pCmp = cmpData) { { IntPtr[] origin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] region = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; IntPtr[] dstOrigin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] dstRegion = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pSrc); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pCmp); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (IntPtr version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pSrc, 0, null, out event0); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, null, out event1); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pCmp, 0, null, out event2); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (IntPtr version)Copy not identical to source with event output and no wait list"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1, event2 }; cq.EnqueueWriteImage(img0, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pSrc, 3, events); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 3, events); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pCmp, 3, events); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (IntPtr version)Copy not identical to source using no event output and a wait list"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pSrc, 3, events, out event3); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 3, events, out event4); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, IntPtr.Zero, IntPtr.Zero, (IntPtr)pCmp, 3, events, out event5); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (IntPtr version)Copy not identical to source using event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); event4.Dispose(); event5.Dispose(); } { int[] origin = new int[3] { 0, 0, 0 }; int[] region = new int[3] { imgWidth, imgHeight, 1 }; int[] dstOrigin = new int[3] { 0, 0, 0 }; int[] dstRegion = new int[3] { imgWidth, imgHeight, 1 }; Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0, 0, (IntPtr)pSrc); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0, 0, (IntPtr)pCmp); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (int version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0, 0, (IntPtr)pSrc, 0, null, out event0); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, null, out event1); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0, 0, (IntPtr)pCmp, 0, null, out event2); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (int version)Copy not identical to source with event output and no wait list"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1, event2 }; cq.EnqueueWriteImage(img0, true, origin, region, 0, 0, (IntPtr)pSrc, 3, events); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, events); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0, 0, (IntPtr)pCmp, 3, events); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (int version)Copy not identical to source using no event output and a wait list"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0, 0, (IntPtr)pSrc, 3, events, out event3); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, events, out event4); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0, 0, (IntPtr)pCmp, 3, events, out event5); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (int version)Copy not identical to source using no event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); event4.Dispose(); event5.Dispose(); } { long[] origin = new long[3] { 0, 0, 0 }; long[] region = new long[3] { imgWidth, imgHeight, 1 }; long[] dstOrigin = new long[3] { 0, 0, 0 }; long[] dstRegion = new long[3] { imgWidth, imgHeight, 1 }; Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0L, 0L, (IntPtr)pSrc); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0L, 0L, (IntPtr)pCmp); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (long version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0L, 0L, (IntPtr)pSrc, 0, null, out event0); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, null, out event1); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0L, 0L, (IntPtr)pCmp, 0, null, out event2); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (long version)Copy not identical to source with event output and no wait list"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1, event2 }; cq.EnqueueWriteImage(img0, true, origin, region, 0L, 0L, (IntPtr)pSrc, 3, events); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, events); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0L, 0L, (IntPtr)pCmp, 3, events); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (long version)Copy not identical to source using no event output and a wait list"); Array.Clear(cmpData, 0, cmpData.Length); cq.EnqueueWriteImage(img0, true, origin, region, 0L, 0L, (IntPtr)pSrc, 3, events, out event3); cq.EnqueueCopyImage(img0, img1, origin, dstOrigin, region, 0, events, out event4); cq.EnqueueBarrier(); cq.EnqueueReadImage(img1, true, origin, region, 0L, 0L, (IntPtr)pCmp, 3, events, out event5); if (!CompareArray(cmpData, srcData)) Error("TestImageReadWriteCopyOps: (long version)Copy not identical to source using no event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); event4.Dispose(); event5.Dispose(); } } } } catch (Exception e) { Error("Exception during testing: "+e.ToString()); } finally { if (img0 != null) img0.Dispose(); if (img1 != null) img1.Dispose(); if (img2 != null) img2.Dispose(); } }
/// <summary> /// Test all versions of: /// /// EnqueueMapBuffer /// EnqueueMapImage /// /// The test bounces an array from a managed byte buffer to a mapped buffer, /// to an image. The image is then mapped and copied to a new managed buffer /// where the result is compared to the original. /// /// On error, the actual point of failure will have to be identified manually. /// </summary> /// <param name="c"></param> /// <param name="cq"></param> private void TestMapBuffer(Context c, CommandQueue cq) { if (!cq.Device.ImageSupport) { Output("Skipping EnqueueMapBuffer and EnqueueMapImage tests(not supported on this device)"); return; } Output("Testing MapBuffer"); OpenCLNet.Image img0 = null; OpenCLNet.Mem mem0 = null; int imgWidth = 1024; int imgHeight = 1024; int bufLen = imgWidth * 4 * imgHeight; byte[] srcData = new byte[bufLen]; byte[] cmpData = new byte[bufLen]; Event event0; Event event1; for (int i = 0; i < srcData.Length; i++) srcData[i] = (byte)(i); Array.Clear(cmpData, 0, cmpData.Length); try { img0 = c.CreateImage2D(MemFlags.READ_WRITE, ImageFormat.RGBA8U, imgWidth, imgHeight); mem0 = c.CreateBuffer(MemFlags.READ_WRITE, bufLen, IntPtr.Zero); Array.Clear(cmpData, 0, cmpData.Length); fixed (byte* pSrc = srcData) { fixed (byte* pCmp = cmpData) { { IntPtr[] origin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] region = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; IntPtr[] dstOrigin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] dstRegion = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; IntPtr mapPtr; byte* pMapPtr; IntPtr image_row_pitch; IntPtr image_slice_pitch; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region); mapPtr = cq.EnqueueMapImage(img0, true, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y*imgWidth*4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (IntPtr version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); Event fdjk; cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region, 0, null, out fdjk); cq.Finish(); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 0, null, out event0 ); cq.EnqueueWaitForEvent(event0); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (IntPtr version)Copy not identical to source when using event output and no wait list"); Event[] waitList = new Event[] { event0 }; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 1, waitList, out event1); cq.EnqueueWaitForEvent(event1); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (IntPtr version)Copy not identical to source when using event output and no wait list"); event0.Dispose(); event1.Dispose(); } { int[] origin = new int[3] { (int)0, (int)0, (int)0 }; int[] region = new int[3] { (int)imgWidth, (int)imgHeight, (int)1 }; IntPtr mapPtr; byte* pMapPtr; int image_row_pitch; int image_slice_pitch; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region); mapPtr = cq.EnqueueMapImage(img0, true, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y*imgWidth*4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (int version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 0, null, out event0 ); cq.EnqueueWaitForEvent(event0); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (int version)Copy not identical to source when using event output and no wait list"); Event[] waitList = new Event[] { event0 }; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 1, waitList, out event1); cq.EnqueueWaitForEvent(event1); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * (int)image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (int version)Copy not identical to source when using event output and no wait list"); event0.Dispose(); event1.Dispose(); } { long[] origin = new long[3] { (long)0, (long)0, (long)0 }; long[] region = new long[3] { (long)imgWidth, (long)imgHeight, (long)1 }; IntPtr mapPtr; byte* pMapPtr; long image_row_pitch; long image_slice_pitch; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, (long)0, origin, region); mapPtr = cq.EnqueueMapImage(img0, true, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (long version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, (long)0, origin, region); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 0, null, out event0); cq.EnqueueWaitForEvent(event0); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (long version)Copy not identical to source when using event output and no wait list"); Event[] waitList = new Event[] { event0 }; Array.Clear(cmpData, 0, cmpData.Length); mapPtr = cq.EnqueueMapBuffer(mem0, true, MapFlags.WRITE, 0, bufLen); pMapPtr = (byte*)mapPtr.ToPointer(); for (int i = 0; i < bufLen; i++) pMapPtr[i] = srcData[i]; cq.EnqueueUnmapMemObject(mem0, mapPtr); cq.EnqueueCopyBufferToImage(mem0, img0, (long)0, origin, region); mapPtr = cq.EnqueueMapImage(img0, false, MapFlags.READ, origin, region, out image_row_pitch, out image_slice_pitch, 1, waitList, out event1); cq.EnqueueWaitForEvent(event1); cq.Finish(); pMapPtr = (byte*)mapPtr.ToPointer(); for (int y = 0; y < imgHeight; y++) { byte* pSrcRowPtr = pMapPtr + y * image_row_pitch; byte* pDstRowPtr = pCmp + y * imgWidth * 4; for (int x = 0; x < imgWidth * 4; x++) { pDstRowPtr[x] = pSrcRowPtr[x]; } } cq.EnqueueUnmapMemObject(img0, mapPtr); if (!CompareArray(cmpData, srcData)) Error("EnqueueEnqueueMapBuffer/EnqueueMapImage: (long version)Copy not identical to source when using event output and no wait list"); event0.Dispose(); event1.Dispose(); } } } } catch (Exception e) { Error("Exception during testing: " + e.ToString()); } finally { if (img0 != null) img0.Dispose(); if (mem0 != null) mem0.Dispose(); } }
/// <summary> /// Test all versions of: /// /// EnqueueCopyImageToBuffer /// EnqueueCopyBufferToImage /// /// The test just copies the entirety of a buffer and checks if the result is equal to the original. /// An error indicates that one of the above functions failed and further manual analysis is required /// to pinpoint the error. /// </summary> /// <param name="c"></param> /// <param name="cq"></param> private void TestTransfersBetweenImageAndBuffers(Context c, CommandQueue cq) { if (!cq.Device.ImageSupport) { Output("Skipping CopyImageToBuffer and CopyBufferToImage tests(not supported on this device)"); return; } Output("Testing CopyImageToBuffer and CopyBufferToImage"); OpenCLNet.Image img0 = null; OpenCLNet.Mem mem0 = null; int imgWidth = 1024; int imgHeight = 1024; int bufLen = imgWidth * 4 * imgHeight; byte[] srcData = new byte[bufLen]; byte[] cmpData = new byte[bufLen]; Event event0; Event event1; Event event2; Event event3; for (int i = 0; i < srcData.Length; i++) srcData[i] = (byte)(i); Array.Clear(cmpData, 0, cmpData.Length); try { img0 = c.CreateImage2D(MemFlags.READ_WRITE, ImageFormat.RGBA8U, imgWidth, imgHeight); mem0 = c.CreateBuffer(MemFlags.READ_WRITE, bufLen, IntPtr.Zero); Array.Clear(cmpData, 0, cmpData.Length); fixed (byte* pSrc = srcData) { fixed (byte* pCmp = cmpData) { { IntPtr[] origin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] region = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; IntPtr[] dstOrigin = new IntPtr[3] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] dstRegion = new IntPtr[3] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 }; Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, (IntPtr)0); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (IntPtr version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region, 0, null, out event0); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, (IntPtr)0, 0, null, out event1); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (IntPtr version)Copy not identical to source when using event output and event args"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1 }; mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, (IntPtr)0, origin, region, 2, events, out event2); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, (IntPtr)0, 2, events, out event3); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (IntPtr version)Copy not identical to source when using event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); } { int[] origin = new int[3] { 0, 0, 0 }; int[] region = new int[3] { imgWidth, imgHeight, 1 }; int[] dstOrigin = new int[3] { 0, 0, 0 }; int[] dstRegion = new int[3] { imgWidth, imgHeight, 1 }; Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (int version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region, 0, null, out event0); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0, 0, null, out event1); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (int version)Copy not identical to source when using event output no event args"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1 }; mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0, origin, region, 2, events, out event2); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0, 2, events, out event3); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (int version)Copy not identical to source when using event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); } { long[] origin = new long[3] { 0, 0, 0 }; long[] region = new long[3] { imgWidth, imgHeight, 1 }; long[] dstOrigin = new long[3] { 0, 0, 0 }; long[] dstRegion = new long[3] { imgWidth, imgHeight, 1 }; Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0L, origin, region); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0L); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (long version)Copy not identical to source when using no event args"); Array.Clear(cmpData, 0, cmpData.Length); mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0L, origin, region, 0, null, out event0); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0L, 0, null, out event1); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (long version)Copy not identical to source when using event output and no event args"); Array.Clear(cmpData, 0, cmpData.Length); Event[] events = new Event[] { event0, event1 }; mem0.Write(cq, 0L, srcData, 0, bufLen); cq.EnqueueBarrier(); cq.EnqueueCopyBufferToImage(mem0, img0, 0L, origin, region, 2, events, out event2); cq.EnqueueBarrier(); cq.EnqueueCopyImageToBuffer(img0, mem0, origin, region, 0L, 2, events, out event3); cq.EnqueueBarrier(); mem0.Read(cq, 0L, cmpData, 0, bufLen); if (!CompareArray(cmpData, srcData)) Error("EnqueueCopyBufferToImage/EnqueueCopyImageToBuffer: (long version)Copy not identical to source when using event output and a wait list"); event0.Dispose(); event1.Dispose(); event2.Dispose(); event3.Dispose(); } } } } catch (Exception e) { Error("Exception during testing: " + e.ToString()); } finally { if (img0 != null) img0.Dispose(); if (mem0 != null) mem0.Dispose(); } }