xref: /aosp_15_r20/external/OpenCL-CTS/test_common/gl/helpers.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
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__,         \
974                       __LINE__);                                               \
975     }
976 
get_gl_vector_type(GLenum internalformat)977 const char *get_gl_vector_type( GLenum internalformat )
978 {
979   switch (internalformat) {
980   case GL_RGBA8:
981   case GL_RGBA16:
982   case GL_RGBA32F_ARB:
983   case GL_RGBA16F_ARB:
984   case GL_DEPTH_COMPONENT16:
985   case GL_DEPTH_COMPONENT32F:
986   case GL_DEPTH24_STENCIL8:
987   case GL_DEPTH32F_STENCIL8:
988     return "vec4";
989     break;
990   case GL_RGBA8I_EXT:
991   case GL_RGBA16I_EXT:
992   case GL_RGBA32I_EXT:
993     return "ivec4";
994     break;
995   case GL_RGBA8UI_EXT:
996   case GL_RGBA16UI_EXT:
997   case GL_RGBA32UI_EXT:
998     return "uvec4";
999     break;
1000   default:
1001     log_error("Test error: unsupported data type\n");
1002     return "";
1003     break;
1004   }
1005 }
1006 
get_gl_data_type(GLenum internalformat)1007 const char *get_gl_data_type( GLenum internalformat )
1008 {
1009   switch (internalformat) {
1010   case GL_RGBA8:
1011   case GL_RGBA16:
1012   case GL_RGBA32F_ARB:
1013   case GL_RGBA16F_ARB:
1014   case GL_DEPTH_COMPONENT16:
1015   case GL_DEPTH_COMPONENT32F:
1016   case GL_DEPTH24_STENCIL8:
1017   case GL_DEPTH32F_STENCIL8:
1018     return "float";
1019     break;
1020   case GL_RGBA8I_EXT:
1021   case GL_RGBA16I_EXT:
1022   case GL_RGBA32I_EXT:
1023     return "int";
1024     break;
1025   case GL_RGBA8UI_EXT:
1026   case GL_RGBA16UI_EXT:
1027   case GL_RGBA32UI_EXT:
1028     return "uint";
1029     break;
1030   default:
1031     log_error("Test error: unsupported data type\n");
1032     return "";
1033     break;
1034   }
1035 }
1036 
1037 
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)1038 void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples,
1039                                     GLenum target, GLenum glFormat,
1040                                     GLenum internalFormat, GLenum glType,
1041                                     ExplicitType type, GLuint *outTextureID,
1042                                     int *outError, bool allocateMem, MTdata d , bool fixedSampleLocations)
1043 {
1044   // This function creates a multisample texture and renders into each sample
1045   // using a GLSL shader
1046 
1047   // Check if the renderer supports enough samples
1048   GLint max_samples = get_gl_max_samples(target, internalFormat);
1049   CHECK_GL_ERROR()
1050 
1051   if (max_samples < (GLint)samples)
1052       log_error("GL error: requested samples (%zu) exceeds renderer max "
1053                 "samples (%d)\n",
1054                 samples, max_samples);
1055 
1056   // Setup the GLSL program
1057   const GLchar *vertex_source =
1058   "#version 140\n"
1059   "in vec4 att0;\n"
1060   "void main (void) {\n"
1061   " gl_Position = vec4(att0.xy,0.0,1.0);\n"
1062   "}\n";
1063 
1064   const GLchar *fragmentSource =
1065   "#version 140\n"
1066     "out %s out0;\n"
1067     "uniform %s colorVal;\n"
1068     "uniform float depthVal;\n"
1069   "void main (void) {\n"
1070     "    out0 = %s(colorVal);\n"
1071     " gl_FragDepth = depthVal;\n"
1072   "}\n";
1073 
1074   GLchar fragmentShader[256];
1075   sprintf(fragmentShader, fragmentSource, get_gl_vector_type(internalFormat), get_gl_data_type(internalFormat), get_gl_vector_type(internalFormat));
1076   const GLchar *fragment_source = &fragmentShader[0];
1077 
1078   glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
1079   glShaderSource(vertex_shader, 1, &vertex_source, NULL);
1080   glCompileShader(vertex_shader);
1081   CHECK_GL_ERROR()
1082 
1083   glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
1084   glShaderSource(fragment_shader, 1, &fragment_source, NULL);
1085   glCompileShader(fragment_shader);
1086   CHECK_GL_ERROR()
1087 
1088   GLuint prog = glCreateProgram();
1089   glAttachShader(prog, vertex_shader);
1090   glAttachShader(prog, fragment_shader);
1091   CHECK_GL_ERROR()
1092 
1093   glBindAttribLocation(prog, 0, "att0");
1094   glLinkProgram(prog);
1095   CHECK_GL_ERROR()
1096 
1097   // Setup the FBO and texture
1098   glFramebufferWrapper fbo;
1099   glGenFramebuffers(1, &fbo);
1100   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1101   CHECK_GL_ERROR()
1102 
1103   glViewport(0, 0, width, height);
1104   CHECK_GL_ERROR()
1105 
1106   GLuint tex = 0;
1107   glGenTextures(1, &tex);
1108   glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
1109   glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, fixedSampleLocations);
1110   CHECK_GL_ERROR()
1111 
1112   GLint attachment;
1113   switch (internalFormat) {
1114     case GL_DEPTH_COMPONENT16:
1115     case GL_DEPTH_COMPONENT32F:
1116     attachment = GL_DEPTH_ATTACHMENT;
1117     break;
1118     case GL_DEPTH24_STENCIL8:
1119     case GL_DEPTH32F_STENCIL8:
1120     attachment = GL_DEPTH_STENCIL_ATTACHMENT;
1121       break;
1122     default:
1123     attachment = GL_COLOR_ATTACHMENT0;
1124       break;
1125   }
1126 
1127   glFramebufferTexture(GL_FRAMEBUFFER, attachment, tex, 0);
1128   CHECK_GL_ERROR()
1129 
1130   GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1131   if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
1132     log_info("GL status: GL_FRAMEBUFFER_UNSUPPORTED format %s multisample is not supported\n", GetGLFormatName(internalFormat));
1133     *outTextureID = 0;
1134     *outError = GL_FRAMEBUFFER_UNSUPPORTED;
1135     return NULL;
1136   }
1137 
1138   if (status != GL_FRAMEBUFFER_COMPLETE) {
1139     log_error("GL error: framebuffer incomplete status 0x%04X\n",status);
1140     *outTextureID = 0;
1141     *outError = status;
1142     return NULL;
1143   }
1144 
1145   // Check if the framebuffer supports enough samples
1146   GLint fbo_samples = 0;
1147   glGetIntegerv(GL_SAMPLES, &fbo_samples);
1148   CHECK_GL_ERROR();
1149 
1150   if (fbo_samples < (GLint)samples)
1151       log_error(
1152           "GL Error: requested samples (%zu) exceeds FBO capability (%d)\n",
1153           samples, fbo_samples);
1154 
1155   glUseProgram(prog);
1156   CHECK_GL_ERROR()
1157 
1158   if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
1159     glDisable(GL_DEPTH_TEST);
1160     CHECK_GL_ERROR()
1161   }
1162   else {
1163     glEnable(GL_DEPTH_TEST);
1164     glDepthFunc(GL_ALWAYS);
1165     CHECK_GL_ERROR()
1166   }
1167 
1168   // Setup the VBO for rendering a quad
1169   GLfloat quad[] = {
1170     -1.0f, -1.0f,
1171     1.0f, -1.0f,
1172     1.0f,  1.0f,
1173     -1.0f,  1.0f
1174   };
1175 
1176   glBufferWrapper vbo;
1177   glGenBuffers(1, &vbo);
1178   glBindBuffer(GL_ARRAY_BUFFER, vbo);
1179   glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
1180   CHECK_GL_ERROR()
1181 
1182   glVertexArraysWrapper vao;
1183   glGenVertexArrays(1, &vao);
1184   glBindVertexArray(vao);
1185   glEnableVertexAttribArray(0);
1186   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
1187   CHECK_GL_ERROR()
1188 
1189   //clearing color and depth buffer
1190   glClearColor(0, 0, 0, 0);
1191   glClear(GL_COLOR_BUFFER_BIT);
1192   glClearDepth(1.0);
1193   glClear(GL_DEPTH_BUFFER_BIT);
1194 
1195   //calculating colors
1196   double color_delta = 1.0 / samples;
1197   double color = color_delta;
1198 
1199   glEnable(GL_SAMPLE_MASK);
1200   for (size_t i=0;i!=samples;++i) {
1201     glSampleMaski(0, 1<<i);
1202     GLint colorUniformLocation = glGetUniformLocation(prog, "colorVal");
1203     switch (internalFormat) {
1204     case GL_RGBA8I_EXT:
1205       glUniform1i(colorUniformLocation, color * 0x7f);
1206       break;
1207     case GL_RGBA16I_EXT:
1208       glUniform1i(colorUniformLocation, color * 0x7fff);
1209       break;
1210     case GL_RGBA32I_EXT:
1211       glUniform1i(colorUniformLocation, color * 0x7fffffff);
1212       break;
1213     case GL_RGBA8UI_EXT:
1214       glUniform1ui(colorUniformLocation, color * 0xff);
1215       break;
1216     case GL_RGBA16UI_EXT:
1217       glUniform1ui(colorUniformLocation, color * 0xffff);
1218       break;
1219     case GL_RGBA32UI_EXT:
1220       glUniform1ui(colorUniformLocation, color * 0xffffffff);
1221       break;
1222     default:
1223       glUniform1f(colorUniformLocation, color);
1224       break;
1225     }
1226 
1227     glUniform1f(glGetUniformLocation(prog, "depthVal"), color);
1228     color += color_delta;
1229 
1230     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1231     CHECK_GL_ERROR();
1232 
1233     glFlush();
1234   }
1235 
1236   glDisable(GL_SAMPLE_MASK);
1237   CHECK_GL_ERROR();
1238 
1239   *outTextureID = tex;
1240 
1241   // Create an output buffer containing the expected results.
1242   unsigned int size = 0;
1243   if ( glType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
1244   {
1245     size = width * height * 2;
1246   }
1247   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))
1248   {
1249     size = width * height;
1250   }
1251   else
1252   {
1253     size = width * height * 4;
1254   }
1255 
1256   char *data = (char *)malloc(get_explicit_type_size(type) * size * samples);
1257   char *p = data;
1258   size_t stride = get_explicit_type_size(type);
1259 
1260   for (size_t s=0;s!=samples;++s) {
1261     double val = color_delta + (color_delta * s);
1262     for (size_t i=0;i!=size;++i) {
1263       switch (type) {
1264       case kChar:
1265         *((char*)p) = val * 0x7f;
1266         break;
1267         case kUChar:
1268         *((unsigned char*)p) = val * 0xff;
1269           break;
1270         case kFloat:
1271           *((float*)p) = val;
1272           break;
1273       case kShort:
1274         *((short*)p) = val*0x7fff;
1275         break;
1276         case kUShort:
1277         *((unsigned short*)p) = val*0xffff;
1278           break;
1279       case kInt:
1280         *((int*)p) = val*0x7fffffff;
1281           break;
1282         case kUInt:
1283         *((unsigned int*)p) = val*0xffffffff;
1284           break;
1285         case kHalf: *((cl_half *)p) = convert_float_to_half(val); break;
1286         default:
1287           log_error("Test error: unexpected type enum 0x%x\n",type);
1288       }
1289 
1290       p += stride;
1291     }
1292   }
1293 
1294 
1295   if (allocateMem)
1296     reorder_verification_buffer(glFormat,glType,data,width*height*samples);
1297 
1298   return data;
1299 }
1300 
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)1301 void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
1302                               size_t total_layers, size_t samples,
1303                               GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
1304                               ExplicitType type, GLuint *outTextureID, int *outError,
1305                               bool allocateMem, MTdata d, bool fixedSampleLocations)
1306 {
1307   // This function creates a multisample texture and renders into each sample
1308   // using a GLSL shader
1309 
1310   // Check if the renderer supports enough samples
1311   GLint max_samples = get_gl_max_samples(target, internalFormat);
1312 
1313   if (max_samples < (GLint)samples)
1314       log_error("GL error: requested samples (%zu) exceeds renderer max "
1315                 "samples (%d)\n",
1316                 samples, max_samples);
1317 
1318   // Setup the GLSL program
1319   const GLchar *vertex_source =
1320   "#version 140\n"
1321   "in vec4 att0;\n"
1322   "void main (void) {\n"
1323   " gl_Position = vec4(att0.xy,0.0,1.0);\n"
1324   "}\n";
1325 
1326   const GLchar *fragmentSource =
1327   "#version 140\n"
1328     "out %s out0;\n"
1329     "uniform %s colorVal;\n"
1330     "uniform float depthVal;\n"
1331   "void main (void) {\n"
1332     "    out0 = %s(colorVal);\n"
1333     " gl_FragDepth = depthVal;\n"
1334   "}\n";
1335 
1336   GLchar fragmentShader[256];
1337   sprintf(fragmentShader, fragmentSource, get_gl_vector_type(internalFormat), get_gl_data_type(internalFormat), get_gl_vector_type(internalFormat));
1338   const GLchar *fragment_source = &fragmentShader[0];
1339 
1340   glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
1341   glShaderSource(vertex_shader, 1, &vertex_source, NULL);
1342   glCompileShader(vertex_shader);
1343   CHECK_GL_ERROR()
1344 
1345   glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
1346   glShaderSource(fragment_shader, 1, &fragment_source, NULL);
1347   glCompileShader(fragment_shader);
1348   CHECK_GL_ERROR()
1349 
1350   glProgramWrapper prog = glCreateProgram();
1351   glAttachShader(prog, vertex_shader);
1352   glAttachShader(prog, fragment_shader);
1353   CHECK_GL_ERROR()
1354 
1355   glBindAttribLocation(prog, 0, "att0");
1356   glLinkProgram(prog);
1357   CHECK_GL_ERROR()
1358 
1359   // Setup the FBO and texture
1360   glFramebufferWrapper fbo;
1361   glGenFramebuffers(1, &fbo);
1362   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1363   CHECK_GL_ERROR()
1364 
1365   glViewport(0, 0, width, height);
1366   CHECK_GL_ERROR()
1367 
1368   GLuint tex = 0;
1369   glGenTextures(1, &tex);
1370   glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex);
1371   glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, internalFormat, width, height, total_layers, fixedSampleLocations);
1372   CHECK_GL_ERROR()
1373 
1374   GLint attachment;
1375   switch (internalFormat) {
1376     case GL_DEPTH_COMPONENT16:
1377     case GL_DEPTH_COMPONENT32F:
1378     attachment = GL_DEPTH_ATTACHMENT;
1379     break;
1380     case GL_DEPTH24_STENCIL8:
1381     case GL_DEPTH32F_STENCIL8:
1382     attachment = GL_DEPTH_STENCIL_ATTACHMENT;
1383       break;
1384     default:
1385     attachment = GL_COLOR_ATTACHMENT0;
1386     break;
1387   }
1388 
1389   //calculating colors
1390   double color_delta = 1.0 / (total_layers * samples);
1391 
1392   if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
1393     glDisable(GL_DEPTH_TEST);
1394     CHECK_GL_ERROR()
1395   }
1396   else {
1397     glEnable(GL_DEPTH_TEST);
1398     glDepthFunc(GL_ALWAYS);
1399     CHECK_GL_ERROR()
1400   }
1401 
1402   // Setup the VBO for rendering a quad
1403   GLfloat quad[] = {
1404     -1.0f, -1.0f,
1405     1.0f, -1.0f,
1406     1.0f,  1.0f,
1407     -1.0f,  1.0f
1408   };
1409 
1410   glBufferWrapper vbo;
1411   glGenBuffers(1, &vbo);
1412   glBindBuffer(GL_ARRAY_BUFFER, vbo);
1413   glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
1414   CHECK_GL_ERROR()
1415 
1416   glVertexArraysWrapper vao;
1417   glGenVertexArrays(1, &vao);
1418   glBindVertexArray(vao);
1419   glEnableVertexAttribArray(0);
1420   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
1421   CHECK_GL_ERROR()
1422 
1423   for (size_t l=0; l!=total_layers; ++l) {
1424     glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, tex, 0, l);
1425     CHECK_GL_ERROR()
1426 
1427     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1428     if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
1429       log_info("GL status: GL_FRAMEBUFFER_UNSUPPORTED format %s multisample array is not supported\n", GetGLFormatName(internalFormat));
1430       *outTextureID = 0;
1431       *outError = GL_FRAMEBUFFER_UNSUPPORTED;
1432       return NULL;
1433     }
1434 
1435     if (status != GL_FRAMEBUFFER_COMPLETE) {
1436       log_error("GL error: framebuffer incomplete status 0x%04X\n",status);
1437       *outTextureID = 0;
1438       *outError = status;
1439       return NULL;
1440     }
1441 
1442     // Check if the framebuffer supports enough samples
1443     GLint fbo_samples = 0;
1444     glGetIntegerv(GL_SAMPLES, &fbo_samples);
1445     CHECK_GL_ERROR();
1446 
1447     if (fbo_samples < (GLint)samples)
1448         log_error(
1449             "GL Error: requested samples (%zu) exceeds FBO capability (%d)\n",
1450             samples, fbo_samples);
1451 
1452     glUseProgram(prog);
1453     CHECK_GL_ERROR()
1454 
1455     //clearing color and depth buffer
1456     glClearColor(0, 0, 0, 0);
1457     glClear(GL_COLOR_BUFFER_BIT);
1458     glClearDepth(1.0);
1459     glClear(GL_DEPTH_BUFFER_BIT);
1460 
1461     glEnable(GL_SAMPLE_MASK);
1462     for (size_t s=0;s!=samples;++s) {
1463       double val = color_delta + color_delta * (l * samples + s);
1464 
1465       glSampleMaski(0, 1<<s);
1466       GLint colorUniformLocation = glGetUniformLocation(prog, "colorVal");
1467       switch (internalFormat) {
1468       case GL_RGBA8I_EXT:
1469         glUniform1i(colorUniformLocation, val * 0x7f);
1470         break;
1471       case GL_RGBA16I_EXT:
1472         glUniform1i(colorUniformLocation, val * 0x7fff);
1473         break;
1474       case GL_RGBA32I_EXT:
1475         glUniform1i(colorUniformLocation, val * 0x7fffffff);
1476         break;
1477       case GL_RGBA8UI_EXT:
1478         glUniform1ui(colorUniformLocation, val * 0xff);
1479         break;
1480       case GL_RGBA16UI_EXT:
1481         glUniform1ui(colorUniformLocation, val * 0xffff);
1482         break;
1483       case GL_RGBA32UI_EXT:
1484         glUniform1ui(colorUniformLocation, val * 0xffffffff);
1485         break;
1486       default:
1487         glUniform1f(colorUniformLocation, val);
1488         break;
1489       }
1490 
1491       glUniform1f(glGetUniformLocation(prog, "depthVal"), val);
1492 
1493       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1494       CHECK_GL_ERROR();
1495 
1496       glFlush();
1497     }
1498 
1499     glDisable(GL_SAMPLE_MASK);
1500     CHECK_GL_ERROR();
1501   }
1502 
1503   *outTextureID = tex;
1504 
1505   // Create an output buffer containing the expected results.
1506   unsigned int size = 0;
1507   if ( glType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
1508   {
1509     size = width * height * 2;
1510   }
1511   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))
1512   {
1513     size = width * height;
1514   }
1515   else
1516   {
1517     size = width * height * 4;
1518   }
1519 
1520   char *data = (char *)malloc(get_explicit_type_size(type) * size * total_layers * samples);
1521   char *p = data;
1522   size_t stride = get_explicit_type_size(type);
1523 
1524   for (size_t s=0;s!=samples;++s) {
1525     for (size_t l=0;l!=total_layers;++l) {
1526       double val = color_delta + color_delta * (l * samples + s);
1527     for (size_t i=0;i!=size;++i) {
1528       switch (type) {
1529         case kChar:
1530           *((char*)p) = val * 0x7f;
1531           break;
1532         case kUChar:
1533           *((unsigned char*)p) = val*0xff;
1534           break;
1535         case kFloat:
1536           *((float*)p) = val;
1537           break;
1538         case kShort:
1539           *((short*)p) = val * 0x7fff;
1540           break;
1541         case kUShort:
1542           *((unsigned short*)p) = val * 0xffff;
1543           break;
1544         case kInt:
1545           *((int*)p) = val * 0x7fffffff;
1546           break;
1547         case kUInt:
1548           *((unsigned int*)p) = val*0xffffffff;
1549           break;
1550         case kHalf: *((cl_half *)p) = convert_float_to_half(val); break;
1551         default:
1552           log_error("Test error: unexpected type enum 0x%x\n",type);
1553       }
1554 
1555       p += stride;
1556     }
1557   }
1558   }
1559 
1560   if (allocateMem)
1561     reorder_verification_buffer(glFormat,glType,data,width*height*samples*total_layers);
1562 
1563   return data;
1564 }
1565 
1566 #endif // GL_VERSION_3_2
1567 
CreateGLRenderbuffer(GLsizei width,GLsizei height,GLenum attachment,GLenum glFormat,GLenum internalFormat,GLenum glType,ExplicitType type,GLuint * outFramebuffer,GLuint * outRenderbuffer,int * outError,MTdata d,bool allocateMem)1568 void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
1569                              GLenum attachment, GLenum glFormat,
1570                              GLenum internalFormat, GLenum glType,
1571                              ExplicitType type,
1572                              GLuint *outFramebuffer,
1573                              GLuint *outRenderbuffer,
1574                              int *outError, MTdata d, bool allocateMem )
1575 {
1576     *outError = CreateGLRenderbufferRaw( width, height, attachment, glFormat, internalFormat,
1577                             glType, outFramebuffer, outRenderbuffer );
1578 
1579     if( *outError != 0 )
1580         return NULL;
1581 
1582     GLenum err = 0;
1583 
1584     // Generate a renderbuffer and bind
1585     glGenRenderbuffersEXT( 1, outRenderbuffer );
1586     glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, *outRenderbuffer );
1587 
1588     // Allocate storage to the renderbuffer
1589     glGetError();
1590     glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, internalFormat, (GLsizei)width,  (GLsizei)height );
1591     err = glGetError();
1592     if( err != GL_NO_ERROR )
1593     {
1594         *outError = 1701;
1595         log_error("Failed to allocate render buffer storage!\n");
1596         return NULL;
1597     }
1598 
1599     GLint realInternalFormat;
1600     glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &realInternalFormat );
1601     internalFormat = realInternalFormat;
1602 
1603 #ifdef DEBUG
1604     GLint rsize, gsize, bsize, asize;
1605     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT,&rsize);
1606     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT,&gsize);
1607     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT,&bsize);
1608     glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT,&asize);
1609 
1610     log_info("Renderbuffer internal format requested: %s actual: %s sizes: r=%d g=%d b=%d a=%d\n",
1611               GetGLFormatName( internalFormat ), GetGLFormatName( realInternalFormat ),
1612               rsize, gsize, bsize, asize );
1613 #endif
1614 
1615     // Create and bind a framebuffer to render with
1616     glGenFramebuffersEXT( 1, outFramebuffer );
1617     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *outFramebuffer );
1618     if( err != GL_NO_ERROR )
1619     {
1620         log_error( "ERROR: Unable to bind framebuffer : Error %s\n",
1621                   gluErrorString( err ));
1622 
1623         *outError = -1;
1624         return NULL;
1625     }
1626 
1627     // Attach to the framebuffer
1628     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *outRenderbuffer );
1629     err = glGetError();
1630     GLint status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
1631     if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
1632     {
1633         *outError = -1;
1634         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s, status %x)\n", gluErrorString( err ), (int)status );
1635         return NULL;
1636     }
1637 
1638     void* buffer = CreateRandomData(type, width * height * 4, d);
1639 
1640 #ifdef DEBUG
1641     log_info( "- Fillling renderbuffer: %d : %d : %s : %s \n",
1642              (int)width, (int)height,
1643              GetGLFormatName(glFormat),
1644              GetGLTypeName(glType));
1645 
1646     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1647 #endif
1648 
1649     // Fill a texture with our input data
1650     glTextureWrapper texture;
1651     glGenTextures( 1, &texture );
1652     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
1653     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1654     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1655     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1656     glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1657     glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, internalFormat, width, height, 0, glFormat, glType, buffer );
1658     glEnable( GL_TEXTURE_RECTANGLE_ARB );
1659 
1660     // Render fullscreen textured quad
1661     glDisable( GL_LIGHTING );
1662     glViewport(0, 0, width, height);
1663     glMatrixMode(GL_MODELVIEW);
1664     glLoadIdentity();
1665     glMatrixMode( GL_TEXTURE );
1666     glLoadIdentity();
1667     glMatrixMode(GL_PROJECTION);
1668     glLoadIdentity();
1669     glClear(GL_COLOR_BUFFER_BIT);
1670     gluOrtho2D( -1.0, 1.0, -1.0, 1.0 );
1671     glMatrixMode( GL_MODELVIEW );
1672     glBegin( GL_QUADS );
1673     {
1674         glColor3f(1.0f, 1.0f, 1.0f);
1675         glTexCoord2f( 0.0f, 0.0f );
1676         glVertex3f( -1.0f, -1.0f, 0.0f );
1677         glTexCoord2f( 0.0f, height );
1678         glVertex3f( -1.0f, 1.0f, 0.0f );
1679         glTexCoord2f( width, height );
1680         glVertex3f( 1.0f, 1.0f, 0.0f );
1681         glTexCoord2f( width, 0.0f );
1682         glVertex3f( 1.0f, -1.0f, 0.0f );
1683     }
1684     glEnd();
1685     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
1686     glDisable( GL_TEXTURE_RECTANGLE_ARB );
1687 
1688     glFlush();
1689 
1690     // Read back the data in the renderbuffer
1691     memset(buffer, 0, width * height * 4 * get_explicit_type_size( type ));
1692     glReadBuffer( attachment );
1693 
1694     glReadPixels( 0, 0, (GLsizei)width, (GLsizei)height, glFormat, glType, buffer );
1695 
1696     err = glGetError();
1697     if( err != GL_NO_ERROR )
1698     {
1699         log_error( "ERROR: Unable to read data via glReadPixels : %d : %d : %s : %s : Error %s\n",
1700                   (int)width, (int)height,
1701                   GetGLFormatName(glFormat),
1702                   GetGLTypeName(glType),
1703                   gluErrorString( err ));
1704         *outError = -1;
1705     }
1706 
1707 #ifdef DEBUG
1708     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1709              (int)width, (int)height,
1710              GetGLFormatName(glFormat),
1711              GetGLTypeName(glType));
1712 
1713     DumpGLBuffer(glType, (int)width, (int)height, (void*)buffer);
1714 #endif
1715 
1716     if( !allocateMem )
1717     {
1718         free( buffer );
1719         return NULL;
1720     }
1721 
1722     if( glType == GL_UNSIGNED_INT_8_8_8_8_REV && glFormat == GL_BGRA && allocateMem )
1723     {
1724         // Reverse and reorder to validate since in the
1725         // kernel the read_imagef() call always returns RGBA
1726         cl_uchar *p = (cl_uchar *)buffer;
1727         for (GLsizei i = 0; i < width * height; i++)
1728         {
1729             cl_uchar uc0 = p[i * 4 + 0];
1730             cl_uchar uc1 = p[i * 4 + 1];
1731             cl_uchar uc2 = p[i * 4 + 2];
1732             cl_uchar uc3 = p[i * 4 + 3];
1733 
1734             p[ i * 4 + 0 ] = uc2;
1735             p[ i * 4 + 1 ] = uc1;
1736             p[ i * 4 + 2 ] = uc0;
1737             p[ i * 4 + 3 ] = uc3;
1738         }
1739     }
1740     else if( glType == GL_UNSIGNED_INT_8_8_8_8 && glFormat == GL_BGRA && allocateMem )
1741     {
1742       // Reverse and reorder to validate since in the
1743       // kernel the read_imagef() call always returns RGBA
1744       cl_uchar *p = (cl_uchar *)buffer;
1745       for (GLsizei i = 0; i < width * height; i++)
1746       {
1747         cl_uchar uc0 = p[i * 4 + 0];
1748         cl_uchar uc1 = p[i * 4 + 1];
1749         cl_uchar uc2 = p[i * 4 + 2];
1750         cl_uchar uc3 = p[i * 4 + 3];
1751 
1752         p[ i * 4 + 0 ] = uc1;
1753         p[ i * 4 + 1 ] = uc2;
1754         p[ i * 4 + 2 ] = uc3;
1755         p[ i * 4 + 3 ] = uc0;
1756       }
1757     }
1758 
1759     return buffer;
1760 }
1761 
ReadGLRenderbuffer(GLuint glFramebuffer,GLuint glRenderbuffer,GLenum attachment,GLenum glFormat,GLenum glInternalFormat,GLenum glType,ExplicitType typeToReadAs,size_t outWidth,size_t outHeight)1762 void * ReadGLRenderbuffer( GLuint glFramebuffer, GLuint glRenderbuffer,
1763                            GLenum attachment, GLenum glFormat,
1764                            GLenum glInternalFormat, GLenum glType,
1765                            ExplicitType typeToReadAs,
1766                            size_t outWidth, size_t outHeight )
1767 {
1768     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, glFramebuffer );
1769     glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, glRenderbuffer );
1770 
1771     // Attach to the framebuffer
1772     GLint err = glGetError();
1773     if( glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ) != GL_FRAMEBUFFER_COMPLETE_EXT )
1774     {
1775         log_error( "ERROR: Unable to attach renderbuffer to framebuffer (%s)\n", gluErrorString( err ) );
1776         return NULL;
1777     }
1778 
1779     // Read results from the GL renderbuffer
1780 #ifdef DEBUG
1781     log_info( "- Reading back from GL: %d x %d : %s : %s : %s\n",
1782              (int)outWidth, (int)outHeight,
1783              GetGLFormatName( glInternalFormat ),
1784              GetGLFormatName( glFormat ),
1785              GetGLTypeName( glType ));
1786 #endif
1787 
1788     GLenum readBackFormat = glFormat == GL_RGBA_INTEGER_EXT ? GL_RGBA_INTEGER_EXT : GL_RGBA;
1789     GLenum readBackType = glType;
1790 
1791     size_t outBytes = outWidth * outHeight * 4 * GetGLTypeSize(readBackType);
1792     void *outBuffer = malloc( outBytes );
1793     memset(outBuffer, 0, outBytes);
1794 
1795     glReadPixels( 0, 0, (GLsizei)outWidth, (GLsizei)outHeight, readBackFormat, readBackType, outBuffer );
1796 
1797 #ifdef DEBUG
1798     log_info( "- glReadPixels: %d : %d : %s : %s \n",
1799              (int)outWidth, (int)outHeight,
1800              GetGLFormatName(readBackFormat),
1801              GetGLTypeName(readBackType));
1802 
1803     DumpGLBuffer(readBackType, outWidth, outHeight, outBuffer);
1804 #endif
1805 
1806     return (void *)outBuffer;
1807 }
1808 
1809 GLenum
GetGLFormat(GLenum internalFormat)1810 GetGLFormat(GLenum internalFormat)
1811 {
1812     GLenum glFormat;
1813     switch (internalFormat)
1814     {
1815         case GL_BGRA:
1816         case GL_RGBA8:
1817         case GL_RGBA16:
1818         case GL_RGBA32F_ARB:
1819             glFormat = GL_RGBA;
1820             break;
1821         case GL_RGBA8I_EXT:
1822         case GL_RGBA16I_EXT:
1823         case GL_RGBA32I_EXT:
1824         case GL_RGBA8UI_EXT:
1825         case GL_RGBA16UI_EXT:
1826         case GL_RGBA32UI_EXT:
1827             glFormat = GL_RGBA_INTEGER_EXT;
1828             break;
1829         default:
1830             glFormat = GL_RGBA;
1831             break;
1832     }
1833 
1834     return glFormat;
1835 }
1836 
GetGLTypeForExplicitType(ExplicitType type)1837 GLenum GetGLTypeForExplicitType(ExplicitType type)
1838 {
1839     switch( type )
1840     {
1841         case kFloat:
1842             return GL_FLOAT;
1843         case kInt:
1844             return GL_INT;
1845         case kUInt:
1846             return GL_UNSIGNED_INT;
1847         case kShort:
1848             return GL_SHORT;
1849         case kUShort:
1850             return GL_UNSIGNED_SHORT;
1851         case kChar:
1852             return GL_BYTE;
1853         case kUChar:
1854             return GL_UNSIGNED_BYTE;
1855         case kHalf:
1856 #if defined( __APPLE__ )
1857             return GL_HALF_FLOAT;
1858 #else
1859             return GL_HALF_FLOAT_ARB;
1860 #endif
1861         default:
1862             return GL_INT;
1863     };
1864 }
1865 
GetGLTypeSize(GLenum type)1866 size_t GetGLTypeSize(GLenum type)
1867 {
1868     switch( type )
1869     {
1870         case GL_FLOAT:
1871             return sizeof(GLfloat);
1872         case GL_INT:
1873             return sizeof(GLint);
1874         case GL_UNSIGNED_INT:
1875         case GL_UNSIGNED_INT_10_10_10_2:
1876         case GL_UNSIGNED_INT_2_10_10_10_REV:
1877         case GL_UNSIGNED_INT_24_8:
1878             return sizeof(GLuint);
1879         case GL_SHORT:
1880             return sizeof(GLshort);
1881         case GL_UNSIGNED_SHORT:
1882             return sizeof(GLushort);
1883         case GL_UNSIGNED_INT_8_8_8_8_REV:
1884         case GL_BYTE:
1885             return sizeof(GLbyte);
1886         case GL_UNSIGNED_BYTE:
1887             return sizeof(GLubyte);
1888 #if defined( __APPLE__ )
1889         case GL_HALF_FLOAT:
1890 #else
1891         case GL_HALF_FLOAT_ARB:
1892 #endif
1893             return sizeof(GLhalf);
1894         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1895             return 2 * sizeof(GLfloat);
1896         default:
1897             log_error("Unknown type 0x%x\n",type);
1898             return 0;
1899     };
1900 }
1901 
GetExplicitTypeForGLType(GLenum type)1902 ExplicitType GetExplicitTypeForGLType(GLenum type)
1903 {
1904     switch( type )
1905     {
1906         case GL_FLOAT:
1907             return kFloat;
1908         case GL_INT:
1909             return kInt;
1910         case GL_UNSIGNED_INT:
1911             return kUInt;
1912         case GL_SHORT:
1913             return kShort;
1914         case GL_UNSIGNED_SHORT:
1915             return kUShort;
1916         case GL_BYTE:
1917             return kChar;
1918         case GL_UNSIGNED_BYTE:
1919             return kUChar;
1920 #if defined( __APPLE__ )
1921         case GL_HALF_FLOAT:
1922 #else
1923         case GL_HALF_FLOAT_ARB:
1924 #endif
1925             return kHalf;
1926         default:
1927             return kFloat;
1928     };
1929 }
1930 
get_base_gl_target(GLenum target)1931 GLenum get_base_gl_target( GLenum target )
1932 {
1933     switch( target )
1934     {
1935         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1936         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1937         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1938         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1939         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1940         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1941             return GL_TEXTURE_CUBE_MAP;
1942         default:
1943             return target;
1944     }
1945 }
1946 
GetGLTypeName(GLenum type)1947 const char *GetGLTypeName( GLenum type )
1948 {
1949     switch( type )
1950     {
1951         case GL_BYTE:            return "GL_BYTE";
1952         case GL_UNSIGNED_BYTE:   return "GL_UNSIGNED_BYTE";
1953         case GL_INT:             return "GL_INT";
1954         case GL_UNSIGNED_INT:    return "GL_UNSIGNED_INT";
1955         case GL_SHORT:           return "GL_SHORT";
1956         case GL_UNSIGNED_SHORT:  return "GL_UNSIGNED_SHORT";
1957 #if defined( __APPLE__ )
1958         case GL_HALF_FLOAT:      return "GL_HALF_FLOAT";
1959 #else
1960         case GL_HALF_FLOAT_ARB:  return "GL_HALF_FLOAT_ARB";
1961 #endif
1962         case GL_FLOAT:           return "GL_FLOAT";
1963         case GL_UNSIGNED_INT_8_8_8_8:        return "GL_UNSIGNED_INT_8_8_8_8";
1964         case GL_UNSIGNED_INT_8_8_8_8_REV:    return "GL_UNSIGNED_INT_8_8_8_8_REV";
1965         case GL_UNSIGNED_INT_10_10_10_2:     return "GL_UNSIGNED_INT_10_10_10_2";
1966         case GL_UNSIGNED_INT_2_10_10_10_REV: return "GL_UNSIGNED_INT_2_10_10_10_REV";
1967 #ifdef GL_VERSION_3_2
1968         case GL_UNSIGNED_INT_24_8: return "GL_UNSIGNED_INT_24_8";
1969         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return "GL_FLOAT_32_UNSIGNED_INT_24_8_REV";
1970 #endif
1971         default:
1972         {
1973             static char foo[ 128 ];
1974             sprintf( foo, "0x%04x", (int)type);
1975             return foo;
1976         }
1977     }
1978 }
1979 
GetGLTargetName(GLenum tgt)1980 const char *GetGLTargetName( GLenum tgt )
1981 {
1982     if( tgt == GL_TEXTURE_BUFFER ) return "GL_TEXTURE_BUFFER";
1983     if( tgt == GL_TEXTURE_1D ) return "GL_TEXTURE_1D";
1984     if( tgt == GL_TEXTURE_2D ) return "GL_TEXTURE_2D";
1985     if( tgt == GL_TEXTURE_3D ) return "GL_TEXTURE_3D";
1986     if( tgt == GL_TEXTURE_RECTANGLE_EXT ) return "GL_TEXTURE_RECTANGLE_EXT";
1987     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_X ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
1988     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
1989     if( tgt == GL_TEXTURE_CUBE_MAP_POSITIVE_Z ) return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
1990     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
1991     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
1992     if( tgt == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
1993     if( tgt == GL_TEXTURE_2D_MULTISAMPLE ) return "GL_TEXTURE_2D_MULTISAMPLE";
1994     if( tgt == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ) return "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
1995 
1996     static char foo[ 128 ];
1997     sprintf( foo, "0x%04x", (int)tgt);
1998     return foo;
1999 }
2000 
GetGLAttachmentName(GLenum att)2001 const char *GetGLAttachmentName( GLenum att )
2002 {
2003     if( att == GL_COLOR_ATTACHMENT0_EXT ) return "GL_COLOR_ATTACHMENT0_EXT";
2004     if( att == GL_COLOR_ATTACHMENT1_EXT ) return "GL_COLOR_ATTACHMENT1_EXT";
2005     if( att == GL_COLOR_ATTACHMENT2_EXT ) return "GL_COLOR_ATTACHMENT2_EXT";
2006     if( att == GL_COLOR_ATTACHMENT3_EXT ) return "GL_COLOR_ATTACHMENT3_EXT";
2007     if( att == GL_COLOR_ATTACHMENT4_EXT ) return "GL_COLOR_ATTACHMENT4_EXT";
2008     if( att == GL_COLOR_ATTACHMENT5_EXT ) return "GL_COLOR_ATTACHMENT5_EXT";
2009     if( att == GL_COLOR_ATTACHMENT6_EXT ) return "GL_COLOR_ATTACHMENT6_EXT";
2010     if( att == GL_COLOR_ATTACHMENT7_EXT ) return "GL_COLOR_ATTACHMENT7_EXT";
2011     if( att == GL_COLOR_ATTACHMENT8_EXT ) return "GL_COLOR_ATTACHMENT8_EXT";
2012     if( att == GL_DEPTH_ATTACHMENT_EXT ) return "GL_DEPTH_ATTACHMENT_EXT";
2013     return "";
2014 }
GetGLBaseFormatName(GLenum baseformat)2015 const char *GetGLBaseFormatName( GLenum baseformat )
2016 {
2017     switch( baseformat )
2018     {
2019         case GL_RGBA8:          return "GL_RGBA";
2020         case GL_RGBA16:         return "GL_RGBA";
2021         case GL_RGBA:           return "GL_RGBA";
2022         case GL_BGRA:           return "GL_BGRA";
2023         case GL_RGBA8I_EXT:     return "GL_RGBA_INTEGER_EXT";
2024         case GL_RGBA16I_EXT:    return "GL_RGBA_INTEGER_EXT";
2025         case GL_RGBA32I_EXT:    return "GL_RGBA_INTEGER_EXT";
2026         case GL_RGBA8UI_EXT:    return "GL_RGBA_INTEGER_EXT";
2027         case GL_RGBA16UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2028         case GL_RGBA32UI_EXT:   return "GL_RGBA_INTEGER_EXT";
2029         case GL_RGBA32F_ARB:    return "GL_RGBA";
2030 
2031         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2032 
2033         case GL_ALPHA4: return "GL_ALPHA";
2034         case GL_ALPHA8: return "GL_ALPHA";
2035         case GL_ALPHA12: return "GL_ALPHA";
2036         case GL_ALPHA16: return "GL_ALPHA";
2037         case GL_LUMINANCE4: return "GL_LUMINANCE";
2038         case GL_LUMINANCE8: return "GL_LUMINANCE";
2039         case GL_LUMINANCE12: return "GL_LUMINANCE";
2040         case GL_LUMINANCE16: return "GL_LUMINANCE";
2041         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE_ALPHA";
2042         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE_ALPHA";
2043         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE_ALPHA";
2044         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE_ALPHA";
2045         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE_ALPHA";
2046         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE_ALPHA";
2047         case GL_INTENSITY: return "GL_INTENSITY";
2048         case GL_INTENSITY4: return "GL_INTENSITY";
2049         case GL_INTENSITY8: return "GL_INTENSITY";
2050         case GL_INTENSITY12: return "GL_INTENSITY";
2051         case GL_INTENSITY16: return "GL_INTENSITY";
2052         case GL_R3_G3_B2: return "GL_RGB";
2053         case GL_RGB4: return "GL_RGB";
2054         case GL_RGB5: return "GL_RGB";
2055         case GL_RGB8: return "GL_RGB";
2056         case GL_RGB10: return "GL_RGB";
2057         case GL_RGB12: return "GL_RGB";
2058         case GL_RGB16: return "GL_RGB";
2059         case GL_RGBA2: return "GL_RGBA";
2060         case GL_RGBA4: return "GL_RGBA";
2061         case GL_RGB5_A1: return "GL_RGBA";
2062         case GL_RGB10_A2: return "GL_RGBA";
2063         case GL_RGBA12: return "GL_RGBA";
2064 #ifdef GL_VERSION_3_2
2065         case GL_DEPTH_COMPONENT: return "GL_DEPTH_COMPONENT";
2066         case GL_DEPTH_COMPONENT16: return "GL_DEPTH_COMPONENT";
2067         case GL_DEPTH_COMPONENT24: return "GL_DEPTH_COMPONENT";
2068         case GL_DEPTH_COMPONENT32: return "GL_DEPTH_COMPONENT";
2069         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT";
2070         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2071         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH_STENCIL";
2072         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH_STENCIL";
2073 #endif
2074         default:
2075         {
2076             static char foo[ 128 ];
2077             sprintf( foo, "0x%04x", (int)baseformat );
2078             return foo;
2079         }
2080     }
2081 }
2082 
GetGLFormatName(GLenum format)2083 const char *GetGLFormatName( GLenum format )
2084 {
2085     switch( format )
2086     {
2087         case GL_RGBA8:          return "GL_RGBA8";
2088         case GL_RGBA16:         return "GL_RGBA16";
2089         case GL_RGBA:           return "GL_RGBA";
2090         case GL_BGRA:           return "GL_BGRA";
2091         case GL_RGBA8I_EXT:     return "GL_RGBA8I_EXT";
2092         case GL_RGBA16I_EXT:    return "GL_RGBA16I_EXT";
2093         case GL_RGBA32I_EXT:    return "GL_RGBA32I_EXT";
2094         case GL_RGBA8UI_EXT:    return "GL_RGBA8UI_EXT";
2095         case GL_RGBA16UI_EXT:   return "GL_RGBA16UI_EXT";
2096         case GL_RGBA32UI_EXT:   return "GL_RGBA32UI_EXT";
2097         case GL_RGBA16F:        return "GL_RGBA16F";
2098         case GL_RGBA32F:        return "GL_RGBA32F";
2099 
2100         case GL_RGBA_INTEGER_EXT:   return "GL_RGBA_INTEGER_EXT";
2101 
2102         case GL_ALPHA4: return "GL_ALPHA4";
2103         case GL_ALPHA8: return "GL_ALPHA8";
2104         case GL_ALPHA12: return "GL_ALPHA12";
2105         case GL_ALPHA16: return "GL_ALPHA16";
2106         case GL_LUMINANCE4: return "GL_LUMINANCE4";
2107         case GL_LUMINANCE8: return "GL_LUMINANCE8";
2108         case GL_LUMINANCE12: return "GL_LUMINANCE12";
2109         case GL_LUMINANCE16: return "GL_LUMINANCE16";
2110         case GL_LUMINANCE4_ALPHA4: return "GL_LUMINANCE4_ALPHA4";
2111         case GL_LUMINANCE6_ALPHA2: return "GL_LUMINANCE6_ALPHA2";
2112         case GL_LUMINANCE8_ALPHA8: return "GL_LUMINANCE8_ALPHA8";
2113         case GL_LUMINANCE12_ALPHA4: return "GL_LUMINANCE12_ALPHA4";
2114         case GL_LUMINANCE12_ALPHA12: return "GL_LUMINANCE12_ALPHA12";
2115         case GL_LUMINANCE16_ALPHA16: return "GL_LUMINANCE16_ALPHA16";
2116         case GL_INTENSITY: return "GL_INTENSITY";
2117         case GL_INTENSITY4: return "GL_INTENSITY4";
2118         case GL_INTENSITY8: return "GL_INTENSITY8";
2119         case GL_INTENSITY12: return "GL_INTENSITY12";
2120         case GL_INTENSITY16: return "GL_INTENSITY16";
2121         case GL_R3_G3_B2: return "GL_R3_G3_B2";
2122         case GL_RGB4: return "GL_RGB4";
2123         case GL_RGB5: return "GL_RGB5";
2124         case GL_RGB8: return "GL_RGB8";
2125         case GL_RGB10: return "GL_RGB10";
2126         case GL_RGB12: return "GL_RGB12";
2127         case GL_RGB16: return "GL_RGB16";
2128         case GL_RGBA2: return "GL_RGBA2";
2129         case GL_RGBA4: return "GL_RGBA4";
2130         case GL_RGB5_A1: return "GL_RGB5_A1";
2131         case GL_RGB10_A2: return "GL_RGB10_A2";
2132         case GL_RGBA12: return "GL_RGBA12";
2133 
2134         case GL_INT:            return "GL_INT";
2135         case GL_UNSIGNED_INT:   return "GL_UNSIGNED_INT";
2136         case GL_SHORT:          return "GL_SHORT";
2137         case GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT";
2138         case GL_BYTE:           return "GL_BYTE";
2139         case GL_UNSIGNED_BYTE:  return "GL_UNSIGNED_BYTE";
2140         case GL_FLOAT:          return "GL_FLOAT";
2141 #if defined( __APPLE__ )
2142         case GL_HALF_FLOAT:     return "GL_HALF_FLOAT";
2143 #else
2144         case GL_HALF_FLOAT_ARB: return "GL_HALF_FLOAT_ARB";
2145 #endif
2146 #ifdef GL_VERSION_3_2
2147         case GL_DEPTH_STENCIL:      return "GL_DEPTH_STENCIL";
2148         case GL_DEPTH_COMPONENT:    return "GL_DEPTH_COMPONENT";
2149         case GL_DEPTH_COMPONENT16:  return "GL_DEPTH_COMPONENT16";
2150         case GL_DEPTH_COMPONENT24:  return "GL_DEPTH_COMPONENT24";
2151         case GL_DEPTH_COMPONENT32:  return "GL_DEPTH_COMPONENT32";
2152         case GL_DEPTH_COMPONENT32F: return "GL_DEPTH_COMPONENT32F";
2153         case GL_DEPTH24_STENCIL8:   return "GL_DEPTH24_STENCIL8";
2154         case GL_DEPTH32F_STENCIL8:  return "GL_DEPTH32F_STENCIL8";
2155 #endif
2156         default:
2157         {
2158             static char foo[ 128 ];
2159             sprintf( foo, "0x%04x", (int)format);
2160             return foo;
2161         }
2162     }
2163 }
2164 
CreateRandomData(ExplicitType type,size_t count,MTdata d)2165 void* CreateRandomData( ExplicitType type, size_t count, MTdata d )
2166 {
2167     switch(type)
2168     {
2169         case (kChar):
2170         {
2171             cl_char *p = (cl_char *)malloc(count * sizeof(cl_char));
2172             if(!p) return 0;
2173 
2174             for( size_t i = 0; i < count; i++ )
2175             {
2176                 p[ i ] = (cl_char)genrand_int32(d);
2177             }
2178             return (void*)p;
2179         }
2180         case (kUChar):
2181         case (kUnsignedChar):
2182         {
2183             cl_uchar *p = (cl_uchar *)malloc(count * sizeof(cl_uchar));
2184             if(!p) return 0;
2185 
2186             for( size_t i = 0; i < count; i++ )
2187             {
2188                 p[ i ] =  (cl_uchar)genrand_int32(d);
2189             }
2190 
2191             return (void*)p;
2192         }
2193         case (kShort):
2194         {
2195             cl_short *p = (cl_short *)malloc(count * sizeof(cl_short));
2196             if(!p) return 0;
2197 
2198             for( size_t i = 0; i < count; i++ )
2199             {
2200                 p[ i ] = (cl_short)genrand_int32(d);
2201             }
2202 
2203             return (void*)p;
2204         }
2205         case (kUShort):
2206         case (kUnsignedShort):
2207         {
2208             cl_ushort *p = (cl_ushort *)malloc(count * sizeof(cl_ushort));
2209             if(!p) return 0;
2210 
2211             for( size_t i = 0; i < count; i++ )
2212             {
2213                 p[ i ] = (cl_ushort)genrand_int32(d);
2214             }
2215 
2216             return (void*)p;
2217         }
2218         case (kInt):
2219         {
2220             cl_int *p = (cl_int *)malloc(count * sizeof(cl_int));
2221             if(!p) return 0;
2222 
2223             for( size_t i = 0; i < count; i++ )
2224             {
2225                 p[ i ] = (cl_int)genrand_int32(d);
2226             }
2227 
2228             return (void*)p;
2229         }
2230         case (kUInt):
2231         case (kUnsignedInt):
2232         {
2233             cl_uint *p = (cl_uint *)malloc(count * sizeof(cl_uint));
2234             if(!p) return 0;
2235 
2236             for( size_t i = 0; i < count; i++ )
2237             {
2238                 p[ i ] =  (cl_uint)genrand_int32(d);
2239             }
2240 
2241             return (void*)p;
2242         }
2243 
2244         case (kFloat):
2245         {
2246             cl_float *p = (cl_float *)malloc(count * sizeof(cl_float));
2247             if(!p) return 0;
2248 
2249             for( size_t i = 0; i < count; i++ )
2250             {
2251                 p[ i ] = get_random_float( 0.f, 1.f, d );
2252             }
2253 
2254             return (void*)p;
2255         }
2256         case (kHalf):
2257         {
2258             cl_half *p = (cl_half *)malloc(count * sizeof(cl_half));
2259             if(!p) return 0;
2260 
2261             for( size_t i = 0; i < count; i++ )
2262             {
2263                 p[ i ] = convert_float_to_half( get_random_float( 0.f, 1.f, d ) );
2264             }
2265 
2266             return (void*)p;
2267         }
2268         default:
2269         {
2270             log_error("Invalid explicit type specified for create random data!\n");
2271             return 0;
2272         }
2273     }
2274     return 0;
2275 }
2276 
DumpGLBuffer(GLenum type,size_t width,size_t height,void * buffer)2277 void DumpGLBuffer(GLenum type, size_t width, size_t height, void* buffer)
2278 {
2279     size_t i;
2280     size_t count = width * height;
2281     if(type == GL_BYTE)
2282     {
2283         cl_char* p = (cl_char*)buffer;
2284         for(i = 0; i < count; i++)
2285             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2286                 p[i* 4 + 0],
2287                 p[i* 4 + 1],
2288                 p[i* 4 + 2],
2289                 p[i* 4 + 3]);
2290     }
2291     else if(type == GL_UNSIGNED_BYTE)
2292     {
2293         cl_uchar* p = (cl_uchar*)buffer;
2294         for(i = 0; i < count; i++)
2295             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2296                 p[i* 4 + 0],
2297                 p[i* 4 + 1],
2298                 p[i* 4 + 2],
2299                 p[i* 4 + 3]);
2300     }
2301     else if(type == GL_INT)
2302     {
2303         cl_int* p = (cl_int*)buffer;
2304         for(i = 0; i < count; i++)
2305             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2306                 p[i* 4 + 0],
2307                 p[i* 4 + 1],
2308                 p[i* 4 + 2],
2309                 p[i* 4 + 3]);
2310     }
2311     else if(type == GL_UNSIGNED_INT)
2312     {
2313         cl_uint* p = (cl_uint*)buffer;
2314         for(i = 0; i < count; i++)
2315             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2316                 p[i* 4 + 0],
2317                 p[i* 4 + 1],
2318                 p[i* 4 + 2],
2319                 p[i* 4 + 3]);
2320     }
2321     else if(type == GL_SHORT)
2322     {
2323         cl_short* p = (cl_short*)buffer;
2324         for(i = 0; i < count; i++)
2325             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2326                 p[i* 4 + 0],
2327                 p[i* 4 + 1],
2328                 p[i* 4 + 2],
2329                 p[i* 4 + 3]);
2330     }
2331     else if(type == GL_UNSIGNED_SHORT)
2332     {
2333         cl_ushort* p = (cl_ushort*)buffer;
2334         for(i = 0; i <  count; i++)
2335             log_info("[%4d] %3d %3d %3d %3d\n", (unsigned int)(i),
2336                 p[i* 4 + 0],
2337                 p[i* 4 + 1],
2338                 p[i* 4 + 2],
2339                 p[i* 4 + 3]);
2340     }
2341     else if(type == GL_FLOAT)
2342     {
2343         cl_float* p = (cl_float*)buffer;
2344         for(i = 0; i < count; i++)
2345             log_info("[%4d] %#f %#f %#f %#f\n", (unsigned int)(i),
2346                p[i* 4 + 0],
2347                p[i* 4 + 1],
2348                p[i* 4 + 2],
2349                p[i* 4 + 3]);
2350     }
2351 }
2352 
2353 #if defined(_WIN32)
2354 #include <string.h>
2355 
gluCheckExtension(const GLubyte * extName,const GLubyte * extString)2356 GLboolean gluCheckExtension(const GLubyte *extName, const GLubyte *extString)
2357 {
2358   const size_t len = strlen((const char*)extName);
2359   const char* str = (const char*)extString;
2360 
2361   while (str != NULL) {
2362     str = strstr(str, (const char*)extName);
2363     if (str == NULL) {
2364       break;
2365     }
2366     if ((str > (const char*)extString || str[-1] == ' ')
2367         && (str[len] == ' ' || str[len] == '\0')) {
2368       return GL_TRUE;
2369     }
2370     str = strchr(str + len, ' ');
2371   }
2372 
2373   return GL_FALSE;
2374 }
2375 
2376 #endif
2377 
2378 // Function pointers for the GL/CL calls
2379 clCreateFromGLBuffer_fn clCreateFromGLBuffer_ptr;
2380 clCreateFromGLTexture_fn clCreateFromGLTexture_ptr;
2381 clCreateFromGLTexture2D_fn clCreateFromGLTexture2D_ptr;
2382 clCreateFromGLTexture3D_fn clCreateFromGLTexture3D_ptr;
2383 clCreateFromGLRenderbuffer_fn clCreateFromGLRenderbuffer_ptr;
2384 clGetGLObjectInfo_fn clGetGLObjectInfo_ptr;
2385 clGetGLTextureInfo_fn clGetGLTextureInfo_ptr;
2386 clEnqueueAcquireGLObjects_fn clEnqueueAcquireGLObjects_ptr;
2387 clEnqueueReleaseGLObjects_fn clEnqueueReleaseGLObjects_ptr;
2388 
init_clgl_ext()2389 int init_clgl_ext() {
2390 
2391     // As OpenCL for the platforms.  Warn if more than one platform found,
2392     // since this might not be the platform we want.  By default, we simply
2393     // use the first returned platform.
2394 
2395     cl_uint nplatforms;
2396     cl_platform_id platform;
2397     clGetPlatformIDs(0, NULL, &nplatforms);
2398     clGetPlatformIDs(1, &platform, NULL);
2399 
2400     if (nplatforms > 1) {
2401         log_info("clGetPlatformIDs returned multiple values.  This is not "
2402             "an error, but might result in obtaining incorrect function "
2403             "pointers if you do not want the first returned platform.\n");
2404 
2405         // Show them the platform name, in case it is a problem.
2406 
2407         size_t size;
2408         char *name;
2409 
2410         clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
2411         name = (char*)malloc(size);
2412         clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
2413 
2414         log_info("Using platform with name: %s \n", name);
2415         free(name);
2416     }
2417 
2418     // Create the function pointer table
2419     clCreateFromGLBuffer_ptr = (clCreateFromGLBuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLBuffer");
2420     if (clCreateFromGLBuffer_ptr == NULL) {
2421         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLBuffer) returned NULL.\n");
2422         return -1;
2423     }
2424     clCreateFromGLTexture2D_ptr = (clCreateFromGLTexture2D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture2D");
2425     if (clCreateFromGLTexture2D_ptr == NULL) {
2426         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture2D) returned NULL.\n");
2427         return -1;
2428     }
2429     clCreateFromGLTexture3D_ptr = (clCreateFromGLTexture3D_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture3D");
2430     if (clCreateFromGLTexture3D_ptr == NULL) {
2431         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLTexture3D\") returned NULL.\n");
2432         return -1;
2433     }
2434     clCreateFromGLTexture_ptr = (clCreateFromGLTexture_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLTexture");
2435     if (clCreateFromGLTexture_ptr == NULL) {
2436          log_error("clGetExtensionFunctionAddressForPlatform(platform,\"clCreateFromGLTexture\") returned NULL.\n");
2437          return -1;
2438     }
2439     clCreateFromGLRenderbuffer_ptr = (clCreateFromGLRenderbuffer_fn)clGetExtensionFunctionAddressForPlatform(platform,"clCreateFromGLRenderbuffer");
2440     if (clCreateFromGLRenderbuffer_ptr == NULL) {
2441         log_error("clGetExtensionFunctionAddressForPlatform(platform,clCreateFromGLRenderbuffer) returned NULL.\n");
2442         return -1;
2443     }
2444     clGetGLObjectInfo_ptr = (clGetGLObjectInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLObjectInfo");
2445     if (clGetGLObjectInfo_ptr == NULL) {
2446         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLObjectInfo) returned NULL.\n");
2447         return -1;
2448     }
2449     clGetGLTextureInfo_ptr = (clGetGLTextureInfo_fn)clGetExtensionFunctionAddressForPlatform(platform,"clGetGLTextureInfo");
2450     if (clGetGLTextureInfo_ptr == NULL) {
2451         log_error("clGetExtensionFunctionAddressForPlatform(platform,clGetGLTextureInfo) returned NULL.\n");
2452         return -1;
2453     }
2454     clEnqueueAcquireGLObjects_ptr = (clEnqueueAcquireGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueAcquireGLObjects");
2455     if (clEnqueueAcquireGLObjects_ptr == NULL) {
2456         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueAcquireGLObjects) returned NULL.\n");
2457         return -1;
2458     }
2459     clEnqueueReleaseGLObjects_ptr = (clEnqueueReleaseGLObjects_fn)clGetExtensionFunctionAddressForPlatform(platform,"clEnqueueReleaseGLObjects");
2460     if (clEnqueueReleaseGLObjects_ptr == NULL) {
2461         log_error("clGetExtensionFunctionAddressForPlatform(platform,clEnqueueReleaseGLObjects) returned NULL.\n");
2462         return -1;
2463     }
2464 
2465     return 0;
2466 }
2467 
get_gl_max_samples(GLenum target,GLenum internalformat)2468 GLint get_gl_max_samples( GLenum target, GLenum internalformat )
2469 {
2470     GLint max_samples = 0;
2471 #ifdef GL_VERSION_4_2
2472     glGetInternalformativ(target, internalformat, GL_SAMPLES, 1, &max_samples);
2473 #else
2474     switch (internalformat)
2475     {
2476         case GL_RGBA8I:
2477         case GL_RGBA16I:
2478         case GL_RGBA32I:
2479         case GL_RGBA8UI:
2480         case GL_RGBA16UI:
2481         case GL_RGBA32UI:
2482             glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &max_samples);
2483             break;
2484         case GL_DEPTH_COMPONENT16:
2485         case GL_DEPTH_COMPONENT32F:
2486         case GL_DEPTH24_STENCIL8:
2487         case GL_DEPTH32F_STENCIL8:
2488             glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &max_samples);
2489             break;
2490         default:
2491             glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_samples);
2492             break;
2493     }
2494 #endif
2495     return max_samples;
2496 }
2497