filename | src/drivers/gl_sl.c |
changeset | 1258:f8a9c0fd2abb |
prev | 1256:a9d29fe74bf3 |
next | 1287:dac8f363f1fe |
author | nkeynes |
date | Mon Mar 05 11:41:03 2012 +1000 (8 years ago) |
permissions | -rw-r--r-- |
last change | Small cleanups: Refactor the post-windowing setup into gl_init_driver() in video_gl.c Move gl_sl.c into src/drivers and tidy up a bit. Fix OS X compiling plugins with -mdynamic-no-pic |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/drivers/gl_sl.c Mon Mar 05 11:41:03 2012 +10001.3 @@ -0,0 +1,474 @@1.4 +/**1.5 + * $Id$1.6 + *1.7 + * GLSL wrapper code to hide the differences between the different gl/sl APIs.1.8 + *1.9 + * Copyright (c) 2007-2010 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +1.22 +#include <assert.h>1.23 +1.24 +#include "lxdream.h"1.25 +#include "display.h"1.26 +#include "pvr2/glutil.h"1.27 +#include "pvr2/shaders.h"1.28 +1.29 +#define MAX_ERROR_BUF 40961.30 +#define INVALID_SHADER 01.31 +#define INVALID_PROGRAM 01.32 +1.33 +#ifdef HAVE_OPENGL_SHADER_ARB1.34 +typedef GLhandleARB gl_program_t;1.35 +typedef GLhandleARB gl_shader_t;1.36 +#else1.37 +typedef GLuint gl_program_t;1.38 +typedef GLuint gl_shader_t;1.39 +#endif1.40 +1.41 +static gl_shader_t glsl_create_vertex_shader( const char *source );1.42 +static gl_shader_t glsl_create_fragment_shader( const char *source );1.43 +static gl_program_t glsl_create_program( gl_shader_t *shaderv );1.44 +static void glsl_use_program(gl_program_t program);1.45 +static void glsl_destroy_shader(gl_shader_t shader);1.46 +static void glsl_destroy_program(gl_program_t program);1.47 +static gboolean glsl_load_shaders( );1.48 +static void glsl_unload_shaders(void);1.49 +1.50 +typedef void (*program_cleanup_fn_t)();1.51 +static void glsl_set_cleanup_fn( program_cleanup_fn_t );1.52 +static void glsl_run_cleanup_fn( );1.53 +1.54 +#ifdef HAVE_OPENGL_SHADER_ARB1.55 +1.56 +static void glsl_print_error( char *msg, GLhandleARB obj )1.57 +{1.58 + char buf[MAX_ERROR_BUF];1.59 + GLsizei length;1.60 + glGetInfoLogARB( obj, sizeof(buf), &length, buf );1.61 + ERROR( "%s: %s", msg, buf );1.62 +}1.63 +1.64 +static gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )1.65 +{1.66 + GLint value;1.67 +1.68 + glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);1.69 + if( value == 0 ) {1.70 + glsl_print_error(msg, obj);1.71 + return FALSE;1.72 + }1.73 + return TRUE;1.74 +}1.75 +1.76 +static gboolean glsl_check_program_error( char *msg, GLhandleARB obj )1.77 +{1.78 + if( glGetError() != GL_NO_ERROR ) {1.79 + glsl_print_error(msg, obj);1.80 + }1.81 + return TRUE;1.82 +}1.83 +1.84 +static gl_shader_t glsl_create_vertex_shader( const char *source )1.85 +{1.86 + gboolean ok;1.87 + gl_shader_t shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);1.88 +1.89 + glShaderSourceARB( shader, 1, &source, NULL );1.90 + glCompileShaderARB(shader);1.91 + ok = glsl_check_shader_error("Failed to compile vertex shader", shader);1.92 + if( !ok ) {1.93 + glDeleteObjectARB(shader);1.94 + return INVALID_SHADER;1.95 + } else {1.96 + return shader;1.97 + }1.98 +}1.99 +1.100 +static gl_shader_t glsl_create_fragment_shader( const char *source )1.101 +{1.102 + gboolean ok;1.103 + gl_shader_t shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);1.104 +1.105 + glShaderSourceARB( shader, 1, &source, NULL );1.106 + glCompileShaderARB(shader);1.107 + ok = glsl_check_shader_error("Failed to compile fragment shader", shader);1.108 + if( !ok ) {1.109 + glDeleteObjectARB(shader);1.110 + return INVALID_SHADER;1.111 + } else {1.112 + return shader;1.113 + }1.114 +}1.115 +1.116 +static gl_program_t glsl_create_program( gl_shader_t *shaderv )1.117 +{1.118 + gboolean ok;1.119 + unsigned i;1.120 + gl_program_t program = glCreateProgramObjectARB();1.121 +1.122 + for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {1.123 + glAttachObjectARB(program, shaderv[i]);1.124 + }1.125 +1.126 + glLinkProgramARB(program);1.127 + ok = glsl_check_program_error( "Failed to link shader program", program );1.128 + if( !ok ) {1.129 + glDeleteObjectARB(program);1.130 + return INVALID_PROGRAM;1.131 + } else {1.132 + return program;1.133 + }1.134 +}1.135 +1.136 +static void glsl_use_program(gl_program_t program)1.137 +{1.138 + glUseProgramObjectARB(program);1.139 +}1.140 +1.141 +static void glsl_destroy_shader(gl_shader_t shader)1.142 +{1.143 + glDeleteObjectARB(shader);1.144 +}1.145 +1.146 +static void glsl_destroy_program(gl_program_t program)1.147 +{1.148 + glDeleteObjectARB(program);1.149 +}1.150 +1.151 +static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)1.152 +{1.153 + return glGetUniformLocationARB(program, name);1.154 +}1.155 +1.156 +static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)1.157 +{1.158 + return glGetAttribLocationARB(program, name);1.159 +}1.160 +1.161 +#define glsl_set_uniform_sampler1D(id,v) glUniform1iARB(id,v)1.162 +#define glsl_set_uniform_sampler2D(id,v) glUniform1iARB(id,v)1.163 +#define glsl_set_uniform_float(id,v) glUniform1fARB(id,v)1.164 +#define glsl_set_uniform_vec2(id,v) glUniform2fvARB(id,1,v)1.165 +#define glsl_set_uniform_vec3(id,v) glUniform3fvARB(id,1,v)1.166 +#define glsl_set_uniform_vec4(id,v) glUniform4fvARB(id,1,v)1.167 +#define glsl_set_uniform_mat4(id,v) glUniformMatrix4fvARB(id,1,GL_FALSE,v)1.168 +#define glsl_set_attrib_vec2(id,stride,v) glVertexAttribPointerARB(id, 2, GL_FLOAT, GL_FALSE, stride, v)1.169 +#define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointerARB(id, 3, GL_FLOAT, GL_FALSE, stride, v)1.170 +#define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointerARB(id, 4, GL_FLOAT, GL_FALSE, stride, v)1.171 +#define glsl_enable_attrib(id) glEnableVertexAttribArrayARB(id)1.172 +#define glsl_disable_attrib(id) glDisableVertexAttribArrayARB(id)1.173 +1.174 +#elif HAVE_OPENGL_SHADER1.175 +1.176 +static gboolean glsl_check_shader_error( char *msg, GLuint shader )1.177 +{1.178 + GLint value;1.179 +1.180 + glGetShaderiv( shader, GL_COMPILE_STATUS, &value );1.181 + if( value == 0 ) {1.182 + char buf[MAX_ERROR_BUF];1.183 + GLsizei length;1.184 + glGetShaderInfoLog( shader, sizeof(buf), &length, buf );1.185 + ERROR( "%s: %s", msg, buf );1.186 + return FALSE;1.187 + }1.188 + return TRUE;1.189 +}1.190 +1.191 +static gboolean glsl_check_program_error( char *msg, GLuint program )1.192 +{1.193 + if( glGetError() != GL_NO_ERROR ) {1.194 + char buf[MAX_ERROR_BUF];1.195 + GLsizei length;1.196 + glGetProgramInfoLog( program, sizeof(buf), &length, buf );1.197 + ERROR( "%s: %s", msg, buf );1.198 + return FALSE;1.199 + }1.200 + return TRUE;1.201 +}1.202 +1.203 +static gl_shader_t glsl_create_vertex_shader( const char *source )1.204 +{1.205 + gboolean ok;1.206 + gl_shader_t shader = glCreateShader(GL_VERTEX_SHADER);1.207 +1.208 + glShaderSource( shader, 1, &source, NULL );1.209 + glCompileShader(shader);1.210 + ok = glsl_check_shader_error( "Failed to compile vertex shader", shader );1.211 + if( !ok ) {1.212 + glDeleteShader(shader);1.213 + return INVALID_SHADER;1.214 + } else {1.215 + return shader;1.216 + }1.217 +1.218 +}1.219 +1.220 +static gl_shader_t glsl_create_fragment_shader( const char *source )1.221 +{1.222 + gboolean ok;1.223 + gl_shader_t shader = glCreateShader(GL_FRAGMENT_SHADER);1.224 +1.225 + glShaderSource( shader, 1, &source, NULL );1.226 + glCompileShader(shader);1.227 + ok = glsl_check_shader_error( "Failed to compile fragment shader", shader );1.228 + if( !ok ) {1.229 + glDeleteShader(shader);1.230 + return INVALID_SHADER;1.231 + } else {1.232 + return shader;1.233 + }1.234 +}1.235 +1.236 +static gl_program_t glsl_create_program( gl_shader_t *shaderv )1.237 +{1.238 + gboolean ok;1.239 + unsigned i;1.240 + gl_program_t program = glCreateProgram();1.241 +1.242 + for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {1.243 + glAttachShader(program, shaderv[i]);1.244 + }1.245 + glLinkProgram(program);1.246 + ok = glsl_check_program_error( "Failed to link shader program", program );1.247 + if( !ok ) {1.248 + glDeleteProgram(program);1.249 + return INVALID_PROGRAM;1.250 + } else {1.251 + return program;1.252 + }1.253 +}1.254 +1.255 +static void glsl_use_program(gl_program_t program)1.256 +{1.257 + glUseProgram(program);1.258 +}1.259 +1.260 +static void glsl_destroy_shader(gl_shader_t shader)1.261 +{1.262 + glDeleteShader(shader);1.263 +}1.264 +1.265 +static void glsl_destroy_program(gl_program_t program)1.266 +{1.267 + glDeleteProgram(program);1.268 +}1.269 +1.270 +static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)1.271 +{1.272 + return glGetUniformLocation(program, name);1.273 +}1.274 +static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)1.275 +{1.276 + return glGetAttribLocation(program, name);1.277 +}1.278 +1.279 +#define glsl_set_uniform_sampler1D(id,v) glUniform1i(id,v)1.280 +#define glsl_set_uniform_sampler2D(id,v) glUniform1i(id,v)1.281 +#define glsl_set_uniform_float(id,v) glUniform1f(id,v)1.282 +#define glsl_set_uniform_vec2(id,v) glUniform2fv(id,1,v)1.283 +#define glsl_set_uniform_vec3(id,v) glUniform3fv(id,1,v)1.284 +#define glsl_set_uniform_vec4(id,v) glUniform4fv(id,1,v)1.285 +#define glsl_set_uniform_mat4(id,v) glUniformMatrix4fv(id,1,GL_FALSE,v)1.286 +#define glsl_set_attrib_vec2(id,stride,v) glVertexAttribPointer(id, 2, GL_FLOAT, GL_FALSE, stride, v)1.287 +#define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointer(id, 3, GL_FLOAT, GL_FALSE, stride, v)1.288 +#define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointer(id, 4, GL_FLOAT, GL_FALSE, stride, v)1.289 +#define glsl_enable_attrib(id) glEnableVertexAttribArray(id)1.290 +#define glsl_disable_attrib(id) glDisableVertexAttribArray(id)1.291 +1.292 +1.293 +#else1.294 +1.295 +static gl_shader_t glsl_create_vertex_shader( const char *source )1.296 +{1.297 + return 0;1.298 +}1.299 +1.300 +static gl_shader_t glsl_create_fragment_shader( const char *source )1.301 +{1.302 + return 0;1.303 +}1.304 +1.305 +static gl_program_t glsl_create_program( gl_shader_t *shaderv )1.306 +{1.307 + return 0;1.308 +}1.309 +1.310 +static void glsl_use_program(gl_program_t program)1.311 +{1.312 +}1.313 +1.314 +static void glsl_destroy_shader(gl_shader_t shader)1.315 +{1.316 +}1.317 +1.318 +static void glsl_destroy_program(gl_program_t program)1.319 +{1.320 +}1.321 +1.322 +static static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)1.323 +{1.324 + return 0;1.325 +}1.326 +1.327 +static static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)1.328 +{1.329 + return 0;1.330 +}1.331 +1.332 +#define glsl_set_uniform_sampler1D(id,v)1.333 +#define glsl_set_uniform_sampler2D(id,v)1.334 +#define glsl_set_uniform_float(id,v)1.335 +#define glsl_set_uniform_vec2(id,v)1.336 +#define glsl_set_uniform_vec3(id,v)1.337 +#define glsl_set_uniform_vec4(id,v)1.338 +#define glsl_set_uniform_mat4(id,v)1.339 +#define glsl_set_attrib_vec2(id,stride,v)1.340 +#define glsl_set_attrib_vec3(id,stride,v)1.341 +#define glsl_set_attrib_vec4(id,stride,v)1.342 +#define glsl_enable_attrib(id)1.343 +#define glsl_disable_attrib(id)1.344 +1.345 +1.346 +#endif1.347 +1.348 +/****************************************************************************/1.349 +1.350 +program_cleanup_fn_t current_cleanup_fn = NULL;1.351 +1.352 +/* Pull in the auto-generated shader definitions */1.353 +1.354 +#include "pvr2/shaders.def"1.355 +1.356 +static gl_program_t program_array[GLSL_NUM_PROGRAMS];1.357 +1.358 +static gboolean glsl_load_shaders()1.359 +{1.360 + gl_shader_t shader_array[GLSL_NUM_SHADERS];1.361 + gboolean ok = TRUE;1.362 + unsigned i, j;1.363 + for( i=0; i<GLSL_NUM_SHADERS; i++ )1.364 + shader_array[i] = INVALID_SHADER;1.365 + for( i=0; i<GLSL_NUM_PROGRAMS; i++ )1.366 + program_array[i] = INVALID_PROGRAM;1.367 +1.368 + /* Compile the shader fragments */1.369 + for( i=0; shader_source[i].type != GLSL_NO_SHADER; i++ ) {1.370 + gl_shader_t shader = INVALID_SHADER;1.371 + switch(shader_source[i].type) {1.372 + case GLSL_VERTEX_SHADER:1.373 + shader = glsl_create_vertex_shader(shader_source[i].source);1.374 + break;1.375 + case GLSL_FRAGMENT_SHADER:1.376 + shader = glsl_create_fragment_shader(shader_source[i].source);1.377 + break;1.378 + }1.379 + if( shader == INVALID_SHADER ) {1.380 + ok = FALSE;1.381 + break;1.382 + } else {1.383 + shader_array[i] = shader;1.384 + }1.385 + }1.386 +1.387 + /* Link the programs */1.388 + if(ok) for( i=0; program_list[i][0] != GLSL_NO_SHADER; i++ ) {1.389 + gl_shader_t shaderv[GLSL_NUM_SHADERS+1];1.390 + for( j=0; program_list[i][j] != GLSL_NO_SHADER; j++ ) {1.391 + shaderv[j] = shader_array[program_list[i][j]];1.392 + }1.393 + shaderv[j] = INVALID_SHADER;1.394 + gl_program_t program = glsl_create_program(shaderv);1.395 + if( program == INVALID_PROGRAM ) {1.396 + ok = FALSE;1.397 + break;1.398 + } else {1.399 + /* Check that we can actually use the program (can this really fail?) */1.400 + glsl_use_program(program);1.401 + if( !glsl_check_program_error( "Failed to activate shader program", program ) ) {1.402 + ok = FALSE;1.403 + }1.404 + program_array[i] = program;1.405 + }1.406 + }1.407 +1.408 + /**1.409 + * Destroy the compiled fragments (the linked programs don't need them1.410 + * anymore)1.411 + */1.412 + for( i=0; i<GLSL_NUM_SHADERS; i++ ) {1.413 + if( shader_array[i] != INVALID_SHADER )1.414 + glsl_destroy_shader(shader_array[i]);1.415 + }1.416 +1.417 + /**1.418 + * If we errored, delete the programs. It's all or nothing.1.419 + */1.420 + if( !ok ) {1.421 + glsl_unload_shaders();1.422 + return FALSE;1.423 + }1.424 +1.425 + glsl_init_programs(program_array);1.426 + glsl_use_program(0);1.427 + return TRUE;1.428 +}1.429 +1.430 +static void glsl_set_cleanup_fn( program_cleanup_fn_t fn )1.431 +{1.432 + if( fn != current_cleanup_fn ) {1.433 + if( current_cleanup_fn != NULL ) {1.434 + current_cleanup_fn();1.435 + }1.436 + current_cleanup_fn = fn;1.437 + }1.438 +}1.439 +1.440 +static void glsl_run_cleanup_fn()1.441 +{1.442 + if( current_cleanup_fn ) {1.443 + current_cleanup_fn();1.444 + }1.445 + current_cleanup_fn = NULL;1.446 +}1.447 +1.448 +static void glsl_unload_shaders()1.449 +{1.450 + unsigned i;1.451 + glsl_run_cleanup_fn();1.452 + for( i=0; i<GLSL_NUM_PROGRAMS; i++ ) {1.453 + if( program_array[i] != INVALID_PROGRAM ) {1.454 + glsl_destroy_program(program_array[i]);1.455 + program_array[i] = INVALID_PROGRAM;1.456 + }1.457 + }1.458 +}1.459 +1.460 +gboolean glsl_init( display_driver_t driver )1.461 +{1.462 + gboolean result;1.463 + if( isGLShaderSupported() && isGLMultitextureSupported() ) {1.464 + if( !glsl_load_shaders( ) ) {1.465 + WARN( "Unable to load GL shaders" );1.466 + result = FALSE;1.467 + } else {1.468 + INFO( "Shaders loaded successfully" );1.469 + result = TRUE;1.470 + }1.471 + } else {1.472 + INFO( "Shaders not supported" );1.473 + result = FALSE;1.474 + }1.475 + driver->capabilities.has_sl = result;1.476 + return result;1.477 +}
.