Skip to content

Instantly share code, notes, and snippets.

@rygorous
Created January 29, 2014 19:38
Show Gist options
  • Save rygorous/8695327 to your computer and use it in GitHub Desktop.
Save rygorous/8695327 to your computer and use it in GitHub Desktop.
#define IGNORE_ERRORS
static S32 check_prog_ok( GLuint * prog )
{
#ifndef IGNORE_ERRORS
GLint ok = 0;
glGetProgramiv( *prog, GL_LINK_STATUS, &ok );
if ( !ok )
{
char errors[ 512 ];
glGetProgramInfoLog( *prog, sizeof( errors ) - 2, &ok, errors );
shader_compilation_err( errors );
glDeleteProgram( *prog );
*prog = 0;
return 0;
}
#endif
return 1;
}
static S32 start_compile_program( GLuint * prog, char const * const * strings, int count )
{
char const * strings_temp[ 32 ];
if ( *prog )
return 1;
if ( s_workarounds & BINKGPU_GL_WORKAROUND_ARRAYSIZE )
{
// for array size workaround, add a special #define at start of shaders.
int i;
strings_temp[0] = "#define BLOCK_INTARR_LEN(x) (((x)+3)/4)\n";
for ( i = 0 ; i < count ; i++ )
strings_temp[i + 1] = strings[i];
strings = strings_temp;
++count;
}
*prog = glCreateShaderProgramv( GL_COMPUTE_SHADER, count, strings );
return *prog != 0;
}
static GLuint compile_shader( GLenum type, char const * const * strings, int count )
{
GLuint shader;
GLint ok = 0;
shader = glCreateShader( type );
glShaderSource( shader, count, strings, 0 );
glCompileShader( shader );
#ifndef IGNORE_ERRORS
glGetShaderiv( shader, GL_COMPILE_STATUS, &ok );
if ( !ok )
{
char errors[ 512 ];
glGetShaderInfoLog( shader, sizeof( errors ) - 2, &ok, errors );
shader_compilation_err( errors );
glDeleteShader( shader );
shader = 0;
}
#endif
return shader;
}
S32 BinkGPU_GL_Init( U32 workaround_flags )
{
GLint major_ver = 0, minor_ver = 0;
int i;
// we need at least GL 4.3 for compute
glGetIntegerv( GL_MAJOR_VERSION, &major_ver );
glGetIntegerv( GL_MINOR_VERSION, &minor_ver );
if ( major_ver < 4 || ( major_ver == 4 && minor_ver < 3 ) )
return 0;
load_extensions();
s_workarounds = workaround_flags;
// kick off compilations but don't check results yet so we get
// potential parallelism.
for ( i = 0 ; i < 4 ; i++ )
{
if ( !start_compile_program( &s_progs[PROG_LUMA_DCT + i], cshader_bink2block[i], NUMFRAGMENTS_cshader_bink2block ) )
goto error;
}
if ( !start_compile_program( &s_progs[PROG_DC_PREDICT], cshader_dc_predict[0], NUMFRAGMENTS_cshader_dc_predict ) )
goto error;
if ( !start_compile_program( &s_progs[PROG_LUMA_DEBLOCK], cshader_deblock_full_plane[0], NUMFRAGMENTS_cshader_deblock_full_plane ) )
goto error;
if ( !start_compile_program( &s_progs[PROG_CHROMA_DEBLOCK], cshader_deblock_sub_plane[0], NUMFRAGMENTS_cshader_deblock_sub_plane ) )
goto error;
if ( !s_progs[PROG_DRAW] )
{
int variant = ( workaround_flags & BINKGPU_GL_WORKAROUND_TEXTUREVIEWS ) ? 1 : 0;
GLuint vert_shader = compile_shader( GL_VERTEX_SHADER, vshader_draw_gl[variant], NUMFRAGMENTS_vshader_draw_gl );
GLuint frag_shader = compile_shader( GL_FRAGMENT_SHADER, pshader_draw_gl[variant], NUMFRAGMENTS_pshader_draw_gl );
if ( vert_shader && frag_shader )
{
GLuint prog = glCreateProgram();
glAttachShader( prog, vert_shader );
glAttachShader( prog, frag_shader );
glLinkProgram( prog );
glDetachShader( prog, vert_shader );
glDetachShader( prog, frag_shader );
check_prog_ok( &prog );
s_progs[PROG_DRAW] = prog;
}
glDeleteShader( vert_shader );
glDeleteShader( frag_shader );
if ( !s_progs[PROG_DRAW] )
goto error;
}
// check for compilation errors here so we can report errors.
for ( i = PROG_COMPUTE_BEGIN ; i < PROG_COMPUTE_END ; i++ )
if ( !check_prog_ok( &s_progs[i] ) )
goto error;
return 1;
error:
BinkGPU_GL_Shutdown();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment