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