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