• 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 "helpers.h"
17 #include "../harness/imageHelpers.h"
18 
19 // convert_float_to_half and convert_half_to_float may be found in test_conformance/images/image_helpers.cpp
20 cl_ushort convert_float_to_half( cl_float f );
21 cl_float  convert_half_to_float( cl_ushort h );
22 
23 #if defined( __APPLE__ )
24     #include <OpenGL/glu.h>
25 #else
26     #include <GL/glu.h>
27 #endif
28 
29 #if defined(__linux__)
30 // On linux we dont link to GLU library to avoid comaptibility issues with
31 // libstdc++
32 // FIXME: Implement this
gluErrorString(GLenum error)33 const GLubyte* gluErrorString (GLenum error)
34 {
35     const char* gl_Error = "OpenGL Error";
36     return (const GLubyte*)gl_Error;
37 }
38 #endif
39 
CreateGLTexture1DArray(size_t width,size_t length,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d)40 void * CreateGLTexture1DArray(size_t width, size_t length,
41   GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
42   ExplicitType type, GLuint *outTextureID, int *outError,
43   bool allocateMem, MTdata d)
44 {
45   *outError = 0;
46   GLenum err = 0;
47 
48   char * buffer;
49   unsigned int size = 0;
50 
51   // width_in_pixels * pixel_width * number_of_images:
52   if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
53   {
54     size = width * length;
55   }
56   else
57   {
58     size = width * length * 4;
59   }
60 
61   buffer = (char *)CreateRandomData(type, size, d);
62 
63   glGenTextures( 1, outTextureID );
64   glBindTexture( get_base_gl_target( target ), *outTextureID );
65   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
66   glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MIN_FILTER, GL_NEAREST );
67   glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MAG_FILTER, GL_NEAREST );
68   err = glGetError();
69   if( err != GL_NO_ERROR ) {
70     log_error( "ERROR: Failed to create GL texture object: %s!\n", gluErrorString( err ));
71     *outError = -1;
72     free( buffer );
73     return NULL;
74   }
75 
76   // use TexImage2D to pump the 1D array fill of bits:
77   glTexImage2D( get_base_gl_target(target), 0, internalFormat, (GLsizei)width,
78     (GLsizei)length, 0, glFormat, glType, buffer );
79 
80   err = glGetError();
81   if( err != GL_NO_ERROR ) {
82     if (err != GL_OUT_OF_MEMORY) {
83         log_error( "ERROR: Unable to load data using glTexImage2D for "
84           "TEXTURE_1D_ARRAY : %s : %s : %d : %d : %s : %s : Error %s\n",
85         GetGLTargetName(target),
86         GetGLFormatName(internalFormat),
87         (int)(width), (int)(length),
88         GetGLFormatName(glFormat),
89         GetGLTypeName(glType),
90         gluErrorString( err ));
91 
92         *outError = -1;
93     } else {
94         log_info( "WARNING: Unable to load data using glTexImage2D for "
95           "TEXTURE_1D_ARRAY : %s : %s : %d : %d : %s : %s : Error %s\n",
96         GetGLTargetName(target),
97         GetGLFormatName(internalFormat),
98         (int)(width), (int)(length),
99         GetGLFormatName(glFormat),
100         GetGLTypeName(glType),
101         gluErrorString( err ));
102 
103         *outError = -2;
104     }
105     free( buffer );
106     return NULL;
107   }
108 
109   if( !allocateMem ) {
110     free( buffer );
111     return NULL;
112   }
113 
114   if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
115   {
116     // Reverse and reorder to validate since in the
117     // kernel the read_imagef() call always returns RGBA
118     cl_uchar *p = (cl_uchar *)buffer;
119     for( size_t i = 0; i < width * length; i++ ) {
120       cl_uchar uc0 = p[i * 4 + 0];
121       cl_uchar uc1 = p[i * 4 + 1];
122       cl_uchar uc2 = p[i * 4 + 2];
123       cl_uchar uc3 = p[i * 4 + 3];
124 
125       p[ i * 4 + 0 ] = uc2;
126       p[ i * 4 + 1 ] = uc1;
127       p[ i * 4 + 2 ] = uc0;
128       p[ i * 4 + 3 ] = uc3;
129     }
130   }
131   else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
132   {
133     // Reverse and reorder to validate since in the
134     // kernel the read_imagef() call always returns RGBA
135     cl_uchar *p = (cl_uchar *)buffer;
136     for( size_t i = 0; i < width * length; i++ )
137     {
138       cl_uchar uc0 = p[i * 4 + 0];
139       cl_uchar uc1 = p[i * 4 + 1];
140       cl_uchar uc2 = p[i * 4 + 2];
141       cl_uchar uc3 = p[i * 4 + 3];
142 
143       p[ i * 4 + 0 ] = uc1;
144       p[ i * 4 + 1 ] = uc2;
145       p[ i * 4 + 2 ] = uc3;
146       p[ i * 4 + 3 ] = uc0;
147     }
148   }
149 
150   return buffer;
151 }
152 
CreateGLTexture2DArray(size_t width,size_t height,size_t length,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d)153 void * CreateGLTexture2DArray(size_t width, size_t height, size_t length,
154   GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
155   ExplicitType type, GLuint *outTextureID, int *outError,
156   bool allocateMem, MTdata d)
157 {
158   *outError = 0;
159 
160   char * buffer;
161   unsigned int size = 0;
162 
163   if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
164   {
165     size = width * height * length;
166   }
167   else
168   {
169     size = width * height * length * 4;
170   }
171 
172   buffer = (char *)CreateRandomData(type, size, d);
173 
174   if( type == kFloat && allocateMem )
175   {
176     // Re-fill the created buffer to just have [0-1] floats, since that's what it'd expect
177     cl_float *p = (cl_float *)buffer;
178     for( size_t i = 0; i < size; i++ )
179     {
180       p[ i ] = (float) genrand_real1( d );
181     }
182   }
183   else if( !allocateMem )
184     memset( buffer, 0, size * get_explicit_type_size( type ) );
185 
186   glGenTextures( 1, outTextureID );
187 
188   glBindTexture( target, *outTextureID );
189   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
190   glTexParameteri( target, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
191   glTexParameteri( target, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
192 
193   glGetError();
194   //the default alignment in OpenGL is 4 bytes and need to be changed for GL_DEPTH_COMPONENT16 which is aligned to 2 bytes
195   if (internalFormat == GL_DEPTH_COMPONENT16)
196     glPixelStorei(GL_UNPACK_ALIGNMENT, get_explicit_type_size( type ));
197 
198   glTexImage3D( target, 0, internalFormat, (GLsizei)width, (GLsizei)height,
199     (GLsizei)length, 0, glFormat, glType, buffer );
200 
201   if (internalFormat == GL_DEPTH_COMPONENT16)
202     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
203 
204   GLenum err = glGetError();
205   if( err != GL_NO_ERROR )
206   {
207     if (err != GL_OUT_OF_MEMORY) {
208         log_error( "ERROR: Unable to load data into GL texture (%s) format %s "
209           "type %s internal format %s\n", gluErrorString( err ),
210           GetGLFormatName( glFormat ), get_explicit_type_name( type ),
211           GetGLFormatName( internalFormat ) );
212         *outError = -1;
213     } else {
214         log_info( "WARNING: Unable to load data into GL texture (%s) format %s "
215           "type %s internal format %s\n", gluErrorString( err ),
216           GetGLFormatName( glFormat ), get_explicit_type_name( type ),
217           GetGLFormatName( internalFormat ) );
218         *outError = -2;
219     }
220     delete [] buffer;
221     return NULL;
222   }
223 
224   if( !allocateMem )
225   {
226     delete [] buffer;
227     return NULL;
228   }
229 
230   if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
231   {
232     // Reverse and reorder to validate since in the
233     // kernel the read_imagef() call always returns RGBA
234     cl_uchar *p = (cl_uchar *)buffer;
235     for( size_t i = 0; i < width * height * length; i++ )
236     {
237       cl_uchar uc0 = p[i * 4 + 0];
238       cl_uchar uc1 = p[i * 4 + 1];
239       cl_uchar uc2 = p[i * 4 + 2];
240       cl_uchar uc3 = p[i * 4 + 3];
241 
242       p[ i * 4 + 0 ] = uc2;
243       p[ i * 4 + 1 ] = uc1;
244       p[ i * 4 + 2 ] = uc0;
245       p[ i * 4 + 3 ] = uc3;
246     }
247   }
248   else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
249   {
250     // Reverse and reorder to validate since in the
251     // kernel the read_imagef() call always returns RGBA
252     cl_uchar *p = (cl_uchar *)buffer;
253     for( size_t i = 0; i < width * length; i++ )
254     {
255       cl_uchar uc0 = p[i * 4 + 0];
256       cl_uchar uc1 = p[i * 4 + 1];
257       cl_uchar uc2 = p[i * 4 + 2];
258       cl_uchar uc3 = p[i * 4 + 3];
259 
260       p[ i * 4 + 0 ] = uc1;
261       p[ i * 4 + 1 ] = uc2;
262       p[ i * 4 + 2 ] = uc3;
263       p[ i * 4 + 3 ] = uc0;
264     }
265   }
266 
267   return buffer;
268 }
269 
CreateGLTextureBuffer(size_t width,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTex,GLuint * outBuf,int * outError,bool allocateMem,MTdata d)270 void * CreateGLTextureBuffer(size_t width, GLenum target,
271   GLenum glFormat, GLenum internalFormat, GLenum glType, ExplicitType type,
272   GLuint *outTex, GLuint *outBuf, int *outError, bool allocateMem, MTdata d)
273 {
274   // First, generate a regular GL Buffer from random data.
275   *outError = 0;
276   GLenum err = 0;
277 
278   char * buffer;
279   unsigned int size = 0;
280 
281   // The buffer should be the array width * number of elements * element pitch
282   if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
283   {
284     size = width;
285   }
286   else
287   {
288     size = width * 4;
289   }
290 
291   buffer = (char*)CreateRandomData(type, size, d);
292 
293   err = glGetError();
294 
295   glGenBuffers(1, outBuf);
296   glBindBuffer(GL_TEXTURE_BUFFER, *outBuf);
297 
298   // Need to multiply by the type size:
299   size *= ( GetGLTypeSize( GetGLTypeForExplicitType(type) ) );
300 
301   glBufferData(GL_TEXTURE_BUFFER, size, buffer, GL_DYNAMIC_DRAW);
302 
303   // Now make a Texture out of this Buffer:
304 
305   glGenTextures(1, outTex);
306   glBindTexture(GL_TEXTURE_BUFFER, *outTex);
307   glTexBuffer(GL_TEXTURE_BUFFER, internalFormat, *outBuf);
308 
309   if ((err = glGetError())) {
310     log_error( "ERROR: Unable to load data into glTexBuffer : %s : %s : %d : %s : %s : Error %s\n",
311               GetGLTargetName(target),
312               GetGLFormatName(internalFormat),
313               (int)(size),
314               GetGLFormatName(glFormat),
315               GetGLTypeName(glType),
316               gluErrorString( err ));
317     *outError = -1;
318     delete [] buffer;
319     return NULL;
320   }
321 
322   if( !allocateMem ) {
323     free( buffer );
324     return NULL;
325   }
326 
327   if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
328   {
329     // Reverse and reorder to validate since in the
330     // kernel the read_imagef() call always returns RGBA
331     cl_uchar *p = (cl_uchar *)buffer;
332     for( size_t i = 0; i < width; i++ ) {
333       cl_uchar uc0 = p[i * 4 + 0];
334       cl_uchar uc1 = p[i * 4 + 1];
335       cl_uchar uc2 = p[i * 4 + 2];
336       cl_uchar uc3 = p[i * 4 + 3];
337 
338       p[ i * 4 + 0 ] = uc2;
339       p[ i * 4 + 1 ] = uc1;
340       p[ i * 4 + 2 ] = uc0;
341       p[ i * 4 + 3 ] = uc3;
342     }
343   }
344   else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
345   {
346     // Reverse and reorder to validate since in the
347     // kernel the read_imagef() call always returns RGBA
348     cl_uchar *p = (cl_uchar *)buffer;
349     for( size_t i = 0; i < width; i++ )
350     {
351       cl_uchar uc0 = p[i * 4 + 0];
352       cl_uchar uc1 = p[i * 4 + 1];
353       cl_uchar uc2 = p[i * 4 + 2];
354       cl_uchar uc3 = p[i * 4 + 3];
355 
356       p[ i * 4 + 0 ] = uc1;
357       p[ i * 4 + 1 ] = uc2;
358       p[ i * 4 + 2 ] = uc3;
359       p[ i * 4 + 3 ] = uc0;
360     }
361   }
362 
363   return buffer;
364 }
365 
CreateGLTexture1D(size_t width,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d)366 void* CreateGLTexture1D( size_t width, GLenum target, GLenum glFormat,
367     GLenum internalFormat, GLenum glType, ExplicitType type,
368     GLuint *outTextureID, int *outError, bool allocateMem, MTdata d )
369 {
370   *outError = 0;
371   GLenum err = 0;
372 
373   char * buffer;
374   unsigned int size = 0;
375 
376   // The buffer should be the array width * number of elements * element pitch
377   if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
378   {
379     size = width;
380   }
381   else
382   {
383     size = width * 4;
384   }
385 
386   buffer = (char*)CreateRandomData(type, size, d);
387 
388   glGenTextures( 1, outTextureID );
389   glBindTexture( get_base_gl_target( target ), *outTextureID );
390   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
391   glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MIN_FILTER, GL_NEAREST );
392   glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MAG_FILTER, GL_NEAREST );
393   err = glGetError();
394   if( err != GL_NO_ERROR )
395   {
396     log_error( "ERROR: Failed to create GL texture object: %s!\n", gluErrorString( err ));
397     *outError = -1;
398     free( buffer );
399     return NULL;
400   }
401 
402   glTexImage1D( get_base_gl_target(target), 0, internalFormat, (GLsizei)width,
403     0, glFormat, glType, buffer );
404 
405   err = glGetError();
406   if( err != GL_NO_ERROR )
407   {
408         if (err != GL_OUT_OF_MEMORY) {
409             log_error( "ERROR: Unable to load data into glTexImage1D : %s : %s : %d : %s : %s : Error %s\n",
410               GetGLTargetName(target),
411               GetGLFormatName(internalFormat),
412               (int)(width),
413               GetGLFormatName(glFormat),
414               GetGLTypeName(glType),
415               gluErrorString( err ));
416             *outError = -1;
417         } else {
418             log_info( "WARNING: Unable to load data into glTexImage1D : %s : %s : %d : %s : %s : Error %s\n",
419               GetGLTargetName(target),
420               GetGLFormatName(internalFormat),
421               (int)(width),
422               GetGLFormatName(glFormat),
423               GetGLTypeName(glType),
424               gluErrorString( err ));
425             *outError = -2;
426         }
427       free( buffer );
428       return NULL;
429   }
430 
431   if( !allocateMem ) {
432     free( buffer );
433     return NULL;
434   }
435 
436   if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
437   {
438     // Reverse and reorder to validate since in the
439     // kernel the read_imagef() call always returns RGBA
440     cl_uchar *p = (cl_uchar *)buffer;
441     for( size_t i = 0; i < width; i++ ) {
442       cl_uchar uc0 = p[i * 4 + 0];
443       cl_uchar uc1 = p[i * 4 + 1];
444       cl_uchar uc2 = p[i * 4 + 2];
445       cl_uchar uc3 = p[i * 4 + 3];
446 
447       p[ i * 4 + 0 ] = uc2;
448       p[ i * 4 + 1 ] = uc1;
449       p[ i * 4 + 2 ] = uc0;
450       p[ i * 4 + 3 ] = uc3;
451     }
452   }
453   else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
454   {
455     // Reverse and reorder to validate since in the
456     // kernel the read_imagef() call always returns RGBA
457     cl_uchar *p = (cl_uchar *)buffer;
458     for( size_t i = 0; i < width; i++ )
459     {
460       cl_uchar uc0 = p[i * 4 + 0];
461       cl_uchar uc1 = p[i * 4 + 1];
462       cl_uchar uc2 = p[i * 4 + 2];
463       cl_uchar uc3 = p[i * 4 + 3];
464 
465       p[ i * 4 + 0 ] = uc1;
466       p[ i * 4 + 1 ] = uc2;
467       p[ i * 4 + 2 ] = uc3;
468       p[ i * 4 + 3 ] = uc0;
469     }
470   }
471 
472   return buffer;
473 }
474 
CreateGLTexture2D(size_t width,size_t height,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d)475 void * CreateGLTexture2D( size_t width, size_t height,
476                         GLenum target, GLenum glFormat,
477                         GLenum internalFormat, GLenum glType,
478                         ExplicitType type, GLuint *outTextureID,
479                         int *outError, bool allocateMem, MTdata d )
480 {
481     *outError = 0;
482     GLenum err = 0;
483 
484     char * buffer;
485     unsigned int size = 0;
486 
487     if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
488     {
489       size = width * height;
490     }
491     else
492     {
493       size = width * height * 4;
494     }
495 
496     buffer = (char *)CreateRandomData(type, size, d);
497 
498     glGenTextures( 1, outTextureID );
499     glBindTexture( get_base_gl_target( target ), *outTextureID );
500     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
501     glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MIN_FILTER, GL_NEAREST );
502     glTexParameteri( get_base_gl_target( target ), GL_TEXTURE_MAG_FILTER, GL_NEAREST );
503     err = glGetError();
504     if( err != GL_NO_ERROR )
505     {
506         log_error( "ERROR: Failed to create GL texture object: %s!\n", gluErrorString( err ));
507         *outError = -1;
508         free( buffer );
509         return NULL;
510     }
511 
512     if( get_base_gl_target( target ) == GL_TEXTURE_CUBE_MAP )
513     {
514         char * temp = (char *)malloc(size * get_explicit_type_size( type ) * sizeof(cl_char));
515         if(allocateMem)
516             memcpy( temp, buffer, size * get_explicit_type_size( type ) );
517         else
518             memset( temp, 0, size * get_explicit_type_size( type ) );
519 
520         glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
521         glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
522         glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
523         glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
524         glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
525         glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, temp );
526         free(temp);
527     }
528     else
529     {
530 #ifdef DEBUG
531         log_info("- glTexImage2D : %s : %s : %d : %d : %s : %s\n",
532             GetGLTargetName(target),
533             GetGLFormatName(internalFormat),
534             width, height,
535             GetGLFormatName(glFormat),
536             GetGLTypeName(glType));
537 
538         DumpGLBuffer(glType, width, height, buffer);
539 #endif
540 
541         //the default alignment in OpenGL is 4 bytes and need to be changed for GL_DEPTH_COMPONENT16 which is aligned to 2 bytes
542         if (internalFormat == GL_DEPTH_COMPONENT16)
543           glPixelStorei(GL_UNPACK_ALIGNMENT, get_explicit_type_size( type ));
544 
545         glTexImage2D( get_base_gl_target(target), 0, internalFormat, (GLsizei)width, (GLsizei)height, 0, glFormat, glType, buffer );
546 
547         if (internalFormat == GL_DEPTH_COMPONENT16)
548           glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
549     }
550 
551     err = glGetError();
552     if( err != GL_NO_ERROR )
553     {
554         if (err != GL_OUT_OF_MEMORY) {
555             log_error( "ERROR: Unable to load data into glTexImage2D : %s : %s : %d : %d : %s : %s : Error %s\n",
556                 GetGLTargetName(target),
557                 GetGLFormatName(internalFormat),
558                 (int)(width), (int)(height),
559                 GetGLFormatName(glFormat),
560                 GetGLTypeName(glType),
561                 gluErrorString( err ));
562             *outError = -1;
563         } else {
564             log_info( "WARNING: Unable to load data into glTexImage2D : %s : %s : %d : %d : %s : %s : Error %s\n",
565                 GetGLTargetName(target),
566                 GetGLFormatName(internalFormat),
567                 (int)(width), (int)(height),
568                 GetGLFormatName(glFormat),
569                 GetGLTypeName(glType),
570                 gluErrorString( err ));
571             *outError = -2;
572         }
573         free( buffer );
574         return NULL;
575     }
576 
577 #ifdef DEBUG
578     char * test = (char *)malloc(width * height * 4 * get_explicit_type_size( type ));
579     memset(test, 0, width * height * 4 * get_explicit_type_size( type ));
580 
581     if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
582     {
583       glFormat = GL_RGBA;
584       glType = GL_FLOAT;
585     }
586 
587     log_info("- glGetTexImage : %s : %s : %s\n",
588         GetGLTargetName(target),
589         GetGLFormatName(glFormat),
590         GetGLTypeName(glType));
591 
592     glGetTexImage(target, 0, glFormat, glType, test);
593 
594     DumpGLBuffer(glType, width, height, test);
595 
596     free(test);
597 
598     err = glGetError();
599     if( err != GL_NO_ERROR )
600     {
601         log_error( "ERROR: Unable to read data from glGetTexImage : %s : %s : %s : Error %s\n",
602         GetGLTargetName(target),
603         GetGLFormatName(glFormat),
604         GetGLTypeName(glType),
605         gluErrorString( err ));
606         return NULL;
607     }
608 #endif
609 
610     if( !allocateMem )
611     {
612         free( buffer );
613         return NULL;
614     }
615 
616     if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
617     {
618         // Reverse and reorder to validate since in the
619         // kernel the read_imagef() call always returns RGBA
620         cl_uchar *p = (cl_uchar *)buffer;
621         for( size_t i = 0; i < width * height; i++ )
622         {
623             cl_uchar uc0 = p[i * 4 + 0];
624             cl_uchar uc1 = p[i * 4 + 1];
625             cl_uchar uc2 = p[i * 4 + 2];
626             cl_uchar uc3 = p[i * 4 + 3];
627 
628             p[ i * 4 + 0 ] = uc2;
629             p[ i * 4 + 1 ] = uc1;
630             p[ i * 4 + 2 ] = uc0;
631             p[ i * 4 + 3 ] = uc3;
632         }
633     }
634     else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
635     {
636       // Reverse and reorder to validate since in the
637       // kernel the read_imagef() call always returns RGBA
638       cl_uchar *p = (cl_uchar *)buffer;
639       for( size_t i = 0; i < width * height; i++ )
640       {
641         cl_uchar uc0 = p[i * 4 + 0];
642         cl_uchar uc1 = p[i * 4 + 1];
643         cl_uchar uc2 = p[i * 4 + 2];
644         cl_uchar uc3 = p[i * 4 + 3];
645 
646         p[ i * 4 + 0 ] = uc1;
647         p[ i * 4 + 1 ] = uc2;
648         p[ i * 4 + 2 ] = uc3;
649         p[ i * 4 + 3 ] = uc0;
650       }
651     }
652 
653     return buffer;
654 }
655 
CreateGLTexture3D(size_t width,size_t height,size_t depth,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,MTdata d,bool allocateMem)656 void * CreateGLTexture3D( size_t width, size_t height, size_t depth,
657                           GLenum target, GLenum glFormat,
658                           GLenum internalFormat, GLenum glType,
659                           ExplicitType type, GLuint *outTextureID,
660                           int *outError, MTdata d, bool allocateMem)
661 {
662     *outError = 0;
663 
664     char * buffer;
665     unsigned int size = 0;
666 
667     if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) )
668     {
669         size = width * height * depth;
670     }
671     else
672     {
673         size = width * height * depth * 4;
674     }
675 
676     buffer = (char *)create_random_data( type, d, size );
677 
678     if( type == kFloat && allocateMem )
679     {
680         // Re-fill the created buffer to just have [0-1] floats, since that's what it'd expect
681         cl_float *p = (cl_float *)buffer;
682         for( size_t i = 0; i < size; i++ )
683         {
684             p[ i ] = (float) genrand_real1( d );
685         }
686     }
687     else if( !allocateMem )
688         memset( buffer, 0, size * get_explicit_type_size( type ) );
689 
690     glGenTextures( 1, outTextureID );
691 
692     glBindTexture( target, *outTextureID );
693     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
694     glTexParameteri( target, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
695     glTexParameteri( target, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
696 
697     glGetError();
698     glTexImage3D( target, 0, internalFormat, (GLsizei)width, (GLsizei)height, (GLsizei)depth, 0, glFormat, glType, buffer );
699     GLenum err = glGetError();
700     if( err != GL_NO_ERROR )
701     {
702         if (err != GL_OUT_OF_MEMORY) {
703             log_error( "ERROR: Unable to load data into GL texture (%s) format %s type %s internal format %s\n", gluErrorString( err ), GetGLFormatName( glFormat ), get_explicit_type_name( type ), GetGLFormatName( internalFormat ) );
704             *outError = -1;
705         } else {
706             log_info( "WARNING: Unable to load data into GL texture (%s) format %s type %s internal format %s\n", gluErrorString( err ), GetGLFormatName( glFormat ), get_explicit_type_name( type ), GetGLFormatName( internalFormat ) );
707             *outError = -2;
708         }
709         delete [] buffer;
710         return NULL;
711     }
712 
713     if( !allocateMem )
714     {
715         delete [] buffer;
716         return NULL;
717     }
718 
719     if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
720     {
721         // Reverse and reorder to validate since in the
722         // kernel the read_imagef() call always returns RGBA
723         cl_uchar *p = (cl_uchar *)buffer;
724         for( size_t i = 0; i < width * height * depth; i++ )
725         {
726             cl_uchar uc0 = p[i * 4 + 0];
727             cl_uchar uc1 = p[i * 4 + 1];
728             cl_uchar uc2 = p[i * 4 + 2];
729             cl_uchar uc3 = p[i * 4 + 3];
730 
731             p[ i * 4 + 0 ] = uc2;
732             p[ i * 4 + 1 ] = uc1;
733             p[ i * 4 + 2 ] = uc0;
734             p[ i * 4 + 3 ] = uc3;
735         }
736     }
737     else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
738     {
739       // Reverse and reorder to validate since in the
740       // kernel the read_imagef() call always returns RGBA
741       cl_uchar *p = (cl_uchar *)buffer;
742       for( size_t i = 0; i < width * height * depth; i++ )
743       {
744         cl_uchar uc0 = p[i * 4 + 0];
745         cl_uchar uc1 = p[i * 4 + 1];
746         cl_uchar uc2 = p[i * 4 + 2];
747         cl_uchar uc3 = p[i * 4 + 3];
748 
749         p[ i * 4 + 0 ] = uc1;
750         p[ i * 4 + 1 ] = uc2;
751         p[ i * 4 + 2 ] = uc3;
752         p[ i * 4 + 3 ] = uc0;
753       }
754     }
755 
756     return buffer;
757 }
758 
ReadGLTexture(GLenum glTarget,GLuint glTexture,GLuint glBuf,GLint width,GLenum glFormat,GLenum glInternalFormat,GLenum glType,ExplicitType typeToReadAs,size_t outWidth,size_t outHeight)759 void * ReadGLTexture( GLenum glTarget, GLuint glTexture, GLuint glBuf, GLint width,
760                         GLenum glFormat, GLenum glInternalFormat,
761                         GLenum glType, ExplicitType typeToReadAs,
762                         size_t outWidth, size_t outHeight )
763 {
764     // Read results from the GL texture
765     glBindTexture(get_base_gl_target(glTarget), glTexture);
766 
767     GLint realWidth, realHeight, realDepth;
768     glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_WIDTH, &realWidth );
769     glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_HEIGHT, &realHeight );
770     glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_DEPTH, &realDepth );
771 
772     realDepth = (realDepth) ? realDepth : 1;
773 
774     GLint realInternalFormat;
775     glGetTexLevelParameteriv( glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &realInternalFormat );
776 
777 #ifdef DEBUG
778     log_info( "- Reading back from GL: %d x %d : %s : %s : %s : %s (stored as %s)\n",
779         realWidth, realHeight,
780         GetGLTargetName( glTarget),
781         GetGLFormatName( glInternalFormat ),
782         GetGLFormatName( glFormat ),
783         GetGLTypeName( glType ),
784         GetGLFormatName( realInternalFormat ));
785 #endif
786 
787     GLenum readBackFormat;
788     switch(glFormat)
789     {
790     case GL_RGBA_INTEGER_EXT:
791       readBackFormat = GL_RGBA_INTEGER_EXT;
792       break;
793     case GL_DEPTH_COMPONENT:
794       readBackFormat = GL_DEPTH_COMPONENT;
795       break;
796     case GL_DEPTH_STENCIL:
797       readBackFormat = GL_DEPTH_STENCIL;
798       break;
799     default:
800       readBackFormat = GL_RGBA;
801       break;
802     }
803 
804     GLenum readBackType;
805     switch (glType) {
806 #ifdef __APPLE__
807       case GL_UNSIGNED_INT_8_8_8_8:
808       case GL_UNSIGNED_INT_8_8_8_8_REV:
809         readBackType = GL_UNSIGNED_BYTE;
810         break;
811 #endif
812       case GL_HALF_FLOAT:
813       case GL_UNSIGNED_BYTE:
814       case GL_UNSIGNED_SHORT:
815       case GL_UNSIGNED_INT:
816       case GL_BYTE:
817       case GL_SHORT:
818       case GL_INT:
819       case GL_FLOAT:
820       default:
821         readBackType = glType;
822     }
823 
824     size_t outBytes;
825     if (get_base_gl_target(glTarget) != GL_TEXTURE_BUFFER) {
826         outBytes = realWidth * realHeight * realDepth * 4
827           * GetGLTypeSize(readBackType);
828     }
829     else {
830         outBytes = width * 4;
831 
832         outBytes *= ( GetGLTypeSize( GetGLTypeForExplicitType(typeToReadAs) ) );
833     }
834 
835     cl_char *outBuffer = (cl_char *)malloc( outBytes );
836     memset(outBuffer, 0, outBytes);
837 
838     if (get_base_gl_target(glTarget) != GL_TEXTURE_BUFFER) {
839         //the default alignment in OpenGL is 4 bytes and need to be changed for GL_DEPTH_COMPONENT16 which is aligned to 2 bytes
840         if (realInternalFormat == GL_DEPTH_COMPONENT16)
841           glPixelStorei(GL_PACK_ALIGNMENT, 2);
842 
843         glGetTexImage( glTarget, 0, readBackFormat, readBackType, outBuffer );
844 
845         if (realInternalFormat == GL_DEPTH_COMPONENT16)
846           glPixelStorei(GL_PACK_ALIGNMENT, 4);
847     }
848     else {
849         glBindBuffer(GL_ARRAY_BUFFER, glBuf);
850         glGetBufferSubData(GL_ARRAY_BUFFER, 0, outBytes, outBuffer);
851     }
852 
853 #ifdef DEBUG
854 
855     log_info( "- glGetTexImage: %s : %s : %s \n",
856         GetGLTargetName( glTarget),
857         GetGLFormatName(readBackFormat),
858         GetGLTypeName(readBackType));
859 
860     DumpGLBuffer(readBackType, realWidth, realHeight, (void*)outBuffer);
861 
862 #endif
863 
864     return (void *)outBuffer;
865 }
866 
CreateGLRenderbufferRaw(GLsizei width,GLsizei height,GLenum attachment,GLenum glFormat,GLenum internalFormat,GLenum glType,GLuint * outFramebuffer,GLuint * outRenderbuffer)867 int CreateGLRenderbufferRaw( GLsizei width, GLsizei height,
868                             GLenum attachment, GLenum glFormat,
869                             GLenum internalFormat, GLenum glType,
870                             GLuint *outFramebuffer,
871                             GLuint *outRenderbuffer )
872 {
873     GLenum err = 0;
874 
875     // Generate a renderbuffer and bind
876     glGenRenderbuffersEXT( 1, outRenderbuffer );
877     glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *outRenderbuffer );
878 
879     // Allocate storage to the renderbuffer
880     glGetError();
881     glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, internalFormat, (GLsizei)width,  (GLsizei)height );
882     err = glGetError();
883     if( err != GL_NO_ERROR )
884     {
885         log_error("Failed to allocate render buffer storage!\n");
886         return 1701;
887     }
888 
889     GLint realInternalFormat;
890     glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &realInternalFormat );
891     internalFormat = realInternalFormat;
892 
893 #ifdef DEBUG
894     GLint rsize, gsize, bsize, asize;
895     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT,&rsize);
896     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT,&gsize);
897     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT,&bsize);
898     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT,&asize);
899 
900     log_info("Renderbuffer internal format requested: %s actual: %s sizes: r=%d g=%d b=%d a=%d\n",
901              GetGLFormatName( internalFormat ), GetGLFormatName( realInternalFormat ),
902              rsize, gsize, bsize, asize );
903 #endif
904 
905     // Create and bind a framebuffer to render with
906     glGenFramebuffersEXT( 1, outFramebuffer );
907     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *outFramebuffer );
908     if( err != GL_NO_ERROR )
909     {
910         log_error( "ERROR: Unable to bind framebuffer : Error %s\n",
911                   gluErrorString( err ));
912 
913         return -1;
914     }
915 
916     // Attach to the framebuffer
917     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *outRenderbuffer );
918     err = glGetError();
919     GLint status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
920     if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
921     {
922         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s, status %x)\n", gluErrorString( err ), (int)status );
923         return -1;
924     }
925 
926     return 0;
927 }
928 
929 
reorder_verification_buffer(GLenum glFormat,GLenum glType,char * buffer,size_t num_pixels)930 void reorder_verification_buffer(GLenum glFormat, GLenum glType, char* buffer, size_t num_pixels)
931 {
932   if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA)
933   {
934     // Reverse and reorder to validate since in the
935     // kernel the read_imagef() call always returns RGBA
936     cl_uchar *p = (cl_uchar *)buffer;
937     for( size_t i = 0; i < num_pixels; i++ )
938     {
939       cl_uchar uc0 = p[i * 4 + 0];
940       cl_uchar uc1 = p[i * 4 + 1];
941       cl_uchar uc2 = p[i * 4 + 2];
942       cl_uchar uc3 = p[i * 4 + 3];
943 
944       p[ i * 4 + 0 ] = uc2;
945       p[ i * 4 + 1 ] = uc1;
946       p[ i * 4 + 2 ] = uc0;
947       p[ i * 4 + 3 ] = uc3;
948     }
949   }
950   else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA)
951   {
952     // Reverse and reorder to validate since in the
953     // kernel the read_imagef() call always returns RGBA
954     cl_uchar *p = (cl_uchar *)buffer;
955     for( size_t i = 0; i < num_pixels; i++ )
956     {
957       cl_uchar uc0 = p[i * 4 + 0];
958       cl_uchar uc1 = p[i * 4 + 1];
959       cl_uchar uc2 = p[i * 4 + 2];
960       cl_uchar uc3 = p[i * 4 + 3];
961 
962       p[ i * 4 + 0 ] = uc1;
963       p[ i * 4 + 1 ] = uc2;
964       p[ i * 4 + 2 ] = uc3;
965       p[ i * 4 + 3 ] = uc0;
966     }
967   }
968 }
969 
970 
971 #ifdef GL_VERSION_3_2
972 
973 #define check_gl_error() \
974 { \
975   GLenum errnom = GL_NO_ERROR;\
976   if ((errnom = glGetError()) != GL_NO_ERROR)\
977     log_error("GL Error: 0x%04X at %s:%d\n", errnom, __FILE__, __LINE__);\
978 }
979 
get_gl_vector_type(GLenum internalformat)980 const char *get_gl_vector_type( GLenum internalformat )
981 {
982   switch (internalformat) {
983   case GL_RGBA8:
984   case GL_RGBA16:
985   case GL_RGBA32F_ARB:
986   case GL_RGBA16F_ARB:
987   case GL_DEPTH_COMPONENT16:
988   case GL_DEPTH_COMPONENT32F:
989   case GL_DEPTH24_STENCIL8:
990   case GL_DEPTH32F_STENCIL8:
991     return "vec4";
992     break;
993   case GL_RGBA8I_EXT:
994   case GL_RGBA16I_EXT:
995   case GL_RGBA32I_EXT:
996     return "ivec4";
997     break;
998   case GL_RGBA8UI_EXT:
999   case GL_RGBA16UI_EXT:
1000   case GL_RGBA32UI_EXT:
1001     return "uvec4";
1002     break;
1003   default:
1004     log_error("Test error: unsupported data type\n");
1005     return "";
1006     break;
1007   }
1008 }
1009 
get_gl_data_type(GLenum internalformat)1010 const char *get_gl_data_type( GLenum internalformat )
1011 {
1012   switch (internalformat) {
1013   case GL_RGBA8:
1014   case GL_RGBA16:
1015   case GL_RGBA32F_ARB:
1016   case GL_RGBA16F_ARB:
1017   case GL_DEPTH_COMPONENT16:
1018   case GL_DEPTH_COMPONENT32F:
1019   case GL_DEPTH24_STENCIL8:
1020   case GL_DEPTH32F_STENCIL8:
1021     return "float";
1022     break;
1023   case GL_RGBA8I_EXT:
1024   case GL_RGBA16I_EXT:
1025   case GL_RGBA32I_EXT:
1026     return "int";
1027     break;
1028   case GL_RGBA8UI_EXT:
1029   case GL_RGBA16UI_EXT:
1030   case GL_RGBA32UI_EXT:
1031     return "uint";
1032     break;
1033   default:
1034     log_error("Test error: unsupported data type\n");
1035     return "";
1036     break;
1037   }
1038 }
1039 
1040 
CreateGLTexture2DMultisample(size_t width,size_t height,size_t samples,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d,bool fixedSampleLocations)1041 void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples,
1042                                     GLenum target, GLenum glFormat,
1043                                     GLenum internalFormat, GLenum glType,
1044                                     ExplicitType type, GLuint *outTextureID,
1045                                     int *outError, bool allocateMem, MTdata d , bool fixedSampleLocations)
1046 {
1047   // This function creates a multisample texture and renders into each sample
1048   // using a GLSL shader
1049 
1050   // Check if the renderer supports enough samples
1051   GLint max_samples = get_gl_max_samples(target, internalFormat);
1052   check_gl_error()
1053 
1054   if (max_samples < (GLint)samples)
1055     log_error("GL error: requested samples (%d) exceeds renderer max samples (%d)\n", samples, max_samples);
1056 
1057   // Setup the GLSL program
1058   const GLchar *vertex_source =
1059   "#version 140\n"
1060   "in vec4 att0;\n"
1061   "void main (void) {\n"
1062   " gl_Position = vec4(att0.xy,0.0,1.0);\n"
1063   "}\n";
1064 
1065   const GLchar *fragmentSource =
1066   "#version 140\n"
1067     "out %s out0;\n"
1068     "uniform %s colorVal;\n"
1069     "uniform float depthVal;\n"
1070   "void main (void) {\n"
1071     "    out0 = %s(colorVal);\n"
1072     " gl_FragDepth = depthVal;\n"
1073   "}\n";
1074 
1075   GLchar fragmentShader[256];
1076   sprintf(fragmentShader, fragmentSource, get_gl_vector_type(internalFormat), get_gl_data_type(internalFormat), get_gl_vector_type(internalFormat));
1077   const GLchar *fragment_source = &fragmentShader[0];
1078 
1079   glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
1080   glShaderSource(vertex_shader, 1, &vertex_source, NULL);
1081   glCompileShader(vertex_shader);
1082   check_gl_error()
1083 
1084   glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
1085   glShaderSource(fragment_shader, 1, &fragment_source, NULL);
1086   glCompileShader(fragment_shader);
1087   check_gl_error()
1088 
1089   GLuint prog = glCreateProgram();
1090   glAttachShader(prog, vertex_shader);
1091   glAttachShader(prog, fragment_shader);
1092   check_gl_error()
1093 
1094   glBindAttribLocation(prog, 0, "att0");
1095   glLinkProgram(prog);
1096   check_gl_error()
1097 
1098   // Setup the FBO and texture
1099   glFramebufferWrapper fbo;
1100   glGenFramebuffers(1, &fbo);
1101   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1102   check_gl_error()
1103 
1104   glViewport(0, 0, width, height);
1105   check_gl_error()
1106 
1107   GLuint tex = 0;
1108   glGenTextures(1, &tex);
1109   glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
1110   glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, fixedSampleLocations);
1111   check_gl_error()
1112 
1113   GLint attachment;
1114   switch (internalFormat) {
1115     case GL_DEPTH_COMPONENT16:
1116     case GL_DEPTH_COMPONENT32F:
1117     attachment = GL_DEPTH_ATTACHMENT;
1118     break;
1119     case GL_DEPTH24_STENCIL8:
1120     case GL_DEPTH32F_STENCIL8:
1121     attachment = GL_DEPTH_STENCIL_ATTACHMENT;
1122       break;
1123     default:
1124     attachment = GL_COLOR_ATTACHMENT0;
1125       break;
1126   }
1127 
1128   glFramebufferTexture(GL_FRAMEBUFFER, attachment, tex, 0);
1129   check_gl_error()
1130 
1131   GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1132   if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
1133     log_info("GL status: GL_FRAMEBUFFER_UNSUPPORTED format %s multisample is not supported\n", GetGLFormatName(internalFormat));
1134     *outTextureID = 0;
1135     *outError = GL_FRAMEBUFFER_UNSUPPORTED;
1136     return NULL;
1137   }
1138 
1139   if (status != GL_FRAMEBUFFER_COMPLETE) {
1140     log_error("GL error: framebuffer incomplete status 0x%04X\n",status);
1141     *outTextureID = 0;
1142     *outError = status;
1143     return NULL;
1144   }
1145 
1146   // Check if the framebuffer supports enough samples
1147   GLint fbo_samples = 0;
1148   glGetIntegerv(GL_SAMPLES, &fbo_samples);
1149   check_gl_error();
1150 
1151   if (fbo_samples < (GLint)samples)
1152     log_error("GL Error: requested samples (%d) exceeds FBO capability (%d)\n", samples, fbo_samples);
1153 
1154   glUseProgram(prog);
1155   check_gl_error()
1156 
1157   if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
1158     glDisable(GL_DEPTH_TEST);
1159     check_gl_error()
1160   }
1161   else {
1162     glEnable(GL_DEPTH_TEST);
1163     glDepthFunc(GL_ALWAYS);
1164     check_gl_error()
1165   }
1166 
1167   // Setup the VBO for rendering a quad
1168   GLfloat quad[] = {
1169     -1.0f, -1.0f,
1170     1.0f, -1.0f,
1171     1.0f,  1.0f,
1172     -1.0f,  1.0f
1173   };
1174 
1175   glBufferWrapper vbo;
1176   glGenBuffers(1, &vbo);
1177   glBindBuffer(GL_ARRAY_BUFFER, vbo);
1178   glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
1179   check_gl_error()
1180 
1181   glVertexArraysWrapper vao;
1182   glGenVertexArrays(1, &vao);
1183   glBindVertexArray(vao);
1184   glEnableVertexAttribArray(0);
1185   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
1186   check_gl_error()
1187 
1188   //clearing color and depth buffer
1189   glClearColor(0, 0, 0, 0);
1190   glClear(GL_COLOR_BUFFER_BIT);
1191   glClearDepth(1.0);
1192   glClear(GL_DEPTH_BUFFER_BIT);
1193 
1194   //calculating colors
1195   double color_delta = 1.0 / samples;
1196   double color = color_delta;
1197 
1198   glEnable(GL_SAMPLE_MASK);
1199   for (size_t i=0;i!=samples;++i) {
1200     glSampleMaski(0, 1<<i);
1201     GLint colorUniformLocation = glGetUniformLocation(prog, "colorVal");
1202     switch (internalFormat) {
1203     case GL_RGBA8I_EXT:
1204       glUniform1i(colorUniformLocation, color * 0x7f);
1205       break;
1206     case GL_RGBA16I_EXT:
1207       glUniform1i(colorUniformLocation, color * 0x7fff);
1208       break;
1209     case GL_RGBA32I_EXT:
1210       glUniform1i(colorUniformLocation, color * 0x7fffffff);
1211       break;
1212     case GL_RGBA8UI_EXT:
1213       glUniform1ui(colorUniformLocation, color * 0xff);
1214       break;
1215     case GL_RGBA16UI_EXT:
1216       glUniform1ui(colorUniformLocation, color * 0xffff);
1217       break;
1218     case GL_RGBA32UI_EXT:
1219       glUniform1ui(colorUniformLocation, color * 0xffffffff);
1220       break;
1221     default:
1222       glUniform1f(colorUniformLocation, color);
1223       break;
1224     }
1225 
1226     glUniform1f(glGetUniformLocation(prog, "depthVal"), color);
1227     color += color_delta;
1228 
1229     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1230     check_gl_error();
1231 
1232     glFlush();
1233   }
1234 
1235   glDisable(GL_SAMPLE_MASK);
1236   check_gl_error();
1237 
1238   *outTextureID = tex;
1239 
1240   // Create an output buffer containing the expected results.
1241   unsigned int size = 0;
1242   if ( glType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
1243   {
1244     size = width * height * 2;
1245   }
1246   else if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) || (attachment == GL_DEPTH_ATTACHMENT) || (attachment == GL_DEPTH_STENCIL_ATTACHMENT))
1247   {
1248     size = width * height;
1249   }
1250   else
1251   {
1252     size = width * height * 4;
1253   }
1254 
1255   char *data = (char *)malloc(get_explicit_type_size(type) * size * samples);
1256   char *p = data;
1257   size_t stride = get_explicit_type_size(type);
1258 
1259   for (size_t s=0;s!=samples;++s) {
1260     double val = color_delta + (color_delta * s);
1261     for (size_t i=0;i!=size;++i) {
1262       switch (type) {
1263       case kChar:
1264         *((char*)p) = val * 0x7f;
1265         break;
1266         case kUChar:
1267         *((unsigned char*)p) = val * 0xff;
1268           break;
1269         case kFloat:
1270           *((float*)p) = val;
1271           break;
1272       case kShort:
1273         *((short*)p) = val*0x7fff;
1274         break;
1275         case kUShort:
1276         *((unsigned short*)p) = val*0xffff;
1277           break;
1278       case kInt:
1279         *((int*)p) = val*0x7fffffff;
1280           break;
1281         case kUInt:
1282         *((unsigned int*)p) = val*0xffffffff;
1283           break;
1284         case kHalf:
1285           *((cl_ushort*)p) = convert_float_to_half(val);
1286           break;
1287         default:
1288           log_error("Test error: unexpected type enum 0x%x\n",type);
1289       }
1290 
1291       p += stride;
1292     }
1293   }
1294 
1295 
1296   if (allocateMem)
1297     reorder_verification_buffer(glFormat,glType,data,width*height*samples);
1298 
1299   return data;
1300 }
1301 
CreateGLTexture2DArrayMultisample(size_t width,size_t height,size_t total_layers,size_t samples,GLenum target,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outTextureID,int * outError,bool allocateMem,MTdata d,bool fixedSampleLocations)1302 void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
1303                               size_t total_layers, size_t samples,
1304                               GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
1305                               ExplicitType type, GLuint *outTextureID, int *outError,
1306                               bool allocateMem, MTdata d, bool fixedSampleLocations)
1307 {
1308   // This function creates a multisample texture and renders into each sample
1309   // using a GLSL shader
1310 
1311   // Check if the renderer supports enough samples
1312   GLint max_samples = get_gl_max_samples(target, internalFormat);
1313 
1314   if (max_samples < (GLint)samples)
1315     log_error("GL error: requested samples (%d) exceeds renderer max samples (%d)\n", samples, max_samples);
1316 
1317   // Setup the GLSL program
1318   const GLchar *vertex_source =
1319   "#version 140\n"
1320   "in vec4 att0;\n"
1321   "void main (void) {\n"
1322   " gl_Position = vec4(att0.xy,0.0,1.0);\n"
1323   "}\n";
1324 
1325   const GLchar *fragmentSource =
1326   "#version 140\n"
1327     "out %s out0;\n"
1328     "uniform %s colorVal;\n"
1329     "uniform float depthVal;\n"
1330   "void main (void) {\n"
1331     "    out0 = %s(colorVal);\n"
1332     " gl_FragDepth = depthVal;\n"
1333   "}\n";
1334 
1335   GLchar fragmentShader[256];
1336   sprintf(fragmentShader, fragmentSource, get_gl_vector_type(internalFormat), get_gl_data_type(internalFormat), get_gl_vector_type(internalFormat));
1337   const GLchar *fragment_source = &fragmentShader[0];
1338 
1339   glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
1340   glShaderSource(vertex_shader, 1, &vertex_source, NULL);
1341   glCompileShader(vertex_shader);
1342   check_gl_error()
1343 
1344   glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
1345   glShaderSource(fragment_shader, 1, &fragment_source, NULL);
1346   glCompileShader(fragment_shader);
1347   check_gl_error()
1348 
1349   glProgramWrapper prog = glCreateProgram();
1350   glAttachShader(prog, vertex_shader);
1351   glAttachShader(prog, fragment_shader);
1352   check_gl_error()
1353 
1354   glBindAttribLocation(prog, 0, "att0");
1355   glLinkProgram(prog);
1356   check_gl_error()
1357 
1358   // Setup the FBO and texture
1359   glFramebufferWrapper fbo;
1360   glGenFramebuffers(1, &fbo);
1361   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1362   check_gl_error()
1363 
1364   glViewport(0, 0, width, height);
1365   check_gl_error()
1366 
1367   GLuint tex = 0;
1368   glGenTextures(1, &tex);
1369   glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex);
1370   glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, internalFormat, width, height, total_layers, fixedSampleLocations);
1371   check_gl_error()
1372 
1373   GLint attachment;
1374   switch (internalFormat) {
1375     case GL_DEPTH_COMPONENT16:
1376     case GL_DEPTH_COMPONENT32F:
1377     attachment = GL_DEPTH_ATTACHMENT;
1378     break;
1379     case GL_DEPTH24_STENCIL8:
1380     case GL_DEPTH32F_STENCIL8:
1381     attachment = GL_DEPTH_STENCIL_ATTACHMENT;
1382       break;
1383     default:
1384     attachment = GL_COLOR_ATTACHMENT0;
1385     break;
1386   }
1387 
1388   //calculating colors
1389   double color_delta = 1.0 / (total_layers * samples);
1390   double color = color_delta;
1391 
1392   if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
1393     glDisable(GL_DEPTH_TEST);
1394   check_gl_error()
1395   }
1396   else {
1397     glEnable(GL_DEPTH_TEST);
1398     glDepthFunc(GL_ALWAYS);
1399     check_gl_error()
1400   }
1401 
1402   // Setup the VBO for rendering a quad
1403   GLfloat quad[] = {
1404     -1.0f, -1.0f,
1405     1.0f, -1.0f,
1406     1.0f,  1.0f,
1407     -1.0f,  1.0f
1408   };
1409 
1410   glBufferWrapper vbo;
1411   glGenBuffers(1, &vbo);
1412   glBindBuffer(GL_ARRAY_BUFFER, vbo);
1413   glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
1414   check_gl_error()
1415 
1416   glVertexArraysWrapper vao;
1417   glGenVertexArrays(1, &vao);
1418   glBindVertexArray(vao);
1419   glEnableVertexAttribArray(0);
1420   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
1421     check_gl_error()
1422 
1423   for (size_t l=0; l!=total_layers; ++l) {
1424     glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, tex, 0, l);
1425       check_gl_error()
1426 
1427     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1428     if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
1429       log_info("GL status: GL_FRAMEBUFFER_UNSUPPORTED format %s multisample array is not supported\n", GetGLFormatName(internalFormat));
1430       *outTextureID = 0;
1431       *outError = GL_FRAMEBUFFER_UNSUPPORTED;
1432       return NULL;
1433     }
1434 
1435     if (status != GL_FRAMEBUFFER_COMPLETE) {
1436       log_error("GL error: framebuffer incomplete status 0x%04X\n",status);
1437       *outTextureID = 0;
1438       *outError = status;
1439       return NULL;
1440     }
1441 
1442     // Check if the framebuffer supports enough samples
1443     GLint fbo_samples = 0;
1444     glGetIntegerv(GL_SAMPLES, &fbo_samples);
1445     check_gl_error();
1446 
1447     if (fbo_samples < (GLint)samples)
1448       log_error("GL Error: requested samples (%d) exceeds FBO capability (%d)\n", samples, fbo_samples);
1449 
1450     glUseProgram(prog);
1451     check_gl_error()
1452 
1453     //clearing color and depth buffer
1454     glClearColor(0, 0, 0, 0);
1455     glClear(GL_COLOR_BUFFER_BIT);
1456     glClearDepth(1.0);
1457     glClear(GL_DEPTH_BUFFER_BIT);
1458 
1459     glEnable(GL_SAMPLE_MASK);
1460     for (size_t s=0;s!=samples;++s) {
1461       double val = color_delta + color_delta * (l * samples + s);
1462 
1463       glSampleMaski(0, 1<<s);
1464       GLint colorUniformLocation = glGetUniformLocation(prog, "colorVal");
1465       switch (internalFormat) {
1466       case GL_RGBA8I_EXT:
1467         glUniform1i(colorUniformLocation, val * 0x7f);
1468         break;
1469       case GL_RGBA16I_EXT:
1470         glUniform1i(colorUniformLocation, val * 0x7fff);
1471         break;
1472       case GL_RGBA32I_EXT:
1473         glUniform1i(colorUniformLocation, val * 0x7fffffff);
1474         break;
1475       case GL_RGBA8UI_EXT:
1476         glUniform1ui(colorUniformLocation, val * 0xff);
1477         break;
1478       case GL_RGBA16UI_EXT:
1479         glUniform1ui(colorUniformLocation, val * 0xffff);
1480         break;
1481       case GL_RGBA32UI_EXT:
1482         glUniform1ui(colorUniformLocation, val * 0xffffffff);
1483         break;
1484       default:
1485         glUniform1f(colorUniformLocation, val);
1486         break;
1487       }
1488 
1489       glUniform1f(glGetUniformLocation(prog, "depthVal"), val);
1490 
1491       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1492       check_gl_error();
1493 
1494       glFlush();
1495     }
1496 
1497     glDisable(GL_SAMPLE_MASK);
1498     check_gl_error();
1499   }
1500 
1501   *outTextureID = tex;
1502 
1503   // Create an output buffer containing the expected results.
1504   unsigned int size = 0;
1505   if ( glType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
1506   {
1507     size = width * height * 2;
1508   }
1509   else if ( (glType == GL_UNSIGNED_INT_2_10_10_10_REV) || (glType == GL_UNSIGNED_INT_10_10_10_2) || (attachment == GL_DEPTH_ATTACHMENT) || (attachment == GL_DEPTH_STENCIL_ATTACHMENT))
1510   {
1511     size = width * height;
1512   }
1513   else
1514   {
1515     size = width * height * 4;
1516   }
1517 
1518   char *data = (char *)malloc(get_explicit_type_size(type) * size * total_layers * samples);
1519   char *p = data;
1520   size_t stride = get_explicit_type_size(type);
1521 
1522   for (size_t s=0;s!=samples;++s) {
1523     for (size_t l=0;l!=total_layers;++l) {
1524       double val = color_delta + color_delta * (l * samples + s);
1525     for (size_t i=0;i!=size;++i) {
1526       switch (type) {
1527         case kChar:
1528           *((char*)p) = val * 0x7f;
1529           break;
1530         case kUChar:
1531           *((unsigned char*)p) = val*0xff;
1532           break;
1533         case kFloat:
1534           *((float*)p) = val;
1535           break;
1536         case kShort:
1537           *((short*)p) = val * 0x7fff;
1538           break;
1539         case kUShort:
1540           *((unsigned short*)p) = val * 0xffff;
1541           break;
1542         case kInt:
1543           *((int*)p) = val * 0x7fffffff;
1544           break;
1545         case kUInt:
1546           *((unsigned int*)p) = val*0xffffffff;
1547           break;
1548         case kHalf:
1549           *((cl_ushort*)p) = convert_float_to_half(val);
1550           break;
1551         default:
1552           log_error("Test error: unexpected type enum 0x%x\n",type);
1553       }
1554 
1555       p += stride;
1556     }
1557   }
1558   }
1559 
1560   if (allocateMem)
1561     reorder_verification_buffer(glFormat,glType,data,width*height*samples*total_layers);
1562 
1563   return data;
1564 }
1565 
1566 #endif // GL_VERSION_3_2
1567 
CreateGLRenderbuffer(GLsizei width,GLsizei height,GLenum attachment,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outFramebuffer,GLuint * outRenderbuffer,int * outError,MTdata d,bool allocateMem)1568 void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
1569                              GLenum attachment, GLenum glFormat,
1570                              GLenum internalFormat, GLenum glType,
1571                              ExplicitType type,
1572                              GLuint *outFramebuffer,
1573                              GLuint *outRenderbuffer,
1574                              int *outError, MTdata d, bool allocateMem )
1575 {
1576     *outError = CreateGLRenderbufferRaw( width, height, attachment, glFormat, internalFormat,
1577                             glType, outFramebuffer, outRenderbuffer );
1578 
1579     if( *outError != 0 )
1580         return NULL;
1581 
1582     GLenum err = 0;
1583 
1584     // Generate a renderbuffer and bind
1585     glGenRenderbuffersEXT( 1, outRenderbuffer );
1586     glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *outRenderbuffer );
1587 
1588     // Allocate storage to the renderbuffer
1589     glGetError();
1590     glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, internalFormat, (GLsizei)width,  (GLsizei)height );
1591     err = glGetError();
1592     if( err != GL_NO_ERROR )
1593     {
1594         *outError = 1701;
1595         log_error("Failed to allocate render buffer storage!\n");
1596         return NULL;
1597     }
1598 
1599     GLint realInternalFormat;
1600     glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &realInternalFormat );
1601     internalFormat = realInternalFormat;
1602 
1603 #ifdef DEBUG
1604     GLint rsize, gsize, bsize, asize;
1605     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT,&rsize);
1606     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT,&gsize);
1607     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT,&bsize);
1608     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT,&asize);
1609 
1610     log_info("Renderbuffer internal format requested: %s actual: %s sizes: r=%d g=%d b=%d a=%d\n",
1611               GetGLFormatName( internalFormat ), GetGLFormatName( realInternalFormat ),
1612               rsize, gsize, bsize, asize );
1613 #endif
1614 
1615     // Create and bind a framebuffer to render with
1616     glGenFramebuffersEXT( 1, outFramebuffer );
1617     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *outFramebuffer );
1618     if( err != GL_NO_ERROR )
1619     {
1620         log_error( "ERROR: Unable to bind framebuffer : Error %s\n",
1621                   gluErrorString( err ));
1622 
1623         *outError = -1;
1624         return NULL;
1625     }
1626 
1627     // Attach to the framebuffer
1628     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *outRenderbuffer );
1629     err = glGetError();
1630     GLint status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
1631     if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
1632     {
1633         *outError = -1;
1634         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s, status %x)\n", gluErrorString( err ), (int)status );
1635         return NULL;
1636     }
1637 
1638     void* buffer = CreateRandomData(type, width * height * 4, d);
1639 
1640 #ifdef DEBUG
1641     log_info( "- Fillling renderbuffer: %d : %d : %s : %s \n",
1642              (int)width, (int)height,
1643              GetGLFormatName(glFormat),
1644              GetGLTypeName(glType));
1645 
1646     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1647 #endif
1648 
1649     // Fill a texture with our input data
1650     glTextureWrapper texture;
1651     glGenTextures( 1, &texture );
1652     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
1653     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1654     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1655     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1656     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1657     glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat, width, height, 0, glFormat, glType, buffer );
1658     glEnable( GL_TEXTURE_RECTANGLE_ARB );
1659 
1660     // Render fullscreen textured quad
1661     glDisable( GL_LIGHTING );
1662     glViewport(0, 0, width, height);
1663     glMatrixMode(GL_MODELVIEW);
1664     glLoadIdentity();
1665     glMatrixMode( GL_TEXTURE );
1666     glLoadIdentity();
1667     glMatrixMode(GL_PROJECTION);
1668     glLoadIdentity();
1669     glClear(GL_COLOR_BUFFER_BIT);
1670     gluOrtho2D( -1.0, 1.0, -1.0, 1.0 );
1671     glMatrixMode( GL_MODELVIEW );
1672     glBegin( GL_QUADS );
1673     {
1674         glColor3f(1.0f, 1.0f, 1.0f);
1675         glTexCoord2f( 0.0f, 0.0f );
1676         glVertex3f( -1.0f, -1.0f, 0.0f );
1677         glTexCoord2f( 0.0f, height );
1678         glVertex3f( -1.0f, 1.0f, 0.0f );
1679         glTexCoord2f( width, height );
1680         glVertex3f( 1.0f, 1.0f, 0.0f );
1681         glTexCoord2f( width, 0.0f );
1682         glVertex3f( 1.0f, -1.0f, 0.0f );
1683     }
1684     glEnd();
1685     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
1686     glDisable( GL_TEXTURE_RECTANGLE_ARB );
1687 
1688     glFlush();
1689 
1690     // Read back the data in the renderbuffer
1691     memset(buffer, 0, width * height * 4 * get_explicit_type_size( type ));
1692     glReadBuffer( attachment );
1693 
1694     glReadPixels( 0, 0, (GLsizei)width, (GLsizei)height, glFormat, glType, buffer );
1695 
1696     err = glGetError();
1697     if( err != GL_NO_ERROR )
1698     {
1699         log_error( "ERROR: Unable to read data via glReadPixels : %d : %d : %s : %s : Error %s\n",
1700                   (int)width, (int)height,
1701                   GetGLFormatName(glFormat),
1702                   GetGLTypeName(glType),
1703                   gluErrorString( err ));
1704         *outError = -1;
1705     }
1706 
1707 #ifdef DEBUG
1708     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1709              (int)width, (int)height,
1710              GetGLFormatName(glFormat),
1711              GetGLTypeName(glType));
1712 
1713     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1714 #endif
1715 
1716     if( !allocateMem )
1717     {
1718         free( buffer );
1719         return NULL;
1720     }
1721 
1722     if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
1723     {
1724         // Reverse and reorder to validate since in the
1725         // kernel the read_imagef() call always returns RGBA
1726         cl_uchar *p = (cl_uchar *)buffer;
1727         for( size_t i = 0; i < (size_t)width * height; i++ )
1728         {
1729             cl_uchar uc0 = p[i * 4 + 0];
1730             cl_uchar uc1 = p[i * 4 + 1];
1731             cl_uchar uc2 = p[i * 4 + 2];
1732             cl_uchar uc3 = p[i * 4 + 3];
1733 
1734             p[ i * 4 + 0 ] = uc2;
1735             p[ i * 4 + 1 ] = uc1;
1736             p[ i * 4 + 2 ] = uc0;
1737             p[ i * 4 + 3 ] = uc3;
1738         }
1739     }
1740     else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
1741     {
1742       // Reverse and reorder to validate since in the
1743       // kernel the read_imagef() call always returns RGBA
1744       cl_uchar *p = (cl_uchar *)buffer;
1745       for( size_t i = 0; i < width * height; i++ )
1746       {
1747         cl_uchar uc0 = p[i * 4 + 0];
1748         cl_uchar uc1 = p[i * 4 + 1];
1749         cl_uchar uc2 = p[i * 4 + 2];
1750         cl_uchar uc3 = p[i * 4 + 3];
1751 
1752         p[ i * 4 + 0 ] = uc1;
1753         p[ i * 4 + 1 ] = uc2;
1754         p[ i * 4 + 2 ] = uc3;
1755         p[ i * 4 + 3 ] = uc0;
1756       }
1757     }
1758 
1759     return buffer;
1760 }
1761 
ReadGLRenderbuffer(GLuint glFramebuffer,GLuint glRenderbuffer,GLenum attachment,GLenum glFormat,GLenum glInternalFormat,GLenum glType,ExplicitType typeToReadAs,size_t outWidth,size_t outHeight)1762 void * ReadGLRenderbuffer( GLuint glFramebuffer, GLuint glRenderbuffer,
1763                            GLenum attachment, GLenum glFormat,
1764                            GLenum glInternalFormat, GLenum glType,
1765                            ExplicitType typeToReadAs,
1766                            size_t outWidth, size_t outHeight )
1767 {
1768     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, glFramebuffer );
1769     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, glRenderbuffer );
1770 
1771     // Attach to the framebuffer
1772     GLint err = glGetError();
1773     if( glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ) != GL_FRAMEBUFFER_COMPLETE_EXT )
1774     {
1775         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s)\n", gluErrorString( err ) );
1776         return NULL;
1777     }
1778 
1779     // Read results from the GL renderbuffer
1780 #ifdef DEBUG
1781     log_info( "- Reading back from GL: %d x %d : %s : %s : %s\n",
1782              (int)outWidth, (int)outHeight,
1783              GetGLFormatName( glInternalFormat ),
1784              GetGLFormatName( glFormat ),
1785              GetGLTypeName( glType ));
1786 #endif
1787 
1788     GLenum readBackFormat = glFormat == GL_RGBA_INTEGER_EXT ? GL_RGBA_INTEGER_EXT : GL_RGBA;
1789     GLenum readBackType = glType;
1790 
1791     size_t outBytes = outWidth * outHeight * 4 * GetGLTypeSize(readBackType);
1792     void *outBuffer = malloc( outBytes );
1793     memset(outBuffer, 0, outBytes);
1794 
1795     glReadPixels( 0, 0, (GLsizei)outWidth, (GLsizei)outHeight, readBackFormat, readBackType, outBuffer );
1796 
1797 #ifdef DEBUG
1798     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1799              (int)outWidth, (int)outHeight,
1800              GetGLFormatName(readBackFormat),
1801              GetGLTypeName(readBackType));
1802 
1803     DumpGLBuffer(readBackType, outWidth, outHeight, outBuffer);
1804 #endif
1805 
1806     return (void *)outBuffer;
1807 }
1808 
1809 GLenum
GetGLFormat(GLenum internalFormat)1810 GetGLFormat(GLenum internalFormat)
1811 {
1812     GLenum glFormat;
1813     switch (internalFormat)
1814     {
1815         case GL_BGRA:
1816         case GL_RGBA8:
1817         case GL_RGBA16:
1818         case GL_RGBA32F_ARB:
1819             glFormat = GL_RGBA;
1820             break;
1821         case GL_RGBA8I_EXT:
1822         case GL_RGBA16I_EXT:
1823         case GL_RGBA32I_EXT:
1824         case GL_RGBA8UI_EXT:
1825         case GL_RGBA16UI_EXT:
1826         case GL_RGBA32UI_EXT:
1827             glFormat = GL_RGBA_INTEGER_EXT;
1828             break;
1829         default:
1830             glFormat = GL_RGBA;
1831             break;
1832     }
1833 
1834     return glFormat;
1835 }
1836 
GetGLTypeForExplicitType(ExplicitType type)1837 GLenum GetGLTypeForExplicitType(ExplicitType type)
1838 {
1839     switch( type )
1840     {
1841         case kFloat:
1842             return GL_FLOAT;
1843         case kInt:
1844             return GL_INT;
1845         case kUInt:
1846             return GL_UNSIGNED_INT;
1847         case kShort:
1848             return GL_SHORT;
1849         case kUShort:
1850             return GL_UNSIGNED_SHORT;
1851         case kChar:
1852             return GL_BYTE;
1853         case kUChar:
1854             return GL_UNSIGNED_BYTE;
1855         case kHalf:
1856 #if defined( __APPLE__ )
1857             return GL_HALF_FLOAT;
1858 #else
1859             return GL_HALF_FLOAT_ARB;
1860 #endif
1861         default:
1862             return GL_INT;
1863     };
1864 }
1865 
GetGLTypeSize(GLenum type)1866 size_t GetGLTypeSize(GLenum type)
1867 {
1868     switch( type )
1869     {
1870         case GL_FLOAT:
1871             return sizeof(GLfloat);
1872         case GL_INT:
1873             return sizeof(GLint);
1874         case GL_UNSIGNED_INT:
1875         case GL_UNSIGNED_INT_10_10_10_2:
1876         case GL_UNSIGNED_INT_2_10_10_10_REV:
1877         case GL_UNSIGNED_INT_24_8:
1878             return sizeof(GLuint);
1879         case GL_SHORT:
1880             return sizeof(GLshort);
1881         case GL_UNSIGNED_SHORT:
1882             return sizeof(GLushort);
1883         case GL_UNSIGNED_INT_8_8_8_8_REV:
1884         case GL_BYTE:
1885             return sizeof(GLbyte);
1886         case GL_UNSIGNED_BYTE:
1887             return sizeof(GLubyte);
1888 #if defined( __APPLE__ )
1889         case GL_HALF_FLOAT:
1890 #else
1891         case GL_HALF_FLOAT_ARB:
1892 #endif
1893             return sizeof(GLhalf);
1894         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1895             return 2 * sizeof(GLfloat);
1896         default:
1897             log_error("Unknown type 0x%x\n",type);
1898             return 0;
1899     };
1900 }
1901 
GetExplicitTypeForGLType(GLenum type)1902 ExplicitType GetExplicitTypeForGLType(GLenum type)
1903 {
1904     switch( type )
1905     {
1906         case GL_FLOAT:
1907             return kFloat;
1908         case GL_INT:
1909             return kInt;
1910         case GL_UNSIGNED_INT:
1911             return kUInt;
1912         case GL_SHORT:
1913             return kShort;
1914         case GL_UNSIGNED_SHORT:
1915             return kUShort;
1916         case GL_BYTE:
1917             return kChar;
1918         case GL_UNSIGNED_BYTE:
1919             return kUChar;
1920 #if defined( __APPLE__ )
1921         case GL_HALF_FLOAT:
1922 #else
1923         case GL_HALF_FLOAT_ARB:
1924 #endif
1925             return kHalf;
1926         default:
1927             return kFloat;
1928     };
1929 }
1930 
get_base_gl_target(GLenum target)1931 GLenum get_base_gl_target( GLenum target )
1932 {
1933     switch( target )
1934     {
1935         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1936         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1937         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1938         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1939         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1940         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1941             return GL_TEXTURE_CUBE_MAP;
1942         default:
1943             return target;
1944     }
1945 }
1946 
GetGLTypeName(GLenum type)1947 const char *GetGLTypeName( GLenum type )
1948 {
1949     switch( type )
1950     {
1951         case GL_BYTE:            return "GL_BYTE";
1952         case GL_UNSIGNED_BYTE:   return "GL_UNSIGNED_BYTE";
1953         case GL_INT:             return "GL_INT";
1954         case GL_UNSIGNED_INT:    return "GL_UNSIGNED_INT";
1955         case GL_SHORT:           return "GL_SHORT";
1956         case GL_UNSIGNED_SHORT:  return "GL_UNSIGNED_SHORT";
1957 #if defined( __APPLE__ )
1958         case GL_HALF_FLOAT:      return "GL_HALF_FLOAT";
1959 #else
1960         case GL_HALF_FLOAT_ARB:  return "GL_HALF_FLOAT_ARB";
1961 #endif
1962         case GL_FLOAT:           return "GL_FLOAT";
1963         case GL_UNSIGNED_INT_8_8_8_8:        return "GL_UNSIGNED_INT_8_8_8_8";
1964         case GL_UNSIGNED_INT_8_8_8_8_REV:    return "GL_UNSIGNED_INT_8_8_8_8_REV";
1965         case GL_UNSIGNED_INT_10_10_10_2:     return "GL_UNSIGNED_INT_10_10_10_2";
1966         case GL_UNSIGNED_INT_2_10_10_10_REV: return "GL_UNSIGNED_INT_2_10_10_10_REV";
1967 #ifdef GL_VERSION_3_2
1968         case GL_UNSIGNED_INT_24_8: return "GL_UNSIGNED_INT_24_8";
1969         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return "GL_FLOAT_32_UNSIGNED_INT_24_8_REV";
1970 #endif
1971         default:
1972         {
1973             static char foo[ 128 ];
1974             sprintf( foo, "0x%04x", (int)type);
1975             return foo;
1976         }
1977     }
1978 }
1979 
GetGLTargetName(GLenum tgt)1980 const char *GetGLTargetName( GLenum tgt )
1981 {
1982     if( tgt == GL_TEXTURE_BUFFER ) return "GL_TEXTURE_BUFFER";
1983     if( tgt == GL_TEXTURE_1D ) return "GL_TEXTURE_1D";
1984     if( tgt == GL_TEXTURE_2D ) return "GL_TEXTURE_2D";
1985     if( tgt == GL_TEXTURE_3D ) return "GL_TEXTURE_3D";
1986     if( tgt == GL_TEXTURE_RECTANGLE_EXT ) return "GL_TEXTURE_RECTANGLE_EXT";
1987     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_X ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
1988     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
1989     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
1990     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
1991     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
1992     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
1993     if( tgt == GL_TEXTURE_2D_MULTISAMPLE ) return "GL_TEXTURE_2D_MULTISAMPLE";
1994     if( tgt == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ) return "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
1995 
1996     static char foo[ 128 ];
1997     sprintf( foo, "0x%04x", (int)tgt);
1998     return foo;
1999 }
2000 
GetGLAttachmentName(GLenum att)2001 const char *GetGLAttachmentName( GLenum att )
2002 {
2003     if( att == GL_COLOR_ATTACHMENT0_EXT ) return "GL_COLOR_ATTACHMENT0_EXT";
2004     if( att == GL_COLOR_ATTACHMENT1_EXT ) return "GL_COLOR_ATTACHMENT1_EXT";
2005     if( att == GL_COLOR_ATTACHMENT2_EXT ) return "GL_COLOR_ATTACHMENT2_EXT";
2006     if( att == GL_COLOR_ATTACHMENT3_EXT ) return "GL_COLOR_ATTACHMENT3_EXT";
2007     if( att == GL_COLOR_ATTACHMENT4_EXT ) return "GL_COLOR_ATTACHMENT4_EXT";
2008     if( att == GL_COLOR_ATTACHMENT5_EXT ) return "GL_COLOR_ATTACHMENT5_EXT";
2009     if( att == GL_COLOR_ATTACHMENT6_EXT ) return "GL_COLOR_ATTACHMENT6_EXT";
2010     if( att == GL_COLOR_ATTACHMENT7_EXT ) return "GL_COLOR_ATTACHMENT7_EXT";
2011     if( att == GL_COLOR_ATTACHMENT8_EXT ) return "GL_COLOR_ATTACHMENT8_EXT";
2012     if( att == GL_DEPTH_ATTACHMENT_EXT ) return "GL_DEPTH_ATTACHMENT_EXT";
2013     return "";
2014 }
GetGLBaseFormatName(GLenum baseformat)2015 const char *GetGLBaseFormatName( GLenum baseformat )
2016 {
2017     switch( baseformat )
2018     {
2019         case GL_RGBA8:          return "GL_RGBA";
2020         case GL_RGBA16:         return "GL_RGBA";
2021         case GL_RGBA:           return "GL_RGBA";
2022         case GL_BGRA:           return "GL_BGRA";
2023         case GL_RGBA8I_EXT:     return "GL_RGBA_INTEGER_EXT";
2024         case GL_RGBA16I_EXT:    return "GL_RGBA_INTEGER_EXT";
2025         case GL_RGBA32I_EXT:    return "GL_RGBA_INTEGER_EXT";
2026         case GL_RGBA8UI_EXT:    return "GL_RGBA_INTEGER_EXT";
2027         case GL_RGBA16UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2028         case GL_RGBA32UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2029         case GL_RGBA32F_ARB:    return "GL_RGBA";
2030 
2031         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2032 
2033         case GL_ALPHA4: return "GL_ALPHA";
2034         case GL_ALPHA8: return "GL_ALPHA";
2035         case GL_ALPHA12: return "GL_ALPHA";
2036         case GL_ALPHA16: return "GL_ALPHA";
2037         case GL_LUMINANCE4: return "GL_LUMINANCE";
2038         case GL_LUMINANCE8: return "GL_LUMINANCE";
2039         case GL_LUMINANCE12: return "GL_LUMINANCE";
2040         case GL_LUMINANCE16: return "GL_LUMINANCE";
2041         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE_ALPHA";
2042         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE_ALPHA";
2043         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE_ALPHA";
2044         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE_ALPHA";
2045         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE_ALPHA";
2046         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE_ALPHA";
2047         case GL_INTENSITY: return "GL_INTENSITY";
2048         case GL_INTENSITY4: return "GL_INTENSITY";
2049         case GL_INTENSITY8: return "GL_INTENSITY";
2050         case GL_INTENSITY12: return "GL_INTENSITY";
2051         case GL_INTENSITY16: return "GL_INTENSITY";
2052         case GL_R3_G3_B2: return "GL_RGB";
2053         case GL_RGB4: return "GL_RGB";
2054         case GL_RGB5: return "GL_RGB";
2055         case GL_RGB8: return "GL_RGB";
2056         case GL_RGB10: return "GL_RGB";
2057         case GL_RGB12: return "GL_RGB";
2058         case GL_RGB16: return "GL_RGB";
2059         case GL_RGBA2: return "GL_RGBA";
2060         case GL_RGBA4: return "GL_RGBA";
2061         case GL_RGB5_A1: return "GL_RGBA";
2062         case GL_RGB10_A2: return "GL_RGBA";
2063         case GL_RGBA12: return "GL_RGBA";
2064 #ifdef GL_VERSION_3_2
2065         case GL_DEPTH_COMPONENT: return "GL_DEPTH_COMPONENT";
2066         case GL_DEPTH_COMPONENT16: return "GL_DEPTH_COMPONENT";
2067         case GL_DEPTH_COMPONENT24: return "GL_DEPTH_COMPONENT";
2068         case GL_DEPTH_COMPONENT32: return "GL_DEPTH_COMPONENT";
2069         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT";
2070         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2071         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH_STENCIL";
2072         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH_STENCIL";
2073 #endif
2074         default:
2075         {
2076             static char foo[ 128 ];
2077             sprintf( foo, "0x%04x", (int)baseformat );
2078             return foo;
2079         }
2080     }
2081 }
2082 
GetGLFormatName(GLenum format)2083 const char *GetGLFormatName( GLenum format )
2084 {
2085     switch( format )
2086     {
2087         case GL_RGBA8:          return "GL_RGBA8";
2088         case GL_RGBA16:         return "GL_RGBA16";
2089         case GL_RGBA:           return "GL_RGBA";
2090         case GL_BGRA:           return "GL_BGRA";
2091         case GL_RGBA8I_EXT:     return "GL_RGBA8I_EXT";
2092         case GL_RGBA16I_EXT:    return "GL_RGBA16I_EXT";
2093         case GL_RGBA32I_EXT:    return "GL_RGBA32I_EXT";
2094         case GL_RGBA8UI_EXT:    return "GL_RGBA8UI_EXT";
2095         case GL_RGBA16UI_EXT:   return "GL_RGBA16UI_EXT";
2096         case GL_RGBA32UI_EXT:   return "GL_RGBA32UI_EXT";
2097         case GL_RGBA16F:        return "GL_RGBA16F";
2098         case GL_RGBA32F:        return "GL_RGBA32F";
2099 
2100         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2101 
2102         case GL_ALPHA4: return "GL_ALPHA4";
2103         case GL_ALPHA8: return "GL_ALPHA8";
2104         case GL_ALPHA12: return "GL_ALPHA12";
2105         case GL_ALPHA16: return "GL_ALPHA16";
2106         case GL_LUMINANCE4: return "GL_LUMINANCE4";
2107         case GL_LUMINANCE8: return "GL_LUMINANCE8";
2108         case GL_LUMINANCE12: return "GL_LUMINANCE12";
2109         case GL_LUMINANCE16: return "GL_LUMINANCE16";
2110         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE4_ALPHA4";
2111         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE6_ALPHA2";
2112         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE8_ALPHA8";
2113         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE12_ALPHA4";
2114         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE12_ALPHA12";
2115         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE16_ALPHA16";
2116         case GL_INTENSITY: return "GL_INTENSITY";
2117         case GL_INTENSITY4: return "GL_INTENSITY4";
2118         case GL_INTENSITY8: return "GL_INTENSITY8";
2119         case GL_INTENSITY12: return "GL_INTENSITY12";
2120         case GL_INTENSITY16: return "GL_INTENSITY16";
2121         case GL_R3_G3_B2: return "GL_R3_G3_B2";
2122         case GL_RGB4: return "GL_RGB4";
2123         case GL_RGB5: return "GL_RGB5";
2124         case GL_RGB8: return "GL_RGB8";
2125         case GL_RGB10: return "GL_RGB10";
2126         case GL_RGB12: return "GL_RGB12";
2127         case GL_RGB16: return "GL_RGB16";
2128         case GL_RGBA2: return "GL_RGBA2";
2129         case GL_RGBA4: return "GL_RGBA4";
2130         case GL_RGB5_A1: return "GL_RGB5_A1";
2131         case GL_RGB10_A2: return "GL_RGB10_A2";
2132         case GL_RGBA12: return "GL_RGBA12";
2133 
2134         case GL_INT:            return "GL_INT";
2135         case GL_UNSIGNED_INT:   return "GL_UNSIGNED_INT";
2136         case GL_SHORT:          return "GL_SHORT";
2137         case GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT";
2138         case GL_BYTE:           return "GL_BYTE";
2139         case GL_UNSIGNED_BYTE:  return "GL_UNSIGNED_BYTE";
2140         case GL_FLOAT:          return "GL_FLOAT";
2141 #if defined( __APPLE__ )
2142         case GL_HALF_FLOAT:     return "GL_HALF_FLOAT";
2143 #else
2144         case GL_HALF_FLOAT_ARB: return "GL_HALF_FLOAT_ARB";
2145 #endif
2146 #ifdef GL_VERSION_3_2
2147         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2148         case GL_DEPTH_COMPONENT:    return "GL_DEPTH_COMPONENT";
2149         case GL_DEPTH_COMPONENT16:  return "GL_DEPTH_COMPONENT16";
2150         case GL_DEPTH_COMPONENT24:  return "GL_DEPTH_COMPONENT24";
2151         case GL_DEPTH_COMPONENT32:  return "GL_DEPTH_COMPONENT32";
2152         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT32F";
2153         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH24_STENCIL8";
2154         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH32F_STENCIL8";
2155 #endif
2156         default:
2157         {
2158             static char foo[ 128 ];
2159             sprintf( foo, "0x%04x", (int)format);
2160             return foo;
2161         }
2162     }
2163 }
2164 
CreateRandomData(ExplicitType type,size_t count,MTdata d)2165 void* CreateRandomData( ExplicitType type, size_t count, MTdata d )
2166 {
2167     switch(type)
2168     {
2169         case (kChar):
2170         {
2171             cl_char *p = (cl_char *)malloc(count * sizeof(cl_char));
2172             if(!p) return 0;
2173 
2174             for( size_t i = 0; i < count; i++ )
2175             {
2176                 p[ i ] = (cl_char)genrand_int32(d);
2177             }
2178             return (void*)p;
2179         }
2180         case (kUChar):
2181         case (kUnsignedChar):
2182         {
2183             cl_uchar *p = (cl_uchar *)malloc(count * sizeof(cl_uchar));
2184             if(!p) return 0;
2185 
2186             for( size_t i = 0; i < count; i++ )
2187             {
2188                 p[ i ] =  (cl_uchar)genrand_int32(d);
2189             }
2190 
2191             return (void*)p;
2192         }
2193         case (kShort):
2194         {
2195             cl_short *p = (cl_short *)malloc(count * sizeof(cl_short));
2196             if(!p) return 0;
2197 
2198             for( size_t i = 0; i < count; i++ )
2199             {
2200                 p[ i ] = (cl_short)genrand_int32(d);
2201             }
2202 
2203             return (void*)p;
2204         }
2205         case (kUShort):
2206         case (kUnsignedShort):
2207         {
2208             cl_ushort *p = (cl_ushort *)malloc(count * sizeof(cl_ushort));
2209             if(!p) return 0;
2210 
2211             for( size_t i = 0; i < count; i++ )
2212             {
2213                 p[ i ] = (cl_ushort)genrand_int32(d);
2214             }
2215 
2216             return (void*)p;
2217         }
2218         case (kInt):
2219         {
2220             cl_int *p = (cl_int *)malloc(count * sizeof(cl_int));
2221             if(!p) return 0;
2222 
2223             for( size_t i = 0; i < count; i++ )
2224             {
2225                 p[ i ] = (cl_int)genrand_int32(d);
2226             }
2227 
2228             return (void*)p;
2229         }
2230         case (kUInt):
2231         case (kUnsignedInt):
2232         {
2233             cl_uint *p = (cl_uint *)malloc(count * sizeof(cl_uint));
2234             if(!p) return 0;
2235 
2236             for( size_t i = 0; i < count; i++ )
2237             {
2238                 p[ i ] =  (cl_uint)genrand_int32(d);
2239             }
2240 
2241             return (void*)p;
2242         }
2243 
2244         case (kFloat):
2245         {
2246             cl_float *p = (cl_float *)malloc(count * sizeof(cl_float));
2247             if(!p) return 0;
2248 
2249             for( size_t i = 0; i < count; i++ )
2250             {
2251                 p[ i ] = get_random_float( 0.f, 1.f, d );
2252             }
2253 
2254             return (void*)p;
2255         }
2256         case (kHalf):
2257         {
2258             cl_half *p = (cl_half *)malloc(count * sizeof(cl_half));
2259             if(!p) return 0;
2260 
2261             for( size_t i = 0; i < count; i++ )
2262             {
2263                 p[ i ] = convert_float_to_half( get_random_float( 0.f, 1.f, d ) );
2264             }
2265 
2266             return (void*)p;
2267         }
2268         default:
2269         {
2270             log_error("Invalid explicit type specified for create random data!\n");
2271             return 0;
2272         }
2273     }
2274     return 0;
2275 }
2276 
DumpGLBuffer(GLenum type,size_t width,size_t height,void * buffer)2277 void DumpGLBuffer(GLenum type, size_t width, size_t height, void* buffer)
2278 {
2279     size_t i;
2280     size_t count = width * height;
2281     if(type == GL_BYTE)
2282     {
2283         cl_char* p = (cl_char*)buffer;
2284         for(i = 0; i < count; i++)
2285             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2286                 p[i* 4 + 0],
2287                 p[i* 4 + 1],
2288                 p[i* 4 + 2],
2289                 p[i* 4 + 3]);
2290     }
2291     else if(type == GL_UNSIGNED_BYTE)
2292     {
2293         cl_uchar* p = (cl_uchar*)buffer;
2294         for(i = 0; i < count; i++)
2295             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2296                 p[i* 4 + 0],
2297                 p[i* 4 + 1],
2298                 p[i* 4 + 2],
2299                 p[i* 4 + 3]);
2300     }
2301     else if(type == GL_INT)
2302     {
2303         cl_int* p = (cl_int*)buffer;
2304         for(i = 0; i < count; i++)
2305             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2306                 p[i* 4 + 0],
2307                 p[i* 4 + 1],
2308                 p[i* 4 + 2],
2309                 p[i* 4 + 3]);
2310     }
2311     else if(type == GL_UNSIGNED_INT)
2312     {
2313         cl_uint* p = (cl_uint*)buffer;
2314         for(i = 0; i < count; i++)
2315             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2316                 p[i* 4 + 0],
2317                 p[i* 4 + 1],
2318                 p[i* 4 + 2],
2319                 p[i* 4 + 3]);
2320     }
2321     else if(type == GL_SHORT)
2322     {
2323         cl_short* p = (cl_short*)buffer;
2324         for(i = 0; i < count; i++)
2325             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2326                 p[i* 4 + 0],
2327                 p[i* 4 + 1],
2328                 p[i* 4 + 2],
2329                 p[i* 4 + 3]);
2330     }
2331     else if(type == GL_UNSIGNED_SHORT)
2332     {
2333         cl_ushort* p = (cl_ushort*)buffer;
2334         for(i = 0; i <  count; i++)
2335             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2336                 p[i* 4 + 0],
2337                 p[i* 4 + 1],
2338                 p[i* 4 + 2],
2339                 p[i* 4 + 3]);
2340     }
2341     else if(type == GL_FLOAT)
2342     {
2343         cl_float* p = (cl_float*)buffer;
2344         for(i = 0; i < count; i++)
2345             log_info("[%4d] %#f %#f %#f %#f\n", (unsigned int)(i),
2346                p[i* 4 + 0],
2347                p[i* 4 + 1],
2348                p[i* 4 + 2],
2349                p[i* 4 + 3]);
2350     }
2351 }
2352 
2353 #if defined(_WIN32)
2354 #include <string.h>
2355 
gluCheckExtension(const GLubyte * extName,const GLubyte * extString)2356 GLboolean gluCheckExtension(const GLubyte *extName, const GLubyte *extString)
2357 {
2358   const size_t len = strlen((const char*)extName);
2359   const char* str = (const char*)extString;
2360 
2361   while (str != NULL) {
2362     str = strstr(str, (const char*)extName);
2363     if (str == NULL) {
2364       break;
2365     }
2366     if ((str > (const char*)extString || str[-1] == ' ')
2367         && (str[len] == ' ' || str[len] == '\0')) {
2368       return GL_TRUE;
2369     }
2370     str = strchr(str + len, ' ');
2371   }
2372 
2373   return GL_FALSE;
2374 }
2375 
2376 #endif
2377 
2378 // Function pointers for the GL/CL calls
2379 clCreateFromGLBuffer_fn clCreateFromGLBuffer_ptr;
2380 clCreateFromGLTexture_fn clCreateFromGLTexture_ptr;
2381 clCreateFromGLTexture2D_fn clCreateFromGLTexture2D_ptr;
2382 clCreateFromGLTexture3D_fn clCreateFromGLTexture3D_ptr;
2383 clCreateFromGLRenderbuffer_fn clCreateFromGLRenderbuffer_ptr;
2384 clGetGLObjectInfo_fn clGetGLObjectInfo_ptr;
2385 clGetGLTextureInfo_fn clGetGLTextureInfo_ptr;
2386 clEnqueueAcquireGLObjects_fn clEnqueueAcquireGLObjects_ptr;
2387 clEnqueueReleaseGLObjects_fn clEnqueueReleaseGLObjects_ptr;
2388 
init_clgl_ext()2389 int init_clgl_ext() {
2390 
2391     // As OpenCL for the platforms.  Warn if more than one platform found,
2392     // since this might not be the platform we want.  By default, we simply
2393     // use the first returned platform.
2394 
2395     cl_uint nplatforms;
2396     cl_platform_id platform;
2397     clGetPlatformIDs(0, NULL, &nplatforms);
2398     clGetPlatformIDs(1, &platform, NULL);
2399 
2400     if (nplatforms > 1) {
2401         log_info("clGetPlatformIDs returned multiple values.  This is not "
2402             "an error, but might result in obtaining incorrect function "
2403             "pointers if you do not want the first returned platform.\n");
2404 
2405         // Show them the platform name, in case it is a problem.
2406 
2407         size_t size;
2408         char *name;
2409 
2410         clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
2411         name = (char*)malloc(size);
2412         clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
2413 
2414         log_info("Using platform with name: %s \n", name);
2415         free(name);
2416     }
2417 
2418     // Create the function pointer table
2419     clCreateFromGLBuffer_ptr = (clCreateFromGLBuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLBuffer");
2420     if (clCreateFromGLBuffer_ptr == NULL) {
2421         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLBuffer) returned NULL.\n");
2422         return -1;
2423     }
2424     clCreateFromGLTexture2D_ptr = (clCreateFromGLTexture2D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture2D");
2425     if (clCreateFromGLTexture2D_ptr == NULL) {
2426         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture2D) returned NULL.\n");
2427         return -1;
2428     }
2429     clCreateFromGLTexture3D_ptr = (clCreateFromGLTexture3D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture3D");
2430     if (clCreateFromGLTexture3D_ptr == NULL) {
2431         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture3D\") returned NULL.\n");
2432         return -1;
2433     }
2434     clCreateFromGLTexture_ptr = (clCreateFromGLTexture_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture");
2435     if (clCreateFromGLTexture_ptr == NULL) {
2436          log_error("clGetExtensionFunctionAddressForPlatform(platform,\"clCreateFromGLTexture\") returned NULL.\n");
2437          return -1;
2438     }
2439     clCreateFromGLRenderbuffer_ptr = (clCreateFromGLRenderbuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLRenderbuffer");
2440     if (clCreateFromGLRenderbuffer_ptr == NULL) {
2441         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLRenderbuffer) returned NULL.\n");
2442         return -1;
2443     }
2444     clGetGLObjectInfo_ptr = (clGetGLObjectInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLObjectInfo");
2445     if (clGetGLObjectInfo_ptr == NULL) {
2446         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLObjectInfo) returned NULL.\n");
2447         return -1;
2448     }
2449     clGetGLTextureInfo_ptr = (clGetGLTextureInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLTextureInfo");
2450     if (clGetGLTextureInfo_ptr == NULL) {
2451         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLTextureInfo) returned NULL.\n");
2452         return -1;
2453     }
2454     clEnqueueAcquireGLObjects_ptr = (clEnqueueAcquireGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueAcquireGLObjects");
2455     if (clEnqueueAcquireGLObjects_ptr == NULL) {
2456         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueAcquireGLObjects) returned NULL.\n");
2457         return -1;
2458     }
2459     clEnqueueReleaseGLObjects_ptr = (clEnqueueReleaseGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueReleaseGLObjects");
2460     if (clEnqueueReleaseGLObjects_ptr == NULL) {
2461         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueReleaseGLObjects) returned NULL.\n");
2462         return -1;
2463     }
2464 
2465     return 0;
2466 }
2467 
get_gl_max_samples(GLenum target,GLenum internalformat)2468 GLint get_gl_max_samples( GLenum target, GLenum internalformat )
2469 {
2470     GLint max_samples = 0;
2471 #ifdef GL_VERSION_4_2
2472     glGetInternalformativ(target, internalformat, GL_SAMPLES, 1, &max_samples);
2473 #else
2474     switch (internalformat)
2475     {
2476         case GL_RGBA8I:
2477         case GL_RGBA16I:
2478         case GL_RGBA32I:
2479         case GL_RGBA8UI:
2480         case GL_RGBA16UI:
2481         case GL_RGBA32UI:
2482             glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &max_samples);
2483             break;
2484         case GL_DEPTH_COMPONENT16:
2485         case GL_DEPTH_COMPONENT32F:
2486         case GL_DEPTH24_STENCIL8:
2487         case GL_DEPTH32F_STENCIL8:
2488             glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &max_samples);
2489             break;
2490         default:
2491             glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_samples);
2492             break;
2493     }
2494 #endif
2495     return max_samples;
2496 }
2497