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