/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #ifndef _OCL_GL_TEXTURE_H_ #define _OCL_GL_TEXTURE_H_ #include #include "OCLGLCommon.h" class OCLGLTexture : public OCLGLCommon { public: static const unsigned int c_imageWidth = 512; static const unsigned int c_imageHeight = 512; static const unsigned int c_elementsPerPixel = 4; OCLGLTexture(); virtual ~OCLGLTexture(); virtual void open(unsigned int test, char* units, double& conversion, unsigned int deviceId); virtual void run(void); virtual unsigned int close(void); private: unsigned int currentTest_; void* inDataGL_; void* outDataGL_; GLuint inGLTexture_; GLuint outGLTexture_; bool testRender_; template bool runTextureTest(GLint internalFormat, GLenum format, GLenum type); }; template bool OCLGLTexture::runTextureTest(GLint internalFormat, GLenum format, GLenum type) { cl_mem image; inDataGL_ = malloc(c_imageWidth * c_imageHeight * c_elementsPerPixel * sizeof(T)); outDataGL_ = malloc(c_imageWidth * c_imageHeight * c_elementsPerPixel * sizeof(T)); // Initialize input data with random values T* inputIterator = (T*)inDataGL_; for (unsigned int i = 0; i < c_imageWidth * c_imageHeight * c_elementsPerPixel; i++) { inputIterator[i] = (T)(rand() % 255); } // Initialize output data with zeros memset(outDataGL_, 0, c_imageWidth * c_imageHeight * c_elementsPerPixel * sizeof(T)); // Generate and Bind in & out OpenGL textures glGenTextures(1, &inGLTexture_); glGenTextures(1, &outGLTexture_); glBindTexture(GL_TEXTURE_2D, inGLTexture_); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, (GLsizei)c_imageWidth, (GLsizei)c_imageHeight, 0, format, type, inDataGL_); glBindTexture(GL_TEXTURE_2D, outGLTexture_); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, (GLsizei)c_imageWidth, (GLsizei)c_imageHeight, 0, format, type, outDataGL_); glFinish(); // Create input buffer from GL input texture image = _wrapper->clCreateFromGLTexture(context_, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, inGLTexture_, &error_); if (error_ != CL_SUCCESS) { printf("Unable to create input buffer from GL texture (%d)", error_); return false; } buffers_.push_back(image); // Create output buffer from GL output texture image = _wrapper->clCreateFromGLTexture(context_, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, outGLTexture_, &error_); if (error_ != CL_SUCCESS) { printf("Unable to create output buffer from GL texture (%d)", error_); return false; } buffers_.push_back(image); size_t gws[2] = {c_imageWidth, c_imageHeight}; // Assign args for (unsigned int i = 0; i < buffers_.size(); i++) { error_ = _wrapper->clSetKernelArg(kernel_, i, sizeof(cl_mem), &buffers()[i]); if (error_ != CL_SUCCESS) { printf("clSetKernelArg() failed (%d)", error_); return false; } } int loop = (testRender_) ? 2 : 1; for (int l = 0; l < loop; ++l) { if (testRender_ && (l == 0)) { GLuint FrameBufferName = 0; glGenFramebuffers(1, &FrameBufferName); glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferName); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, inGLTexture_, 0); glClearColor(.5f, 1.f, 1.0f, 0); glClear(GL_COLOR_BUFFER_BIT); glFinish(); } error_ = _wrapper->clEnqueueAcquireGLObjects(cmdQueues_[_deviceId], 2, &buffers()[0], 0, NULL, NULL); if (error_ != CL_SUCCESS) { printf("Unable to acquire GL objects (%d)", error_); return false; } error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, gws, NULL, 0, NULL, NULL); if (error_ != CL_SUCCESS) { printf("clEnqueueNDRangeKernel() failed (%d)", error_); return false; } error_ = _wrapper->clEnqueueReleaseGLObjects(cmdQueues_[_deviceId], 2, &buffers()[0], 0, NULL, NULL); if (error_ != CL_SUCCESS) { printf("clEnqueueReleaseGLObjects failed (%d)", error_); return false; } error_ = _wrapper->clFinish(cmdQueues_[_deviceId]); if (error_ != CL_SUCCESS) { printf("clFinish() failed (%d)", error_); return false; } if (testRender_ && (l == 0)) { glClearColor(1.f, 1.f, 1.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); glFinish(); } } // Get the results from GL texture glBindTexture(GL_TEXTURE_2D, outGLTexture_); glActiveTexture(GL_TEXTURE0); glGetTexImage(GL_TEXTURE_2D, 0, format, type, outDataGL_); // Check output texture data inputIterator = (T*)inDataGL_; T* outputIterator = (T*)outDataGL_; T color; switch (type) { case GL_UNSIGNED_INT: color = (T)0x3f800000; break; case GL_UNSIGNED_BYTE: color = (T)0xff; break; case GL_SHORT: color = (T)0x7fff; break; case GL_FLOAT: color = (T)1.f; break; default: return false; } for (unsigned int i = 0; i < c_imageWidth * c_imageHeight * c_elementsPerPixel; i++) { if (testRender_) { if (outputIterator[i] != color) { std::cout << "Element " << i << " in output texture is incorrect! (internal format = " << internalFormat << "\n\t expected:" << inputIterator[i] << " differs from actual clear color:" << color << std::endl; return false; } } else if (inputIterator[i] != outputIterator[i]) { std::cout << "Element " << i << " in output texture is incorrect! (internal format = " << internalFormat << "\n\t expected:" << inputIterator[i] << " differs from actual: " << outputIterator[i] << std::endl; return false; } } return true; } #endif // _OCL_GL_TEXTURE_H_