diff options
Diffstat (limited to 'src/osd/modules/opengl')
-rw-r--r-- | src/osd/modules/opengl/gl_shader_mgr.cpp | 376 | ||||
-rw-r--r-- | src/osd/modules/opengl/gl_shader_mgr.h | 84 | ||||
-rw-r--r-- | src/osd/modules/opengl/gl_shader_tool.cpp | 649 | ||||
-rw-r--r-- | src/osd/modules/opengl/gl_shader_tool.h | 221 | ||||
-rw-r--r-- | src/osd/modules/opengl/osd_opengl.h | 156 |
5 files changed, 805 insertions, 681 deletions
diff --git a/src/osd/modules/opengl/gl_shader_mgr.cpp b/src/osd/modules/opengl/gl_shader_mgr.cpp index 0cf3f9b6617..4567a8e8085 100644 --- a/src/osd/modules/opengl/gl_shader_mgr.cpp +++ b/src/osd/modules/opengl/gl_shader_mgr.cpp @@ -1,13 +1,17 @@ // license:BSD-3-Clause // copyright-holders:Sven Gothel -#include <stdio.h> /* snprintf */ -#include <stdlib.h> /* malloc */ + +#include "gl_shader_mgr.h" #include "osdcomm.h" -#include "osd_opengl.h" -#include "gl_shader_mgr.h" -#include "gl_shader_tool.h" +#include "util/strformat.h" + +#include <algorithm> +#include <iterator> + + +namespace { #define GLSL_VERTEX_SHADER_INT_NUMBER 1 // general #define GLSL_VERTEX_SHADER_MAX_NUMBER 2 // general + custom @@ -15,16 +19,16 @@ #ifdef GLSL_SOURCE_ON_DISK -static char const *const glsl_mamebm_vsh_files [GLSL_VERTEX_SHADER_INT_NUMBER] = +static char const *const glsl_mamebm_vsh_files[GLSL_VERTEX_SHADER_INT_NUMBER] = { - "/tmp/glsl_general.vsh" // general + "/tmp/glsl_general.vsh" // general }; -static char const *const glsl_mamebm_fsh_files [GLSL_SHADER_FEAT_INT_NUMBER] = +static char const *const glsl_mamebm_fsh_files[glsl_shader_info::FEAT_INT_NUMBER] = { - "/tmp/glsl_plain_rgb32_dir.fsh", // rgb32 dir plain - "/tmp/glsl_bilinear_rgb32_dir.fsh", // rgb32 dir bilinear - "/tmp/glsl_bicubic_rgb32_dir.fsh", // rgb32 dir bicubic + "/tmp/glsl_plain_rgb32_dir.fsh", // rgb32 dir plain + "/tmp/glsl_bilinear_rgb32_dir.fsh", // rgb32 dir bilinear + "/tmp/glsl_bicubic_rgb32_dir.fsh", // rgb32 dir bicubic }; #else // GLSL_SOURCE_ON_DISK @@ -35,209 +39,239 @@ static char const *const glsl_mamebm_fsh_files [GLSL_SHADER_FEAT_INT_NUMBER] = #include "shader/glsl_bilinear_rgb32_dir.fsh.c" #include "shader/glsl_bicubic_rgb32_dir.fsh.c" -static char const *const glsl_mamebm_vsh_sources [GLSL_VERTEX_SHADER_INT_NUMBER] = +static char const *const glsl_mamebm_vsh_sources[GLSL_VERTEX_SHADER_INT_NUMBER] = { - glsl_general_vsh_src // general + glsl_general_vsh_src // general }; -static char const *const glsl_mamebm_fsh_sources [GLSL_SHADER_FEAT_INT_NUMBER] = +static char const *const glsl_mamebm_fsh_sources[glsl_shader_info::FEAT_INT_NUMBER] = { - glsl_plain_rgb32_dir_fsh_src, // rgb32 dir plain - glsl_bilinear_rgb32_dir_fsh_src, // rgb32 dir bilinear - glsl_bicubic_rgb32_dir_fsh_src, // rgb32 dir bicubic + glsl_plain_rgb32_dir_fsh_src, // rgb32 dir plain + glsl_bilinear_rgb32_dir_fsh_src, // rgb32 dir bilinear + glsl_bicubic_rgb32_dir_fsh_src, // rgb32 dir bicubic }; #endif // GLSL_SOURCE_ON_DISK -static char const *const glsl_mamebm_filter_names [GLSL_SHADER_FEAT_MAX_NUMBER] = -{ - "plain", - "bilinear", - "bicubic", - "custom" -}; - -static GLhandleARB glsl_mamebm_programs [GLSL_SHADER_FEAT_MAX_NUMBER+9] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* rgb32 dir: plain, bilinear, bicubic, custom0-9, .. */ -}; +static char const *const glsl_mamebm_filter_names[glsl_shader_info::FEAT_MAX_NUMBER]{ + "plain", + "bilinear", + "bicubic", + "custom" }; /** * fragment shader -> vertex shader mapping */ -static int glsl_mamebm_fsh2vsh[GLSL_SHADER_FEAT_MAX_NUMBER] = +static const int glsl_mamebm_fsh2vsh[glsl_shader_info::FEAT_MAX_NUMBER] = { 0, // plain -> general 0, // bilinear -> general 0, // bicubic -> general - 1, // custom -> custom -}; - -static GLhandleARB glsl_mamebm_vsh_shader[GLSL_VERTEX_SHADER_MAX_NUMBER+9] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; /* general, custom0-9 */ - -static GLhandleARB glsl_mamebm_fsh_shader [GLSL_SHADER_FEAT_MAX_NUMBER+9] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* rgb32 dir: plain, bilinear, bicubic, custom0-9 */ + 1, // custom -> custom }; -static GLhandleARB glsl_scrn_programs [10] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* rgb32: custom0-9, .. */ -}; - -static GLhandleARB glsl_scrn_vsh_shader[10] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; /* custom0-9 */ - -static GLhandleARB glsl_scrn_fsh_shader [10] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; /* rgb32: custom0-9 */ - -const char * glsl_shader_get_filter_name_mamebm(int glslShaderFeature) -{ - if ( !(0 <= glslShaderFeature && glslShaderFeature < GLSL_SHADER_FEAT_MAX_NUMBER) ) - return "illegal shader feature"; - - return glsl_mamebm_filter_names[glslShaderFeature]; -} - -GLhandleARB glsl_shader_get_program_mamebm(int glslShaderFeature, int idx) -{ - if ( !(0 <= glslShaderFeature && glslShaderFeature < GLSL_SHADER_FEAT_MAX_NUMBER) ) - return 0; - - return glsl_mamebm_programs[glslShaderFeature+idx]; -} - -GLhandleARB glsl_shader_get_program_scrn(int idx) +class glsl_shader_impl : public glsl_shader_info { - if ( !(0 <= idx && idx < 10) ) - return 0; - - return glsl_scrn_programs[idx]; -} +public: + glsl_shader_impl( +#if defined(USE_DISPATCH_GL) + osd_gl_dispatch *gld +#endif + ) +#if defined(USE_DISPATCH_GL) + : glsl_shader_info(gld) +#endif + { + std::fill(std::begin(mamebm_programs), std::end(mamebm_programs), GLhandleARB(0)); + std::fill(std::begin(mamebm_vsh_shader), std::end(mamebm_vsh_shader), GLhandleARB(0)); + std::fill(std::begin(mamebm_fsh_shader), std::end(mamebm_fsh_shader), GLhandleARB(0)); + std::fill(std::begin(scrn_programs), std::end(scrn_programs), GLhandleARB(0)); + std::fill(std::begin(scrn_vsh_shader), std::end(scrn_vsh_shader), GLhandleARB(0)); + std::fill(std::begin(scrn_fsh_shader), std::end(scrn_fsh_shader), GLhandleARB(0)); + } -glsl_shader_info *glsl_shader_init(osd_gl_context *gl_ctx) -{ - int i,j, err; + bool initalize(osd_gl_context &gl_ctx) + { + if (!load_extension(gl_ctx)) + return false; - err = gl_shader_loadExtention(gl_ctx); - if(err) return nullptr; + int err = 0; - for (i=0; !err && i<GLSL_VERTEX_SHADER_INT_NUMBER; i++) - { - #ifdef GLSL_SOURCE_ON_DISK - if(glsl_mamebm_vsh_files[i]) - err = gl_compile_shader_file ( &glsl_mamebm_vsh_shader[i], GL_VERTEX_SHADER_ARB, - glsl_mamebm_vsh_files[i], 0); - #else - if(glsl_mamebm_vsh_sources[i]) - err = gl_compile_shader_source( &glsl_mamebm_vsh_shader[i], GL_VERTEX_SHADER_ARB, - glsl_mamebm_vsh_sources[i], 0); - #endif + for (int i = 0; !err && (i < GLSL_VERTEX_SHADER_INT_NUMBER); i++) + { +#ifdef GLSL_SOURCE_ON_DISK + if (glsl_mamebm_vsh_files[i]) + err = compile_file( + &mamebm_vsh_shader[i], + GL_VERTEX_SHADER_ARB, + glsl_mamebm_vsh_files[i], + false); +#else + if (glsl_mamebm_vsh_sources[i]) + err = compile_source( + &mamebm_vsh_shader[i], + GL_VERTEX_SHADER_ARB, + glsl_mamebm_vsh_sources[i], + false); +#endif + } + if (err) + return false; + + for (int j = 0; !err && (j < FEAT_INT_NUMBER); j++) + { +#ifdef GLSL_SOURCE_ON_DISK + if (glsl_mamebm_fsh_files[j]) + err = compile_files( + &mamebm_programs[j], + &mamebm_vsh_shader[glsl_mamebm_fsh2vsh[j]], + &mamebm_fsh_shader[j], + nullptr, // precompiled + glsl_mamebm_fsh_files[j], + false); +#else + if (glsl_mamebm_fsh_sources[j]) + err = compile_sources( + &mamebm_programs[j], + &mamebm_vsh_shader[glsl_mamebm_fsh2vsh[j]], + &mamebm_fsh_shader[j], + nullptr, // precompiled + glsl_mamebm_fsh_sources[j]); +#endif + } + if (err) + return false; + + return true; } - if(err) return nullptr; - - for (j=0; !err && j<GLSL_SHADER_FEAT_INT_NUMBER; j++) + virtual ~glsl_shader_impl() { - #ifdef GLSL_SOURCE_ON_DISK - if(glsl_mamebm_fsh_files[j]) - err = gl_compile_shader_files (&glsl_mamebm_programs[j], - &glsl_mamebm_vsh_shader[glsl_mamebm_fsh2vsh[j]], - &glsl_mamebm_fsh_shader[j], - nullptr /*precompiled*/, glsl_mamebm_fsh_files[j], 0); - #else - if(glsl_mamebm_fsh_sources[j]) - err = gl_compile_shader_sources(&glsl_mamebm_programs[j], - &glsl_mamebm_vsh_shader[glsl_mamebm_fsh2vsh[j]], - &glsl_mamebm_fsh_shader[j], - nullptr /*precompiled*/, glsl_mamebm_fsh_sources[j]); - #endif + pfn_glUseProgramObjectARB(0); + glFinish(); + + for (int i = 0; i < GLSL_VERTEX_SHADER_MAX_NUMBER + 9; i++) + { + if (mamebm_vsh_shader[i]) + delete_shader(nullptr, &mamebm_vsh_shader[i], nullptr); + } + + for (int j = 0; j < FEAT_MAX_NUMBER + 9; j++) + { + if (mamebm_fsh_shader[j]) + delete_shader(nullptr, nullptr, &mamebm_fsh_shader[j]); + } + + for (int j = 0; j < FEAT_MAX_NUMBER + 9; j++) + { + if (mamebm_programs[j]) + delete_shader(&mamebm_programs[j], nullptr, nullptr); + } + + for (int i = 0; i < 10; i++) + { + if (scrn_vsh_shader[i]) + delete_shader(nullptr, &scrn_vsh_shader[i], nullptr); + if (scrn_fsh_shader[i]) + delete_shader(nullptr, nullptr, &scrn_fsh_shader[i]); + if (scrn_programs[i]) + delete_shader(&scrn_programs[i], nullptr, nullptr); + } } - if (err) return nullptr; - return (glsl_shader_info *) malloc(sizeof(glsl_shader_info *)); -} -int glsl_shader_free(glsl_shader_info *shinfo) -{ - int i,j; + virtual const char *get_filter_name_mamebm(int glslShaderFeature) override + { + if ((0 > glslShaderFeature) || (glslShaderFeature >= FEAT_MAX_NUMBER)) + return "illegal shader feature"; - pfn_glUseProgramObjectARB(0); // back to fixed function pipeline - glFinish(); + return glsl_mamebm_filter_names[glslShaderFeature]; + } - for (i=0; i<GLSL_VERTEX_SHADER_MAX_NUMBER+9; i++) + virtual GLhandleARB get_program_mamebm(int glslShaderFeature, int idx) override { - if ( glsl_mamebm_vsh_shader[i] ) - (void) gl_delete_shader(nullptr, &glsl_mamebm_vsh_shader[i], nullptr); + if ((0 > glslShaderFeature) || (glslShaderFeature >= FEAT_MAX_NUMBER)) + return 0; + + return mamebm_programs[glslShaderFeature + idx]; } - for (j=0; j<GLSL_SHADER_FEAT_MAX_NUMBER+9; j++) + virtual GLhandleARB get_program_scrn(int idx) override { - if ( glsl_mamebm_fsh_shader[j] ) - (void) gl_delete_shader(nullptr, nullptr, &glsl_mamebm_fsh_shader[j]); + if ((0 > idx) || (idx >= 10)) + return 0; + + return scrn_programs[idx]; } - for (j=0; j<GLSL_SHADER_FEAT_MAX_NUMBER+9; j++) + virtual int add_mamebm(const char *custShaderPrefix, int idx) override { - if ( glsl_mamebm_programs[j] ) - (void) gl_delete_shader( &glsl_mamebm_programs[j], nullptr, nullptr); + int err; + + err = compile_file( + &mamebm_vsh_shader[GLSL_VERTEX_SHADER_CUSTOM + idx], + GL_VERTEX_SHADER_ARB, + util::string_format("%s.vsh", custShaderPrefix).c_str(), + false); + if (err) + return err; + + err = compile_files( + &mamebm_programs[FEAT_CUSTOM + idx], + &mamebm_vsh_shader[GLSL_VERTEX_SHADER_CUSTOM + idx], + &mamebm_fsh_shader[FEAT_CUSTOM + idx], + nullptr, // precompiled + util::string_format("%s_rgb32_dir.fsh", custShaderPrefix).c_str(), + false); + return err; } - for (i=0; i<10; i++) + virtual int add_scrn(const char *custShaderPrefix, int idx) override { - if ( glsl_scrn_vsh_shader[i] ) - (void) gl_delete_shader(nullptr, &glsl_scrn_vsh_shader[i], nullptr); - if ( glsl_scrn_fsh_shader[i] ) - (void) gl_delete_shader(nullptr, nullptr, &glsl_scrn_fsh_shader[i]); - if ( glsl_scrn_programs[i] ) - (void) gl_delete_shader( &glsl_scrn_programs[i], nullptr, nullptr); + int err; + + err = compile_file( + &scrn_vsh_shader[idx], + GL_VERTEX_SHADER_ARB, + util::string_format("%s.vsh", custShaderPrefix).c_str(), + false); + if (err) + return err; + + err = compile_files( + &scrn_programs[idx], + &scrn_vsh_shader[idx], + &scrn_fsh_shader[idx], + nullptr, // precompiled + util::string_format("%s.fsh", custShaderPrefix).c_str(), + false); + return err; } - free(shinfo); - return 0; -} - -int glsl_shader_add_mamebm(glsl_shader_info *shinfo, const char * custShaderPrefix, int idx) -{ - int err; - static char fname[8192]; - - snprintf(fname, 8192, "%s.vsh", custShaderPrefix); fname[8191]=0; - - err = gl_compile_shader_file ( &glsl_mamebm_vsh_shader[GLSL_VERTEX_SHADER_CUSTOM+idx], GL_VERTEX_SHADER_ARB, fname, 0); - if(err) return err; - - snprintf(fname, 8192, "%s_rgb32_dir.fsh", custShaderPrefix); fname[8191]=0; +private: + GLhandleARB mamebm_programs[FEAT_MAX_NUMBER + 9]; // rgb32 dir: plain, bilinear, bicubic, custom0-9, .. + GLhandleARB mamebm_vsh_shader[GLSL_VERTEX_SHADER_MAX_NUMBER + 9]; // general, custom0-9 + GLhandleARB mamebm_fsh_shader[FEAT_MAX_NUMBER+9]; // rgb32 dir: plain, bilinear, bicubic, custom0-9 + GLhandleARB scrn_programs[10]; // rgb32: custom0-9, .. + GLhandleARB scrn_vsh_shader[10]; // custom0-9 + GLhandleARB scrn_fsh_shader[10]; // rgb32: custom0-9 +}; - err = gl_compile_shader_files (&glsl_mamebm_programs[GLSL_SHADER_FEAT_CUSTOM+idx], - &glsl_mamebm_vsh_shader[GLSL_VERTEX_SHADER_CUSTOM+idx], - &glsl_mamebm_fsh_shader[GLSL_SHADER_FEAT_CUSTOM+idx], - nullptr /*precompiled*/, fname, 0); +} // anonymous namespace - return err; -} -int glsl_shader_add_scrn(glsl_shader_info *shinfo, const char * custShaderPrefix, int idx) +std::unique_ptr<glsl_shader_info> glsl_shader_info::init( + osd_gl_context &gl_ctx +#if defined(USE_DISPATCH_GL) + , osd_gl_dispatch *gld +#endif + ) { - int err; - static char fname[8192]; - - snprintf(fname, 8192, "%s.vsh", custShaderPrefix); fname[8191]=0; - - err = gl_compile_shader_file ( &glsl_scrn_vsh_shader[idx], GL_VERTEX_SHADER_ARB, fname, 0); - if(err) return err; - - snprintf(fname, 8192, "%s.fsh", custShaderPrefix); fname[8191]=0; - - err = gl_compile_shader_files (&glsl_scrn_programs[idx], - &glsl_scrn_vsh_shader[idx], - &glsl_scrn_fsh_shader[idx], - nullptr /*precompiled*/, fname, 0); - return err; + auto result = std::make_unique<glsl_shader_impl>( +#if defined(USE_DISPATCH_GL) + gld +#endif + ); + if (!result->initalize(gl_ctx)) + result.reset(); + return result; } diff --git a/src/osd/modules/opengl/gl_shader_mgr.h b/src/osd/modules/opengl/gl_shader_mgr.h index f95ec8c2244..ad9e248ac5f 100644 --- a/src/osd/modules/opengl/gl_shader_mgr.h +++ b/src/osd/modules/opengl/gl_shader_mgr.h @@ -1,51 +1,57 @@ // license:BSD-3-Clause // copyright-holders:Sven Gothel +#ifndef MAME_OSD_OPENGL_GL_SHADER_MGR_H +#define MAME_OSD_OPENGL_GL_SHADER_MGR_H -#ifndef GL_SHADER_MGR_H -#define GL_SHADER_MGR_H +#pragma once +#include "gl_shader_tool.h" #include "osd_opengl.h" +#include <memory> + + // #define GLSL_SOURCE_ON_DISK 1 -enum GLSL_SHADER_FEATURE { - GLSL_SHADER_FEAT_PLAIN, - GLSL_SHADER_FEAT_BILINEAR, - GLSL_SHADER_FEAT_BICUBIC, - GLSL_SHADER_FEAT_INT_NUMBER, - GLSL_SHADER_FEAT_CUSTOM = GLSL_SHADER_FEAT_INT_NUMBER, - GLSL_SHADER_FEAT_MAX_NUMBER -}; -// old code passed sdl_info * to functions here -// however the parameter was not used -// changed interface to more generic one. -struct glsl_shader_info +class glsl_shader_info : public gl_shader_tool { - int dummy; // avoid compiler breakage +public: + enum FEATURE + { + FEAT_PLAIN, + FEAT_BILINEAR, + FEAT_BICUBIC, + FEAT_INT_NUMBER, + FEAT_CUSTOM = FEAT_INT_NUMBER, + FEAT_MAX_NUMBER + }; + + using gl_shader_tool::gl_shader_tool; + + virtual ~glsl_shader_info() = default; + + /** + * returns the GLSL program if ok/available, otherwise 0 + */ + virtual GLhandleARB get_program_mamebm(int glslShaderFeature, int idx) = 0; + + virtual const char *get_filter_name_mamebm(int glslShaderFeature) = 0; + + virtual int add_mamebm(const char *custShaderPrefix, int idx) = 0; + + virtual GLhandleARB get_program_scrn(int idx) = 0; + virtual int add_scrn(const char *custShaderPrefix, int idx) = 0; + + /** + * returns pointer if OK, otherwise nullptr + */ + static std::unique_ptr<glsl_shader_info> init( + osd_gl_context &gl_ctx +#if defined(USE_DISPATCH_GL) + , osd_gl_dispatch *gld +#endif + ); }; - -/** - * returns pointer if ok, otherwise nullptr - */ -glsl_shader_info *glsl_shader_init(osd_gl_context *gl_ctx); - -/** - * returns 0 if ok, otherwise an error value - */ -int glsl_shader_free(glsl_shader_info *shinfo); - -/** - * returns the GLSL program if ok/available, otherwise 0 - */ -GLhandleARB glsl_shader_get_program_mamebm(int glslShaderFeature, int idx); - -const char * glsl_shader_get_filter_name_mamebm(int glslShaderFeature); - -int glsl_shader_add_mamebm(glsl_shader_info *shinfo, const char * custShaderPrefix, int idx); - -GLhandleARB glsl_shader_get_program_scrn(int idx); -int glsl_shader_add_scrn(glsl_shader_info *shinfo, const char * custShaderPrefix, int idx); - -#endif // GL_SHADER_MGR_H +#endif // MAME_OSD_OPENGL_GL_SHADER_MGR_H diff --git a/src/osd/modules/opengl/gl_shader_tool.cpp b/src/osd/modules/opengl/gl_shader_tool.cpp index dedb59fbb7c..fb880178b98 100644 --- a/src/osd/modules/opengl/gl_shader_tool.cpp +++ b/src/osd/modules/opengl/gl_shader_tool.cpp @@ -15,59 +15,90 @@ * */ -#include "emu.h" #include "gl_shader_tool.h" -PFNGLGETOBJECTPARAMETERIVARBPROC pfn_glGetObjectParameterivARB= nullptr; -PFNGLGETINFOLOGARBPROC pfn_glGetInfoLogARB= nullptr; -PFNGLDELETEOBJECTARBPROC pfn_glDeleteObjectARB= nullptr; -PFNGLCREATESHADEROBJECTARBPROC pfn_glCreateShaderObjectARB= nullptr; -PFNGLSHADERSOURCEARBPROC pfn_glShaderSourceARB= nullptr; -PFNGLCOMPILESHADERARBPROC pfn_glCompileShaderARB= nullptr; -PFNGLCREATEPROGRAMOBJECTARBPROC pfn_glCreateProgramObjectARB= nullptr; -PFNGLATTACHOBJECTARBPROC pfn_glAttachObjectARB= nullptr; -PFNGLLINKPROGRAMARBPROC pfn_glLinkProgramARB= nullptr; -PFNGLVALIDATEPROGRAMARBPROC pfn_glValidateProgramARB= nullptr; -PFNGLUSEPROGRAMOBJECTARBPROC pfn_glUseProgramObjectARB= nullptr; -PFNGLGETUNIFORMLOCATIONARBPROC pfn_glGetUniformLocationARB= nullptr; -PFNGLUNIFORM1FARBPROC pfn_glUniform1fARB= nullptr; -PFNGLUNIFORM1IARBPROC pfn_glUniform1iARB= nullptr; -PFNGLUNIFORM1FVARBPROC pfn_glUniform1fvARB= nullptr; -PFNGLUNIFORM2FVARBPROC pfn_glUniform2fvARB= nullptr; -PFNGLUNIFORM3FVARBPROC pfn_glUniform3fvARB= nullptr; -PFNGLUNIFORM4FVARBPROC pfn_glUniform4fvARB= nullptr; -PFNGLUNIFORM1IVARBPROC pfn_glUniform1ivARB= nullptr; -PFNGLUNIFORM2IVARBPROC pfn_glUniform2ivARB= nullptr; -PFNGLUNIFORM3IVARBPROC pfn_glUniform3ivARB= nullptr; -PFNGLUNIFORM4IVARBPROC pfn_glUniform4ivARB= nullptr; - - -int gl_shader_loadExtention(osd_gl_context *gl_ctx) +#include "osdcore.h" + + +#define GL_CHECK_ERROR_VERBOSE() check_error(CHECK_ALWAYS_VERBOSE, __FILE__, __LINE__) +#define GL_CHECK_ERROR_NORMAL() check_error(CHECK_VERBOSE, __FILE__, __LINE__) +#define GL_CHECK_ERROR_QUIET() check_error(CHECK_QUIET, __FILE__, __LINE__) +#define GL_CHECK_ERROR(m) check_error(m, __FILE__, __LINE__) + +#define GL_SHADER_CHECK_ERROR_VERBOSE(o,q) check_error(o, q, CHECK_ALWAYS_VERBOSE, __FILE__, __LINE__) +#define GL_SHADER_CHECK_ERROR_NORMAL(o,q) check_error(o, q, CHECK_VERBOSE, __FILE__, __LINE__) +#define GL_SHADER_CHECK_ERROR_QUIET(o,q) check_error(o, q, CHECK_QUIET, __FILE__, __LINE__) +#define GL_SHADER_CHECK_ERROR(o,q,m) check_error(o, q, m, __FILE__, __LINE__) + +#ifdef GL_SHADER_TOOL_DEBUG + #define GL_SHADER_CHECK(o, q) GL_SHADER_CHECK_ERROR_VERBOSE(o, q) + #define GL_CHECK() GL_CHECK_ERROR_VERBOSE() +#else + #define GL_SHADER_CHECK(o, q) GL_SHADER_CHECK_ERROR_NORMAL(o, q) + #define GL_CHECK() GL_CHECK_ERROR_NORMAL() +#endif + + +gl_shader_tool::gl_shader_tool( +#if defined(USE_DISPATCH_GL) + osd_gl_dispatch *gld +#endif + ) + : pfn_glGetObjectParameterivARB(nullptr) + , pfn_glGetInfoLogARB(nullptr) + , pfn_glDeleteObjectARB(nullptr) + , pfn_glCreateShaderObjectARB(nullptr) + , pfn_glShaderSourceARB(nullptr) + , pfn_glCompileShaderARB(nullptr) + , pfn_glCreateProgramObjectARB(nullptr) + , pfn_glAttachObjectARB(nullptr) + , pfn_glLinkProgramARB(nullptr) + , pfn_glValidateProgramARB(nullptr) + , pfn_glUseProgramObjectARB(nullptr) + , pfn_glGetUniformLocationARB(nullptr) + , pfn_glUniform1fARB(nullptr) + , pfn_glUniform1iARB(nullptr) + , pfn_glUniform1fvARB(nullptr) + , pfn_glUniform2fvARB(nullptr) + , pfn_glUniform3fvARB(nullptr) + , pfn_glUniform4fvARB(nullptr) + , pfn_glUniform1ivARB(nullptr) + , pfn_glUniform2ivARB(nullptr) + , pfn_glUniform3ivARB(nullptr) + , pfn_glUniform4ivARB(nullptr) +#if defined(USE_DISPATCH_GL) + , gl_dispatch(gld) +#endif +{ +} + + +bool gl_shader_tool::load_extension(osd_gl_context &gl_ctx) { - pfn_glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) gl_ctx->getProcAddress("glGetObjectParameterivARB"); - pfn_glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) gl_ctx->getProcAddress ("glGetInfoLogARB"); - pfn_glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) gl_ctx->getProcAddress ("glDeleteObjectARB"); - pfn_glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) gl_ctx->getProcAddress ("glCreateShaderObjectARB"); - pfn_glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) gl_ctx->getProcAddress ("glShaderSourceARB"); - pfn_glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) gl_ctx->getProcAddress ("glCompileShaderARB"); - pfn_glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) gl_ctx->getProcAddress ("glCreateProgramObjectARB"); - pfn_glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) gl_ctx->getProcAddress ("glAttachObjectARB"); - pfn_glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) gl_ctx->getProcAddress ("glLinkProgramARB"); - pfn_glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) gl_ctx->getProcAddress ("glValidateProgramARB"); - pfn_glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) gl_ctx->getProcAddress ("glUseProgramObjectARB"); - pfn_glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) gl_ctx->getProcAddress ("glGetUniformLocationARB"); - pfn_glUniform1fARB = (PFNGLUNIFORM1FARBPROC) gl_ctx->getProcAddress ("glUniform1fARB"); - pfn_glUniform1iARB = (PFNGLUNIFORM1IARBPROC) gl_ctx->getProcAddress ("glUniform1iARB"); - pfn_glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) gl_ctx->getProcAddress ("glUniform1fvARB"); - pfn_glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) gl_ctx->getProcAddress ("glUniform2fvARB"); - pfn_glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) gl_ctx->getProcAddress ("glUniform3fvARB"); - pfn_glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) gl_ctx->getProcAddress ("glUniform4fvARB"); - pfn_glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) gl_ctx->getProcAddress ("glUniform1ivARB"); - pfn_glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) gl_ctx->getProcAddress ("glUniform2ivARB"); - pfn_glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) gl_ctx->getProcAddress ("glUniform3ivARB"); - pfn_glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) gl_ctx->getProcAddress ("glUniform4ivARB"); - - if ( pfn_glGetObjectParameterivARB && pfn_glGetInfoLogARB && pfn_glDeleteObjectARB && pfn_glCreateShaderObjectARB && + gl_ctx.get_proc_address(pfn_glGetObjectParameterivARB, "glGetObjectParameterivARB"); + gl_ctx.get_proc_address(pfn_glGetInfoLogARB, "glGetInfoLogARB"); + gl_ctx.get_proc_address(pfn_glDeleteObjectARB, "glDeleteObjectARB"); + gl_ctx.get_proc_address(pfn_glCreateShaderObjectARB, "glCreateShaderObjectARB"); + gl_ctx.get_proc_address(pfn_glShaderSourceARB, "glShaderSourceARB"); + gl_ctx.get_proc_address(pfn_glCompileShaderARB, "glCompileShaderARB"); + gl_ctx.get_proc_address(pfn_glCreateProgramObjectARB, "glCreateProgramObjectARB"); + gl_ctx.get_proc_address(pfn_glAttachObjectARB, "glAttachObjectARB"); + gl_ctx.get_proc_address(pfn_glLinkProgramARB, "glLinkProgramARB"); + gl_ctx.get_proc_address(pfn_glValidateProgramARB, "glValidateProgramARB"); + gl_ctx.get_proc_address(pfn_glUseProgramObjectARB, "glUseProgramObjectARB"); + gl_ctx.get_proc_address(pfn_glGetUniformLocationARB, "glGetUniformLocationARB"); + gl_ctx.get_proc_address(pfn_glUniform1fARB, "glUniform1fARB"); + gl_ctx.get_proc_address(pfn_glUniform1iARB, "glUniform1iARB"); + gl_ctx.get_proc_address(pfn_glUniform1fvARB, "glUniform1fvARB"); + gl_ctx.get_proc_address(pfn_glUniform2fvARB, "glUniform2fvARB"); + gl_ctx.get_proc_address(pfn_glUniform3fvARB, "glUniform3fvARB"); + gl_ctx.get_proc_address(pfn_glUniform4fvARB, "glUniform4fvARB"); + gl_ctx.get_proc_address(pfn_glUniform1ivARB, "glUniform1ivARB"); + gl_ctx.get_proc_address(pfn_glUniform2ivARB, "glUniform2ivARB"); + gl_ctx.get_proc_address(pfn_glUniform3ivARB, "glUniform3ivARB"); + gl_ctx.get_proc_address(pfn_glUniform4ivARB, "glUniform4ivARB"); + + if (pfn_glGetObjectParameterivARB && pfn_glGetInfoLogARB && pfn_glDeleteObjectARB && pfn_glCreateShaderObjectARB && pfn_glShaderSourceARB && pfn_glCompileShaderARB && pfn_glCreateProgramObjectARB && pfn_glAttachObjectARB && pfn_glLinkProgramARB && pfn_glValidateProgramARB && pfn_glUseProgramObjectARB && pfn_glGetUniformLocationARB && pfn_glUniform1fARB && pfn_glUniform1iARB && @@ -75,62 +106,52 @@ int gl_shader_loadExtention(osd_gl_context *gl_ctx) pfn_glUniform1ivARB && pfn_glUniform2ivARB && pfn_glUniform3ivARB && pfn_glUniform4ivARB ) { - return 0; + return true; } osd_printf_error("OpenGL: missing ARB shader function: "); - if (!pfn_glGetObjectParameterivARB) osd_printf_error("glGetObjectParameterivARB, "); - if (!pfn_glGetInfoLogARB) osd_printf_error("glGetInfoLogARB, "); - if (!pfn_glDeleteObjectARB) osd_printf_error("glDeleteObjectARB, "); - if (!pfn_glCreateShaderObjectARB) osd_printf_error("glCreateShaderObjectARB, "); - if (!pfn_glShaderSourceARB) osd_printf_error("glShaderSourceARB, "); - if (!pfn_glCompileShaderARB) osd_printf_error("glCompileShaderARB, "); - if (!pfn_glCreateProgramObjectARB) osd_printf_error("glCreateProgramObjectARB, "); - if (!pfn_glAttachObjectARB) osd_printf_error("glAttachObjectARB, "); - if (!pfn_glLinkProgramARB) osd_printf_error("glLinkProgramARB, "); - if (!pfn_glValidateProgramARB) osd_printf_error("glValidateProgramARB, "); - if (!pfn_glUseProgramObjectARB) osd_printf_error("glUseProgramObjectARB, "); - if (!pfn_glGetUniformLocationARB) osd_printf_error("glGetUniformLocationARB, "); - if (!pfn_glUniform1fARB) osd_printf_error("glUniform1fARB, "); - if (!pfn_glUniform1iARB) osd_printf_error("glUniform1iARB"); - if (!pfn_glUniform1fvARB) osd_printf_error("glUniform1fvARB, "); - if (!pfn_glUniform2fvARB) osd_printf_error("glUniform2fvARB, "); - if (!pfn_glUniform3fvARB) osd_printf_error("glUniform3fvARB, "); - if (!pfn_glUniform4fvARB) osd_printf_error("glUniform4fvARB, "); - if (!pfn_glUniform1ivARB) osd_printf_error("glUniform1ivARB"); - if (!pfn_glUniform2ivARB) osd_printf_error("glUniform2ivARB"); - if (!pfn_glUniform3ivARB) osd_printf_error("glUniform3ivARB"); - if (!pfn_glUniform4ivARB) osd_printf_error("glUniform4ivARB"); + if (!pfn_glGetObjectParameterivARB) osd_printf_error(" glGetObjectParameterivARB"); + if (!pfn_glGetInfoLogARB) osd_printf_error(" glGetInfoLogARB"); + if (!pfn_glDeleteObjectARB) osd_printf_error(" glDeleteObjectARB"); + if (!pfn_glCreateShaderObjectARB) osd_printf_error(" glCreateShaderObjectARB"); + if (!pfn_glShaderSourceARB) osd_printf_error(" glShaderSourceARB"); + if (!pfn_glCompileShaderARB) osd_printf_error(" glCompileShaderARB"); + if (!pfn_glCreateProgramObjectARB) osd_printf_error(" glCreateProgramObjectARB"); + if (!pfn_glAttachObjectARB) osd_printf_error(" glAttachObjectARB"); + if (!pfn_glLinkProgramARB) osd_printf_error(" glLinkProgramARB"); + if (!pfn_glValidateProgramARB) osd_printf_error(" glValidateProgramARB"); + if (!pfn_glUseProgramObjectARB) osd_printf_error(" glUseProgramObjectARB"); + if (!pfn_glGetUniformLocationARB) osd_printf_error(" glGetUniformLocationARB"); + if (!pfn_glUniform1fARB) osd_printf_error(" glUniform1fARB"); + if (!pfn_glUniform1iARB) osd_printf_error(" glUniform1iARB"); + if (!pfn_glUniform1fvARB) osd_printf_error(" glUniform1fvARB"); + if (!pfn_glUniform2fvARB) osd_printf_error(" glUniform2fvARB"); + if (!pfn_glUniform3fvARB) osd_printf_error(" glUniform3fvARB"); + if (!pfn_glUniform4fvARB) osd_printf_error(" glUniform4fvARB"); + if (!pfn_glUniform1ivARB) osd_printf_error(" glUniform1ivARB"); + if (!pfn_glUniform2ivARB) osd_printf_error(" glUniform2ivARB"); + if (!pfn_glUniform3ivARB) osd_printf_error(" glUniform3ivARB"); + if (!pfn_glUniform4ivARB) osd_printf_error(" glUniform4ivARB"); osd_printf_error("\n"); - return -1; + return false; } -int gl_check_error(GLSLCheckMode m, const char *file, const int line) +int gl_shader_tool::check_error(GLSLCheckMode m, const char *file, const int line) { - GLenum glerr = glGetError(); - - if (GL_NO_ERROR != glerr) - { - if ( CHECK_VERBOSE <= m ) - { - osd_printf_warning( "%s:%d: GL Error: %d 0x%X\n", file, line, (int)glerr, (unsigned int)glerr); - } - } - return (GL_NO_ERROR != glerr)? glerr : 0; + GLenum const glerr = glGetError(); + if (GL_NO_ERROR != glerr) + { + if (CHECK_VERBOSE <= m) + osd_printf_warning("%s:%d: GL Error: %d 0x%X\n", file, line, int(glerr), unsigned(glerr)); + } + return (GL_NO_ERROR != glerr) ? glerr : 0; } -int gl_shader_check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, const char *file, const int line) +int gl_shader_tool::check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, const char *file, const int line) { - GLsizei length; - GLcharARB buffer[255]; - GLenum glerr; - GLint param; - int res=0; - - glerr = gl_check_error(m, file, line); - - if(!obj) + GLenum const glerr = check_error(m, file, line); + if (!obj) return glerr; if(obj_query != GL_OBJECT_TYPE_ARB && @@ -144,79 +165,88 @@ int gl_shader_check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, co return -1; } + GLint param; pfn_glGetObjectParameterivARB(obj, obj_query, ¶m); + int res = 0; switch(obj_query) { - case GL_OBJECT_TYPE_ARB: - if( param!=GL_PROGRAM_OBJECT_ARB && param!=GL_SHADER_OBJECT_ARB ) + case GL_OBJECT_TYPE_ARB: + if (param != GL_PROGRAM_OBJECT_ARB && param != GL_SHADER_OBJECT_ARB) { if ( CHECK_VERBOSE <= m ) osd_printf_warning("%s:%d: GL Error: object type 0x%X generation failed\n", file, line, (unsigned int)(uintptr_t)obj); res=-1; - } else if ( CHECK_ALWAYS_VERBOSE <= m ) + } + else if (CHECK_ALWAYS_VERBOSE <= m) { - if(param==GL_PROGRAM_OBJECT_ARB) + if (param==GL_PROGRAM_OBJECT_ARB) osd_printf_warning("%s:%d: GL Error: object type 0x%X is PROGRAM, successful\n", file, line, (unsigned int)(uintptr_t)obj); else osd_printf_warning("%s:%d: GL Info: object type 0x%X is SHADER, successful\n", file, line, (unsigned int)(uintptr_t)obj); } break; - case GL_OBJECT_DELETE_STATUS_ARB: - if(param!=1) + case GL_OBJECT_DELETE_STATUS_ARB: + if (param != 1) { - if ( CHECK_ALWAYS_VERBOSE <= m ) + if (CHECK_ALWAYS_VERBOSE <= m) osd_printf_warning("%s:%d: GL Info: object 0x%X not yet marked for deletion\n", file, line, (unsigned int)(uintptr_t)obj); - } else if ( CHECK_ALWAYS_VERBOSE <= m ) + } + else if (CHECK_ALWAYS_VERBOSE <= m) { osd_printf_warning("%s:%d: GL Info: object 0x%X deletion successful\n", file, line, (unsigned int)(uintptr_t)obj); } break; - case GL_OBJECT_COMPILE_STATUS_ARB: - if(param!=1) + case GL_OBJECT_COMPILE_STATUS_ARB: + if (param != 1) { - if ( CHECK_VERBOSE <= m ) + if (CHECK_VERBOSE <= m) osd_printf_warning("%s:%d: GL Error: object 0x%X compilation failed\n", file, line, (unsigned int)(uintptr_t)obj); - res=-1; - } else if ( CHECK_ALWAYS_VERBOSE <= m ) + res = -1; + } + else if (CHECK_ALWAYS_VERBOSE <= m) { osd_printf_warning("%s:%d: GL Info: object 0x%X compiled successful\n", file, line, (unsigned int)(uintptr_t)obj); } break; - case GL_OBJECT_LINK_STATUS_ARB: - if(param!=1) + case GL_OBJECT_LINK_STATUS_ARB: + if (param != 1) { - if ( CHECK_VERBOSE <= m ) + if (CHECK_VERBOSE <= m) osd_printf_warning("%s:%d: GL Error: object 0x%X linking failed\n", file, line, (unsigned int)(uintptr_t)obj); - res=-1; - } else if ( CHECK_ALWAYS_VERBOSE <= m ) + res = -1; + } + else if (CHECK_ALWAYS_VERBOSE <= m) { osd_printf_warning("%s:%d: GL Info: object 0x%X linked successful\n", file, line, (unsigned int)(uintptr_t)obj); } break; - case GL_OBJECT_VALIDATE_STATUS_ARB: - if(param!=1) + case GL_OBJECT_VALIDATE_STATUS_ARB: + if (param != 1) { - if ( CHECK_VERBOSE <= m ) + if (CHECK_VERBOSE <= m) osd_printf_warning("%s:%d: GL Error: object 0x%X validation failed\n", file, line, (unsigned int)(uintptr_t)obj); - res=-1; - } else if ( CHECK_ALWAYS_VERBOSE <= m ) + res = -1; + } + else if (CHECK_ALWAYS_VERBOSE <= m + ) { osd_printf_warning("%s:%d: GL Info: object 0x%X validation successful\n", file, line, (unsigned int)(uintptr_t)obj); } break; - } + } - if ( res<0 || CHECK_ALWAYS_VERBOSE <= m ) + if (res < 0 || CHECK_ALWAYS_VERBOSE <= m) { + GLsizei length; + GLcharARB buffer[255]; length=0; pfn_glGetInfoLogARB(obj, sizeof(buffer), &length, buffer); - if(length>0) + if (length>0) osd_printf_warning("%s:%d glInfoLog: %s\n", file, line, buffer); } - (void) glGetError(); // ;-) - + (void)glGetError(); // ;-) return res; } @@ -234,157 +264,175 @@ int gl_round_to_pow2(int v) return v; } -int gl_texture_check_size(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - GLint *avail_width, GLint *avail_height, - int verbose) +int gl_shader_tool::texture_check_size( + GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLint *avail_width, + GLint *avail_height, + bool verbose) { - int err=1; - GLenum texTargetProxy = (target==GL_TEXTURE_RECTANGLE_ARB)?GL_PROXY_TEXTURE_RECTANGLE_ARB:GL_PROXY_TEXTURE_2D; - - if ( !avail_width || !avail_height) - return -1; + if (!avail_width || !avail_height) + return -1; *avail_width = 0; *avail_height = 0; GL_CHECK_ERROR_QUIET(); - /* Test the max texture size */ - while(err && width>=1 && height>=1 /* && width>=64 && height>=64 */) - { - glTexImage2D (texTargetProxy, level, - internalFormat, - width, height, - border, format, type, nullptr); - if ( 0!=(err=GL_CHECK_ERROR_NORMAL() )) return err; - - glGetTexLevelParameteriv( texTargetProxy, level, GL_TEXTURE_WIDTH, avail_width); - glGetTexLevelParameteriv( texTargetProxy, level, GL_TEXTURE_HEIGHT, avail_height); - if ( 0!=(err=GL_CHECK_ERROR_NORMAL() )) return err; - - if ( (*avail_width) != width || (*avail_height) != height ) + // Test the max texture size + int err = 1; + GLenum const texTargetProxy = (target == GL_TEXTURE_RECTANGLE_ARB) ? GL_PROXY_TEXTURE_RECTANGLE_ARB : GL_PROXY_TEXTURE_2D; + while (err && width>=1 && height>=1 /* && width>=64 && height>=64 */) { - err=1; - - if(verbose) + glTexImage2D(texTargetProxy, level, + internalFormat, + width, height, + border, format, type, nullptr); + if (0 != (err=GL_CHECK_ERROR_NORMAL())) + return err; + + glGetTexLevelParameteriv(texTargetProxy, level, GL_TEXTURE_WIDTH, avail_width); + glGetTexLevelParameteriv(texTargetProxy, level, GL_TEXTURE_HEIGHT, avail_height); + if (0 != (err=GL_CHECK_ERROR_NORMAL())) + return err; + + if ((*avail_width != width) || (*avail_height != height)) { - osd_printf_warning("gl_texture_size_check: " - "TexImage2D(0x%X, %d, 0x%X, %d, %d, %d, 0x%X, 0x%X): returned size does not match: %dx%d\n", - (unsigned int)target, (int)level, (int)internalFormat, - (int)width, (int)height, (int)border, (unsigned int)format, (unsigned int)type, - (int)*avail_width, (int)*avail_height); - } - - if ( (*avail_width) == width ) - height /= 2; - else if ( (*avail_height) == height ) - width /= 2; - else if (width > height) + err = 1; + + if (verbose) + { + osd_printf_warning("gl_texture_size_check: " + "TexImage2D(0x%X, %d, 0x%X, %d, %d, %d, 0x%X, 0x%X): returned size does not match: %dx%d\n", + (unsigned int)target, (int)level, (int)internalFormat, + width, height, border, (unsigned int)format, (unsigned int)type, + *avail_width, *avail_height); + } + + if (*avail_width == width) + height /= 2; + else if (*avail_height == height) width /= 2; - else + else if (width > height) + width /= 2; + else height /= 2; - if(verbose) + if (verbose) + { + osd_printf_verbose("gl_texture_size_check: trying [%dx%d] !\n", height, width); + } + } + else { - fprintf (stderr, "gl_texture_size_check: trying [%dx%d] !\n", (int)height, (int)width); + err = 0; } - } else { - err=0; - } } - if(!err) + if (!err) { - *avail_width = width; + *avail_width = width; *avail_height = height; } return err; } -static int delete_shader_tool( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, int externalcall) +int gl_shader_tool::delete_shader_tool( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader, + bool externalcall) { - int res=0; + int res = 0; GL_CHECK_ERROR_QUIET(); - if(program!= nullptr && *program!=0) + if (program && *program!=0) { pfn_glDeleteObjectARB(*program); - if(externalcall) - { + if (externalcall) res |= GL_SHADER_CHECK(*program, GL_OBJECT_DELETE_STATUS_ARB); - } - *program=0; + *program = 0; } - if(vertex_shader!= nullptr && *vertex_shader!=0) + if (vertex_shader && *vertex_shader!=0) { pfn_glDeleteObjectARB(*vertex_shader); - if(externalcall) - { + if (externalcall) res |= GL_SHADER_CHECK(*vertex_shader, GL_OBJECT_DELETE_STATUS_ARB); - } *vertex_shader=0; } - if(fragment_shader!= nullptr && *fragment_shader!=0) + if (fragment_shader && *fragment_shader!=0) { pfn_glDeleteObjectARB(*fragment_shader); - if(externalcall) - { + if (externalcall) res |= GL_SHADER_CHECK(*fragment_shader, GL_OBJECT_DELETE_STATUS_ARB); - } *fragment_shader=0; } - return res; + return res; } -int gl_compile_shader_source( GLhandleARB *shader, GLenum type, const char * shader_source, int verbose ) +int gl_shader_tool::compile_source( + GLhandleARB *shader, + GLenum type, + const char *shader_source, + bool verbose) { - int err = 0; + int err = 0; - if(shader== nullptr || shader_source== nullptr) + if (!shader || !shader_source) { - if(shader== nullptr) + if (!shader) osd_printf_warning("error: gl_compile_shader_source: nullptr shader passed\n"); - if(shader_source== nullptr) + if (!shader_source) osd_printf_warning("error: gl_compile_shader_source: nullptr shader source passed\n"); return -1; } - *shader = pfn_glCreateShaderObjectARB(type); - err=GL_SHADER_CHECK(*shader, GL_OBJECT_TYPE_ARB); - if(err) goto errout; + *shader = pfn_glCreateShaderObjectARB(type); + err = GL_SHADER_CHECK(*shader, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; - pfn_glShaderSourceARB(*shader, 1, (const GLcharARB **)&shader_source, nullptr); + pfn_glShaderSourceARB(*shader, 1, (const GLcharARB **)&shader_source, nullptr); - pfn_glCompileShaderARB(*shader); - err=GL_SHADER_CHECK(*shader, GL_OBJECT_COMPILE_STATUS_ARB); - if(err) goto errout; + pfn_glCompileShaderARB(*shader); + err = GL_SHADER_CHECK(*shader, GL_OBJECT_COMPILE_STATUS_ARB); + if (err) + goto errout; - if(verbose) + if (verbose) osd_printf_warning( "<%s>\n", shader_source); return 0; errout: - if(*shader!=0) - { + if (*shader != 0) pfn_glDeleteObjectARB(*shader); - } + osd_printf_warning("failed to process shader: <%s>\n", shader_source); - return err; + return err; } -int gl_compile_shader_file( GLhandleARB *shader, GLenum type, const char * shader_file, int verbose ) +int gl_shader_tool::compile_file( + GLhandleARB *shader, + GLenum type, + const char *shader_file, + bool verbose) { - if(shader== nullptr || shader_file== nullptr) + if (!shader || !shader_file) { - if(shader== nullptr) + if (!shader) osd_printf_warning("error: gl_compile_shader_source: nullptr shader passed\n"); - if(shader_file== nullptr) + if (!shader_file) osd_printf_warning("error: gl_compile_shader_source: nullptr shader file passed\n"); return -1; } FILE *const file = fopen(shader_file, "r"); - if(!file) + if (!file) { osd_printf_warning("cannot open shader_file: %s\n", shader_file); return -1; @@ -395,19 +443,20 @@ int gl_compile_shader_file( GLhandleARB *shader, GLenum type, const char * shade int const buffer_len = (int)ftell(file); fseek(file, 0, SEEK_SET); - GLcharARB *const buffer = (GLcharARB *)malloc(buffer_len + 1); + auto *const buffer = (GLcharARB *)malloc(buffer_len + 1); memset(buffer, 0, buffer_len + 1); /* Load Shader Sources */ - for( int i = 0, c = 0; i<buffer_len && EOF!=(c=fgetc(file)); i++ ) - buffer[i]=(char)c; + for (int i = 0, c = 0; i<buffer_len && EOF!=(c=fgetc(file)); i++) + buffer[i] = char(c); fclose(file); - int const err=gl_compile_shader_source(shader, type, buffer, verbose); + int const err = compile_source(shader, type, buffer, verbose); free(buffer); - if(err) goto errout; + if (err) + goto errout; - if(verbose) + if (verbose) osd_printf_warning("shader file: %s\n", shader_file); return 0; @@ -418,180 +467,204 @@ errout: } -int gl_compile_shader_files( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, - const char * vertex_shader_file, - const char * fragment_shader_file, - int verbose - ) +int gl_shader_tool::compile_files( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader, + const char * vertex_shader_file, + const char * fragment_shader_file, + bool verbose) { int err; if (!program) { - err=-1; + err = -1; osd_printf_warning("no program ptr passed\n"); goto errout; } if (!vertex_shader) { - err=-1; + err = -1; osd_printf_warning("no vertex_shader ptr passed\n"); goto errout; } if (!fragment_shader) { - err=-1; + err = -1; osd_printf_warning("no fragment_shader ptr passed\n"); goto errout; } - *program = pfn_glCreateProgramObjectARB(); - err=GL_SHADER_CHECK(*program, GL_OBJECT_TYPE_ARB); - if(err) goto errout; + *program = pfn_glCreateProgramObjectARB(); + err=GL_SHADER_CHECK(*program, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; - if(!vertex_shader_file) + if (!vertex_shader_file) { if (!(*vertex_shader)) { - err=-1; + err = -1; osd_printf_warning("no vertex_shader_file, nor vertex_shader id passed\n"); goto errout; } - err=GL_SHADER_CHECK(*vertex_shader, GL_OBJECT_TYPE_ARB); - if(err) goto errout; - } else { - err = gl_compile_shader_file(vertex_shader, GL_VERTEX_SHADER_ARB, vertex_shader_file, verbose); - if(err) return err; + err = GL_SHADER_CHECK(*vertex_shader, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; + } + else + { + err = compile_file(vertex_shader, GL_VERTEX_SHADER_ARB, vertex_shader_file, verbose); + if (err) + return err; } - pfn_glAttachObjectARB(*program, *vertex_shader); + pfn_glAttachObjectARB(*program, *vertex_shader); - if(!fragment_shader_file) + if (!fragment_shader_file) { if (!(*fragment_shader)) { - err=-1; + err = -1; osd_printf_warning("no fragment_shader_file, nor fragment_shader id passed\n"); goto errout; } - err=GL_SHADER_CHECK(*fragment_shader, GL_OBJECT_TYPE_ARB); - if(err) goto errout; - } else { - err = gl_compile_shader_file(fragment_shader, GL_FRAGMENT_SHADER_ARB, fragment_shader_file, verbose); - if(err) return err; + err = GL_SHADER_CHECK(*fragment_shader, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; + } + else + { + err = compile_file(fragment_shader, GL_FRAGMENT_SHADER_ARB, fragment_shader_file, verbose); + if (err) + return err; } - pfn_glAttachObjectARB(*program, *fragment_shader); + pfn_glAttachObjectARB(*program, *fragment_shader); - pfn_glLinkProgramARB(*program); - err=GL_SHADER_CHECK(*program, GL_OBJECT_LINK_STATUS_ARB); - if(err) goto errout; + pfn_glLinkProgramARB(*program); + err = GL_SHADER_CHECK(*program, GL_OBJECT_LINK_STATUS_ARB); + if (err) + goto errout; - pfn_glValidateProgramARB(*program); - err=GL_SHADER_CHECK(*program, GL_OBJECT_VALIDATE_STATUS_ARB); - if(err) goto errout; + pfn_glValidateProgramARB(*program); + err = GL_SHADER_CHECK(*program, GL_OBJECT_VALIDATE_STATUS_ARB); + if (err) + goto errout; - return 0; + return 0; errout: - delete_shader_tool(program, vertex_shader, fragment_shader, 0); - return err; + delete_shader_tool(program, vertex_shader, fragment_shader, false); + return err; } -int gl_compile_shader_sources( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, - const GLcharARB * vertex_shader_source, - const GLcharARB * fragment_shader_source - ) +int gl_shader_tool::compile_sources( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader, + const GLcharARB * vertex_shader_source, + const GLcharARB * fragment_shader_source) { - int err = 0; + int err = 0; if (!program) { - err=-1; + err = -1; osd_printf_warning("no program ptr passed\n"); goto errout; } if (!vertex_shader) { - err=-1; + err = -1; osd_printf_warning("no vertex_shader ptr passed\n"); goto errout; } if (!fragment_shader) { - err=-1; + err = -1; osd_printf_warning("no fragment_shader ptr passed\n"); goto errout; } - *program = pfn_glCreateProgramObjectARB(); - err=GL_SHADER_CHECK(*program, GL_OBJECT_TYPE_ARB); - if(err) goto errout; + *program = pfn_glCreateProgramObjectARB(); + err = GL_SHADER_CHECK(*program, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; - if(!vertex_shader_source) + if (!vertex_shader_source) { if (!(*vertex_shader)) { - err=-1; + err = -1; osd_printf_warning("no vertex_shader_source nor a vertex_shader id passed\n"); goto errout; } - err=GL_SHADER_CHECK(*vertex_shader, GL_OBJECT_TYPE_ARB); - if(err) goto errout; + err = GL_SHADER_CHECK(*vertex_shader, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; } - if(!fragment_shader_source) + if (!fragment_shader_source) { if (!(*fragment_shader)) { - err=-1; + err = -1; osd_printf_warning("no fragment_shader_source nor a fragment_shader id passed\n"); goto errout; } - err=GL_SHADER_CHECK(*fragment_shader, GL_OBJECT_TYPE_ARB); - if(err) goto errout; + err = GL_SHADER_CHECK(*fragment_shader, GL_OBJECT_TYPE_ARB); + if (err) + goto errout; } - if(vertex_shader_source) + if (vertex_shader_source) { - err=gl_compile_shader_source(vertex_shader, GL_VERTEX_SHADER_ARB, vertex_shader_source, 0); - if(err) goto errout; + err = compile_source(vertex_shader, GL_VERTEX_SHADER_ARB, vertex_shader_source, false); + if (err) + goto errout; } - pfn_glAttachObjectARB(*program, *vertex_shader); + pfn_glAttachObjectARB(*program, *vertex_shader); - if(fragment_shader_source) + if (fragment_shader_source) { - err=gl_compile_shader_source(fragment_shader, GL_FRAGMENT_SHADER_ARB, fragment_shader_source, 0); - if(err) goto errout; + err = compile_source(fragment_shader, GL_FRAGMENT_SHADER_ARB, fragment_shader_source, false); + if (err) + goto errout; } - pfn_glAttachObjectARB(*program, *fragment_shader); + pfn_glAttachObjectARB(*program, *fragment_shader); - pfn_glLinkProgramARB(*program); - err=GL_SHADER_CHECK(*program, GL_OBJECT_LINK_STATUS_ARB); - if(err) { + pfn_glLinkProgramARB(*program); + err = GL_SHADER_CHECK(*program, GL_OBJECT_LINK_STATUS_ARB); + if (err) + { osd_printf_warning("failed to link program\n"); osd_printf_warning("vertex shader: <%s>\n", vertex_shader_source); osd_printf_warning("fragment shader: <%s>\n", fragment_shader_source); goto errout; } - pfn_glValidateProgramARB(*program); - err=GL_SHADER_CHECK(*program, GL_OBJECT_VALIDATE_STATUS_ARB); - if(err) { + pfn_glValidateProgramARB(*program); + err = GL_SHADER_CHECK(*program, GL_OBJECT_VALIDATE_STATUS_ARB); + if (err) + { osd_printf_warning("failed to validate program\n"); osd_printf_warning("vertex shader: <%s>\n", vertex_shader_source); osd_printf_warning("fragment shader: <%s>\n", fragment_shader_source); goto errout; } - return 0; + return 0; errout: - delete_shader_tool(program, vertex_shader, fragment_shader, 0); - return err; - + delete_shader_tool(program, vertex_shader, fragment_shader, false); + return err; } -int gl_delete_shader( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader ) +int gl_shader_tool::delete_shader( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader) { - return delete_shader_tool(program, vertex_shader, fragment_shader, 1); + return delete_shader_tool(program, vertex_shader, fragment_shader, true); } diff --git a/src/osd/modules/opengl/gl_shader_tool.h b/src/osd/modules/opengl/gl_shader_tool.h index 2e0160cf85d..50845bd590f 100644 --- a/src/osd/modules/opengl/gl_shader_tool.h +++ b/src/osd/modules/opengl/gl_shader_tool.h @@ -7,7 +7,8 @@ * Copyright (c) 2007, Sven Gothel * Copyright (c) 2007, MAME Team * - * GPL version 2 + * May be distributed under the terms of the GNU General Public + * License, version 2.0, or the 3-Clause BSD License. * * OpenGL GLSL ARB extensions: * @@ -17,10 +18,14 @@ * GL_ARB_fragment_shader * */ +#ifndef MAME_OSD_OPENGL_GL_SHADER_TOOL_H +#define MAME_OSD_OPENGL_GL_SHADER_TOOL_H +#pragma once -#ifndef _GL_SHADER_TOOL_ -#define _GL_SHADER_TOOL_ +#include "osd_opengl.h" + +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -36,14 +41,10 @@ extern "C" { * */ -#include <stdint.h> - #ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES 1 #endif -#include "osd_opengl.h" - #if defined(SDLMAME_MACOSX) #ifndef APIENTRY @@ -55,80 +56,6 @@ extern "C" { #endif -typedef void * (APIENTRYP PFNGLGETPROCADDRESSOS)(const char *procName); - -/** - * YOU HAVE TO CALL THIS FUNCTION ONCE ! - * @return 0 - ok .. all shader ARB functions loaded - * otherwise !=0 - */ -int gl_shader_loadExtention(osd_gl_context *gl_ctx); - -enum GLSLCheckMode { - CHECK_QUIET, /* just return 0, if no error, otherwise the GL error code, no stderr output */ - CHECK_VERBOSE, /* same as CHECK_QUIET, but in the case of an error, use stderr to be verbose */ - CHECK_ALWAYS_VERBOSE /* always print out all information available */ -}; - -#define GL_CHECK_ERROR_VERBOSE() gl_check_error(CHECK_ALWAYS_VERBOSE,__FILE__,__LINE__) -#define GL_CHECK_ERROR_NORMAL() gl_check_error(CHECK_VERBOSE,__FILE__,__LINE__) -#define GL_CHECK_ERROR_QUIET() gl_check_error(CHECK_QUIET,__FILE__,__LINE__) -#define GL_CHECK_ERROR(m) gl_check_error(m,__FILE__,__LINE__) - -#define GL_SHADER_CHECK_ERROR_VERBOSE(o,q) gl_shader_check_error(o,q,CHECK_ALWAYS_VERBOSE,__FILE__,__LINE__) -#define GL_SHADER_CHECK_ERROR_NORMAL(o,q) gl_shader_check_error(o,q,CHECK_VERBOSE,__FILE__,__LINE__) -#define GL_SHADER_CHECK_ERROR_QUIET(o,q) gl_shader_check_error(o,q,CHECK_QUIET,__FILE__,__LINE__) -#define GL_SHADER_CHECK_ERROR(o,q,m) gl_shader_check_error(o,q,m,__FILE__,__LINE__) - -#ifdef GL_SHADER_TOOL_DEBUG - #define GL_SHADER_CHECK(o,q) GL_SHADER_CHECK_ERROR_VERBOSE(o,q) - #define GL_CHECK() GL_CHECK_ERROR_VERBOSE() -#else - #define GL_SHADER_CHECK(o,q) GL_SHADER_CHECK_ERROR_NORMAL(o,q) - #define GL_CHECK() GL_CHECK_ERROR_NORMAL() -#endif - -int gl_check_error(GLSLCheckMode m, const char *file, const int line); - -int gl_texture_check_size(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - GLsizei *avail_width, GLsizei *avail_height, - int verbose); - -int gl_round_to_pow2(int v); - -/** - * @param obj_query Can be either GL_OBJECT_TYPE_ARB, GL_OBJECT_DELETE_STATUS_ARB, GL_OBJECT_COMPILE_STATUS_ARB, - * GL_OBJECT_LINK_STATUS_ARB, GL_OBJECT_VALIDATE_STATUS_ARB - * Should be used after the referring action, i.e. GL_OBJECT_DELETE_STATUS_ARB after a - * glDeleteObjectARB call, etc. - */ -int gl_shader_check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, const char *file, const int line); - -int gl_compile_shader_file ( GLhandleARB *shader, GLenum type, const char * shader_file, int verbose ); -int gl_compile_shader_source( GLhandleARB *shader, GLenum type, const char * shader_source, int verbose ); - -/** - * you can pass either a valid shader_file, or a precompiled vertex_shader, - * this is true for both, vertex and fragment shaders. - */ -int gl_compile_shader_files( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, - const char * vertex_shader_file, - const char * fragment_shader_file, - int verbose - ); - -/** - * you can pass either a valid shader_file, or a precompiled vertex_shader, - * this is true for both, vertex and fragment shaders. - */ -int gl_compile_shader_sources( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, - const GLcharARB * vertex_shader_source, - const GLcharARB * fragment_shader_source - ); - -int gl_delete_shader( GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader ); - #if defined(SDLMAME_MACOSX) #ifndef GL_ARB_shader_objects typedef char GLcharARB; @@ -158,32 +85,118 @@ typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); #endif -extern PFNGLGETOBJECTPARAMETERIVARBPROC pfn_glGetObjectParameterivARB; -extern PFNGLGETINFOLOGARBPROC pfn_glGetInfoLogARB; -extern PFNGLDELETEOBJECTARBPROC pfn_glDeleteObjectARB; -extern PFNGLCREATESHADEROBJECTARBPROC pfn_glCreateShaderObjectARB; -extern PFNGLSHADERSOURCEARBPROC pfn_glShaderSourceARB; -extern PFNGLCOMPILESHADERARBPROC pfn_glCompileShaderARB; -extern PFNGLCREATEPROGRAMOBJECTARBPROC pfn_glCreateProgramObjectARB; -extern PFNGLATTACHOBJECTARBPROC pfn_glAttachObjectARB; -extern PFNGLLINKPROGRAMARBPROC pfn_glLinkProgramARB; -extern PFNGLVALIDATEPROGRAMARBPROC pfn_glValidateProgramARB; -extern PFNGLUSEPROGRAMOBJECTARBPROC pfn_glUseProgramObjectARB; -extern PFNGLGETUNIFORMLOCATIONARBPROC pfn_glGetUniformLocationARB; -extern PFNGLUNIFORM1FARBPROC pfn_glUniform1fARB; -extern PFNGLUNIFORM1IARBPROC pfn_glUniform1iARB; -extern PFNGLUNIFORM1FVARBPROC pfn_glUniform1fvARB; -extern PFNGLUNIFORM2FVARBPROC pfn_glUniform2fvARB; -extern PFNGLUNIFORM3FVARBPROC pfn_glUniform3fvARB; -extern PFNGLUNIFORM4FVARBPROC pfn_glUniform4fvARB; -extern PFNGLUNIFORM1IVARBPROC pfn_glUniform1ivARB; -extern PFNGLUNIFORM2IVARBPROC pfn_glUniform2ivARB; -extern PFNGLUNIFORM3IVARBPROC pfn_glUniform3ivARB; -extern PFNGLUNIFORM4IVARBPROC pfn_glUniform4ivARB; - +typedef void * (APIENTRYP PFNGLGETPROCADDRESSOS)(const char *procName); #ifdef __cplusplus } #endif +class gl_shader_tool +{ +public: + gl_shader_tool( +#if defined(USE_DISPATCH_GL) + osd_gl_dispatch *gld #endif + ); + + PFNGLGETOBJECTPARAMETERIVARBPROC pfn_glGetObjectParameterivARB; + PFNGLGETINFOLOGARBPROC pfn_glGetInfoLogARB; + PFNGLDELETEOBJECTARBPROC pfn_glDeleteObjectARB; + PFNGLCREATESHADEROBJECTARBPROC pfn_glCreateShaderObjectARB; + PFNGLSHADERSOURCEARBPROC pfn_glShaderSourceARB; + PFNGLCOMPILESHADERARBPROC pfn_glCompileShaderARB; + PFNGLCREATEPROGRAMOBJECTARBPROC pfn_glCreateProgramObjectARB; + PFNGLATTACHOBJECTARBPROC pfn_glAttachObjectARB; + PFNGLLINKPROGRAMARBPROC pfn_glLinkProgramARB; + PFNGLVALIDATEPROGRAMARBPROC pfn_glValidateProgramARB; + PFNGLUSEPROGRAMOBJECTARBPROC pfn_glUseProgramObjectARB; + PFNGLGETUNIFORMLOCATIONARBPROC pfn_glGetUniformLocationARB; + PFNGLUNIFORM1FARBPROC pfn_glUniform1fARB; + PFNGLUNIFORM1IARBPROC pfn_glUniform1iARB; + PFNGLUNIFORM1FVARBPROC pfn_glUniform1fvARB; + PFNGLUNIFORM2FVARBPROC pfn_glUniform2fvARB; + PFNGLUNIFORM3FVARBPROC pfn_glUniform3fvARB; + PFNGLUNIFORM4FVARBPROC pfn_glUniform4fvARB; + PFNGLUNIFORM1IVARBPROC pfn_glUniform1ivARB; + PFNGLUNIFORM2IVARBPROC pfn_glUniform2ivARB; + PFNGLUNIFORM3IVARBPROC pfn_glUniform3ivARB; + PFNGLUNIFORM4IVARBPROC pfn_glUniform4ivARB; + + /** + * YOU HAVE TO CALL THIS FUNCTION ONCE ! + * @return true - ok .. all shader ARB functions loaded + * otherwise false + */ + bool load_extension(osd_gl_context &gl_ctx); + + int texture_check_size( + GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei *avail_width, + GLsizei *avail_height, + bool verbose); + +protected: + int compile_file(GLhandleARB *shader, GLenum type, const char *shader_file, bool verbose); + int compile_source(GLhandleARB *shader, GLenum type, const char *shader_source, bool verbose); + + /** + * you can pass either a valid shader_file, or a precompiled vertex_shader, + * this is true for both, vertex and fragment shaders. + */ + int compile_files( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader, + const char *vertex_shader_file, + const char *fragment_shader_file, + bool verbose); + + /** + * you can pass either a valid shader_file, or a precompiled vertex_shader, + * this is true for both, vertex and fragment shaders. + */ + int compile_sources( + GLhandleARB *program, + GLhandleARB *vertex_shader, + GLhandleARB *fragment_shader, + const GLcharARB *vertex_shader_source, + const GLcharARB *fragment_shader_source); + + int delete_shader(GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader); + +#if defined(USE_DISPATCH_GL) + osd_gl_dispatch *const gl_dispatch; // name is magic, can't be changed +#endif + +private: + enum GLSLCheckMode + { + CHECK_QUIET, // just return 0, if no error, otherwise the GL error code, no stderr output + CHECK_VERBOSE, // same as CHECK_QUIET, but in the case of an error, use stderr to be verbose + CHECK_ALWAYS_VERBOSE // always print out all information available + }; + + int check_error(GLSLCheckMode m, const char *file, const int line); + + /** + * @param obj_query Can be either GL_OBJECT_TYPE_ARB, GL_OBJECT_DELETE_STATUS_ARB, GL_OBJECT_COMPILE_STATUS_ARB, + * GL_OBJECT_LINK_STATUS_ARB, GL_OBJECT_VALIDATE_STATUS_ARB + * Should be used after the referring action, i.e. GL_OBJECT_DELETE_STATUS_ARB after a + * glDeleteObjectARB call, etc. + */ + int check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, const char *file, const int line); + + int delete_shader_tool(GLhandleARB *program, GLhandleARB *vertex_shader, GLhandleARB *fragment_shader, bool externalcall); +}; + +int gl_round_to_pow2(int v); + +#endif // MAME_OSD_OPENGL_GL_SHADER_TOOL_H diff --git a/src/osd/modules/opengl/osd_opengl.h b/src/osd/modules/opengl/osd_opengl.h index 47d0b3c429c..712b3b880b4 100644 --- a/src/osd/modules/opengl/osd_opengl.h +++ b/src/osd/modules/opengl/osd_opengl.h @@ -21,7 +21,7 @@ #ifdef _MSC_VER #include <windows.h> #include "GL/GL.h" - #include "bgfx/3rdparty/khronos/gl/glext.h " + #include "bgfx/3rdparty/khronos/gl/glext.h" #ifndef USE_DISPATCH_GL #include "bgfx/3rdparty/khronos/wgl/wglext.h" #endif @@ -36,35 +36,38 @@ #include <OpenGL/gl.h> #include <OpenGL/glext.h> #else - #include <SDL2/SDL_version.h> - - #if (SDL_VERSION_ATLEAST(1,2,10)) - #if defined(SDLMAME_WIN32) - // Avoid that winnt.h (included via sdl_opengl.h, windows.h, windef.h includes intrin.h - #define __INTRIN_H_ - #endif - #include <SDL2/SDL_opengl.h> - #endif + #include <SDL2/SDL_version.h> + #include <SDL2/SDL_opengl.h> #endif class osd_gl_context { public: - osd_gl_context() { } - virtual ~osd_gl_context() { } - virtual void MakeCurrent() = 0; - virtual const char *LastErrorMsg() = 0; - virtual void *getProcAddress(const char *proc) = 0; + virtual ~osd_gl_context() = default; + + virtual explicit operator bool() const = 0; + + virtual void make_current() = 0; + virtual const char *last_error_message() = 0; + virtual void *get_proc_address(const char *proc) = 0; + /* * 0 for immediate updates, * 1 for updates synchronized with the vertical retrace, * -1 for late swap tearing * - * returns -1 if swap interval is not supported - * + * returns false if swap interval is not supported */ - virtual int SetSwapInterval(const int swap) = 0; - virtual void SwapBuffer() = 0; + virtual bool set_swap_interval(const int swap) = 0; + + virtual void swap_buffer() = 0; + + template <typename T> + bool get_proc_address(T &ptr, const char *name) + { + ptr = T(uintptr_t(get_proc_address(name))); + return bool(ptr); + } }; @@ -100,11 +103,6 @@ #undef OSD_GL #undef OSD_GL_UNUSED -#ifdef _MSC_VER - extern "C" osd_gl_dispatch *gl_dispatch; -#endif - extern osd_gl_dispatch *gl_dispatch; - /* * Use gl_mangle to map function names */ @@ -127,67 +125,67 @@ * ***************************************************************/ - #define glAccum MANGLE(Accum) - #define glActiveStencilFaceEXT MANGLE(ActiveStencilFaceEXT) - #define glActiveTextureARB MANGLE(ActiveTextureARB) - #define glActiveTexture MANGLE(ActiveTexture) - #define glAlphaFragmentOp1ATI MANGLE(AlphaFragmentOp1ATI) - #define glAlphaFragmentOp2ATI MANGLE(AlphaFragmentOp2ATI) - #define glAlphaFragmentOp3ATI MANGLE(AlphaFragmentOp3ATI) - #define glAlphaFunc MANGLE(AlphaFunc) - #define glApplyTextureEXT MANGLE(ApplyTextureEXT) - #define glAreProgramsResidentNV MANGLE(AreProgramsResidentNV) + #define glAccum MANGLE(Accum) + #define glActiveStencilFaceEXT MANGLE(ActiveStencilFaceEXT) + #define glActiveTextureARB MANGLE(ActiveTextureARB) + #define glActiveTexture MANGLE(ActiveTexture) + #define glAlphaFragmentOp1ATI MANGLE(AlphaFragmentOp1ATI) + #define glAlphaFragmentOp2ATI MANGLE(AlphaFragmentOp2ATI) + #define glAlphaFragmentOp3ATI MANGLE(AlphaFragmentOp3ATI) + #define glAlphaFunc MANGLE(AlphaFunc) + #define glApplyTextureEXT MANGLE(ApplyTextureEXT) + #define glAreProgramsResidentNV MANGLE(AreProgramsResidentNV) #define glAreTexturesResidentEXT MANGLE(AreTexturesResidentEXT) - #define glAreTexturesResident MANGLE(AreTexturesResident) - #define glArrayElementEXT MANGLE(ArrayElementEXT) - #define glArrayElement MANGLE(ArrayElement) - #define glArrayObjectATI MANGLE(ArrayObjectATI) - #define glAsyncMarkerSGIX MANGLE(AsyncMarkerSGIX) - #define glAttachObjectARB MANGLE(AttachObjectARB) - #define glAttachShader MANGLE(AttachShader) + #define glAreTexturesResident MANGLE(AreTexturesResident) + #define glArrayElementEXT MANGLE(ArrayElementEXT) + #define glArrayElement MANGLE(ArrayElement) + #define glArrayObjectATI MANGLE(ArrayObjectATI) + #define glAsyncMarkerSGIX MANGLE(AsyncMarkerSGIX) + #define glAttachObjectARB MANGLE(AttachObjectARB) + #define glAttachShader MANGLE(AttachShader) #define glBeginFragmentShaderATI MANGLE(BeginFragmentShaderATI) - #define glBegin MANGLE(Begin) - #define glBeginOcclusionQueryNV MANGLE(BeginOcclusionQueryNV) - #define glBeginQueryARB MANGLE(BeginQueryARB) - #define glBeginQuery MANGLE(BeginQuery) - #define glBeginVertexShaderEXT MANGLE(BeginVertexShaderEXT) - #define glBindAttribLocationARB MANGLE(BindAttribLocationARB) - #define glBindAttribLocation MANGLE(BindAttribLocation) - #define glBindBufferARB MANGLE(BindBufferARB) - #define glBindBuffer MANGLE(BindBuffer) - #define glBindFragmentShaderATI MANGLE(BindFragmentShaderATI) - #define glBindFramebufferEXT MANGLE(BindFramebufferEXT) - #define glBindLightParameterEXT MANGLE(BindLightParameterEXT) + #define glBegin MANGLE(Begin) + #define glBeginOcclusionQueryNV MANGLE(BeginOcclusionQueryNV) + #define glBeginQueryARB MANGLE(BeginQueryARB) + #define glBeginQuery MANGLE(BeginQuery) + #define glBeginVertexShaderEXT MANGLE(BeginVertexShaderEXT) + #define glBindAttribLocationARB MANGLE(BindAttribLocationARB) + #define glBindAttribLocation MANGLE(BindAttribLocation) + #define glBindBufferARB MANGLE(BindBufferARB) + #define glBindBuffer MANGLE(BindBuffer) + #define glBindFragmentShaderATI MANGLE(BindFragmentShaderATI) + #define glBindFramebufferEXT MANGLE(BindFramebufferEXT) + #define glBindLightParameterEXT MANGLE(BindLightParameterEXT) #define glBindMaterialParameterEXT MANGLE(BindMaterialParameterEXT) - #define glBindParameterEXT MANGLE(BindParameterEXT) - #define glBindProgramARB MANGLE(BindProgramARB) - #define glBindProgramNV MANGLE(BindProgramNV) - #define glBindRenderbufferEXT MANGLE(BindRenderbufferEXT) + #define glBindParameterEXT MANGLE(BindParameterEXT) + #define glBindProgramARB MANGLE(BindProgramARB) + #define glBindProgramNV MANGLE(BindProgramNV) + #define glBindRenderbufferEXT MANGLE(BindRenderbufferEXT) #define glBindTexGenParameterEXT MANGLE(BindTexGenParameterEXT) - #define glBindTextureEXT MANGLE(BindTextureEXT) - #define glBindTexture MANGLE(BindTexture) - #define glBindTextureUnitParameterEXT MANGLE(BindTextureUnitParameterEXT) - #define glBindVertexArrayAPPLE MANGLE(BindVertexArrayAPPLE) - #define glBindVertexShaderEXT MANGLE(BindVertexShaderEXT) - #define glBinormal3bEXT MANGLE(Binormal3bEXT) - #define glBinormal3bvEXT MANGLE(Binormal3bvEXT) - #define glBinormal3dEXT MANGLE(Binormal3dEXT) - #define glBinormal3dvEXT MANGLE(Binormal3dvEXT) - #define glBinormal3fEXT MANGLE(Binormal3fEXT) - #define glBinormal3fvEXT MANGLE(Binormal3fvEXT) - #define glBinormal3iEXT MANGLE(Binormal3iEXT) - #define glBinormal3ivEXT MANGLE(Binormal3ivEXT) - #define glBinormal3sEXT MANGLE(Binormal3sEXT) - #define glBinormal3svEXT MANGLE(Binormal3svEXT) - #define glBinormalPointerEXT MANGLE(BinormalPointerEXT) - #define glBitmap MANGLE(Bitmap) - #define glBlendColorEXT MANGLE(BlendColorEXT) - #define glBlendColor MANGLE(BlendColor) - #define glBlendEquationEXT MANGLE(BlendEquationEXT) - #define glBlendEquation MANGLE(BlendEquation) + #define glBindTextureEXT MANGLE(BindTextureEXT) + #define glBindTexture MANGLE(BindTexture) + #define glBindTextureUnitParameterEXT MANGLE(BindTextureUnitParameterEXT) + #define glBindVertexArrayAPPLE MANGLE(BindVertexArrayAPPLE) + #define glBindVertexShaderEXT MANGLE(BindVertexShaderEXT) + #define glBinormal3bEXT MANGLE(Binormal3bEXT) + #define glBinormal3bvEXT MANGLE(Binormal3bvEXT) + #define glBinormal3dEXT MANGLE(Binormal3dEXT) + #define glBinormal3dvEXT MANGLE(Binormal3dvEXT) + #define glBinormal3fEXT MANGLE(Binormal3fEXT) + #define glBinormal3fvEXT MANGLE(Binormal3fvEXT) + #define glBinormal3iEXT MANGLE(Binormal3iEXT) + #define glBinormal3ivEXT MANGLE(Binormal3ivEXT) + #define glBinormal3sEXT MANGLE(Binormal3sEXT) + #define glBinormal3svEXT MANGLE(Binormal3svEXT) + #define glBinormalPointerEXT MANGLE(BinormalPointerEXT) + #define glBitmap MANGLE(Bitmap) + #define glBlendColorEXT MANGLE(BlendColorEXT) + #define glBlendColor MANGLE(BlendColor) + #define glBlendEquationEXT MANGLE(BlendEquationEXT) + #define glBlendEquation MANGLE(BlendEquation) #define glBlendEquationSeparateATI MANGLE(BlendEquationSeparateATI) #define glBlendEquationSeparateEXT MANGLE(BlendEquationSeparateEXT) - #define glBlendEquationSeparate MANGLE(BlendEquationSeparate) + #define glBlendEquationSeparate MANGLE(BlendEquationSeparate) #define glBlendFunc MANGLE(BlendFunc) #define glBlendFuncSeparateEXT MANGLE(BlendFuncSeparateEXT) #define glBlendFuncSeparateINGR MANGLE(BlendFuncSeparateINGR) |