mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-22 11:04:35 +00:00
Merge branch 'improve_texturing':
OpenGL mipmap support for LUT textures is ready for upstream inclusion.
This commit is contained in:
commit
61ba7afc1c
1
Makefile
1
Makefile
@ -30,6 +30,7 @@ OBJ = frontend/frontend.o \
|
||||
conf/config_file.o \
|
||||
screenshot.o \
|
||||
gfx/scaler/scaler.o \
|
||||
gfx/shader_common.o \
|
||||
gfx/shader_parse.o \
|
||||
gfx/scaler/pixconv.o \
|
||||
gfx/scaler/scaler_int.o \
|
||||
|
@ -102,7 +102,6 @@ struct cg_fbo_params
|
||||
CGparameter coord;
|
||||
};
|
||||
|
||||
#define MAX_LUT_TEXTURES 8
|
||||
#define MAX_VARIABLES 64
|
||||
#define PREV_TEXTURES (MAX_TEXTURES - 1)
|
||||
|
||||
@ -142,7 +141,7 @@ static unsigned active_index;
|
||||
static struct gfx_shader *cg_shader;
|
||||
|
||||
static state_tracker_t *state_tracker;
|
||||
static GLuint lut_textures[MAX_LUT_TEXTURES];
|
||||
static GLuint lut_textures[GFX_MAX_TEXTURES];
|
||||
|
||||
static CGparameter cg_attribs[PREV_TEXTURES + 1 + 4 + GFX_MAX_SHADERS];
|
||||
static unsigned cg_attrib_index;
|
||||
@ -496,53 +495,6 @@ static bool load_plain(const char *path)
|
||||
|
||||
#define print_buf(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__)
|
||||
|
||||
static void load_texture_data(GLuint obj, const struct texture_image *img, bool smooth, GLenum wrap)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, obj);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, smooth ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, smooth ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
#ifndef HAVE_PSGL
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, img->width, img->height,
|
||||
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, img->pixels);
|
||||
}
|
||||
|
||||
static bool load_textures(void)
|
||||
{
|
||||
unsigned i;
|
||||
if (!cg_shader->luts)
|
||||
return true;
|
||||
|
||||
glGenTextures(cg_shader->luts, lut_textures);
|
||||
|
||||
for (i = 0; i < cg_shader->luts; i++)
|
||||
{
|
||||
RARCH_LOG("Loading image from: \"%s\".\n",
|
||||
cg_shader->lut[i].path);
|
||||
|
||||
struct texture_image img = {0};
|
||||
if (!texture_image_load(cg_shader->lut[i].path, &img))
|
||||
{
|
||||
RARCH_ERR("Failed to load picture ...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
load_texture_data(lut_textures[i], &img,
|
||||
cg_shader->lut[i].filter != RARCH_FILTER_NEAREST,
|
||||
gl_wrap_type_to_enum(cg_shader->lut[i].wrap));
|
||||
texture_image_free(&img);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load_imports(void)
|
||||
{
|
||||
unsigned i;
|
||||
@ -646,7 +598,7 @@ static bool load_preset(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (!load_textures())
|
||||
if (!gl_load_luts(cg_shader, lut_textures))
|
||||
{
|
||||
RARCH_ERR("Failed to load lookup textures ...\n");
|
||||
return false;
|
||||
|
82
gfx/shader_common.c
Normal file
82
gfx/shader_common.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "shader_common.h"
|
||||
#include "../retroarch_logger.h"
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
// gl_common.c may or may not be a better location for these functions.
|
||||
void gl_load_texture_data(GLuint obj, const struct texture_image *img,
|
||||
GLenum wrap, bool linear, bool mipmap)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, obj);
|
||||
|
||||
#ifdef HAVE_OPENGLES2
|
||||
GLenum wrap = GL_CLAMP_TO_EDGE;
|
||||
#endif
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||
|
||||
GLint filter = linear ? (mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
|
||||
(mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
|
||||
#ifndef HAVE_PSGL
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, img->width, img->height,
|
||||
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, img->pixels);
|
||||
if (mipmap)
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned num_luts = min(generic_shader->luts, GFX_MAX_TEXTURES);
|
||||
if (!generic_shader->luts)
|
||||
return true;
|
||||
|
||||
// Original shader_glsl.c code only generated one texture handle. I assume
|
||||
// it was a bug, but if not, replace num_luts with 1 when GLSL is used.
|
||||
glGenTextures(num_luts, lut_textures);
|
||||
for (i = 0; i < num_luts; i++)
|
||||
{
|
||||
RARCH_LOG("Loading texture image from: \"%s\" ...\n",
|
||||
generic_shader->lut[i].path);
|
||||
struct texture_image img = {0};
|
||||
if (!texture_image_load(generic_shader->lut[i].path, &img))
|
||||
{
|
||||
RARCH_ERR("Failed to load texture image from: \"%s\"\n", generic_shader->lut[i].path);
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_load_texture_data(lut_textures[i], &img,
|
||||
gl_wrap_type_to_enum(generic_shader->lut[i].wrap),
|
||||
generic_shader->lut[i].filter != RARCH_FILTER_NEAREST,
|
||||
generic_shader->lut[i].mipmap);
|
||||
texture_image_free(&img);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return true;
|
||||
}
|
||||
#endif // HAVE_OPENGL
|
||||
|
||||
|
@ -56,5 +56,9 @@ struct gl_shader_backend
|
||||
enum rarch_shader_type type;
|
||||
};
|
||||
|
||||
void gl_load_texture_data(GLuint obj, const struct texture_image *img,
|
||||
GLenum wrap, bool linear, bool mipmap);
|
||||
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -263,50 +263,6 @@ static GLint get_attrib(GLuint prog, const char *base)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool load_luts(void)
|
||||
{
|
||||
unsigned i;
|
||||
if (!glsl_shader->luts)
|
||||
return true;
|
||||
|
||||
glGenTextures(1, gl_teximage);
|
||||
|
||||
for (i = 0; i < glsl_shader->luts; i++)
|
||||
{
|
||||
RARCH_LOG("Loading texture image from: \"%s\" ...\n",
|
||||
glsl_shader->lut[i].path);
|
||||
|
||||
struct texture_image img = {0};
|
||||
if (!texture_image_load(glsl_shader->lut[i].path, &img))
|
||||
{
|
||||
RARCH_ERR("Failed to load texture image from: \"%s\"\n", glsl_shader->lut[i].path);
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl_teximage[i]);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, BORDER_FUNC);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, BORDER_FUNC);
|
||||
|
||||
GLenum filter = glsl_shader->lut[i].filter == RARCH_FILTER_NEAREST ?
|
||||
GL_NEAREST : GL_LINEAR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32,
|
||||
img.width, img.height, 0,
|
||||
driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32,
|
||||
RARCH_GL_FORMAT32, img.pixels);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
texture_image_free(&img);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void print_shader_log(GLuint obj)
|
||||
{
|
||||
GLint info_len = 0;
|
||||
@ -786,7 +742,7 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
if (!compile_programs(&gl_program[1]))
|
||||
goto error;
|
||||
|
||||
if (!load_luts())
|
||||
if (!gl_load_luts(glsl_shader, gl_teximage))
|
||||
{
|
||||
RARCH_ERR("[GL]: Failed to load LUTs.\n");
|
||||
goto error;
|
||||
|
@ -80,7 +80,6 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
|
||||
// Smooth
|
||||
char filter_name_buf[64];
|
||||
print_buf(filter_name_buf, "filter_linear%u", i);
|
||||
|
||||
bool smooth = false;
|
||||
if (config_get_bool(conf, filter_name_buf, &smooth))
|
||||
pass->filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
|
||||
@ -244,7 +243,6 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
|
||||
|
||||
char id_filter[64];
|
||||
print_buf(id_filter, "%s_linear", id);
|
||||
|
||||
bool smooth = false;
|
||||
if (config_get_bool(conf, id_filter, &smooth))
|
||||
shader->lut[shader->luts].filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
|
||||
@ -256,6 +254,14 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
|
||||
char wrap_mode[64];
|
||||
if (config_get_array(conf, id_wrap, wrap_mode, sizeof(wrap_mode)))
|
||||
shader->lut[shader->luts].wrap = wrap_str_to_mode(wrap_mode);
|
||||
|
||||
char id_mipmap[64];
|
||||
print_buf(id_mipmap, "%s_mipmap", id);
|
||||
bool mipmap = false;
|
||||
if (config_get_bool(conf, id_mipmap, &mipmap))
|
||||
shader->lut[shader->luts].mipmap = mipmap;
|
||||
else
|
||||
shader->lut[shader->luts].mipmap = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1084,11 +1090,14 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, const struct gfx_shader *sha
|
||||
if (shader->lut[i].filter != RARCH_FILTER_UNSPEC)
|
||||
{
|
||||
print_buf(key, "%s_linear", shader->lut[i].id);
|
||||
config_set_bool(conf, key, shader->lut[i].filter != RARCH_FILTER_LINEAR);
|
||||
config_set_bool(conf, key, shader->lut[i].filter == RARCH_FILTER_LINEAR);
|
||||
}
|
||||
|
||||
print_buf(key, "%s_wrap_mode", shader->lut[i].id);
|
||||
config_set_string(conf, key, wrap_mode_to_str(shader->lut[i].wrap));
|
||||
|
||||
print_buf(key, "%s_mipmap", shader->lut[i].id);
|
||||
config_set_bool(conf, key, shader->lut[i].mipmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ struct gfx_shader_lut
|
||||
char path[PATH_MAX];
|
||||
enum gfx_filter_type filter;
|
||||
enum gfx_wrap_type wrap;
|
||||
bool mipmap;
|
||||
};
|
||||
|
||||
// This is pretty big, shouldn't be put on the stack.
|
||||
|
Loading…
x
Reference in New Issue
Block a user