diff options
Diffstat (limited to 'src/osd/modules/opengl/gl_shader_mgr.cpp')
-rw-r--r-- | src/osd/modules/opengl/gl_shader_mgr.cpp | 376 |
1 files changed, 205 insertions, 171 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; } |