Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/gl/OCLGLPerfSepia.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

548 lines
19 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "OCLGLPerfSepia.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define WIDTH 1024
#define HEIGHT 1024
// Quiet pesky warnings
#ifdef WIN_OS
#define SNPRINTF sprintf_s
#else
#define SNPRINTF snprintf
#endif
#define MAX(a, b) (a > b ? a : b)
const char* sepiaVertexProgram =
"!!ARBvp1.0\n"
"\n"
"\n"
"OPTION ARB_position_invariant;\n"
"\n"
"PARAM p0 = program.local[2];\n"
"PARAM p1 = program.local[3];\n"
"ATTRIB a0 = vertex.texcoord[0];\n"
"OUTPUT o0 = result.texcoord[0];\n"
"OUTPUT o1 = result.texcoord[1];\n"
"TEMP r0, r1;\n"
"\n"
"MOV o0, a0;\n"
"#SWZ r1, a0, x, y, 0, 0;\n"
"#DPH r0.x, r1, p0;\n"
"#DPH r0.y, r1, p1;\n"
"#MOV o1, r0;\n"
"MOV o1, a0;\n"
"\n"
"END\n";
const char* sepiaFragmentProgram =
"!!ARBfp1.0\n"
"\n"
"\n"
"PARAM p0 = {1e-4, 0.085, 0.0, 0.0};\n"
"PARAM p1 = {0.2125, 0.7154, 0.0721, 0.0};\n"
"PARAM p2 = {-3605.984, 0.1323156, 0.0, -0.1991615};\n"
"PARAM p3 = {708.7939, -0.3903106, -0.05854013, 0.6621023};\n"
"PARAM p4 = {-50.93341, 0.4654831, 1.027555, -0.9069088};\n"
"PARAM p5 = {3.116672, 0.7926372, 0.03219686, 1.411847};\n"
"PARAM p6 = {8.95663e-4, -0.001104567, -6.0827e-4, 0.03277428};\n"
"PARAM p7 = program.local[0];\n"
"PARAM p8 = program.local[1];\n"
"ATTRIB a0 = fragment.texcoord[1];\n"
"OUTPUT o0 = result.color;\n"
"TEMP r0, r1, r2, r3;\n"
"\n"
"TEX r1, a0, texture[0], RECT;\n"
"#MAX r0, p0.x, r1.w;\n"
"#RCP r2, r0.x;\n"
"#DP3 r3, r1, p1;\n"
"#MUL r0, r3, r2;\n"
"#MAD r2, r0, p2, p3;\n"
"#MAD r2, r2, r0, p4;\n"
"#MAD r0, r2, r0, p5;\n"
"#MUL r2, r1.w, p6;\n"
"#MAD r2, r0, r3, r2;\n"
"#MAD r0, r1.w, p0.y, -r3;\n"
"#CMP r2.x, -r0, r2.x, r2.w;\n"
"#MAD r0, r3, r3, -r3;\n"
"#CMP r0, r0.x, r2, r3;\n"
"#MOV r0.w, r1;\n"
"#MUL r0, r0, p7;\n"
"#LRP o0, p8.x, r0, r1;\n"
"MOV o0, r1;\n"
"\n"
"END\n";
const static char* strKernel =
"\n"
"__kernel void program(write_only image2d_t dest, int flipped, int4 dim, "
"float2 st_origin, float4 st_delta, float4 l0, float4 l1, float4 l2, "
"float4 l3, read_only image2d_t t0, sampler_t t_sampler0)\n"
"{\n"
" const sampler_t sam = CLK_NORMALIZED_COORDS_FALSE | "
"CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;\n"
"// const float4 p0 = (float4)( 0x1.b33334p-3, 0x1.6e48e8p-1, "
"0x1.275254p-4, 0x0p+0 );\n"
"// const float4 p1 = (float4)( 0x1.a36e2ep-14, 0x1.5c28f6p-4, 0x0p+0, "
"0x0p+0 );\n"
"// const float4 p2 = (float4)( 0x1.d595dap-11, -0x1.218e3cp-10, "
"-0x1.3ee89ep-11, 0x1.0c7ca6p-5 );\n"
"// const float4 p3 = (float4)( -0x1.c2bf7cp+11, 0x1.0efb7cp-3, "
"0x0p+0, -0x1.97e1fcp-3 );\n"
"// const float4 p4 = (float4)( 0x1.62659ep+9, -0x1.8fad94p-2, "
"-0x1.df8f8cp-5, 0x1.52ff12p-1 );\n"
"// const float4 p5 = (float4)( -0x1.9777ap+5, 0x1.dca79ap-2, "
"0x1.070dd8p+0, -0x1.d0565ap-1 );\n"
"// const float4 p6 = (float4)( 0x1.8eef1cp+1, 0x1.95d48cp-1, "
"0x1.07c1b6p-5, 0x1.696ecep+0 );\n"
"// int dest_width = dim.x;\n"
"// int dest_height = dim.y;\n"
" float4 o0, r0, r1, r2, r3, r4;\n"
"// float4 false_vector = (float4) 0.0f;\n"
"// float4 true_vector = (float4) 1.0f;\n"
" int2 loc = (int2)( get_global_id(0), get_global_id(1) );\n"
"// if ((loc.x >= dim.x) || loc.y >= dim.y) return;\n"
"// float4 f0 = (float4)( st_origin.x + ((float)loc.x + 0.5f) * "
"st_delta.x + ((float)loc.y + 0.5f) * st_delta.z, st_origin.y + "
"((float)loc.x + 0.5f) * st_delta.y + ((float)loc.y + 0.5f) * st_delta.w, "
"0.0f, 0.0f );\n"
"// r2 = f0;\n"
"// r0.x = dot(r2.xy,l2.xy) + l2.w;\n"
"// r0.y = dot(r2.xy,l3.xy) + l3.w;\n"
"// r4 = r0;\n"
" r1 = read_imagef(t0, sam/*t_sampler0*/, r4.xy);\n"
"// r3 = dot(r1.xyz,p0.xyz);\n"
"// r2 = max(p1.xxxx, r1.wwww);\n"
"// r0 = native_recip(r2.xxxx);\n"
"// r4 = r3*r0;\n"
"// r2 = r1.wwww*p2;\n"
"// r0 = mad(r4,p3,p4);\n"
"// r0 = mad(r0,r4,p5);\n"
"// r0 = mad(r0,r4,p6);\n"
"// r2 = mad(r0,r3,r2);\n"
"// r0 = mad(r1.wwww,p1.yyyy,-r3);\n"
"// r2.x = select(r2.w,r2.x, isless(-r0.x, 0.0f));\n"
"// r0 = mad(r3,r3,-r3);\n"
"// r0 = select(r3,r2, isless(r0.xxxx, 0.0f));\n"
"// r0.w = r1.w;\n"
"// r0 = r0*l0;\n"
"// r0 = mix(r1,r0, l1.xxxx);\n"
"// r0.xyz = min(r0.xyz, r0.www);\n"
"// o0 = r0;\n"
" write_imagef(dest, loc /*(int2)( loc.x + dim.z , flipped ? "
"get_image_height(dest) - (loc.y + dim.w + 1) : loc.y + dim.w )*/, r1 "
"/*o0*/);\n"
"}\n";
OCLGLPerfSepia::OCLGLPerfSepia() { _numSubTests = 2; }
OCLGLPerfSepia::~OCLGLPerfSepia() {}
void OCLGLPerfSepia::open(unsigned int test, char* units, double& conversion,
unsigned int deviceId) {
bVerify_ = false;
silentFailure_ = false;
iterations_ = 50000;
bpr_ = 0;
data_ = 0;
result_ = 0;
width_ = 0;
height_ = 0;
_crcword = 0;
conversion = 1.0f;
_deviceId = deviceId;
_openTest = test;
texId = 0;
format_.image_channel_order = CL_RGBA;
format_.image_channel_data_type = CL_UNORM_INT8;
srand(0x8956); // some constant instead of time() so that we get same random
// numbers
if (!IsGLEnabled(test, units, conversion, deviceId)) {
silentFailure_ = true;
return;
}
OCLGLCommon::open(test, units, conversion, deviceId);
if (_errorFlag) return;
if (test == 0) {
// Build the kernel
program_ = _wrapper->clCreateProgramWithSource(context_, 1, &strKernel, NULL, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateProgramWithSource() failed (%d)", error_);
const char* optionsGPU = "-cl-denorms-are-zero -cl-mad-enable";
error_ = _wrapper->clBuildProgram(program_, 1, &devices_[deviceId], optionsGPU, NULL, NULL);
if (error_ != CL_SUCCESS) {
char programLog[1024];
_wrapper->clGetProgramBuildInfo(program_, devices_[deviceId], CL_PROGRAM_BUILD_LOG, 1024,
programLog, 0);
printf("\n%s\n", programLog);
fflush(stdout);
}
CHECK_RESULT((error_ != CL_SUCCESS), "clBuildProgram() failed (%d)", error_);
kernel_ = _wrapper->clCreateKernel(program_, "program", &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed (%d)", error_);
}
}
void OCLGLPerfSepia::populateData(void) {
width_ = WIDTH;
height_ = HEIGHT;
bpr_ = 4 * width_;
data_ = (cl_uchar*)malloc(height_ * bpr_);
for (unsigned int n = 0; n < (height_ * bpr_); n++) {
data_[n] = (n & 3) ? (rand() % 256) : 0xFF;
}
}
void OCLGLPerfSepia::runGL(void) {
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DITHER);
glDisable(GL_CULL_FACE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_FALSE);
glStencilMask(0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// let's create the textures we need
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texId);
// have GL alloc memory for us for our destination texture which we will be
// rendering into
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width_, height_, 0, GL_BGRA /*RGBA*/,
GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// for the source texture we will provide a data ptr and hang on to it
GLuint srcTexture;
glGenTextures(1, &srcTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, srcTexture);
glPixelStorei(GL_UNPACK_ROW_LENGTH, width_);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, height_);
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
// XXX Alex -- use optimal texture upload format.
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width_, height_, 0, GL_BGRA, /* GL_RGBA,*/
format_.image_channel_order == CL_RGBA ? GL_UNSIGNED_INT_8_8_8_8
: GL_UNSIGNED_INT_8_8_8_8_REV,
data_);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
GLuint vertexProgram;
GLuint fragmentProgram;
glGenProgramsARB(1, &vertexProgram);
glGenProgramsARB(1, &fragmentProgram);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexProgram);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
(GLsizei)strlen(sepiaVertexProgram), sepiaVertexProgram);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragmentProgram);
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
(GLsizei)strlen(sepiaFragmentProgram), sepiaFragmentProgram);
GLfloat l0[] = {1.0f, 0.99f, 0.92f, 1.0f};
GLfloat l1[] = {0.5, 0, 0, 0};
GLfloat l2[] = {1, 0, 0, 0};
GLfloat l3[] = {0, -1, 0, (GLfloat)height_};
glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 0, l0);
glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 1, l1);
glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 2, l2);
glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 3, l3);
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, l0);
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 1, l1);
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 2, l2);
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 3, l3);
GLuint fbo;
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
texId, 0);
glViewport(0, 0, width_, height_);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width_, 0, height_, -1, 1);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
// warm up
for (unsigned int k = 0; k < (iterations_ / 10); k++) {
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(0, (GLfloat)height_);
glTexCoord2f((GLfloat)width_, 0);
glVertex2f((GLfloat)width_, (GLfloat)height_);
glTexCoord2f((GLfloat)width_, (GLfloat)height_);
glVertex2f((GLfloat)width_, 0);
glTexCoord2f(0, (GLfloat)height_);
glVertex2f(0, 0);
glEnd();
glFlush();
glFinish();
}
// actual test
for (unsigned int k = 0; k < iterations_; k++) {
if (k == 1) {
timer_.Reset();
timer_.Start();
}
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(0, (GLfloat)height_);
glTexCoord2f((GLfloat)width_, 0);
glVertex2f((GLfloat)width_, (GLfloat)height_);
glTexCoord2f((GLfloat)width_, (GLfloat)height_);
glVertex2f((GLfloat)width_, 0);
glTexCoord2f(0, (GLfloat)height_);
glVertex2f(0, 0);
glEnd();
}
glFlush();
glFinish();
timer_.Stop();
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
// now let's read back the pixels
result_ = (cl_uchar*)malloc(width_ * height_ * 4);
glReadPixels(0, 0, width_, height_, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, result_);
// bind back default frame buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &fbo);
glDeleteTextures(1, &srcTexture);
glDeleteProgramsARB(1, &vertexProgram);
glDeleteProgramsARB(1, &fragmentProgram);
}
void OCLGLPerfSepia::runCL(void) {
cl_mem dst, src;
cl_sampler nearestZero;
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texId);
// XXX Alex: have GL alloc memory for us ...
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width_, height_, 0, GL_RGBA /*BGRA*/,
GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
dst = _wrapper->clCreateFromGLTexture2D(context_, CL_MEM_READ_WRITE, GL_TEXTURE_RECTANGLE_EXT, 0,
texId, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateFromGLTexture2D error (%d)", error_);
nearestZero =
_wrapper->clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP, CL_FILTER_NEAREST, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateSampler error (%d)", error_);
src = _wrapper->clCreateImage2D(context_, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &format_,
width_, height_, bpr_, data_, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateImage2D error (%d)", error_);
int numArgs = 0;
int dim[2] = {(int)width_, (int)height_};
int flipped[] = {1};
int dims[] = {(int)width_, (int)height_, 0, 0};
float st_origin[] = {0, 0};
float st_delta[] = {1, 0, 0, 1};
_wrapper->clSetKernelArg(kernel_, numArgs++, sizeof(cl_mem),
&dst); // arg is a image2DGL named "dst"
_wrapper->clSetKernelArg(kernel_, numArgs++, sizeof(int),
&flipped); // arg is a int1 named "flipped"
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(int),
&dims); // arg is a int4 named "dim"
_wrapper->clSetKernelArg(kernel_, numArgs++, 2 * sizeof(float),
&st_origin); // arg is a float2 named "st_origin"
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(float),
&st_delta); // arg is a float4 named "st_delta"
float l0[] = {1.0f, 0.99f, 0.92f, 1.0f};
float l1[] = {0.5f, 0.0f, 0.0f, 0.0f};
float l2[] = {1.0f, 0.0f, 0.0f, 0.0f};
float l3[] = {0.0f, -1.0f, 0.0f, (float)height_};
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(float),
&l0); // arg is a float4 named "l0"
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(float),
&l1); // arg is a float4 named "l1"
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(float),
&l2); // arg is a float4 named "l2"
_wrapper->clSetKernelArg(kernel_, numArgs++, 4 * sizeof(float),
&l3); // arg is a float4 named "l3"
_wrapper->clSetKernelArg(kernel_, numArgs++, sizeof(cl_mem),
&src); // arg is a image2D named "t0"
_wrapper->clSetKernelArg(kernel_, numArgs++, sizeof(cl_sampler),
&nearestZero); // arg is a sampler named "t_sampler0"
size_t execution_threads[2];
size_t execution_local[2];
cl_uint work_dim = 2;
error_ =
_wrapper->clGetKernelWorkGroupInfo(kernel_, devices_[_deviceId], CL_KERNEL_WORK_GROUP_SIZE,
sizeof(execution_local[0]), &execution_local[0], 0);
CHECK_RESULT((error_ != CL_SUCCESS), "clGetKernelWorkGroupInfo error (%d)", error_);
execution_local[1] = 1;
work_dim = 2;
GetKernelExecDimsForImage((unsigned int)execution_local[0], dim[0], dim[1], execution_threads,
execution_local);
result_ = (cl_uchar*)malloc(height_ * bpr_);
const size_t origin[] = {0, 0, 0};
const size_t region[] = {width_, height_, 1};
// warm up
for (unsigned int k = 0; k < (iterations_ / 10); k++) {
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, work_dim, NULL,
execution_threads, execution_local, 0, NULL, NULL);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel error (%d)", error_);
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_RESULT((error_ != CL_SUCCESS), "clFinish error (%d)", error_);
}
// actual test
for (unsigned int k = 0; k < iterations_; k++) {
if (k == 1) {
timer_.Reset();
timer_.Start();
}
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, work_dim, NULL,
execution_threads, execution_local, 0, NULL, NULL);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel error (%d)", error_);
}
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_RESULT((error_ != CL_SUCCESS), "clFinish error (%d)", error_);
timer_.Stop();
error_ = _wrapper->clEnqueueReadImage(cmdQueues_[_deviceId], dst, true, origin, region, bpr_, 0,
result_, 0, NULL, NULL);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadImage error (%d)", error_);
_wrapper->clFinish(cmdQueues_[_deviceId]);
_wrapper->clReleaseMemObject(src), src = NULL;
_wrapper->clReleaseSampler(nearestZero);
_wrapper->clReleaseMemObject(dst), dst = NULL;
}
void OCLGLPerfSepia::GetKernelExecDimsForImage(unsigned int work_group_size, unsigned int w,
unsigned int h, size_t* global, size_t* local) {
unsigned int a, b;
static const unsigned int tile_size = 16;
// local[0] and local[1] must be at least 1
local[0] = tile_size < work_group_size ? tile_size : work_group_size;
local[1] =
work_group_size / tile_size > tile_size ? tile_size : MAX(work_group_size / tile_size, 1);
a = w;
b = (unsigned int)local[0];
global[0] = ((a % b) != 0) ? (a / b + 1) : (a / b);
global[0] *= local[0];
a = h;
b = (unsigned int)local[1];
global[1] = ((a % b) != 0) ? (a / b + 1) : (a / b);
global[1] *= local[1];
}
void OCLGLPerfSepia::run(void) {
if (_errorFlag || silentFailure_) {
return;
}
populateData();
if (_openTest == 0) {
runCL();
} else {
runGL();
}
if (bVerify_) {
verifyResult();
}
char buf[100];
SNPRINTF(buf, sizeof(buf), "%s iterations# %d", (_openTest == 0) ? "CL" : "GL", iterations_);
testDescString = buf;
_perfInfo = (float)timer_.GetElapsedTime();
}
void OCLGLPerfSepia::verifyResult(void) {
int r = 0, g = 0, b = 0, a = 0, d = 0;
for (unsigned int k = 0; k < height_ * bpr_; k += 4) {
a = a + result_[k + 0];
r = r + result_[k + 1];
g = g + result_[k + 2];
b = b + result_[k + 3];
}
d = abs(r - 152797810) + abs(g - 125868080) + abs(b - 76147833) + abs(a - 267386880);
CHECK_RESULT(d > 20000, "wrong result");
}
unsigned int OCLGLPerfSepia::close(void) {
if (silentFailure_) {
return 0;
}
if (data_) {
free(data_);
}
if (result_) {
free(result_);
}
if (texId) {
glDeleteTextures(1, &texId);
}
return OCLGLCommon::close();
}