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