1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "testBase.h"
17 #include "common.h"
18
19 #if defined(__APPLE__)
20 #include <OpenGL/glu.h>
21 #else
22 #include <GL/glu.h>
23 #include <CL/cl_gl.h>
24 #endif
25
26 extern int supportsHalf(cl_context context, bool *supports_half);
27
test_image_info(cl_context context,cl_command_queue queue,GLenum glTarget,GLuint glTexture,size_t imageWidth,size_t imageHeight,size_t imageDepth,cl_image_format * outFormat,ExplicitType * outType,void ** outResultBuffer)28 static int test_image_info(cl_context context, cl_command_queue queue,
29 GLenum glTarget, GLuint glTexture, size_t imageWidth,
30 size_t imageHeight, size_t imageDepth,
31 cl_image_format *outFormat, ExplicitType *outType,
32 void **outResultBuffer)
33 {
34 clMemWrapper streams[2];
35
36 int error;
37
38 // Create a CL image from the supplied GL texture
39 streams[0] = (*clCreateFromGLTexture_ptr)(context, CL_MEM_READ_ONLY,
40 glTarget, 0, glTexture, &error);
41 if (error != CL_SUCCESS)
42 {
43 print_error(error, "Unable to create CL image from GL texture");
44 GLint fmt;
45 glGetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
46 log_error(" Supplied GL texture was format %s\n",
47 GetGLFormatName(fmt));
48 return error;
49 }
50
51 // Determine data type and format that CL came up with
52 error = clGetImageInfo(streams[0], CL_IMAGE_FORMAT, sizeof(cl_image_format),
53 outFormat, NULL);
54 test_error(error, "Unable to get CL image format");
55
56 cl_gl_object_type object_type;
57 switch (glTarget)
58 {
59 case GL_TEXTURE_1D: object_type = CL_GL_OBJECT_TEXTURE1D; break;
60 case GL_TEXTURE_BUFFER:
61 object_type = CL_GL_OBJECT_TEXTURE_BUFFER;
62 break;
63 case GL_TEXTURE_1D_ARRAY:
64 object_type = CL_GL_OBJECT_TEXTURE1D_ARRAY;
65 break;
66 case GL_TEXTURE_2D:
67 case GL_TEXTURE_RECTANGLE_EXT:
68 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
69 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
70 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
71 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
72 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
73 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
74 object_type = CL_GL_OBJECT_TEXTURE2D;
75 break;
76 case GL_TEXTURE_2D_ARRAY:
77 object_type = CL_GL_OBJECT_TEXTURE2D_ARRAY;
78 break;
79 case GL_TEXTURE_3D: object_type = CL_GL_OBJECT_TEXTURE3D; break;
80 default: log_error("Unsupported texture target."); return 1;
81 }
82
83 return CheckGLObjectInfo(streams[0], object_type, glTexture, glTarget, 0);
84 }
85
test_image_format_get_info(cl_context context,cl_command_queue queue,size_t width,size_t height,size_t depth,GLenum target,const format * fmt,MTdata data)86 static int test_image_format_get_info(cl_context context,
87 cl_command_queue queue, size_t width,
88 size_t height, size_t depth,
89 GLenum target, const format *fmt,
90 MTdata data)
91 {
92 int error = 0;
93
94 // If we're testing a half float format, then we need to determine the
95 // rounding mode of this machine. Punt if we fail to do so.
96
97 if (fmt->type == kHalf)
98 {
99 if (DetectFloatToHalfRoundingMode(queue)) return 0;
100 bool supports_half = false;
101 error = supportsHalf(context, &supports_half);
102 if (error != 0) return error;
103 if (!supports_half) return 0;
104 }
105
106 size_t w = width, h = height, d = depth;
107
108 // Unpack the format and use it, along with the target, to create an
109 // appropriate GL texture.
110
111 GLenum gl_fmt = fmt->formattype;
112 GLenum gl_internal_fmt = fmt->internal;
113 GLenum gl_type = fmt->datatype;
114 ExplicitType type = fmt->type;
115
116 glTextureWrapper texture;
117 glBufferWrapper glbuf;
118
119 // If we're testing a half float format, then we need to determine the
120 // rounding mode of this machine. Punt if we fail to do so.
121
122 if (fmt->type == kHalf)
123 if (DetectFloatToHalfRoundingMode(queue)) return 1;
124
125 // Use the correct texture creation function depending on the target, and
126 // adjust width, height, depth as appropriate so subsequent size
127 // calculations succeed.
128
129 switch (target)
130 {
131 case GL_TEXTURE_1D:
132 h = 1;
133 d = 1;
134 CreateGLTexture1D(width, target, gl_fmt, gl_internal_fmt, gl_type,
135 type, &texture, &error, false, data);
136 break;
137 case GL_TEXTURE_BUFFER:
138 h = 1;
139 d = 1;
140 CreateGLTextureBuffer(width, target, gl_fmt, gl_internal_fmt,
141 gl_type, type, &texture, &glbuf, &error,
142 false, data);
143 break;
144 case GL_TEXTURE_1D_ARRAY:
145 d = 1;
146 CreateGLTexture1DArray(width, height, target, gl_fmt,
147 gl_internal_fmt, gl_type, type, &texture,
148 &error, false, data);
149 break;
150 case GL_TEXTURE_RECTANGLE_EXT:
151 case GL_TEXTURE_2D:
152 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
154 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
155 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
157 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
158 d = 1;
159 CreateGLTexture2D(width, height, target, gl_fmt, gl_internal_fmt,
160 gl_type, type, &texture, &error, false, data);
161 break;
162 case GL_TEXTURE_2D_ARRAY:
163 CreateGLTexture2DArray(width, height, depth, target, gl_fmt,
164 gl_internal_fmt, gl_type, type, &texture,
165 &error, false, data);
166 break;
167 case GL_TEXTURE_3D:
168 d = 1;
169 CreateGLTexture3D(width, height, depth, target, gl_fmt,
170 gl_internal_fmt, gl_type, type, &texture, &error,
171 data, false);
172 break;
173 default: log_error("Unsupported texture target.\n"); return 1;
174 }
175
176 if (error == -2)
177 {
178 log_info("OpenGL texture couldn't be created, because a texture is too "
179 "big. Skipping test.\n");
180 return 0;
181 }
182
183 if (error != 0)
184 {
185 if ((gl_fmt == GL_RGBA_INTEGER_EXT)
186 && (!CheckGLIntegerExtensionSupport()))
187 {
188 log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. "
189 "Skipping test.\n");
190 return 0;
191 }
192 else
193 {
194 return error;
195 }
196 }
197
198 cl_image_format clFormat;
199 ExplicitType actualType;
200 char *outBuffer;
201
202 // Perform the info check:
203 return test_image_info(context, queue, target, texture, w, h, d, &clFormat,
204 &actualType, (void **)&outBuffer);
205 }
206
test_images_get_info_common(cl_device_id device,cl_context context,cl_command_queue queue,const format * formats,size_t nformats,GLenum * targets,size_t ntargets,sizevec_t * sizes,size_t nsizes)207 int test_images_get_info_common(cl_device_id device, cl_context context,
208 cl_command_queue queue, const format *formats,
209 size_t nformats, GLenum *targets,
210 size_t ntargets, sizevec_t *sizes,
211 size_t nsizes)
212 {
213 int error = 0;
214 RandomSeed seed(gRandomSeed);
215
216 // First, ensure this device supports images.
217
218 if (checkForImageSupport(device))
219 {
220 log_info("Device does not support images. Skipping test.\n");
221 return 0;
222 }
223
224 size_t fidx, tidx, sidx;
225
226 // Test each format on every target, every size.
227
228 for (fidx = 0; fidx < nformats; fidx++)
229 {
230 for (tidx = 0; tidx < ntargets; tidx++)
231 {
232
233 if (formats[fidx].datatype == GL_UNSIGNED_INT_2_10_10_10_REV)
234 {
235 // Check if the RGB 101010 format is supported
236 if (is_rgb_101010_supported(context, targets[tidx]) == 0)
237 break; // skip
238 }
239
240 log_info("Testing image info for GL format %s : %s : %s : %s\n",
241 GetGLTargetName(targets[tidx]),
242 GetGLFormatName(formats[fidx].internal),
243 GetGLBaseFormatName(formats[fidx].formattype),
244 GetGLTypeName(formats[fidx].datatype));
245
246 for (sidx = 0; sidx < nsizes; sidx++)
247 {
248
249 // Test this format + size:
250
251 if (test_image_format_get_info(
252 context, queue, sizes[sidx].width, sizes[sidx].height,
253 sizes[sidx].depth, targets[tidx], &formats[fidx], seed))
254 {
255 // We land here in the event of test failure.
256
257 log_error("ERROR: Image info test failed for %s : %s : %s "
258 ": %s\n\n",
259 GetGLTargetName(targets[tidx]),
260 GetGLFormatName(formats[fidx].internal),
261 GetGLBaseFormatName(formats[fidx].formattype),
262 GetGLTypeName(formats[fidx].datatype));
263 error++;
264
265 // Skip the other sizes for this format.
266
267 break;
268 }
269 }
270 }
271 }
272
273 return error;
274 }
275