• 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 
1385   if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
1386     glDisable(GL_DEPTH_TEST);
1387   check_gl_error()
1388   }
1389   else {
1390     glEnable(GL_DEPTH_TEST);
1391     glDepthFunc(GL_ALWAYS);
1392     check_gl_error()
1393   }
1394 
1395   // Setup the VBO for rendering a quad
1396   GLfloat quad[] = {
1397     -1.0f, -1.0f,
1398     1.0f, -1.0f,
1399     1.0f,  1.0f,
1400     -1.0f,  1.0f
1401   };
1402 
1403   glBufferWrapper vbo;
1404   glGenBuffers(1, &vbo);
1405   glBindBuffer(GL_ARRAY_BUFFER, vbo);
1406   glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
1407   check_gl_error()
1408 
1409   glVertexArraysWrapper vao;
1410   glGenVertexArrays(1, &vao);
1411   glBindVertexArray(vao);
1412   glEnableVertexAttribArray(0);
1413   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
1414     check_gl_error()
1415 
1416   for (size_t l=0; l!=total_layers; ++l) {
1417     glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, tex, 0, l);
1418       check_gl_error()
1419 
1420     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1421     if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
1422       log_info("GL status: GL_FRAMEBUFFER_UNSUPPORTED format %s multisample array is not supported\n", GetGLFormatName(internalFormat));
1423       *outTextureID = 0;
1424       *outError = GL_FRAMEBUFFER_UNSUPPORTED;
1425       return NULL;
1426     }
1427 
1428     if (status != GL_FRAMEBUFFER_COMPLETE) {
1429       log_error("GL error: framebuffer incomplete status 0x%04X\n",status);
1430       *outTextureID = 0;
1431       *outError = status;
1432       return NULL;
1433     }
1434 
1435     // Check if the framebuffer supports enough samples
1436     GLint fbo_samples = 0;
1437     glGetIntegerv(GL_SAMPLES, &fbo_samples);
1438     check_gl_error();
1439 
1440     if (fbo_samples < (GLint)samples)
1441       log_error("GL Error: requested samples (%d) exceeds FBO capability (%d)\n", samples, fbo_samples);
1442 
1443     glUseProgram(prog);
1444     check_gl_error()
1445 
1446     //clearing color and depth buffer
1447     glClearColor(0, 0, 0, 0);
1448     glClear(GL_COLOR_BUFFER_BIT);
1449     glClearDepth(1.0);
1450     glClear(GL_DEPTH_BUFFER_BIT);
1451 
1452     glEnable(GL_SAMPLE_MASK);
1453     for (size_t s=0;s!=samples;++s) {
1454       double val = color_delta + color_delta * (l * samples + s);
1455 
1456       glSampleMaski(0, 1<<s);
1457       GLint colorUniformLocation = glGetUniformLocation(prog, "colorVal");
1458       switch (internalFormat) {
1459       case GL_RGBA8I_EXT:
1460         glUniform1i(colorUniformLocation, val * 0x7f);
1461         break;
1462       case GL_RGBA16I_EXT:
1463         glUniform1i(colorUniformLocation, val * 0x7fff);
1464         break;
1465       case GL_RGBA32I_EXT:
1466         glUniform1i(colorUniformLocation, val * 0x7fffffff);
1467         break;
1468       case GL_RGBA8UI_EXT:
1469         glUniform1ui(colorUniformLocation, val * 0xff);
1470         break;
1471       case GL_RGBA16UI_EXT:
1472         glUniform1ui(colorUniformLocation, val * 0xffff);
1473         break;
1474       case GL_RGBA32UI_EXT:
1475         glUniform1ui(colorUniformLocation, val * 0xffffffff);
1476         break;
1477       default:
1478         glUniform1f(colorUniformLocation, val);
1479         break;
1480       }
1481 
1482       glUniform1f(glGetUniformLocation(prog, "depthVal"), val);
1483 
1484       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1485       check_gl_error();
1486 
1487       glFlush();
1488     }
1489 
1490     glDisable(GL_SAMPLE_MASK);
1491     check_gl_error();
1492   }
1493 
1494   *outTextureID = tex;
1495 
1496   // Create an output buffer containing the expected results.
1497   unsigned int size = 0;
1498   if ( glType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
1499   {
1500     size = width * height * 2;
1501   }
1502   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))
1503   {
1504     size = width * height;
1505   }
1506   else
1507   {
1508     size = width * height * 4;
1509   }
1510 
1511   char *data = (char *)malloc(get_explicit_type_size(type) * size * total_layers * samples);
1512   char *p = data;
1513   size_t stride = get_explicit_type_size(type);
1514 
1515   for (size_t s=0;s!=samples;++s) {
1516     for (size_t l=0;l!=total_layers;++l) {
1517       double val = color_delta + color_delta * (l * samples + s);
1518     for (size_t i=0;i!=size;++i) {
1519       switch (type) {
1520         case kChar:
1521           *((char*)p) = val * 0x7f;
1522           break;
1523         case kUChar:
1524           *((unsigned char*)p) = val*0xff;
1525           break;
1526         case kFloat:
1527           *((float*)p) = val;
1528           break;
1529         case kShort:
1530           *((short*)p) = val * 0x7fff;
1531           break;
1532         case kUShort:
1533           *((unsigned short*)p) = val * 0xffff;
1534           break;
1535         case kInt:
1536           *((int*)p) = val * 0x7fffffff;
1537           break;
1538         case kUInt:
1539           *((unsigned int*)p) = val*0xffffffff;
1540           break;
1541         case kHalf: *((cl_half *)p) = convert_float_to_half(val); break;
1542         default:
1543           log_error("Test error: unexpected type enum 0x%x\n",type);
1544       }
1545 
1546       p += stride;
1547     }
1548   }
1549   }
1550 
1551   if (allocateMem)
1552     reorder_verification_buffer(glFormat,glType,data,width*height*samples*total_layers);
1553 
1554   return data;
1555 }
1556 
1557 #endif // GL_VERSION_3_2
1558 
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)1559 void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
1560                              GLenum attachment, GLenum glFormat,
1561                              GLenum internalFormat, GLenum glType,
1562                              ExplicitType type,
1563                              GLuint *outFramebuffer,
1564                              GLuint *outRenderbuffer,
1565                              int *outError, MTdata d, bool allocateMem )
1566 {
1567     *outError = CreateGLRenderbufferRaw( width, height, attachment, glFormat, internalFormat,
1568                             glType, outFramebuffer, outRenderbuffer );
1569 
1570     if( *outError != 0 )
1571         return NULL;
1572 
1573     GLenum err = 0;
1574 
1575     // Generate a renderbuffer and bind
1576     glGenRenderbuffersEXT( 1, outRenderbuffer );
1577     glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *outRenderbuffer );
1578 
1579     // Allocate storage to the renderbuffer
1580     glGetError();
1581     glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, internalFormat, (GLsizei)width,  (GLsizei)height );
1582     err = glGetError();
1583     if( err != GL_NO_ERROR )
1584     {
1585         *outError = 1701;
1586         log_error("Failed to allocate render buffer storage!\n");
1587         return NULL;
1588     }
1589 
1590     GLint realInternalFormat;
1591     glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &realInternalFormat );
1592     internalFormat = realInternalFormat;
1593 
1594 #ifdef DEBUG
1595     GLint rsize, gsize, bsize, asize;
1596     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT,&rsize);
1597     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT,&gsize);
1598     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT,&bsize);
1599     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT,&asize);
1600 
1601     log_info("Renderbuffer internal format requested: %s actual: %s sizes: r=%d g=%d b=%d a=%d\n",
1602               GetGLFormatName( internalFormat ), GetGLFormatName( realInternalFormat ),
1603               rsize, gsize, bsize, asize );
1604 #endif
1605 
1606     // Create and bind a framebuffer to render with
1607     glGenFramebuffersEXT( 1, outFramebuffer );
1608     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *outFramebuffer );
1609     if( err != GL_NO_ERROR )
1610     {
1611         log_error( "ERROR: Unable to bind framebuffer : Error %s\n",
1612                   gluErrorString( err ));
1613 
1614         *outError = -1;
1615         return NULL;
1616     }
1617 
1618     // Attach to the framebuffer
1619     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *outRenderbuffer );
1620     err = glGetError();
1621     GLint status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
1622     if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
1623     {
1624         *outError = -1;
1625         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s, status %x)\n", gluErrorString( err ), (int)status );
1626         return NULL;
1627     }
1628 
1629     void* buffer = CreateRandomData(type, width * height * 4, d);
1630 
1631 #ifdef DEBUG
1632     log_info( "- Fillling renderbuffer: %d : %d : %s : %s \n",
1633              (int)width, (int)height,
1634              GetGLFormatName(glFormat),
1635              GetGLTypeName(glType));
1636 
1637     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1638 #endif
1639 
1640     // Fill a texture with our input data
1641     glTextureWrapper texture;
1642     glGenTextures( 1, &texture );
1643     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
1644     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1645     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1646     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1647     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1648     glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat, width, height, 0, glFormat, glType, buffer );
1649     glEnable( GL_TEXTURE_RECTANGLE_ARB );
1650 
1651     // Render fullscreen textured quad
1652     glDisable( GL_LIGHTING );
1653     glViewport(0, 0, width, height);
1654     glMatrixMode(GL_MODELVIEW);
1655     glLoadIdentity();
1656     glMatrixMode( GL_TEXTURE );
1657     glLoadIdentity();
1658     glMatrixMode(GL_PROJECTION);
1659     glLoadIdentity();
1660     glClear(GL_COLOR_BUFFER_BIT);
1661     gluOrtho2D( -1.0, 1.0, -1.0, 1.0 );
1662     glMatrixMode( GL_MODELVIEW );
1663     glBegin( GL_QUADS );
1664     {
1665         glColor3f(1.0f, 1.0f, 1.0f);
1666         glTexCoord2f( 0.0f, 0.0f );
1667         glVertex3f( -1.0f, -1.0f, 0.0f );
1668         glTexCoord2f( 0.0f, height );
1669         glVertex3f( -1.0f, 1.0f, 0.0f );
1670         glTexCoord2f( width, height );
1671         glVertex3f( 1.0f, 1.0f, 0.0f );
1672         glTexCoord2f( width, 0.0f );
1673         glVertex3f( 1.0f, -1.0f, 0.0f );
1674     }
1675     glEnd();
1676     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
1677     glDisable( GL_TEXTURE_RECTANGLE_ARB );
1678 
1679     glFlush();
1680 
1681     // Read back the data in the renderbuffer
1682     memset(buffer, 0, width * height * 4 * get_explicit_type_size( type ));
1683     glReadBuffer( attachment );
1684 
1685     glReadPixels( 0, 0, (GLsizei)width, (GLsizei)height, glFormat, glType, buffer );
1686 
1687     err = glGetError();
1688     if( err != GL_NO_ERROR )
1689     {
1690         log_error( "ERROR: Unable to read data via glReadPixels : %d : %d : %s : %s : Error %s\n",
1691                   (int)width, (int)height,
1692                   GetGLFormatName(glFormat),
1693                   GetGLTypeName(glType),
1694                   gluErrorString( err ));
1695         *outError = -1;
1696     }
1697 
1698 #ifdef DEBUG
1699     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1700              (int)width, (int)height,
1701              GetGLFormatName(glFormat),
1702              GetGLTypeName(glType));
1703 
1704     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1705 #endif
1706 
1707     if( !allocateMem )
1708     {
1709         free( buffer );
1710         return NULL;
1711     }
1712 
1713     if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
1714     {
1715         // Reverse and reorder to validate since in the
1716         // kernel the read_imagef() call always returns RGBA
1717         cl_uchar *p = (cl_uchar *)buffer;
1718         for( size_t i = 0; i < (size_t)width * height; i++ )
1719         {
1720             cl_uchar uc0 = p[i * 4 + 0];
1721             cl_uchar uc1 = p[i * 4 + 1];
1722             cl_uchar uc2 = p[i * 4 + 2];
1723             cl_uchar uc3 = p[i * 4 + 3];
1724 
1725             p[ i * 4 + 0 ] = uc2;
1726             p[ i * 4 + 1 ] = uc1;
1727             p[ i * 4 + 2 ] = uc0;
1728             p[ i * 4 + 3 ] = uc3;
1729         }
1730     }
1731     else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
1732     {
1733       // Reverse and reorder to validate since in the
1734       // kernel the read_imagef() call always returns RGBA
1735       cl_uchar *p = (cl_uchar *)buffer;
1736       for( size_t i = 0; i < width * height; i++ )
1737       {
1738         cl_uchar uc0 = p[i * 4 + 0];
1739         cl_uchar uc1 = p[i * 4 + 1];
1740         cl_uchar uc2 = p[i * 4 + 2];
1741         cl_uchar uc3 = p[i * 4 + 3];
1742 
1743         p[ i * 4 + 0 ] = uc1;
1744         p[ i * 4 + 1 ] = uc2;
1745         p[ i * 4 + 2 ] = uc3;
1746         p[ i * 4 + 3 ] = uc0;
1747       }
1748     }
1749 
1750     return buffer;
1751 }
1752 
ReadGLRenderbuffer(GLuint glFramebuffer,GLuint glRenderbuffer,GLenum attachment,GLenum glFormat,GLenum glInternalFormat,GLenum glType,ExplicitType typeToReadAs,size_t outWidth,size_t outHeight)1753 void * ReadGLRenderbuffer( GLuint glFramebuffer, GLuint glRenderbuffer,
1754                            GLenum attachment, GLenum glFormat,
1755                            GLenum glInternalFormat, GLenum glType,
1756                            ExplicitType typeToReadAs,
1757                            size_t outWidth, size_t outHeight )
1758 {
1759     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, glFramebuffer );
1760     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, glRenderbuffer );
1761 
1762     // Attach to the framebuffer
1763     GLint err = glGetError();
1764     if( glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ) != GL_FRAMEBUFFER_COMPLETE_EXT )
1765     {
1766         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s)\n", gluErrorString( err ) );
1767         return NULL;
1768     }
1769 
1770     // Read results from the GL renderbuffer
1771 #ifdef DEBUG
1772     log_info( "- Reading back from GL: %d x %d : %s : %s : %s\n",
1773              (int)outWidth, (int)outHeight,
1774              GetGLFormatName( glInternalFormat ),
1775              GetGLFormatName( glFormat ),
1776              GetGLTypeName( glType ));
1777 #endif
1778 
1779     GLenum readBackFormat = glFormat == GL_RGBA_INTEGER_EXT ? GL_RGBA_INTEGER_EXT : GL_RGBA;
1780     GLenum readBackType = glType;
1781 
1782     size_t outBytes = outWidth * outHeight * 4 * GetGLTypeSize(readBackType);
1783     void *outBuffer = malloc( outBytes );
1784     memset(outBuffer, 0, outBytes);
1785 
1786     glReadPixels( 0, 0, (GLsizei)outWidth, (GLsizei)outHeight, readBackFormat, readBackType, outBuffer );
1787 
1788 #ifdef DEBUG
1789     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1790              (int)outWidth, (int)outHeight,
1791              GetGLFormatName(readBackFormat),
1792              GetGLTypeName(readBackType));
1793 
1794     DumpGLBuffer(readBackType, outWidth, outHeight, outBuffer);
1795 #endif
1796 
1797     return (void *)outBuffer;
1798 }
1799 
1800 GLenum
GetGLFormat(GLenum internalFormat)1801 GetGLFormat(GLenum internalFormat)
1802 {
1803     GLenum glFormat;
1804     switch (internalFormat)
1805     {
1806         case GL_BGRA:
1807         case GL_RGBA8:
1808         case GL_RGBA16:
1809         case GL_RGBA32F_ARB:
1810             glFormat = GL_RGBA;
1811             break;
1812         case GL_RGBA8I_EXT:
1813         case GL_RGBA16I_EXT:
1814         case GL_RGBA32I_EXT:
1815         case GL_RGBA8UI_EXT:
1816         case GL_RGBA16UI_EXT:
1817         case GL_RGBA32UI_EXT:
1818             glFormat = GL_RGBA_INTEGER_EXT;
1819             break;
1820         default:
1821             glFormat = GL_RGBA;
1822             break;
1823     }
1824 
1825     return glFormat;
1826 }
1827 
GetGLTypeForExplicitType(ExplicitType type)1828 GLenum GetGLTypeForExplicitType(ExplicitType type)
1829 {
1830     switch( type )
1831     {
1832         case kFloat:
1833             return GL_FLOAT;
1834         case kInt:
1835             return GL_INT;
1836         case kUInt:
1837             return GL_UNSIGNED_INT;
1838         case kShort:
1839             return GL_SHORT;
1840         case kUShort:
1841             return GL_UNSIGNED_SHORT;
1842         case kChar:
1843             return GL_BYTE;
1844         case kUChar:
1845             return GL_UNSIGNED_BYTE;
1846         case kHalf:
1847 #if defined( __APPLE__ )
1848             return GL_HALF_FLOAT;
1849 #else
1850             return GL_HALF_FLOAT_ARB;
1851 #endif
1852         default:
1853             return GL_INT;
1854     };
1855 }
1856 
GetGLTypeSize(GLenum type)1857 size_t GetGLTypeSize(GLenum type)
1858 {
1859     switch( type )
1860     {
1861         case GL_FLOAT:
1862             return sizeof(GLfloat);
1863         case GL_INT:
1864             return sizeof(GLint);
1865         case GL_UNSIGNED_INT:
1866         case GL_UNSIGNED_INT_10_10_10_2:
1867         case GL_UNSIGNED_INT_2_10_10_10_REV:
1868         case GL_UNSIGNED_INT_24_8:
1869             return sizeof(GLuint);
1870         case GL_SHORT:
1871             return sizeof(GLshort);
1872         case GL_UNSIGNED_SHORT:
1873             return sizeof(GLushort);
1874         case GL_UNSIGNED_INT_8_8_8_8_REV:
1875         case GL_BYTE:
1876             return sizeof(GLbyte);
1877         case GL_UNSIGNED_BYTE:
1878             return sizeof(GLubyte);
1879 #if defined( __APPLE__ )
1880         case GL_HALF_FLOAT:
1881 #else
1882         case GL_HALF_FLOAT_ARB:
1883 #endif
1884             return sizeof(GLhalf);
1885         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1886             return 2 * sizeof(GLfloat);
1887         default:
1888             log_error("Unknown type 0x%x\n",type);
1889             return 0;
1890     };
1891 }
1892 
GetExplicitTypeForGLType(GLenum type)1893 ExplicitType GetExplicitTypeForGLType(GLenum type)
1894 {
1895     switch( type )
1896     {
1897         case GL_FLOAT:
1898             return kFloat;
1899         case GL_INT:
1900             return kInt;
1901         case GL_UNSIGNED_INT:
1902             return kUInt;
1903         case GL_SHORT:
1904             return kShort;
1905         case GL_UNSIGNED_SHORT:
1906             return kUShort;
1907         case GL_BYTE:
1908             return kChar;
1909         case GL_UNSIGNED_BYTE:
1910             return kUChar;
1911 #if defined( __APPLE__ )
1912         case GL_HALF_FLOAT:
1913 #else
1914         case GL_HALF_FLOAT_ARB:
1915 #endif
1916             return kHalf;
1917         default:
1918             return kFloat;
1919     };
1920 }
1921 
get_base_gl_target(GLenum target)1922 GLenum get_base_gl_target( GLenum target )
1923 {
1924     switch( target )
1925     {
1926         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1927         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1928         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1929         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1930         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1931         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1932             return GL_TEXTURE_CUBE_MAP;
1933         default:
1934             return target;
1935     }
1936 }
1937 
GetGLTypeName(GLenum type)1938 const char *GetGLTypeName( GLenum type )
1939 {
1940     switch( type )
1941     {
1942         case GL_BYTE:            return "GL_BYTE";
1943         case GL_UNSIGNED_BYTE:   return "GL_UNSIGNED_BYTE";
1944         case GL_INT:             return "GL_INT";
1945         case GL_UNSIGNED_INT:    return "GL_UNSIGNED_INT";
1946         case GL_SHORT:           return "GL_SHORT";
1947         case GL_UNSIGNED_SHORT:  return "GL_UNSIGNED_SHORT";
1948 #if defined( __APPLE__ )
1949         case GL_HALF_FLOAT:      return "GL_HALF_FLOAT";
1950 #else
1951         case GL_HALF_FLOAT_ARB:  return "GL_HALF_FLOAT_ARB";
1952 #endif
1953         case GL_FLOAT:           return "GL_FLOAT";
1954         case GL_UNSIGNED_INT_8_8_8_8:        return "GL_UNSIGNED_INT_8_8_8_8";
1955         case GL_UNSIGNED_INT_8_8_8_8_REV:    return "GL_UNSIGNED_INT_8_8_8_8_REV";
1956         case GL_UNSIGNED_INT_10_10_10_2:     return "GL_UNSIGNED_INT_10_10_10_2";
1957         case GL_UNSIGNED_INT_2_10_10_10_REV: return "GL_UNSIGNED_INT_2_10_10_10_REV";
1958 #ifdef GL_VERSION_3_2
1959         case GL_UNSIGNED_INT_24_8: return "GL_UNSIGNED_INT_24_8";
1960         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return "GL_FLOAT_32_UNSIGNED_INT_24_8_REV";
1961 #endif
1962         default:
1963         {
1964             static char foo[ 128 ];
1965             sprintf( foo, "0x%04x", (int)type);
1966             return foo;
1967         }
1968     }
1969 }
1970 
GetGLTargetName(GLenum tgt)1971 const char *GetGLTargetName( GLenum tgt )
1972 {
1973     if( tgt == GL_TEXTURE_BUFFER ) return "GL_TEXTURE_BUFFER";
1974     if( tgt == GL_TEXTURE_1D ) return "GL_TEXTURE_1D";
1975     if( tgt == GL_TEXTURE_2D ) return "GL_TEXTURE_2D";
1976     if( tgt == GL_TEXTURE_3D ) return "GL_TEXTURE_3D";
1977     if( tgt == GL_TEXTURE_RECTANGLE_EXT ) return "GL_TEXTURE_RECTANGLE_EXT";
1978     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_X ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
1979     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
1980     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
1981     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
1982     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
1983     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
1984     if( tgt == GL_TEXTURE_2D_MULTISAMPLE ) return "GL_TEXTURE_2D_MULTISAMPLE";
1985     if( tgt == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ) return "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
1986 
1987     static char foo[ 128 ];
1988     sprintf( foo, "0x%04x", (int)tgt);
1989     return foo;
1990 }
1991 
GetGLAttachmentName(GLenum att)1992 const char *GetGLAttachmentName( GLenum att )
1993 {
1994     if( att == GL_COLOR_ATTACHMENT0_EXT ) return "GL_COLOR_ATTACHMENT0_EXT";
1995     if( att == GL_COLOR_ATTACHMENT1_EXT ) return "GL_COLOR_ATTACHMENT1_EXT";
1996     if( att == GL_COLOR_ATTACHMENT2_EXT ) return "GL_COLOR_ATTACHMENT2_EXT";
1997     if( att == GL_COLOR_ATTACHMENT3_EXT ) return "GL_COLOR_ATTACHMENT3_EXT";
1998     if( att == GL_COLOR_ATTACHMENT4_EXT ) return "GL_COLOR_ATTACHMENT4_EXT";
1999     if( att == GL_COLOR_ATTACHMENT5_EXT ) return "GL_COLOR_ATTACHMENT5_EXT";
2000     if( att == GL_COLOR_ATTACHMENT6_EXT ) return "GL_COLOR_ATTACHMENT6_EXT";
2001     if( att == GL_COLOR_ATTACHMENT7_EXT ) return "GL_COLOR_ATTACHMENT7_EXT";
2002     if( att == GL_COLOR_ATTACHMENT8_EXT ) return "GL_COLOR_ATTACHMENT8_EXT";
2003     if( att == GL_DEPTH_ATTACHMENT_EXT ) return "GL_DEPTH_ATTACHMENT_EXT";
2004     return "";
2005 }
GetGLBaseFormatName(GLenum baseformat)2006 const char *GetGLBaseFormatName( GLenum baseformat )
2007 {
2008     switch( baseformat )
2009     {
2010         case GL_RGBA8:          return "GL_RGBA";
2011         case GL_RGBA16:         return "GL_RGBA";
2012         case GL_RGBA:           return "GL_RGBA";
2013         case GL_BGRA:           return "GL_BGRA";
2014         case GL_RGBA8I_EXT:     return "GL_RGBA_INTEGER_EXT";
2015         case GL_RGBA16I_EXT:    return "GL_RGBA_INTEGER_EXT";
2016         case GL_RGBA32I_EXT:    return "GL_RGBA_INTEGER_EXT";
2017         case GL_RGBA8UI_EXT:    return "GL_RGBA_INTEGER_EXT";
2018         case GL_RGBA16UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2019         case GL_RGBA32UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2020         case GL_RGBA32F_ARB:    return "GL_RGBA";
2021 
2022         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2023 
2024         case GL_ALPHA4: return "GL_ALPHA";
2025         case GL_ALPHA8: return "GL_ALPHA";
2026         case GL_ALPHA12: return "GL_ALPHA";
2027         case GL_ALPHA16: return "GL_ALPHA";
2028         case GL_LUMINANCE4: return "GL_LUMINANCE";
2029         case GL_LUMINANCE8: return "GL_LUMINANCE";
2030         case GL_LUMINANCE12: return "GL_LUMINANCE";
2031         case GL_LUMINANCE16: return "GL_LUMINANCE";
2032         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE_ALPHA";
2033         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE_ALPHA";
2034         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE_ALPHA";
2035         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE_ALPHA";
2036         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE_ALPHA";
2037         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE_ALPHA";
2038         case GL_INTENSITY: return "GL_INTENSITY";
2039         case GL_INTENSITY4: return "GL_INTENSITY";
2040         case GL_INTENSITY8: return "GL_INTENSITY";
2041         case GL_INTENSITY12: return "GL_INTENSITY";
2042         case GL_INTENSITY16: return "GL_INTENSITY";
2043         case GL_R3_G3_B2: return "GL_RGB";
2044         case GL_RGB4: return "GL_RGB";
2045         case GL_RGB5: return "GL_RGB";
2046         case GL_RGB8: return "GL_RGB";
2047         case GL_RGB10: return "GL_RGB";
2048         case GL_RGB12: return "GL_RGB";
2049         case GL_RGB16: return "GL_RGB";
2050         case GL_RGBA2: return "GL_RGBA";
2051         case GL_RGBA4: return "GL_RGBA";
2052         case GL_RGB5_A1: return "GL_RGBA";
2053         case GL_RGB10_A2: return "GL_RGBA";
2054         case GL_RGBA12: return "GL_RGBA";
2055 #ifdef GL_VERSION_3_2
2056         case GL_DEPTH_COMPONENT: return "GL_DEPTH_COMPONENT";
2057         case GL_DEPTH_COMPONENT16: return "GL_DEPTH_COMPONENT";
2058         case GL_DEPTH_COMPONENT24: return "GL_DEPTH_COMPONENT";
2059         case GL_DEPTH_COMPONENT32: return "GL_DEPTH_COMPONENT";
2060         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT";
2061         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2062         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH_STENCIL";
2063         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH_STENCIL";
2064 #endif
2065         default:
2066         {
2067             static char foo[ 128 ];
2068             sprintf( foo, "0x%04x", (int)baseformat );
2069             return foo;
2070         }
2071     }
2072 }
2073 
GetGLFormatName(GLenum format)2074 const char *GetGLFormatName( GLenum format )
2075 {
2076     switch( format )
2077     {
2078         case GL_RGBA8:          return "GL_RGBA8";
2079         case GL_RGBA16:         return "GL_RGBA16";
2080         case GL_RGBA:           return "GL_RGBA";
2081         case GL_BGRA:           return "GL_BGRA";
2082         case GL_RGBA8I_EXT:     return "GL_RGBA8I_EXT";
2083         case GL_RGBA16I_EXT:    return "GL_RGBA16I_EXT";
2084         case GL_RGBA32I_EXT:    return "GL_RGBA32I_EXT";
2085         case GL_RGBA8UI_EXT:    return "GL_RGBA8UI_EXT";
2086         case GL_RGBA16UI_EXT:   return "GL_RGBA16UI_EXT";
2087         case GL_RGBA32UI_EXT:   return "GL_RGBA32UI_EXT";
2088         case GL_RGBA16F:        return "GL_RGBA16F";
2089         case GL_RGBA32F:        return "GL_RGBA32F";
2090 
2091         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2092 
2093         case GL_ALPHA4: return "GL_ALPHA4";
2094         case GL_ALPHA8: return "GL_ALPHA8";
2095         case GL_ALPHA12: return "GL_ALPHA12";
2096         case GL_ALPHA16: return "GL_ALPHA16";
2097         case GL_LUMINANCE4: return "GL_LUMINANCE4";
2098         case GL_LUMINANCE8: return "GL_LUMINANCE8";
2099         case GL_LUMINANCE12: return "GL_LUMINANCE12";
2100         case GL_LUMINANCE16: return "GL_LUMINANCE16";
2101         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE4_ALPHA4";
2102         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE6_ALPHA2";
2103         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE8_ALPHA8";
2104         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE12_ALPHA4";
2105         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE12_ALPHA12";
2106         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE16_ALPHA16";
2107         case GL_INTENSITY: return "GL_INTENSITY";
2108         case GL_INTENSITY4: return "GL_INTENSITY4";
2109         case GL_INTENSITY8: return "GL_INTENSITY8";
2110         case GL_INTENSITY12: return "GL_INTENSITY12";
2111         case GL_INTENSITY16: return "GL_INTENSITY16";
2112         case GL_R3_G3_B2: return "GL_R3_G3_B2";
2113         case GL_RGB4: return "GL_RGB4";
2114         case GL_RGB5: return "GL_RGB5";
2115         case GL_RGB8: return "GL_RGB8";
2116         case GL_RGB10: return "GL_RGB10";
2117         case GL_RGB12: return "GL_RGB12";
2118         case GL_RGB16: return "GL_RGB16";
2119         case GL_RGBA2: return "GL_RGBA2";
2120         case GL_RGBA4: return "GL_RGBA4";
2121         case GL_RGB5_A1: return "GL_RGB5_A1";
2122         case GL_RGB10_A2: return "GL_RGB10_A2";
2123         case GL_RGBA12: return "GL_RGBA12";
2124 
2125         case GL_INT:            return "GL_INT";
2126         case GL_UNSIGNED_INT:   return "GL_UNSIGNED_INT";
2127         case GL_SHORT:          return "GL_SHORT";
2128         case GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT";
2129         case GL_BYTE:           return "GL_BYTE";
2130         case GL_UNSIGNED_BYTE:  return "GL_UNSIGNED_BYTE";
2131         case GL_FLOAT:          return "GL_FLOAT";
2132 #if defined( __APPLE__ )
2133         case GL_HALF_FLOAT:     return "GL_HALF_FLOAT";
2134 #else
2135         case GL_HALF_FLOAT_ARB: return "GL_HALF_FLOAT_ARB";
2136 #endif
2137 #ifdef GL_VERSION_3_2
2138         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2139         case GL_DEPTH_COMPONENT:    return "GL_DEPTH_COMPONENT";
2140         case GL_DEPTH_COMPONENT16:  return "GL_DEPTH_COMPONENT16";
2141         case GL_DEPTH_COMPONENT24:  return "GL_DEPTH_COMPONENT24";
2142         case GL_DEPTH_COMPONENT32:  return "GL_DEPTH_COMPONENT32";
2143         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT32F";
2144         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH24_STENCIL8";
2145         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH32F_STENCIL8";
2146 #endif
2147         default:
2148         {
2149             static char foo[ 128 ];
2150             sprintf( foo, "0x%04x", (int)format);
2151             return foo;
2152         }
2153     }
2154 }
2155 
CreateRandomData(ExplicitType type,size_t count,MTdata d)2156 void* CreateRandomData( ExplicitType type, size_t count, MTdata d )
2157 {
2158     switch(type)
2159     {
2160         case (kChar):
2161         {
2162             cl_char *p = (cl_char *)malloc(count * sizeof(cl_char));
2163             if(!p) return 0;
2164 
2165             for( size_t i = 0; i < count; i++ )
2166             {
2167                 p[ i ] = (cl_char)genrand_int32(d);
2168             }
2169             return (void*)p;
2170         }
2171         case (kUChar):
2172         case (kUnsignedChar):
2173         {
2174             cl_uchar *p = (cl_uchar *)malloc(count * sizeof(cl_uchar));
2175             if(!p) return 0;
2176 
2177             for( size_t i = 0; i < count; i++ )
2178             {
2179                 p[ i ] =  (cl_uchar)genrand_int32(d);
2180             }
2181 
2182             return (void*)p;
2183         }
2184         case (kShort):
2185         {
2186             cl_short *p = (cl_short *)malloc(count * sizeof(cl_short));
2187             if(!p) return 0;
2188 
2189             for( size_t i = 0; i < count; i++ )
2190             {
2191                 p[ i ] = (cl_short)genrand_int32(d);
2192             }
2193 
2194             return (void*)p;
2195         }
2196         case (kUShort):
2197         case (kUnsignedShort):
2198         {
2199             cl_ushort *p = (cl_ushort *)malloc(count * sizeof(cl_ushort));
2200             if(!p) return 0;
2201 
2202             for( size_t i = 0; i < count; i++ )
2203             {
2204                 p[ i ] = (cl_ushort)genrand_int32(d);
2205             }
2206 
2207             return (void*)p;
2208         }
2209         case (kInt):
2210         {
2211             cl_int *p = (cl_int *)malloc(count * sizeof(cl_int));
2212             if(!p) return 0;
2213 
2214             for( size_t i = 0; i < count; i++ )
2215             {
2216                 p[ i ] = (cl_int)genrand_int32(d);
2217             }
2218 
2219             return (void*)p;
2220         }
2221         case (kUInt):
2222         case (kUnsignedInt):
2223         {
2224             cl_uint *p = (cl_uint *)malloc(count * sizeof(cl_uint));
2225             if(!p) return 0;
2226 
2227             for( size_t i = 0; i < count; i++ )
2228             {
2229                 p[ i ] =  (cl_uint)genrand_int32(d);
2230             }
2231 
2232             return (void*)p;
2233         }
2234 
2235         case (kFloat):
2236         {
2237             cl_float *p = (cl_float *)malloc(count * sizeof(cl_float));
2238             if(!p) return 0;
2239 
2240             for( size_t i = 0; i < count; i++ )
2241             {
2242                 p[ i ] = get_random_float( 0.f, 1.f, d );
2243             }
2244 
2245             return (void*)p;
2246         }
2247         case (kHalf):
2248         {
2249             cl_half *p = (cl_half *)malloc(count * sizeof(cl_half));
2250             if(!p) return 0;
2251 
2252             for( size_t i = 0; i < count; i++ )
2253             {
2254                 p[ i ] = convert_float_to_half( get_random_float( 0.f, 1.f, d ) );
2255             }
2256 
2257             return (void*)p;
2258         }
2259         default:
2260         {
2261             log_error("Invalid explicit type specified for create random data!\n");
2262             return 0;
2263         }
2264     }
2265     return 0;
2266 }
2267 
DumpGLBuffer(GLenum type,size_t width,size_t height,void * buffer)2268 void DumpGLBuffer(GLenum type, size_t width, size_t height, void* buffer)
2269 {
2270     size_t i;
2271     size_t count = width * height;
2272     if(type == GL_BYTE)
2273     {
2274         cl_char* p = (cl_char*)buffer;
2275         for(i = 0; i < count; i++)
2276             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2277                 p[i* 4 + 0],
2278                 p[i* 4 + 1],
2279                 p[i* 4 + 2],
2280                 p[i* 4 + 3]);
2281     }
2282     else if(type == GL_UNSIGNED_BYTE)
2283     {
2284         cl_uchar* p = (cl_uchar*)buffer;
2285         for(i = 0; i < count; i++)
2286             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2287                 p[i* 4 + 0],
2288                 p[i* 4 + 1],
2289                 p[i* 4 + 2],
2290                 p[i* 4 + 3]);
2291     }
2292     else if(type == GL_INT)
2293     {
2294         cl_int* p = (cl_int*)buffer;
2295         for(i = 0; i < count; i++)
2296             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2297                 p[i* 4 + 0],
2298                 p[i* 4 + 1],
2299                 p[i* 4 + 2],
2300                 p[i* 4 + 3]);
2301     }
2302     else if(type == GL_UNSIGNED_INT)
2303     {
2304         cl_uint* p = (cl_uint*)buffer;
2305         for(i = 0; i < count; i++)
2306             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2307                 p[i* 4 + 0],
2308                 p[i* 4 + 1],
2309                 p[i* 4 + 2],
2310                 p[i* 4 + 3]);
2311     }
2312     else if(type == GL_SHORT)
2313     {
2314         cl_short* p = (cl_short*)buffer;
2315         for(i = 0; i < count; i++)
2316             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2317                 p[i* 4 + 0],
2318                 p[i* 4 + 1],
2319                 p[i* 4 + 2],
2320                 p[i* 4 + 3]);
2321     }
2322     else if(type == GL_UNSIGNED_SHORT)
2323     {
2324         cl_ushort* p = (cl_ushort*)buffer;
2325         for(i = 0; i <  count; i++)
2326             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2327                 p[i* 4 + 0],
2328                 p[i* 4 + 1],
2329                 p[i* 4 + 2],
2330                 p[i* 4 + 3]);
2331     }
2332     else if(type == GL_FLOAT)
2333     {
2334         cl_float* p = (cl_float*)buffer;
2335         for(i = 0; i < count; i++)
2336             log_info("[%4d] %#f %#f %#f %#f\n", (unsigned int)(i),
2337                p[i* 4 + 0],
2338                p[i* 4 + 1],
2339                p[i* 4 + 2],
2340                p[i* 4 + 3]);
2341     }
2342 }
2343 
2344 #if defined(_WIN32)
2345 #include <string.h>
2346 
gluCheckExtension(const GLubyte * extName,const GLubyte * extString)2347 GLboolean gluCheckExtension(const GLubyte *extName, const GLubyte *extString)
2348 {
2349   const size_t len = strlen((const char*)extName);
2350   const char* str = (const char*)extString;
2351 
2352   while (str != NULL) {
2353     str = strstr(str, (const char*)extName);
2354     if (str == NULL) {
2355       break;
2356     }
2357     if ((str > (const char*)extString || str[-1] == ' ')
2358         && (str[len] == ' ' || str[len] == '\0')) {
2359       return GL_TRUE;
2360     }
2361     str = strchr(str + len, ' ');
2362   }
2363 
2364   return GL_FALSE;
2365 }
2366 
2367 #endif
2368 
2369 // Function pointers for the GL/CL calls
2370 clCreateFromGLBuffer_fn clCreateFromGLBuffer_ptr;
2371 clCreateFromGLTexture_fn clCreateFromGLTexture_ptr;
2372 clCreateFromGLTexture2D_fn clCreateFromGLTexture2D_ptr;
2373 clCreateFromGLTexture3D_fn clCreateFromGLTexture3D_ptr;
2374 clCreateFromGLRenderbuffer_fn clCreateFromGLRenderbuffer_ptr;
2375 clGetGLObjectInfo_fn clGetGLObjectInfo_ptr;
2376 clGetGLTextureInfo_fn clGetGLTextureInfo_ptr;
2377 clEnqueueAcquireGLObjects_fn clEnqueueAcquireGLObjects_ptr;
2378 clEnqueueReleaseGLObjects_fn clEnqueueReleaseGLObjects_ptr;
2379 
init_clgl_ext()2380 int init_clgl_ext() {
2381 
2382     // As OpenCL for the platforms.  Warn if more than one platform found,
2383     // since this might not be the platform we want.  By default, we simply
2384     // use the first returned platform.
2385 
2386     cl_uint nplatforms;
2387     cl_platform_id platform;
2388     clGetPlatformIDs(0, NULL, &nplatforms);
2389     clGetPlatformIDs(1, &platform, NULL);
2390 
2391     if (nplatforms > 1) {
2392         log_info("clGetPlatformIDs returned multiple values.  This is not "
2393             "an error, but might result in obtaining incorrect function "
2394             "pointers if you do not want the first returned platform.\n");
2395 
2396         // Show them the platform name, in case it is a problem.
2397 
2398         size_t size;
2399         char *name;
2400 
2401         clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
2402         name = (char*)malloc(size);
2403         clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
2404 
2405         log_info("Using platform with name: %s \n", name);
2406         free(name);
2407     }
2408 
2409     // Create the function pointer table
2410     clCreateFromGLBuffer_ptr = (clCreateFromGLBuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLBuffer");
2411     if (clCreateFromGLBuffer_ptr == NULL) {
2412         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLBuffer) returned NULL.\n");
2413         return -1;
2414     }
2415     clCreateFromGLTexture2D_ptr = (clCreateFromGLTexture2D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture2D");
2416     if (clCreateFromGLTexture2D_ptr == NULL) {
2417         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture2D) returned NULL.\n");
2418         return -1;
2419     }
2420     clCreateFromGLTexture3D_ptr = (clCreateFromGLTexture3D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture3D");
2421     if (clCreateFromGLTexture3D_ptr == NULL) {
2422         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture3D\") returned NULL.\n");
2423         return -1;
2424     }
2425     clCreateFromGLTexture_ptr = (clCreateFromGLTexture_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture");
2426     if (clCreateFromGLTexture_ptr == NULL) {
2427          log_error("clGetExtensionFunctionAddressForPlatform(platform,\"clCreateFromGLTexture\") returned NULL.\n");
2428          return -1;
2429     }
2430     clCreateFromGLRenderbuffer_ptr = (clCreateFromGLRenderbuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLRenderbuffer");
2431     if (clCreateFromGLRenderbuffer_ptr == NULL) {
2432         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLRenderbuffer) returned NULL.\n");
2433         return -1;
2434     }
2435     clGetGLObjectInfo_ptr = (clGetGLObjectInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLObjectInfo");
2436     if (clGetGLObjectInfo_ptr == NULL) {
2437         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLObjectInfo) returned NULL.\n");
2438         return -1;
2439     }
2440     clGetGLTextureInfo_ptr = (clGetGLTextureInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLTextureInfo");
2441     if (clGetGLTextureInfo_ptr == NULL) {
2442         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLTextureInfo) returned NULL.\n");
2443         return -1;
2444     }
2445     clEnqueueAcquireGLObjects_ptr = (clEnqueueAcquireGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueAcquireGLObjects");
2446     if (clEnqueueAcquireGLObjects_ptr == NULL) {
2447         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueAcquireGLObjects) returned NULL.\n");
2448         return -1;
2449     }
2450     clEnqueueReleaseGLObjects_ptr = (clEnqueueReleaseGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueReleaseGLObjects");
2451     if (clEnqueueReleaseGLObjects_ptr == NULL) {
2452         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueReleaseGLObjects) returned NULL.\n");
2453         return -1;
2454     }
2455 
2456     return 0;
2457 }
2458 
get_gl_max_samples(GLenum target,GLenum internalformat)2459 GLint get_gl_max_samples( GLenum target, GLenum internalformat )
2460 {
2461     GLint max_samples = 0;
2462 #ifdef GL_VERSION_4_2
2463     glGetInternalformativ(target, internalformat, GL_SAMPLES, 1, &max_samples);
2464 #else
2465     switch (internalformat)
2466     {
2467         case GL_RGBA8I:
2468         case GL_RGBA16I:
2469         case GL_RGBA32I:
2470         case GL_RGBA8UI:
2471         case GL_RGBA16UI:
2472         case GL_RGBA32UI:
2473             glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &max_samples);
2474             break;
2475         case GL_DEPTH_COMPONENT16:
2476         case GL_DEPTH_COMPONENT32F:
2477         case GL_DEPTH24_STENCIL8:
2478         case GL_DEPTH32F_STENCIL8:
2479             glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &max_samples);
2480             break;
2481         default:
2482             glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_samples);
2483             break;
2484     }
2485 #endif
2486     return max_samples;
2487 }
2488