From cbaafa7941759596e82f5c03df69cec0d439f476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 10 Mar 2015 20:58:30 +0100 Subject: [PATCH] Initial import --- Makefile | 5 + check_glsl.c | 224 ++++++++++++++++++++++++++++++++ syntax_checkers/glsl/driver.vim | 68 ++++++++++ 3 files changed, 297 insertions(+) create mode 100644 Makefile create mode 100644 check_glsl.c create mode 100644 syntax_checkers/glsl/driver.vim diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7e50e3c --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +check-glsl: check_glsl.c + $(CC) -g -O0 -lGL -lX11 -o check-glsl check_glsl.c + +clean: + rm -f check-glsl diff --git a/check_glsl.c b/check_glsl.c new file mode 100644 index 0000000..9d68311 --- /dev/null +++ b/check_glsl.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include +#include + +static int vAttributes[] = { + None +}; + +static int cAttributes[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB , 4 , + GLX_CONTEXT_MINOR_VERSION_ARB , 2 , + GLX_CONTEXT_PROFILE_MASK_ARB , + GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB , + 0 +}; + +static int bAttributes[] = { + GLX_PBUFFER_WIDTH , 32 , + GLX_PBUFFER_HEIGHT , 32 , + None +}; + + +#define gglp(t,n) \ + (t)glXGetProcAddress( "gl" n ) + + +static int errmsg( char const* msg ) +{ + fprintf( stderr , "%s\n" , msg ); + return 0; +} + + +static Display * xDisplay; +static GLXContext glxContext; +static GLXPbuffer pBuffer; +static PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv; +static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +static PFNGLDELETEPROGRAMPROC glDeleteProgram; + + +static void debugCallback( GLenum source , GLenum type , GLuint id , + GLenum severity , GLsizei length , GLchar const* message , + void const* userParam ) +{ + fprintf( stderr , "%x %x %x %x %s\n" , source , type , id , severity , + message ); +} + + +static int initContext( ) +{ + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs; + GLXFBConfig * fbc; + int fbcount; + + xDisplay = XOpenDisplay( 0 ); + if ( !xDisplay ) { + return errmsg( "Could not open display" ); + } + + fbc = glXChooseFBConfig( xDisplay , DefaultScreen( xDisplay ) , + vAttributes , &fbcount ); + if ( !fbc ) { + return errmsg( "No framebuffer config" ); + } + + glXCreateContextAttribs = gglp( PFNGLXCREATECONTEXTATTRIBSARBPROC , + "XCreateContextAttribsARB" ); + + glxContext = glXCreateContextAttribs( xDisplay , fbc[ 0 ] , NULL , + GL_TRUE , cAttributes ); + if ( !glxContext ) { + return errmsg( "Could not create GL3.0+ context" ); + } + + pBuffer = glXCreatePbuffer( xDisplay , fbc[ 0 ] , bAttributes ); + if ( !pBuffer ) { + return errmsg( "Could not create PBuffer" ); + } + + XFree( fbc ); + XSync( xDisplay , False ); + if ( ! glXMakeContextCurrent( xDisplay , pBuffer , pBuffer , + glxContext ) ) { + return errmsg( "Could not activate context" ); + } + + glCreateShaderProgramv = gglp( PFNGLCREATESHADERPROGRAMVPROC , + "CreateShaderProgramv" ); + glGetProgramInfoLog = gglp( PFNGLGETPROGRAMINFOLOGPROC , + "GetProgramInfoLog" ); + glDeleteProgram = gglp( PFNGLDELETEPROGRAMPROC , "DeleteProgram" ); + + return 1; +} + + +static void killContext( ) +{ + glXDestroyPbuffer( xDisplay , pBuffer ); + glXMakeCurrent( xDisplay , 0 , 0 ); + glXDestroyContext( xDisplay , glxContext ); + XCloseDisplay( xDisplay ); +} + + +static GLenum getShaderType( char const* argument ) +{ + if ( !strcmp( argument , "v" ) ) + return GL_VERTEX_SHADER; + if ( !strcmp( argument , "f" ) ) + return GL_FRAGMENT_SHADER; + if ( !strcmp( argument , "g" ) ) + return GL_GEOMETRY_SHADER; + if ( !strcmp( argument , "tc" ) ) + return GL_TESS_CONTROL_SHADER; + if ( !strcmp( argument , "te" ) ) + return GL_TESS_EVALUATION_SHADER; + if ( !strcmp( argument , "c" ) ) + return GL_COMPUTE_SHADER; + fprintf( stderr , "Invalid shader type '%s'\n" , argument ); + return 0; +} + +static char * loadFile( char const* name ) +{ + FILE * f = fopen( name , "r" ); + if ( !f ) { + fprintf( stderr , "%s: file not found\n" , name ); + return NULL; + } + + int sz; + fseek( f , 0 , SEEK_END ); + sz = ftell( f ); + if ( sz <= 0 ) { + fprintf( stderr , "%s: fseek failed / empty file\n" , name ); + return NULL; + } + fseek( f , 0 , SEEK_SET ); + + char * buffer = malloc( sz + 1 ); + if ( !buffer ) { + fprintf( stderr , "%s: malloc() failed (%d bytes)\n" , name , + sz ); + return NULL; + } + if ( !fread( buffer , 1 , sz , f ) ) { + fprintf( stderr , "%s: could not read file contents\n" , name ); + return NULL; + } + buffer[ sz ] = 0; + fclose(f); + + return buffer; +} + + +void loadShader( GLenum type , char const* file ) +{ + GLuint program; + char * source = loadFile( file ); + if ( source == NULL ) { + return; + } + + program = glCreateShaderProgramv( type , 1 , (GLchar const**) &source ); + free( source ); + + char infoLog[ 128 * 1024 ]; + int sz , i , j; + glGetProgramInfoLog( program , sizeof( infoLog ) , &sz , infoLog ); + + i = 0; + while ( i < sz ) { + j = i; + while ( j < sz && infoLog[ j ] != '\n' ) { + j ++; + } + if ( j < sz ) { + infoLog[ j ] = 0; + } + fprintf( stderr , "%s: %s\n" , file , &infoLog[ i ] ); + i = j + 1; + } + + glDeleteProgram( program ); +} + + +int main( int argc , char ** argv ) +{ + if ( !initContext( ) ) { + return 1; + } + + if ( argc > 1 ) { + if ( argc < 3 ) { + fprintf( stderr , + "Syntax: %s [v|f|g|tc|te|c] file...\n" , + argv[ 0 ] ); + return 1; + } + + GLenum type = getShaderType( argv[ 1 ] ); + if ( type == 0 ) { + return 1; + } + + int i; + for ( i = 2 ; i < argc ; i ++ ) { + loadShader( type , argv[ i ] ); + } + } + + killContext( ); + return 0; +} diff --git a/syntax_checkers/glsl/driver.vim b/syntax_checkers/glsl/driver.vim new file mode 100644 index 0000000..278631c --- /dev/null +++ b/syntax_checkers/glsl/driver.vim @@ -0,0 +1,68 @@ +if exists("g:loaded_syntastic_glsl_driver_checker") + finish +endif +let g:loaded_syntastic_glsl_driver_checker = 1 + +let s:glsl_extensions = { + \ 'glslf': 'f', + \ 'glslv': 'v', + \ 'frag': 'f', + \ 'vert': 'v', + \ 'geom': 'g', + \ 'fp': 'f', + \ 'vp': 'v' + \ } + +let s:save_cpo = &cpo +set cpo&vim + +function! SyntaxCheckers_glsl_driver_GetLocList() dict " {{{1 + let makeprg = self.makeprgBuild({ + \ 'args_before': s:GetShaderType() }) + + let errorformat = + \ "%E%f: 0(%l) : error %m," . + \ "%W%f: 0(%l) : warning %m," . + \ "%E%f: (0) : error %m," . + \ "%W%f: (0) : warning %m" + + return SyntasticMake({ + \ 'makeprg': makeprg, + \ 'errorformat': errorformat }) +endfunction " }}}1 + +function! s:GetShaderType() " {{{2 + let save_view = winsaveview() + let old_foldenable = &foldenable + let old_lazyredraw = &lazyredraw + + let &lazyredraw = 1 + let &foldenable = 0 + call cursor(1, 1) + + let magic = '\m\C^// type:\s*' + let line = search(magic, 'c') + + call winrestview(save_view) + let &foldenable = old_foldenable + let &lazyredraw = old_lazyredraw + + if line + let profile = matchstr(getline(line), magic . '\zs.*') + else + let profile = get(s:extensions, tolower(expand('%:e', 1)), 'v') + endif + + return profile +endfunction " }}}2 + +call g:SyntasticRegistry.CreateAndRegisterChecker({ + \'filetype': 'glsl', + \'name': 'driver', + \'exec': 'check-glsl'}) + +let &cpo = s:save_cpo +unlet s:save_cpo + +" vim: set sw=4 sts=4 et fdm=marker: +