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