Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLSL Bilinear Filter Fixes and Add Bicubic Filter #2989

Merged
merged 3 commits into from
Jan 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/osd/modules/lib/osdobj_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_GL_VBO, "1", OPTION_BOOLEAN, "enable OpenGL VBO, if available (default on)" },
{ OSDOPTION_GL_PBO, "1", OPTION_BOOLEAN, "enable OpenGL PBO, if available (default on)" },
{ OSDOPTION_GL_GLSL, "0", OPTION_BOOLEAN, "enable OpenGL GLSL, if available (default off)" },
{ OSDOPTION_GLSL_FILTER, "1", OPTION_STRING, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default)" },
{ OSDOPTION_GLSL_FILTER, "1", OPTION_STRING, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default), 2-bicubic" },
{ OSDOPTION_SHADER_MAME "0", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 0" },
{ OSDOPTION_SHADER_MAME "1", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 1" },
{ OSDOPTION_SHADER_MAME "2", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 2" },
Expand Down
2 changes: 1 addition & 1 deletion src/osd/modules/lib/osdobj_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class osd_options : public emu_options
bool gl_vbo() const { return bool_value(OSDOPTION_GL_VBO); }
bool gl_pbo() const { return bool_value(OSDOPTION_GL_PBO); }
bool gl_glsl() const { return bool_value(OSDOPTION_GL_GLSL); }
bool glsl_filter() const { return bool_value(OSDOPTION_GLSL_FILTER); }
int glsl_filter() const { return int_value(OSDOPTION_GLSL_FILTER); }
const char *shader_mame(int index) const { return value(string_format("%s%d", OSDOPTION_SHADER_MAME, index).c_str()); }
const char *shader_screen(int index) const { return value(string_format("%s%d", OSDOPTION_SHADER_SCREEN, index).c_str()); }

Expand Down
17 changes: 11 additions & 6 deletions src/osd/modules/opengl/gl_shader_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ static const char * glsl_mamebm_vsh_files [GLSL_VERTEX_SHADER_INT_NUMBER] =
static const char * glsl_mamebm_fsh_files [GLSL_SHADER_FEAT_INT_NUMBER] =
{
"/tmp/glsl_plain_rgb32_dir.fsh", // rgb32 dir plain
"/tmp/glsl_bilinear_rgb32_dir.fsh" // rgb32 dir bilinear
"/tmp/glsl_bilinear_rgb32_dir.fsh", // rgb32 dir bilinear
"/tmp/glsl_bicubic_rgb32_dir.fsh", // rgb32 dir bicubic
};

#else // GLSL_SOURCE_ON_DISK
Expand All @@ -32,6 +33,7 @@ static const char * glsl_mamebm_fsh_files [GLSL_SHADER_FEAT_INT_NUMBER] =

#include "shader/glsl_plain_rgb32_dir.fsh.c"
#include "shader/glsl_bilinear_rgb32_dir.fsh.c"
#include "shader/glsl_bicubic_rgb32_dir.fsh.c"

static const char * glsl_mamebm_vsh_sources [GLSL_VERTEX_SHADER_INT_NUMBER] =
{
Expand All @@ -40,8 +42,9 @@ static const char * glsl_mamebm_vsh_sources [GLSL_VERTEX_SHADER_INT_NUMBER] =

static const char * glsl_mamebm_fsh_sources [GLSL_SHADER_FEAT_INT_NUMBER] =
{
glsl_plain_rgb32_dir_fsh_src, // rgb32 dir plain
glsl_bilinear_rgb32_dir_fsh_src // rgb32 dir bilinear
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
Expand All @@ -50,12 +53,13 @@ static const char * 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 /* rgb32 dir: plain, bilinear, custom0-9, .. */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* rgb32 dir: plain, bilinear, bicubic, custom0-9, .. */
};

/**
Expand All @@ -65,6 +69,7 @@ static int glsl_mamebm_fsh2vsh[GLSL_SHADER_FEAT_MAX_NUMBER] =
{
0, // plain -> general
0, // bilinear -> general
0, // bicubic -> general
1, // custom -> custom
};

Expand All @@ -75,7 +80,7 @@ static GLhandleARB glsl_mamebm_vsh_shader[GLSL_VERTEX_SHADER_MAX_NUMBER+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 /* rgb32 dir: plain, bilinear, custom0-9 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* rgb32 dir: plain, bilinear, bicubic, custom0-9 */
};

static GLhandleARB glsl_scrn_programs [10] =
Expand Down Expand Up @@ -145,7 +150,7 @@ glsl_shader_info *glsl_shader_init(osd_gl_context *gl_ctx)
if(glsl_mamebm_fsh_files[j])
err = gl_compile_shader_files (&glsl_mamebm_programs[j],
&glsl_mamebm_vsh_shader[glsl_mamebm_fsh2vsh[j]],
&glsl_mamebmfsh_shader[j],
&glsl_mamebm_fsh_shader[j],
nullptr /*precompiled*/, glsl_mamebm_fsh_files[j], 0);
#else
if(glsl_mamebm_fsh_sources[j])
Expand Down
1 change: 1 addition & 0 deletions src/osd/modules/opengl/gl_shader_mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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
Expand Down
4 changes: 4 additions & 0 deletions src/osd/modules/opengl/shader/genc.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ echo "const char glsl_bilinear_rgb32_dir_fsh_src[] =" > glsl_bilinear_rgb32_dir.
sed -e 's/^/"/g' -e 's/$/\\n"/g' glsl_bilinear_rgb32_dir.fsh >> glsl_bilinear_rgb32_dir.fsh.c
echo ";" >> glsl_bilinear_rgb32_dir.fsh.c

echo "const char glsl_bicubic_rgb32_dir_fsh_src[] =" > glsl_bicubic_rgb32_dir.fsh.c
sed -e 's/^/"/g' -e 's/$/\\n"/g' glsl_bicubic_rgb32_dir.fsh >> glsl_bicubic_rgb32_dir.fsh.c
echo ";" >> glsl_bicubic_rgb32_dir.fsh.c

81 changes: 81 additions & 0 deletions src/osd/modules/opengl/shader/glsl_bicubic_rgb32_dir.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Stover
#pragma optimize (on)
#pragma debug (off)

uniform sampler2D color_texture;
uniform vec2 color_texture_pow2_sz; // pow2 tex size
uniform vec4 vid_attributes; // gamma, contrast, brightness

#define TEX2D(v) texture2D(color_texture,(v))

void main()
{
vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5;
vec2 uv_ratio = fract(pixel);
vec2 one = 1.0 / color_texture_pow2_sz;
vec2 xy = (floor(pixel) + 0.5) * one;

//
// Robert G. Keys'
//
// 'Cubic Convolution Interpolation for Digital Image Processing'
// IEEE TRANSACTIONS ON ACOUSTICS, SPEECH, AND SIGNAL PROCESSING,
// VOL. ASSP-29, NO. 6, DECEMBER 1981
//
// gives the following equation:
//
// g(x) = c_k-1(-s^3 + 2s^2 - s)/2
// + c_k(3s^3 - 5s^2 + 2)/2
// + c_k+1(-3s^3 + 4s^2 + s)/2
// + c_k+2(s^3 - s^2)/2
//
// c_* are the sample values, s is our uv_ratio.
//
// Weight equations are taken from above.
//
vec2 s = uv_ratio;
vec2 s2 = uv_ratio*uv_ratio;
vec2 s3 = uv_ratio*uv_ratio*uv_ratio;
vec2 w0 = 0.5 * (-s3 + 2.0*s2 - s);
vec2 w1 = 0.5 * (3.0*s3 - 5.0*s2 + 2.0);
vec2 w2 = 0.5 * (-3.0*s3 + 4.0*s2 + s);
vec2 w3 = 0.5 * (s3 - s2);

// Compute the coordinates to sample from
vec2 pos0 = xy - 1.0*one.xy;
vec2 pos1 = xy;
vec2 pos2 = xy + 1.0*one.xy;
vec2 pos3 = xy + 2.0*one.xy;

// Finally - take the samples, multiply by weight, and sum
vec4 col = vec4(0.0);
col += TEX2D(vec2(pos0.x, pos0.y)) * w0.x * w0.y;
col += TEX2D(vec2(pos1.x, pos0.y)) * w1.x * w0.y;
col += TEX2D(vec2(pos2.x, pos0.y)) * w2.x * w0.y;
col += TEX2D(vec2(pos3.x, pos0.y)) * w3.x * w0.y;

col += TEX2D(vec2(pos0.x, pos1.y)) * w0.x * w1.y;
col += TEX2D(vec2(pos1.x, pos1.y)) * w1.x * w1.y;
col += TEX2D(vec2(pos2.x, pos1.y)) * w2.x * w1.y;
col += TEX2D(vec2(pos3.x, pos1.y)) * w3.x * w1.y;

col += TEX2D(vec2(pos0.x, pos2.y)) * w0.x * w2.y;
col += TEX2D(vec2(pos1.x, pos2.y)) * w1.x * w2.y;
col += TEX2D(vec2(pos2.x, pos2.y)) * w2.x * w2.y;
col += TEX2D(vec2(pos3.x, pos2.y)) * w3.x * w2.y;

col += TEX2D(vec2(pos0.x, pos3.y)) * w0.x * w3.y;
col += TEX2D(vec2(pos1.x, pos3.y)) * w1.x * w3.y;
col += TEX2D(vec2(pos2.x, pos3.y)) * w2.x * w3.y;
col += TEX2D(vec2(pos3.x, pos3.y)) * w3.x * w3.y;

#ifdef DO_GAMMA
// gamma/contrast/brightness
vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);
gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;
#else
// contrast/brightness
gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;
#endif
}
82 changes: 82 additions & 0 deletions src/osd/modules/opengl/shader/glsl_bicubic_rgb32_dir.fsh.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const char glsl_bicubic_rgb32_dir_fsh_src[] =
"// license:BSD-3-Clause\n"
"// copyright-holders:Aaron Stover\n"
"#pragma optimize (on)\n"
"#pragma debug (off)\n"
"\n"
"uniform sampler2D color_texture;\n"
"uniform vec2 color_texture_pow2_sz; // pow2 tex size\n"
"uniform vec4 vid_attributes; // gamma, contrast, brightness\n"
"\n"
"#define TEX2D(v) texture2D(color_texture,(v))\n"
"\n"
"void main()\n"
"{\n"
" vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5;\n"
" vec2 uv_ratio = fract(pixel);\n"
" vec2 one = 1.0 / color_texture_pow2_sz;\n"
" vec2 xy = (floor(pixel) + 0.5) * one;\n"
"\n"
" //\n"
" // Robert G. Keys'\n"
" //\n"
" // 'Cubic Convolution Interpolation for Digital Image Processing'\n"
" // IEEE TRANSACTIONS ON ACOUSTICS, SPEECH, AND SIGNAL PROCESSING, \n"
" // VOL. ASSP-29, NO. 6, DECEMBER 1981 \n"
" //\n"
" // gives the following equation:\n"
" //\n"
" // g(x) = c_k-1(-s^3 + 2s^2 - s)/2 \n"
" // + c_k(3s^3 - 5s^2 + 2)/2\n"
" // + c_k+1(-3s^3 + 4s^2 + s)/2 \n"
" // + c_k+2(s^3 - s^2)/2\n"
" //\n"
" // c_* are the sample values, s is our uv_ratio. \n"
" //\n"
" // Weight equations are taken from above.\n"
" //\n"
" vec2 s = uv_ratio;\n"
" vec2 s2 = uv_ratio*uv_ratio;\n"
" vec2 s3 = uv_ratio*uv_ratio*uv_ratio;\n"
" vec2 w0 = 0.5 * (-s3 + 2.0*s2 - s);\n"
" vec2 w1 = 0.5 * (3.0*s3 - 5.0*s2 + 2.0);\n"
" vec2 w2 = 0.5 * (-3.0*s3 + 4.0*s2 + s);\n"
" vec2 w3 = 0.5 * (s3 - s2);\n"
"\n"
" // Compute the coordinates to sample from\n"
" vec2 pos0 = xy - 1.0*one.xy;\n"
" vec2 pos1 = xy;\n"
" vec2 pos2 = xy + 1.0*one.xy;\n"
" vec2 pos3 = xy + 2.0*one.xy;\n"
"\n"
" // Finally - take the samples, multiply by weight, and sum\n"
" vec4 col = vec4(0.0);\n"
" col += TEX2D(vec2(pos0.x, pos0.y)) * w0.x * w0.y;\n"
" col += TEX2D(vec2(pos1.x, pos0.y)) * w1.x * w0.y;\n"
" col += TEX2D(vec2(pos2.x, pos0.y)) * w2.x * w0.y;\n"
" col += TEX2D(vec2(pos3.x, pos0.y)) * w3.x * w0.y;\n"
"\n"
" col += TEX2D(vec2(pos0.x, pos1.y)) * w0.x * w1.y;\n"
" col += TEX2D(vec2(pos1.x, pos1.y)) * w1.x * w1.y;\n"
" col += TEX2D(vec2(pos2.x, pos1.y)) * w2.x * w1.y;\n"
" col += TEX2D(vec2(pos3.x, pos1.y)) * w3.x * w1.y;\n"
" \n"
" col += TEX2D(vec2(pos0.x, pos2.y)) * w0.x * w2.y;\n"
" col += TEX2D(vec2(pos1.x, pos2.y)) * w1.x * w2.y;\n"
" col += TEX2D(vec2(pos2.x, pos2.y)) * w2.x * w2.y;\n"
" col += TEX2D(vec2(pos3.x, pos2.y)) * w3.x * w2.y;\n"
"\n"
" col += TEX2D(vec2(pos0.x, pos3.y)) * w0.x * w3.y;\n"
" col += TEX2D(vec2(pos1.x, pos3.y)) * w1.x * w3.y;\n"
" col += TEX2D(vec2(pos2.x, pos3.y)) * w2.x * w3.y;\n"
" col += TEX2D(vec2(pos3.x, pos3.y)) * w3.x * w3.y;\n"
"\n"
"#ifdef DO_GAMMA\n"
" // gamma/contrast/brightness\n"
" vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);\n"
" gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;\n"
"#else\n"
" // contrast/brightness\n"
" gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;\n"
"#endif\n"
"}\n";
10 changes: 5 additions & 5 deletions src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ uniform vec4 vid_attributes; // gamma, contrast, brightness

void main()
{
vec2 xy = gl_TexCoord[0].st;

// mix(x,y,a): x*(1-a) + y*a
//
// bilinear filtering includes 2 mix:
Expand All @@ -25,9 +23,11 @@ void main()
//
// so we can use the build in mix function for these 2 computations ;-)
//
vec2 uv_ratio = fract(xy*color_texture_pow2_sz); // xy*color_texture_pow2_sz - floor(xy*color_texture_pow2_sz);
vec2 one = 1.0/color_texture_pow2_sz;

vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5;
vec2 uv_ratio = fract(pixel);
vec2 one = 1.0 / color_texture_pow2_sz;
vec2 xy = (floor(pixel) + 0.5) * one;

#if 1
vec4 col, col2;

Expand Down
63 changes: 31 additions & 32 deletions src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Sven Gothel
const char glsl_bilinear_rgb32_dir_fsh_src[] =
"\n"
"// license:BSD-3-Clause\n"
"// copyright-holders:Sven Gothel\n"
"#pragma optimize (on)\n"
"#pragma debug (off)\n"
"\n"
Expand All @@ -15,43 +14,43 @@ const char glsl_bilinear_rgb32_dir_fsh_src[] =
"\n"
"void main()\n"
"{\n"
" vec2 xy = gl_TexCoord[0].st;\n"
"\n"
" // mix(x,y,a): x*(1-a) + y*a\n"
" //\n"
" // bilinear filtering includes 2 mix:\n"
" //\n"
" // pix1 = tex[x0][y0] * ( 1 - u_ratio ) + tex[x1][y0] * u_ratio\n"
" // pix2 = tex[x0][y1] * ( 1 - u_ratio ) + tex[x1][y1] * u_ratio\n"
" // fin = pix1 * ( 1 - v_ratio ) + pix2 * v_ratio\n"
" //\n"
" // so we can use the build in mix function for these 2 computations ;-)\n"
" //\n"
" vec2 uv_ratio = fract(xy*color_texture_pow2_sz); // xy*color_texture_pow2_sz - floor(xy*color_texture_pow2_sz);\n"
" vec2 one = 1.0/color_texture_pow2_sz;\n"
"\n"
" // mix(x,y,a): x*(1-a) + y*a\n"
" //\n"
" // bilinear filtering includes 2 mix:\n"
" //\n"
" // pix1 = tex[x0][y0] * ( 1 - u_ratio ) + tex[x1][y0] * u_ratio\n"
" // pix2 = tex[x0][y1] * ( 1 - u_ratio ) + tex[x1][y1] * u_ratio\n"
" // fin = pix1 * ( 1 - v_ratio ) + pix2 * v_ratio\n"
" //\n"
" // so we can use the build in mix function for these 2 computations ;-)\n"
" //\n"
" vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5;\n"
" vec2 uv_ratio = fract(pixel);\n"
" vec2 one = 1.0 / color_texture_pow2_sz;\n"
" vec2 xy = (floor(pixel) + 0.5) * one;\n"
" \n"
"#if 1\n"
" vec4 col, col2;\n"
" vec4 col, col2;\n"
"\n"
" col = mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x);\n"
" col2 = mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x);\n"
" col = mix ( col, col2, uv_ratio.y );\n"
" col = mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x);\n"
" col2 = mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x);\n"
" col = mix ( col, col2, uv_ratio.y );\n"
"#else\n"
" // doesn't work on MacOSX GLSL engine ..\n"
" //\n"
" vec4 col = mix ( mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x),\n"
" mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x), uv_ratio.y );\n"
" // doesn't work on MacOSX GLSL engine ..\n"
" //\n"
" vec4 col = mix ( mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x),\n"
" mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x), uv_ratio.y );\n"
"#endif\n"
"\n"
" // gamma, contrast, brightness equation from: rendutil.h / apply_brightness_contrast_gamma_fp\n"
" // gamma, contrast, brightness equation from: rendutil.h / apply_brightness_contrast_gamma_fp\n"
"\n"
"#ifdef DO_GAMMA\n"
" // gamma/contrast/brightness\n"
" vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);\n"
" gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;\n"
" // gamma/contrast/brightness\n"
" vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);\n"
" gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;\n"
"#else\n"
" // contrast/brightness\n"
" gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;\n"
" // contrast/brightness\n"
" gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;\n"
"#endif\n"
"}\n"
"\n"
Expand Down