filename | src/drivers/gl_sl.c |
changeset | 1287:dac8f363f1fe |
prev | 1258:f8a9c0fd2abb |
author | nkeynes |
date | Sun May 24 19:46:06 2015 +1000 (8 years ago) |
permissions | -rw-r--r-- |
last change | Remove static from gl_load_frame_buffer() - also needed by video_egl.c Fix error location in gl_frame_buffer_to_tex |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * GLSL wrapper code to hide the differences between the different gl/sl APIs.
5 *
6 * Copyright (c) 2007-2010 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <assert.h>
21 #include "lxdream.h"
22 #include "display.h"
23 #include "pvr2/glutil.h"
24 #include "pvr2/shaders.h"
26 #define MAX_ERROR_BUF 4096
27 #define INVALID_SHADER 0
28 #define INVALID_PROGRAM 0
30 #ifdef HAVE_OPENGL_SHADER_ARB
31 typedef GLhandleARB gl_program_t;
32 typedef GLhandleARB gl_shader_t;
33 #else
34 typedef GLuint gl_program_t;
35 typedef GLuint gl_shader_t;
36 #endif
38 static gl_shader_t glsl_create_vertex_shader( const char *source );
39 static gl_shader_t glsl_create_fragment_shader( const char *source );
40 static gl_program_t glsl_create_program( gl_shader_t *shaderv );
41 static void glsl_use_program(gl_program_t program);
42 static void glsl_destroy_shader(gl_shader_t shader);
43 static void glsl_destroy_program(gl_program_t program);
44 static gboolean glsl_load_shaders( );
45 static void glsl_unload_shaders(void);
47 typedef void (*program_cleanup_fn_t)();
48 static void glsl_set_cleanup_fn( program_cleanup_fn_t );
49 static void glsl_run_cleanup_fn( );
51 #ifdef HAVE_OPENGL_SHADER_ARB
53 static void glsl_print_error( char *msg, GLhandleARB obj )
54 {
55 char buf[MAX_ERROR_BUF];
56 GLsizei length;
57 glGetInfoLogARB( obj, sizeof(buf), &length, buf );
58 ERROR( "%s: %s", msg, buf );
59 }
61 static gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
62 {
63 GLint value;
65 glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
66 if( value == 0 ) {
67 glsl_print_error(msg, obj);
68 return FALSE;
69 }
70 return TRUE;
71 }
73 static gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
74 {
75 if( glGetError() != GL_NO_ERROR ) {
76 glsl_print_error(msg, obj);
77 }
78 return TRUE;
79 }
81 static gl_shader_t glsl_create_vertex_shader( const char *source )
82 {
83 gboolean ok;
84 gl_shader_t shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
86 glShaderSourceARB( shader, 1, &source, NULL );
87 glCompileShaderARB(shader);
88 ok = glsl_check_shader_error("Failed to compile vertex shader", shader);
89 if( !ok ) {
90 glDeleteObjectARB(shader);
91 return INVALID_SHADER;
92 } else {
93 return shader;
94 }
95 }
97 static gl_shader_t glsl_create_fragment_shader( const char *source )
98 {
99 gboolean ok;
100 gl_shader_t shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
102 glShaderSourceARB( shader, 1, &source, NULL );
103 glCompileShaderARB(shader);
104 ok = glsl_check_shader_error("Failed to compile fragment shader", shader);
105 if( !ok ) {
106 glDeleteObjectARB(shader);
107 return INVALID_SHADER;
108 } else {
109 return shader;
110 }
111 }
113 static gl_program_t glsl_create_program( gl_shader_t *shaderv )
114 {
115 gboolean ok;
116 unsigned i;
117 gl_program_t program = glCreateProgramObjectARB();
119 for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
120 glAttachObjectARB(program, shaderv[i]);
121 }
123 glLinkProgramARB(program);
124 ok = glsl_check_program_error( "Failed to link shader program", program );
125 if( !ok ) {
126 glDeleteObjectARB(program);
127 return INVALID_PROGRAM;
128 } else {
129 return program;
130 }
131 }
133 static void glsl_use_program(gl_program_t program)
134 {
135 glUseProgramObjectARB(program);
136 }
138 static void glsl_destroy_shader(gl_shader_t shader)
139 {
140 glDeleteObjectARB(shader);
141 }
143 static void glsl_destroy_program(gl_program_t program)
144 {
145 glDeleteObjectARB(program);
146 }
148 static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
149 {
150 return glGetUniformLocationARB(program, name);
151 }
153 static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
154 {
155 return glGetAttribLocationARB(program, name);
156 }
158 #define glsl_set_uniform_sampler1D(id,v) glUniform1iARB(id,v)
159 #define glsl_set_uniform_sampler2D(id,v) glUniform1iARB(id,v)
160 #define glsl_set_uniform_float(id,v) glUniform1fARB(id,v)
161 #define glsl_set_uniform_vec2(id,v) glUniform2fvARB(id,1,v)
162 #define glsl_set_uniform_vec3(id,v) glUniform3fvARB(id,1,v)
163 #define glsl_set_uniform_vec4(id,v) glUniform4fvARB(id,1,v)
164 #define glsl_set_uniform_mat4(id,v) glUniformMatrix4fvARB(id,1,GL_FALSE,v)
165 #define glsl_set_attrib_vec2(id,stride,v) glVertexAttribPointerARB(id, 2, GL_FLOAT, GL_FALSE, stride, v)
166 #define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointerARB(id, 3, GL_FLOAT, GL_FALSE, stride, v)
167 #define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointerARB(id, 4, GL_FLOAT, GL_FALSE, stride, v)
168 #define glsl_enable_attrib(id) glEnableVertexAttribArrayARB(id)
169 #define glsl_disable_attrib(id) glDisableVertexAttribArrayARB(id)
171 #elif HAVE_OPENGL_SHADER
173 static gboolean glsl_check_shader_error( char *msg, GLuint shader )
174 {
175 GLint value;
177 glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
178 if( value == 0 ) {
179 char buf[MAX_ERROR_BUF];
180 GLsizei length;
181 glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
182 ERROR( "%s: %s", msg, buf );
183 return FALSE;
184 }
185 return TRUE;
186 }
188 static gboolean glsl_check_program_error( char *msg, GLuint program )
189 {
190 if( glGetError() != GL_NO_ERROR ) {
191 char buf[MAX_ERROR_BUF];
192 GLsizei length;
193 glGetProgramInfoLog( program, sizeof(buf), &length, buf );
194 ERROR( "%s: %s", msg, buf );
195 return FALSE;
196 }
197 return TRUE;
198 }
200 static gl_shader_t glsl_create_vertex_shader( const char *source )
201 {
202 gboolean ok;
203 gl_shader_t shader = glCreateShader(GL_VERTEX_SHADER);
205 glShaderSource( shader, 1, &source, NULL );
206 glCompileShader(shader);
207 ok = glsl_check_shader_error( "Failed to compile vertex shader", shader );
208 if( !ok ) {
209 glDeleteShader(shader);
210 return INVALID_SHADER;
211 } else {
212 return shader;
213 }
215 }
217 static gl_shader_t glsl_create_fragment_shader( const char *source )
218 {
219 gboolean ok;
220 gl_shader_t shader = glCreateShader(GL_FRAGMENT_SHADER);
222 glShaderSource( shader, 1, &source, NULL );
223 glCompileShader(shader);
224 ok = glsl_check_shader_error( "Failed to compile fragment shader", shader );
225 if( !ok ) {
226 glDeleteShader(shader);
227 return INVALID_SHADER;
228 } else {
229 return shader;
230 }
231 }
233 static gl_program_t glsl_create_program( gl_shader_t *shaderv )
234 {
235 gboolean ok;
236 unsigned i;
237 gl_program_t program = glCreateProgram();
239 for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
240 glAttachShader(program, shaderv[i]);
241 }
242 glLinkProgram(program);
243 ok = glsl_check_program_error( "Failed to link shader program", program );
244 if( !ok ) {
245 glDeleteProgram(program);
246 return INVALID_PROGRAM;
247 } else {
248 return program;
249 }
250 }
252 static void glsl_use_program(gl_program_t program)
253 {
254 glUseProgram(program);
255 }
257 static void glsl_destroy_shader(gl_shader_t shader)
258 {
259 glDeleteShader(shader);
260 }
262 static void glsl_destroy_program(gl_program_t program)
263 {
264 glDeleteProgram(program);
265 }
267 static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
268 {
269 return glGetUniformLocation(program, name);
270 }
271 static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
272 {
273 return glGetAttribLocation(program, name);
274 }
276 #define glsl_set_uniform_sampler1D(id,v) glUniform1i(id,v)
277 #define glsl_set_uniform_sampler2D(id,v) glUniform1i(id,v)
278 #define glsl_set_uniform_float(id,v) glUniform1f(id,v)
279 #define glsl_set_uniform_vec2(id,v) glUniform2fv(id,1,v)
280 #define glsl_set_uniform_vec3(id,v) glUniform3fv(id,1,v)
281 #define glsl_set_uniform_vec4(id,v) glUniform4fv(id,1,v)
282 #define glsl_set_uniform_mat4(id,v) glUniformMatrix4fv(id,1,GL_FALSE,v)
283 #define glsl_set_attrib_vec2(id,stride,v) glVertexAttribPointer(id, 2, GL_FLOAT, GL_FALSE, stride, v)
284 #define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointer(id, 3, GL_FLOAT, GL_FALSE, stride, v)
285 #define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointer(id, 4, GL_FLOAT, GL_FALSE, stride, v)
286 #define glsl_enable_attrib(id) glEnableVertexAttribArray(id)
287 #define glsl_disable_attrib(id) glDisableVertexAttribArray(id)
290 #else
292 static gl_shader_t glsl_create_vertex_shader( const char *source )
293 {
294 return 0;
295 }
297 static gl_shader_t glsl_create_fragment_shader( const char *source )
298 {
299 return 0;
300 }
302 static gl_program_t glsl_create_program( gl_shader_t *shaderv )
303 {
304 return 0;
305 }
307 static void glsl_use_program(gl_program_t program)
308 {
309 }
311 static void glsl_destroy_shader(gl_shader_t shader)
312 {
313 }
315 static void glsl_destroy_program(gl_program_t program)
316 {
317 }
319 static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
320 {
321 return 0;
322 }
324 static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
325 {
326 return 0;
327 }
329 #define glsl_set_uniform_sampler1D(id,v)
330 #define glsl_set_uniform_sampler2D(id,v)
331 #define glsl_set_uniform_float(id,v)
332 #define glsl_set_uniform_vec2(id,v)
333 #define glsl_set_uniform_vec3(id,v)
334 #define glsl_set_uniform_vec4(id,v)
335 #define glsl_set_uniform_mat4(id,v)
336 #define glsl_set_attrib_vec2(id,stride,v)
337 #define glsl_set_attrib_vec3(id,stride,v)
338 #define glsl_set_attrib_vec4(id,stride,v)
339 #define glsl_enable_attrib(id)
340 #define glsl_disable_attrib(id)
343 #endif
345 /****************************************************************************/
347 program_cleanup_fn_t current_cleanup_fn = NULL;
349 /* Pull in the auto-generated shader definitions */
351 #include "pvr2/shaders.def"
353 static gl_program_t program_array[GLSL_NUM_PROGRAMS];
355 static gboolean glsl_load_shaders()
356 {
357 gl_shader_t shader_array[GLSL_NUM_SHADERS];
358 gboolean ok = TRUE;
359 unsigned i, j;
360 for( i=0; i<GLSL_NUM_SHADERS; i++ )
361 shader_array[i] = INVALID_SHADER;
362 for( i=0; i<GLSL_NUM_PROGRAMS; i++ )
363 program_array[i] = INVALID_PROGRAM;
365 /* Compile the shader fragments */
366 for( i=0; shader_source[i].type != GLSL_NO_SHADER; i++ ) {
367 gl_shader_t shader = INVALID_SHADER;
368 switch(shader_source[i].type) {
369 case GLSL_VERTEX_SHADER:
370 shader = glsl_create_vertex_shader(shader_source[i].source);
371 break;
372 case GLSL_FRAGMENT_SHADER:
373 shader = glsl_create_fragment_shader(shader_source[i].source);
374 break;
375 }
376 if( shader == INVALID_SHADER ) {
377 ok = FALSE;
378 break;
379 } else {
380 shader_array[i] = shader;
381 }
382 }
384 /* Link the programs */
385 if(ok) for( i=0; program_list[i][0] != GLSL_NO_SHADER; i++ ) {
386 gl_shader_t shaderv[GLSL_NUM_SHADERS+1];
387 for( j=0; program_list[i][j] != GLSL_NO_SHADER; j++ ) {
388 shaderv[j] = shader_array[program_list[i][j]];
389 }
390 shaderv[j] = INVALID_SHADER;
391 gl_program_t program = glsl_create_program(shaderv);
392 if( program == INVALID_PROGRAM ) {
393 ok = FALSE;
394 break;
395 } else {
396 /* Check that we can actually use the program (can this really fail?) */
397 glsl_use_program(program);
398 if( !glsl_check_program_error( "Failed to activate shader program", program ) ) {
399 ok = FALSE;
400 }
401 program_array[i] = program;
402 }
403 }
405 /**
406 * Destroy the compiled fragments (the linked programs don't need them
407 * anymore)
408 */
409 for( i=0; i<GLSL_NUM_SHADERS; i++ ) {
410 if( shader_array[i] != INVALID_SHADER )
411 glsl_destroy_shader(shader_array[i]);
412 }
414 /**
415 * If we errored, delete the programs. It's all or nothing.
416 */
417 if( !ok ) {
418 glsl_unload_shaders();
419 return FALSE;
420 }
422 glsl_init_programs(program_array);
423 glsl_use_program(0);
424 return TRUE;
425 }
427 static void glsl_set_cleanup_fn( program_cleanup_fn_t fn )
428 {
429 if( fn != current_cleanup_fn ) {
430 if( current_cleanup_fn != NULL ) {
431 current_cleanup_fn();
432 }
433 current_cleanup_fn = fn;
434 }
435 }
437 static void glsl_run_cleanup_fn()
438 {
439 if( current_cleanup_fn ) {
440 current_cleanup_fn();
441 }
442 current_cleanup_fn = NULL;
443 }
445 static void glsl_unload_shaders()
446 {
447 unsigned i;
448 glsl_run_cleanup_fn();
449 for( i=0; i<GLSL_NUM_PROGRAMS; i++ ) {
450 if( program_array[i] != INVALID_PROGRAM ) {
451 glsl_destroy_program(program_array[i]);
452 program_array[i] = INVALID_PROGRAM;
453 }
454 }
455 }
457 gboolean glsl_init( display_driver_t driver )
458 {
459 gboolean result;
460 if( isGLShaderSupported() && isGLMultitextureSupported() ) {
461 if( !glsl_load_shaders( ) ) {
462 WARN( "Unable to load GL shaders" );
463 result = FALSE;
464 } else {
465 INFO( "Shaders loaded successfully" );
466 result = TRUE;
467 }
468 } else {
469 INFO( "Shaders not supported" );
470 result = FALSE;
471 }
472 driver->capabilities.has_sl = result;
473 return result;
474 }
.