• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 #if defined( __APPLE__ )
19     #include <OpenGL/glu.h>
20 #else
21     #include <GL/glu.h>
22     #include <CL/cl_gl.h>
23 #endif
24 
25 #if defined (__linux__)
26 GLboolean
gluCheckExtension(const GLubyte * extension,const GLubyte * extensions)27 gluCheckExtension(const GLubyte *extension, const GLubyte *extensions)
28 {
29   const GLubyte *start;
30   GLubyte *where, *terminator;
31 
32   /* Extension names should not have spaces. */
33   where = (GLubyte *) strchr((const char*)extension, ' ');
34   if (where || *extension == '\0')
35     return 0;
36   /* It takes a bit of care to be fool-proof about parsing the
37      OpenGL extensions string. Don't be fooled by sub-strings,
38      etc. */
39   start = extensions;
40   for (;;) {
41     where = (GLubyte *) strstr((const char *) start, (const char*) extension);
42     if (!where)
43       break;
44     terminator = where + strlen((const char*) extension);
45     if (where == start || *(where - 1) == ' ')
46       if (*terminator == ' ' || *terminator == '\0')
47         return 1;
48     start = terminator;
49   }
50   return 0;
51 }
52 #endif
53 
54 
55 // This is defined in the write common code:
56 extern int test_cl_image_write( cl_context context, cl_command_queue queue,
57   GLenum target, cl_mem clImage, size_t width, size_t height, size_t depth,
58   cl_image_format *outFormat, ExplicitType *outType, void **outSourceBuffer,
59   MTdata d, bool supports_half );
60 
61 extern int test_cl_image_read( cl_context context, cl_command_queue queue,
62   GLenum gl_target, cl_mem image, size_t width, size_t height, size_t depth, size_t sampleNum,
63   cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer );
64 
65 extern int supportsHalf(cl_context context, bool* supports_half);
66 
test_attach_renderbuffer_read_image(cl_context context,cl_command_queue queue,GLenum glTarget,GLuint glRenderbuffer,size_t imageWidth,size_t imageHeight,cl_image_format * outFormat,ExplicitType * outType,void ** outResultBuffer)67 static int test_attach_renderbuffer_read_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
68                     size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, void **outResultBuffer )
69 {
70     int error;
71 
72     // Create a CL image from the supplied GL renderbuffer
73     cl_mem image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_READ_ONLY, glRenderbuffer, &error );
74     if( error != CL_SUCCESS )
75     {
76         print_error( error, "Unable to create CL image from GL renderbuffer" );
77         return error;
78     }
79 
80     return test_cl_image_read( context, queue, glTarget, image, imageWidth,
81     imageHeight, 1, 1, outFormat, outType, outResultBuffer );
82 }
83 
test_renderbuffer_read_image(cl_context context,cl_command_queue queue,GLsizei width,GLsizei height,GLenum attachment,GLenum format,GLenum internalFormat,GLenum glType,ExplicitType type,MTdata d)84 int test_renderbuffer_read_image( cl_context context, cl_command_queue queue,
85                             GLsizei width, GLsizei height, GLenum attachment,
86                             GLenum format, GLenum internalFormat,
87                             GLenum glType, ExplicitType type, MTdata d )
88 {
89     int error;
90 
91     if( type == kHalf )
92         if( DetectFloatToHalfRoundingMode(queue) )
93             return 1;
94 
95     // Create the GL renderbuffer
96     glFramebufferWrapper glFramebuffer;
97     glRenderbufferWrapper glRenderbuffer;
98     void *tmp = CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, true );
99     BufferOwningPtr<char> inputBuffer(tmp);
100     if( error != 0 )
101     {
102         if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
103         {
104             log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
105             return 0;
106         }
107         else
108         {
109             return error;
110         }
111     }
112 
113     // Run and get the results
114     cl_image_format clFormat;
115     ExplicitType actualType;
116     char *outBuffer;
117     error = test_attach_renderbuffer_read_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &actualType, (void **)&outBuffer );
118     if( error != 0 )
119         return error;
120     BufferOwningPtr<char> actualResults(outBuffer);
121 
122     log_info( "- Read [%4d x %4d] : GL renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
123                     GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
124                     GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
125 
126 #ifdef DEBUG
127     log_info("- start read GL data -- \n");
128     DumpGLBuffer(glType, width, height, actualResults);
129     log_info("- end read GL data -- \n");
130 #endif
131 
132     // We have to convert our input buffer to the returned type, so we can validate.
133     BufferOwningPtr<char> convertedInput(convert_to_expected( inputBuffer, width * height, type, actualType, get_channel_order_channel_count(clFormat.image_channel_order) ));
134 
135 #ifdef DEBUG
136     log_info("- start input data -- \n");
137     DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, convertedInput);
138     log_info("- end input data -- \n");
139 #endif
140 
141 #ifdef DEBUG
142     log_info("- start converted data -- \n");
143     DumpGLBuffer(GetGLTypeForExplicitType(actualType), width, height, actualResults);
144     log_info("- end converted data -- \n");
145 #endif
146 
147     // Now we validate
148     int valid = 0;
149     if(convertedInput) {
150         if( actualType == kFloat )
151             valid = validate_float_results( convertedInput, actualResults, width, height, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
152         else
153             valid = validate_integer_results( convertedInput, actualResults, width, height, 1, get_explicit_type_size( actualType ) );
154     }
155 
156     return valid;
157 }
158 
test_renderbuffer_read(cl_device_id device,cl_context context,cl_command_queue queue,int numElements)159 int test_renderbuffer_read( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
160 {
161     GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
162 
163     struct {
164         GLenum internal;
165         GLenum format;
166         GLenum datatype;
167         ExplicitType type;
168 
169     } formats[] = {
170         { GL_RGBA,         GL_BGRA,             GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
171         { GL_RGBA,         GL_RGBA,             GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
172         { GL_RGBA8,        GL_RGBA,             GL_UNSIGNED_BYTE,            kUChar },
173         { GL_RGBA16,       GL_RGBA,             GL_UNSIGNED_SHORT,           kUShort },
174 
175 // Renderbuffers with integer formats do not seem to work reliably across
176 // platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
177 
178 #ifdef TEST_INTEGER_FORMATS
179 
180         { GL_RGBA8I_EXT,   GL_RGBA_INTEGER_EXT, GL_BYTE,                     kChar },
181         { GL_RGBA16I_EXT,  GL_RGBA_INTEGER_EXT, GL_SHORT,                    kShort },
182         { GL_RGBA32I_EXT,  GL_RGBA_INTEGER_EXT, GL_INT,                      kInt },
183         { GL_RGBA8UI_EXT,  GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE,            kUChar },
184         { GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT,           kUShort },
185         { GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT,             kUInt },
186 #endif
187         { GL_RGBA32F_ARB,  GL_RGBA,             GL_FLOAT,                    kFloat },
188         { GL_RGBA16F_ARB,  GL_RGBA,             GL_HALF_FLOAT,               kHalf }
189     };
190 
191     size_t fmtIdx, attIdx;
192     int error = 0;
193 #ifdef DEBUG
194     size_t iter = 1;
195 #else
196     size_t iter = 6;
197 #endif
198     RandomSeed seed( gRandomSeed );
199 
200   // Check if images are supported
201   if (checkForImageSupport(device)) {
202     log_info("Device does not support images. Skipping test.\n");
203     return 0;
204   }
205 
206     if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
207     {
208         log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
209         return 0;
210     }
211 
212     // Loop through a set of GL formats, testing a set of sizes against each one
213     for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
214     {
215         for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
216         {
217             size_t i;
218 
219             log_info( "Testing renderbuffer read for %s : %s : %s : %s\n",
220                 GetGLAttachmentName( attachments[ attIdx ] ),
221                 GetGLFormatName( formats[ fmtIdx ].internal ),
222                 GetGLBaseFormatName( formats[ fmtIdx ].format ),
223                 GetGLTypeName( formats[ fmtIdx ].datatype ) );
224 
225             for( i = 0; i < iter; i++ )
226             {
227                 GLsizei width = random_in_range( 16, 512, seed );
228                 GLsizei height = random_in_range( 16, 512, seed );
229 #ifdef DEBUG
230                 width = height = 4;
231 #endif
232 
233                 if( test_renderbuffer_read_image( context, queue, width, height,
234                                                   attachments[ attIdx ],
235                                                   formats[ fmtIdx ].format,
236                                                   formats[ fmtIdx ].internal,
237                                                   formats[ fmtIdx ].datatype,
238                                                   formats[ fmtIdx ].type, seed ) )
239 
240                 {
241                     log_error( "ERROR: Renderbuffer read test failed for %s : %s : %s : %s\n\n",
242                                 GetGLAttachmentName( attachments[ attIdx ] ),
243                                 GetGLFormatName( formats[ fmtIdx ].internal ),
244                                 GetGLBaseFormatName( formats[ fmtIdx ].format ),
245                                 GetGLTypeName( formats[ fmtIdx ].datatype ) );
246 
247                     error++;
248                     break;    // Skip other sizes for this combination
249                 }
250             }
251             if( i == iter )
252             {
253                 log_info( "passed: Renderbuffer read test passed for %s : %s : %s : %s\n\n",
254                           GetGLAttachmentName( attachments[ attIdx ] ),
255                           GetGLFormatName( formats[ fmtIdx ].internal ),
256                           GetGLBaseFormatName( formats[ fmtIdx ].format ),
257                           GetGLTypeName( formats[ fmtIdx ].datatype ) );
258             }
259         }
260     }
261 
262     return error;
263 }
264 
265 
266 #pragma mark -------------------- Write tests -------------------------
267 
test_attach_renderbuffer_write_to_image(cl_context context,cl_command_queue queue,GLenum glTarget,GLuint glRenderbuffer,size_t imageWidth,size_t imageHeight,cl_image_format * outFormat,ExplicitType * outType,MTdata d,void ** outSourceBuffer,bool supports_half)268 int test_attach_renderbuffer_write_to_image( cl_context context, cl_command_queue queue, GLenum glTarget, GLuint glRenderbuffer,
269                      size_t imageWidth, size_t imageHeight, cl_image_format *outFormat, ExplicitType *outType, MTdata d, void **outSourceBuffer, bool supports_half )
270 {
271     int error;
272 
273     // Create a CL image from the supplied GL renderbuffer
274     clMemWrapper image = (*clCreateFromGLRenderbuffer_ptr)( context, CL_MEM_WRITE_ONLY, glRenderbuffer, &error );
275     if( error != CL_SUCCESS )
276     {
277         print_error( error, "Unable to create CL image from GL renderbuffer" );
278         return error;
279     }
280 
281     return test_cl_image_write( context, queue, glTarget, image, imageWidth,
282     imageHeight, 1, outFormat, outType, outSourceBuffer, d, supports_half );
283 }
284 
test_renderbuffer_image_write(cl_context context,cl_command_queue queue,GLsizei width,GLsizei height,GLenum attachment,GLenum format,GLenum internalFormat,GLenum glType,ExplicitType type,MTdata d)285 int test_renderbuffer_image_write( cl_context context, cl_command_queue queue,
286                                    GLsizei width, GLsizei height, GLenum attachment,
287                                    GLenum format, GLenum internalFormat,
288                                      GLenum glType, ExplicitType type, MTdata d )
289 {
290     int error;
291 
292     if( type == kHalf )
293         if( DetectFloatToHalfRoundingMode(queue) )
294             return 1;
295 
296     // Create the GL renderbuffer
297     glFramebufferWrapper glFramebuffer;
298     glRenderbufferWrapper glRenderbuffer;
299     CreateGLRenderbuffer( width, height, attachment, format, internalFormat, glType, type, &glFramebuffer, &glRenderbuffer, &error, d, false );
300     if( error != 0 )
301     {
302         if ((format == GL_RGBA_INTEGER_EXT) && (!CheckGLIntegerExtensionSupport()))
303         {
304             log_info("OpenGL version does not support GL_RGBA_INTEGER_EXT. Skipping test.\n");
305             return 0;
306         }
307         else
308         {
309             return error;
310         }
311     }
312 
313     // Run and get the results
314     cl_image_format clFormat;
315     ExplicitType sourceType;
316     ExplicitType validationType;
317     void *outSourceBuffer;
318 
319     bool supports_half = false;
320     error = supportsHalf(context, &supports_half);
321     if( error != 0 )
322         return error;
323 
324     error = test_attach_renderbuffer_write_to_image( context, queue, attachment, glRenderbuffer, width, height, &clFormat, &sourceType, d, (void **)&outSourceBuffer, supports_half );
325     if( error != 0 || ((sourceType == kHalf ) && !supports_half))
326         return error;
327 
328     // If actual source type was half, convert to float for validation.
329     if( sourceType == kHalf )
330         validationType = kFloat;
331     else
332         validationType = sourceType;
333 
334     BufferOwningPtr<char> validationSource( convert_to_expected( outSourceBuffer, width * height, sourceType, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
335 
336     log_info( "- Write [%4d x %4d] : GL Renderbuffer : %s : %s : %s => CL Image : %s : %s \n", width, height,
337                     GetGLFormatName( format ), GetGLFormatName( internalFormat ), GetGLTypeName( glType),
338                     GetChannelOrderName( clFormat.image_channel_order ), GetChannelTypeName( clFormat.image_channel_data_type ));
339 
340     // Now read the results from the GL renderbuffer
341     BufferOwningPtr<char> resultData( ReadGLRenderbuffer( glFramebuffer, glRenderbuffer, attachment, format, internalFormat, glType, type, width, height ) );
342 
343 #ifdef DEBUG
344     log_info("- start result data -- \n");
345     DumpGLBuffer(glType, width, height, resultData);
346     log_info("- end result data -- \n");
347 #endif
348 
349     // We have to convert our input buffer to the returned type, so we can validate.
350     BufferOwningPtr<char> convertedData( convert_to_expected( resultData, width * height, type, validationType, get_channel_order_channel_count(clFormat.image_channel_order) ) );
351 
352 #ifdef DEBUG
353     log_info("- start input data -- \n");
354     DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, validationSource);
355     log_info("- end input data -- \n");
356 #endif
357 
358 #ifdef DEBUG
359     log_info("- start converted data -- \n");
360     DumpGLBuffer(GetGLTypeForExplicitType(validationType), width, height, convertedData);
361     log_info("- end converted data -- \n");
362 #endif
363 
364     // Now we validate
365     int valid = 0;
366     if(convertedData) {
367         if( sourceType == kFloat || sourceType == kHalf )
368             valid = validate_float_results( validationSource, convertedData, width, height, 1, get_channel_order_channel_count(clFormat.image_channel_order) );
369         else
370             valid = validate_integer_results( validationSource, convertedData, width, height, 1, get_explicit_type_size( type ) );
371     }
372 
373     return valid;
374 }
375 
test_renderbuffer_write(cl_device_id device,cl_context context,cl_command_queue queue,int numElements)376 int test_renderbuffer_write( cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
377 {
378     GLenum attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
379 
380     struct {
381         GLenum internal;
382         GLenum format;
383         GLenum datatype;
384         ExplicitType type;
385 
386     } formats[] = {
387         { GL_RGBA,         GL_BGRA,             GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
388         { GL_RGBA,         GL_RGBA,             GL_UNSIGNED_INT_8_8_8_8_REV, kUChar },
389         { GL_RGBA8,        GL_RGBA,             GL_UNSIGNED_BYTE,            kUChar },
390         { GL_RGBA16,       GL_RGBA,             GL_UNSIGNED_SHORT,           kUShort },
391 
392 // Renderbuffers with integer formats do not seem to work reliably across
393 // platforms/implementations. Disabling this in version 1.0 of CL conformance tests.
394 
395 #ifdef TEST_INTEGER_FORMATS
396 
397         { GL_RGBA8I_EXT,   GL_RGBA_INTEGER_EXT, GL_BYTE,                     kChar },
398         { GL_RGBA16I_EXT,  GL_RGBA_INTEGER_EXT, GL_SHORT,                    kShort },
399         { GL_RGBA32I_EXT,  GL_RGBA_INTEGER_EXT, GL_INT,                      kInt },
400         { GL_RGBA8UI_EXT,  GL_RGBA_INTEGER_EXT, GL_UNSIGNED_BYTE,            kUChar },
401         { GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_SHORT,           kUShort },
402         { GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT,             kUInt },
403 #endif
404         { GL_RGBA32F_ARB,  GL_RGBA,             GL_FLOAT,                    kFloat },
405         { GL_RGBA16F_ARB,  GL_RGBA,             GL_HALF_FLOAT,               kHalf }
406     };
407 
408     size_t fmtIdx, attIdx;
409     int error = 0;
410     size_t iter = 6;
411 #ifdef DEBUG
412     iter = 1;
413 #endif
414     RandomSeed seed( gRandomSeed );
415 
416   // Check if images are supported
417   if (checkForImageSupport(device)) {
418     log_info("Device does not support images. Skipping test.\n");
419     return 0;
420   }
421 
422     if( !gluCheckExtension( (const GLubyte *)"GL_EXT_framebuffer_object", glGetString( GL_EXTENSIONS ) ) )
423     {
424         log_info( "Renderbuffers are not supported by this OpenGL implementation; skipping test\n" );
425         return 0;
426     }
427 
428     // Loop through a set of GL formats, testing a set of sizes against each one
429     for( fmtIdx = 0; fmtIdx < sizeof( formats ) / sizeof( formats[ 0 ] ); fmtIdx++ )
430     {
431         for( attIdx = 0; attIdx < sizeof( attachments ) / sizeof( attachments[ 0 ] ); attIdx++ )
432         {
433             log_info( "Testing Renderbuffer write test for %s : %s : %s : %s\n",
434                 GetGLAttachmentName( attachments[ attIdx ] ),
435                 GetGLFormatName( formats[ fmtIdx ].internal ),
436                 GetGLBaseFormatName( formats[ fmtIdx ].format ),
437                 GetGLTypeName( formats[ fmtIdx ].datatype ) );
438 
439             size_t i;
440             for( i = 0; i < iter; i++ )
441             {
442                 GLsizei width = random_in_range( 16, 512, seed );
443                 GLsizei height = random_in_range( 16, 512, seed );
444 #ifdef DEBUG
445                 width = height = 4;
446 #endif
447 
448                 if( test_renderbuffer_image_write( context, queue, width, height,
449                                                    attachments[ attIdx ],
450                                                    formats[ fmtIdx ].format,
451                                                    formats[ fmtIdx ].internal,
452                                                    formats[ fmtIdx ].datatype,
453                                                    formats[ fmtIdx ].type, seed ) )
454                 {
455                     log_error( "ERROR: Renderbuffer write test failed for %s : %s : %s : %s\n\n",
456                           GetGLAttachmentName( attachments[ attIdx ] ),
457                           GetGLFormatName( formats[ fmtIdx ].internal ),
458                           GetGLBaseFormatName( formats[ fmtIdx ].format ),
459                           GetGLTypeName( formats[ fmtIdx ].datatype ) );
460 
461                     error++;
462                     break;    // Skip other sizes for this combination
463                 }
464             }
465             if( i == iter )
466             {
467                 log_info( "passed: Renderbuffer write test passed for %s : %s : %s : %s\n\n",
468                           GetGLAttachmentName( attachments[ attIdx ] ),
469                           GetGLFormatName( formats[ fmtIdx ].internal ),
470                           GetGLBaseFormatName( formats[ fmtIdx ].format ),
471                           GetGLTypeName( formats[ fmtIdx ].datatype ) );
472             }
473         }
474     }
475 
476     return error;
477 }
478