From 692dc9f6a902d53048b5edcb8a314d41bd927184 Mon Sep 17 00:00:00 2001 From: LazyBumHorse Date: Tue, 4 Jun 2019 21:52:58 +0200 Subject: [PATCH] refactor shader checks affected by last commit and more: - gl.c: refactor backend fallback into more general gl2_get_fallback_shader_type - d3d9-12, gl_core, gx2_gfx, gl, vulkan: more consistent shader init and `set_shader` behavior - configuration.c: remove check_shader_compatibility - shader_glsl.c, shader_gl_cg.c: use `video_shader_get_type_from_ext` - shader_gl_cg.c: add shader type check with fallback to stock like in shader_glsl.c - menu_shader.c: use `enum rarch_shader_type` instead of `unsigned` - video_shader_parse.c: add `video_shader_to_str` for easier logging - remove `type` from `struct video_shader`, which was always set to CG and wrongly used in lang_process.cpp's `slang_process()` (has no further consequences because the code is unused) --- configuration.c | 57 +------- gfx/common/metal_common.m | 6 +- gfx/drivers/d3d10.c | 18 +-- gfx/drivers/d3d11.c | 14 +- gfx/drivers/d3d12.c | 26 ++-- gfx/drivers/d3d9.c | 21 ++- gfx/drivers/gl.c | 211 ++++++++++++++++----------- gfx/drivers/gl_core.c | 21 ++- gfx/drivers/gx2_gfx.c | 40 +++-- gfx/drivers/metal.m | 15 +- gfx/drivers/vulkan.c | 19 ++- gfx/drivers_context/x_ctx.c | 6 +- gfx/drivers_shader/shader_gl_cg.c | 31 ++-- gfx/drivers_shader/shader_glsl.c | 65 +++++---- gfx/drivers_shader/slang_process.cpp | 4 +- gfx/video_shader_parse.c | 82 ++++++----- gfx/video_shader_parse.h | 4 +- menu/menu_setting.c | 2 +- menu/menu_shader.c | 21 +-- menu/menu_shader.h | 5 +- retroarch.c | 2 +- 21 files changed, 333 insertions(+), 337 deletions(-) diff --git a/configuration.c b/configuration.c index 72e2a2e12e..7b77816231 100644 --- a/configuration.c +++ b/configuration.c @@ -2608,35 +2608,6 @@ static bool check_menu_driver_compatibility(void) } #endif -static bool check_shader_compatibility(enum file_path_enum enum_idx) -{ - settings_t *settings = config_get_ptr(); - - if (string_is_equal(settings->arrays.video_driver, "vulkan") || - string_is_equal(settings->arrays.video_driver, "metal") || - string_is_equal(settings->arrays.video_driver, "glcore") || - string_is_equal(settings->arrays.video_driver, "d3d11") || - string_is_equal(settings->arrays.video_driver, "d3d12") || - string_is_equal(settings->arrays.video_driver, "gx2")) - { - if (enum_idx != FILE_PATH_SLANGP_EXTENSION) - return false; - return true; - } - - if (string_is_equal(settings->arrays.video_driver, "gl") || - string_is_equal(settings->arrays.video_driver, "d3d8") || - string_is_equal(settings->arrays.video_driver, "d3d9") - ) - { - if (enum_idx == FILE_PATH_SLANGP_EXTENSION) - return false; - return true; - } - - return false; -} - /** * config_load: * @path : path to be read from. @@ -3125,26 +3096,6 @@ static bool config_load_file(const char *path, settings_t *settings) config_read_keybinds_conf(conf); - shader_ext = path_get_extension(settings->paths.path_shader); - - if (!string_is_empty(shader_ext)) - { - for (i = FILE_PATH_CGP_EXTENSION; i <= FILE_PATH_SLANGP_EXTENSION; i++) - { - enum file_path_enum ext = (enum file_path_enum)(i); - if (!strstr(file_path_str(ext), shader_ext)) - continue; - - if (check_shader_compatibility(ext)) - continue; - - RARCH_LOG("Incompatible shader for backend %s, clearing...\n", - settings->arrays.video_driver); - settings->paths.path_shader[0] = '\0'; - break; - } - } - #if defined(HAVE_MENU) && defined(HAVE_RGUI) if (!check_menu_driver_compatibility()) strlcpy(settings->arrays.menu_driver, "rgui", sizeof(settings->arrays.menu_driver)); @@ -3582,9 +3533,6 @@ static bool config_load_shader_preset_internal( for (idx = FILE_PATH_CGP_EXTENSION; idx <= FILE_PATH_SLANGP_EXTENSION; idx++) { - if (!check_shader_compatibility((enum file_path_enum)(idx))) - continue; - /* Concatenate strings into full paths */ fill_pathname_join_special_ext(shader_path, shader_directory, core_name, @@ -4398,8 +4346,5 @@ bool config_replace(bool config_replace_save_on_exit, char *path) /* Load core in new config. */ path_clear(RARCH_PATH_CORE); - if (!task_push_start_dummy_core(&content_info)) - return false; - - return true; + return task_push_start_dummy_core(&content_info); } diff --git a/gfx/common/metal_common.m b/gfx/common/metal_common.m index 8b8200b369..187ed3ce57 100644 --- a/gfx/common/metal_common.m +++ b/gfx/common/metal_common.m @@ -1134,6 +1134,10 @@ typedef struct MTLALIGN(16) - (BOOL)setShaderFromPath:(NSString *)path { + /* TODO use stock shader if string_is_empty(path.UTF8String), this is just a safety guard: */ + if (string_is_empty(path.UTF8String)) + return YES; + [self _freeVideoShader:_shader]; _shader = nil; @@ -1196,7 +1200,7 @@ typedef struct MTLALIGN(16) return NO; #ifdef DEBUG - bool save_msl = true; + bool save_msl = true; #else bool save_msl = false; #endif diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index d09aca89f7..92ee57a319 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -322,8 +322,7 @@ static void d3d10_free_shader_preset(d3d10_video_t* d3d10) d3d10->resize_render_targets = false; } -static bool d3d10_gfx_set_shader(void* data, - enum rarch_shader_type type, const char* path) +static bool d3d10_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) { #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) unsigned i; @@ -337,12 +336,12 @@ static bool d3d10_gfx_set_shader(void* data, D3D10Flush(d3d10->device); d3d10_free_shader_preset(d3d10); - if (!path) + if (string_is_empty(path)) return true; if (type != RARCH_SHADER_SLANG) { - RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); + RARCH_WARN("[D3D10] Only Slang shaders are supported. Falling back to stock.\n"); return false; } @@ -423,7 +422,6 @@ static bool d3d10_gfx_set_shader(void* data, const char* slang_path = d3d10->shader_preset->pass[i].source.path; const char* vs_src = d3d10->shader_preset->pass[i].source.string.vertex; const char* ps_src = d3d10->shader_preset->pass[i].source.string.fragment; - int base_len = strlen(slang_path) - STRLEN_CONST(".slang"); strlcpy(vs_path, slang_path, sizeof(vs_path)); strlcpy(ps_path, slang_path, sizeof(ps_path)); @@ -950,13 +948,9 @@ d3d10_gfx_init(const video_info_t* video, font_driver_init_osd(d3d10, false, video->is_threaded, FONT_DRIVER_RENDER_D3D10_API); - if (settings->bools.video_shader_enable) - { - const char* ext = path_get_extension(retroarch_get_shader_preset()); - - if (ext && !strncmp(ext, "slang", 5)) - d3d10_gfx_set_shader(d3d10, RARCH_SHADER_SLANG, retroarch_get_shader_preset()); - } + const char *shader_preset = retroarch_get_shader_preset(); + enum rarch_shader_type type = video_shader_parse_type(shader_preset); + d3d10_gfx_set_shader(d3d10, type, shader_preset); #if 0 if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 872935d8e4..ccf41fe71a 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -355,12 +355,12 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const D3D11Flush(d3d11->context); d3d11_free_shader_preset(d3d11); - if (!path) + if (string_is_empty(path)) return true; if (type != RARCH_SHADER_SLANG) { - RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); + RARCH_WARN("[D3D11] Only Slang shaders are supported. Falling back to stock.\n"); return false; } @@ -1024,13 +1024,9 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i font_driver_init_osd(d3d11, false, video->is_threaded, FONT_DRIVER_RENDER_D3D11_API); - if (settings->bools.video_shader_enable) - { - const char* ext = path_get_extension(retroarch_get_shader_preset()); - - if (ext && !strncmp(ext, "slang", 5)) - d3d11_gfx_set_shader(d3d11, RARCH_SHADER_SLANG, retroarch_get_shader_preset()); - } + const char *shader_preset = retroarch_get_shader_preset(); + enum rarch_shader_type type = video_shader_parse_type(shader_preset); + d3d11_gfx_set_shader(d3d11, type, shader_preset); if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && video_driver_get_hw_context()->version_major == 11) diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index e436490ea9..d731b332ef 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -334,23 +334,22 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const { #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) unsigned i; - d3d12_texture_t* source = NULL; config_file_t* conf = NULL; + d3d12_texture_t* source = NULL; d3d12_video_t* d3d12 = (d3d12_video_t*)data; if (!d3d12) return false; d3d12_gfx_sync(d3d12); - d3d12_free_shader_preset(d3d12); - if (!path) + if (string_is_empty(path)) return true; if (type != RARCH_SHADER_SLANG) { - RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); + RARCH_WARN("[D3D12] Only Slang shaders are supported. Falling back to stock.\n"); return false; } @@ -408,8 +407,8 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const /* clang-format on */ if (!slang_process( - d3d12->shader_preset, i, RARCH_SHADER_HLSL, 50, &semantics_map, - &d3d12->pass[i].semantics)) + d3d12->shader_preset, i, RARCH_SHADER_HLSL, 50, &semantics_map, + &d3d12->pass[i].semantics)) goto error; { @@ -435,7 +434,6 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const const char* slang_path = d3d12->shader_preset->pass[i].source.path; const char* vs_src = d3d12->shader_preset->pass[i].source.string.vertex; const char* ps_src = d3d12->shader_preset->pass[i].source.string.fragment; - int base_len = strlen(slang_path) - STRLEN_CONST(".slang"); strlcpy(vs_path, slang_path, sizeof(vs_path)); strlcpy(ps_path, slang_path, sizeof(ps_path)); @@ -581,8 +579,8 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12) desc.InputLayout.NumElements = countof(inputElementDesc); if (!d3d12_init_pipeline( - d3d12->device, vs_code, ps_code, NULL, &desc, - &d3d12->pipes[VIDEO_SHADER_STOCK_BLEND])) + d3d12->device, vs_code, ps_code, NULL, &desc, + &d3d12->pipes[VIDEO_SHADER_STOCK_BLEND])) goto error; Release(vs_code); @@ -998,13 +996,9 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i font_driver_init_osd(d3d12, false, video->is_threaded, FONT_DRIVER_RENDER_D3D12_API); - if (settings->bools.video_shader_enable) - { - const char* ext = path_get_extension(retroarch_get_shader_preset()); - - if (ext && string_is_equal(ext, "slangp")) - d3d12_gfx_set_shader(d3d12, RARCH_SHADER_SLANG, retroarch_get_shader_preset()); - } + const char *shader_preset = retroarch_get_shader_preset(); + enum rarch_shader_type type = video_shader_parse_type(shader_preset); + d3d12_gfx_set_shader(d3d12, type, shader_preset); return d3d12; diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index f2acaa91de..58eb94f0b7 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -1807,13 +1807,18 @@ end: static bool d3d9_set_shader(void *data, enum rarch_shader_type type, const char *path) { - d3d9_video_t *d3d = (d3d9_video_t*)data; - char *old_shader = (d3d && !string_is_empty(d3d->shader_path)) ? strdup(d3d->shader_path) : NULL; + d3d9_video_t *d3d = (d3d9_video_t*)data; + + if (!d3d) + return false; if (!string_is_empty(d3d->shader_path)) free(d3d->shader_path); d3d->shader_path = NULL; + if (string_is_empty(path)) + return true; + switch (type) { case RARCH_SHADER_CG: @@ -1822,19 +1827,13 @@ static bool d3d9_set_shader(void *data, d3d->shader_path = strdup(path); break; default: - break; + RARCH_WARN("[D3D9]: Only Cg shaders are supported. Falling back to stock.\n"); + return false; } if (!d3d9_process_shader(d3d) || !d3d9_restore(d3d)) { - RARCH_ERR("[D3D9]: Setting shader failed.\n"); - if (!string_is_empty(old_shader)) - { - d3d->shader_path = strdup(old_shader); - d3d9_process_shader(d3d); - d3d9_restore(d3d); - } - free(old_shader); + RARCH_ERR("[D3D9]: Failed to set shader.\n"); return false; } diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 01817cfb5f..e407a307d6 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -1998,45 +1998,87 @@ static void gl2_set_viewport_wrapper(void *data, unsigned viewport_width, } /* Shaders */ + +/** + * gl2_get_fallback_shader_type: + * @type : shader type which should be used if possible + * + * Returns a supported fallback shader type in case the given one is not supported. + * For gl2, shader support is completely defined by the context driver shader flags. + * + * gl2_get_fallback_shader_type(RARCH_SHADER_NONE) returns a default shader type. + * if gl2_get_fallback_shader_type(type) != type, type was not supported. + * + * Returns: A supported shader type. + * If RARCH_SHADER_NONE is returned, no shader backend is supported. + **/ +static enum rarch_shader_type gl2_get_fallback_shader_type(enum rarch_shader_type type) +{ +#if defined(HAVE_GLSL) || defined(HAVE_CG) + unsigned i; + gfx_ctx_flags_t flags; + flags.flags = 0; + video_context_driver_get_flags(&flags); + + if (type != RARCH_SHADER_CG && type != RARCH_SHADER_GLSL) + { + type = DEFAULT_SHADER_TYPE; + + if (type != RARCH_SHADER_CG && type != RARCH_SHADER_GLSL) + type = RARCH_SHADER_GLSL; + } + + for (i = 0; i < 2; i++) + { + switch (type) + { + case RARCH_SHADER_CG: +#ifdef HAVE_CG + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_SHADERS_CG)) + return RARCH_SHADER_CG; +#endif + type = RARCH_SHADER_GLSL; + break; + + case RARCH_SHADER_GLSL: +#ifdef HAVE_GLSL + if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_SHADERS_GLSL)) + return RARCH_SHADER_GLSL; +#endif + type = RARCH_SHADER_CG; + break; + + default: + return RARCH_SHADER_NONE; + } + } +#endif + return RARCH_SHADER_NONE; +} + static const shader_backend_t *gl_shader_driver_set_backend( enum rarch_shader_type type) { - switch (type) + enum rarch_shader_type fallback = gl2_get_fallback_shader_type(type); + if (fallback != type) + RARCH_ERR("[Shader driver]: Shader backend %d not supported, falling back to %d.", type, fallback); + + switch (fallback) { - case RARCH_SHADER_CG: - { #ifdef HAVE_CG - gfx_ctx_flags_t flags; - flags.flags = 0; - video_context_driver_get_flags(&flags); - - if (BIT32_GET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT)) - { - RARCH_ERR("[Shader driver]: Cg cannot be used with core" - " GL context. Trying to fall back to GLSL...\n"); - return gl_shader_driver_set_backend(RARCH_SHADER_GLSL); - } - - RARCH_LOG("[Shader driver]: Using Cg shader backend.\n"); - return &gl_cg_backend; -#else - break; + case RARCH_SHADER_CG: + RARCH_LOG("[Shader driver]: Using Cg shader backend.\n"); + return &gl_cg_backend; #endif - } - case RARCH_SHADER_GLSL: #ifdef HAVE_GLSL + case RARCH_SHADER_GLSL: RARCH_LOG("[Shader driver]: Using GLSL shader backend.\n"); return &gl_glsl_backend; -#else - break; #endif - case RARCH_SHADER_HLSL: - case RARCH_SHADER_NONE: default: - break; + RARCH_LOG("[Shader driver]: No supported shader backend.\n"); + return NULL; } - - return NULL; } static bool gl_shader_driver_init(video_shader_ctx_init_t *init) @@ -2064,7 +2106,7 @@ static bool gl_shader_driver_init(video_shader_ctx_init_t *init) init->shader->init_menu_shaders(tmp); } - init->shader_data = tmp; + init->shader_data = tmp; return true; } @@ -2074,33 +2116,33 @@ static bool gl2_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver, ) { video_shader_ctx_init_t init_data; - bool ret = false; - const char *shader_path = retroarch_get_shader_preset(); - enum rarch_shader_type type = video_shader_parse_type(shader_path); + bool ret = false; + const char *shader_path = retroarch_get_shader_preset(); + enum rarch_shader_type parse_type = video_shader_parse_type(shader_path); + enum rarch_shader_type type; + + type = gl2_get_fallback_shader_type(parse_type); if (type == RARCH_SHADER_NONE) - type = gl->core_context_in_use ? RARCH_SHADER_GLSL : DEFAULT_SHADER_TYPE; - - switch (type) { -#ifdef HAVE_CG - case RARCH_SHADER_CG: - if (gl->core_context_in_use) - shader_path = NULL; - break; -#endif + RARCH_ERR("[GL]: Couldn't find any supported shader backend! Continuing without shaders.\n"); + return true; + } -#ifdef HAVE_GLSL - case RARCH_SHADER_GLSL: - gl_glsl_set_get_proc_address(ctx_driver->get_proc_address); - gl_glsl_set_context_type(gl->core_context_in_use, - hwr->version_major, hwr->version_minor); - break; -#endif + if (type != parse_type) + { + if (!string_is_empty(shader_path)) + RARCH_WARN("[GL] Shader preset %s is using unsupported shader type %s, falling back to stock %s.\n", + shader_path, video_shader_to_str(parse_type), video_shader_to_str(type)); - default: - RARCH_ERR("[GL]: Not loading any shader, or couldn't find valid shader backend. Continuing without shaders.\n"); - return true; + shader_path = NULL; + } + + if (type == RARCH_SHADER_GLSL) + { + gl_glsl_set_get_proc_address(ctx_driver->get_proc_address); + gl_glsl_set_context_type(gl->core_context_in_use, + hwr->version_major, hwr->version_minor); } init_data.gl.core_context_enabled = gl->core_context_in_use; @@ -3987,10 +4029,7 @@ static void gl2_update_tex_filter_frame(gl_t *gl) smooth = settings->bools.video_smooth; mip_level = 1; - - wrap_type = gl->shader->wrap_type( - gl->shader_data, 1); - + wrap_type = gl->shader->wrap_type(gl->shader_data, 1); wrap_mode = gl2_wrap_type_to_enum(wrap_type); gl->tex_mipmap = gl->shader->mipmap_input(gl->shader_data, mip_level); gl->video_info.smooth = smooth; @@ -4024,6 +4063,7 @@ static bool gl2_set_shader(void *data, #if defined(HAVE_GLSL) || defined(HAVE_CG) unsigned textures; video_shader_ctx_init_t init_data; + enum rarch_shader_type fallback; gl_t *gl = (gl_t*)data; if (!gl) @@ -4031,27 +4071,28 @@ static bool gl2_set_shader(void *data, gl2_context_bind_hw_render(gl, false); - if (type == RARCH_SHADER_NONE) - return false; - gl->shader->deinit(gl->shader_data); gl->shader_data = NULL; - switch (type) + if (string_is_empty(path)) { -#ifdef HAVE_GLSL - case RARCH_SHADER_GLSL: - break; -#endif + gl2_context_bind_hw_render(gl, true); + return true; + } -#ifdef HAVE_CG - case RARCH_SHADER_CG: - break; -#endif + fallback = gl2_get_fallback_shader_type(type); - default: - RARCH_ERR("[GL]: Cannot find shader core for path: %s.\n", path); - goto error; + if (fallback == RARCH_SHADER_NONE) + { + RARCH_ERR("[GL]: No supported shader backend found!\n"); + goto error; + } + + if (type != fallback) + { + RARCH_ERR("[GL]: %s shader not supported, falling back to stock %s\n", + video_shader_to_str(type), video_shader_to_str(fallback)); + path = NULL; } if (gl->fbo_inited) @@ -4062,7 +4103,7 @@ static bool gl2_set_shader(void *data, glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); } - init_data.shader_type = type; + init_data.shader_type = fallback; init_data.shader = NULL; init_data.data = gl; init_data.path = path; @@ -4121,12 +4162,12 @@ static bool gl2_set_shader(void *data, /* Apparently need to set viewport for passes when we aren't using FBOs. */ gl2_set_shader_viewports(gl); gl2_context_bind_hw_render(gl, true); -#endif return true; error: gl2_context_bind_hw_render(gl, true); +#endif return false; } @@ -4134,7 +4175,7 @@ static void gl2_viewport_info(void *data, struct video_viewport *vp) { unsigned width, height; unsigned top_y, top_dist; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; video_driver_get_size(&width, &height); @@ -4151,10 +4192,11 @@ static void gl2_viewport_info(void *data, struct video_viewport *vp) static bool gl2_read_viewport(void *data, uint8_t *buffer, bool is_idle) { gl_t *gl = (gl_t*)data; + if (!gl) return false; - return gl2_renderchain_read_viewport(gl, - buffer, is_idle); + + return gl2_renderchain_read_viewport(gl, buffer, is_idle); } #if 0 @@ -4248,7 +4290,7 @@ static bool gl2_overlay_load(void *data, || !gl->overlay_color_coord) return false; - gl->overlays = num_images; + gl->overlays = num_images; glGenTextures(num_images, gl->overlay_tex); for (i = 0; i < num_images; i++) @@ -4276,7 +4318,7 @@ static bool gl2_overlay_load(void *data, static void gl2_overlay_enable(void *data, bool state) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; if (!gl) return; @@ -4297,17 +4339,18 @@ static void gl2_overlay_full_screen(void *data, bool enable) static void gl2_overlay_set_alpha(void *data, unsigned image, float mod) { - GLfloat *color = NULL; - gl_t *gl = (gl_t*)data; + GLfloat *color; + gl_t *gl = (gl_t*)data; + if (!gl) return; - color = (GLfloat*)&gl->overlay_color_coord[image * 16]; + color = (GLfloat*)&gl->overlay_color_coord[image * 16]; - color[ 0 + 3] = mod; - color[ 4 + 3] = mod; - color[ 8 + 3] = mod; - color[12 + 3] = mod; + color[ 0 + 3] = mod; + color[ 4 + 3] = mod; + color[ 8 + 3] = mod; + color[12 + 3] = mod; } static const video_overlay_interface_t gl2_overlay_interface = { @@ -4341,7 +4384,7 @@ static retro_proc_address_t gl2_get_proc_address(void *data, const char *sym) static void gl2_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; switch (aspect_ratio_idx) { diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c index 9cfd76a538..3724882035 100644 --- a/gfx/drivers/gl_core.c +++ b/gfx/drivers/gl_core.c @@ -780,10 +780,9 @@ static bool gl_core_init_filter_chain_preset(gl_core_t *gl, const char *shader_p static bool gl_core_init_filter_chain(gl_core_t *gl) { const char *shader_path = retroarch_get_shader_preset(); - enum rarch_shader_type type = video_shader_parse_type(shader_path); - if (type == RARCH_SHADER_NONE) + if (string_is_empty(shader_path)) { RARCH_LOG("[GLCore]: Loading stock shader.\n"); return gl_core_init_default_filter_chain(gl); @@ -791,11 +790,11 @@ static bool gl_core_init_filter_chain(gl_core_t *gl) if (type != RARCH_SHADER_SLANG) { - RARCH_LOG("[GLCore]: Only SLANG shaders are supported, falling back to stock.\n"); + RARCH_WARN("[GLCore]: Only Slang shaders are supported, falling back to stock.\n"); return gl_core_init_default_filter_chain(gl); } - if (!shader_path || !gl_core_init_filter_chain_preset(gl, shader_path)) + if (!gl_core_init_filter_chain_preset(gl, shader_path)) gl_core_init_default_filter_chain(gl); return true; @@ -1374,18 +1373,18 @@ static bool gl_core_set_shader(void *data, return false; gl_core_context_bind_hw_render(gl, false); - if (type != RARCH_SHADER_SLANG && path) - { - RARCH_WARN("[GLCore]: Only .slang or .slangp shaders are supported. Falling back to stock.\n"); - gl_core_context_bind_hw_render(gl, true); - path = NULL; - } if (gl->filter_chain) gl_core_filter_chain_free(gl->filter_chain); gl->filter_chain = NULL; - if (!path) + if (!string_is_empty(path) && type != RARCH_SHADER_SLANG) + { + RARCH_WARN("[GLCore]: Only Slang shaders are supported. Falling back to stock.\n"); + path = NULL; + } + + if (string_is_empty(path)) { gl_core_init_default_filter_chain(gl); gl_core_context_bind_hw_render(gl, true); diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index 69995cf1fa..d85e86f1b3 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -450,13 +450,10 @@ static void *wiiu_gfx_init(const video_info_t *video, video->is_threaded, FONT_DRIVER_RENDER_WIIU); - if(settings->bools.video_shader_enable && - !string_is_empty(retroarch_get_shader_preset())) { - const char* ext = path_get_extension(retroarch_get_shader_preset()); - - if(ext && !strncmp(ext, "slang", 5)) - wiiu_gfx_set_shader(wiiu, RARCH_SHADER_SLANG, retroarch_get_shader_preset()); + const char *shader_preset = retroarch_get_shader_preset(); + enum rarch_shader_type type = video_shader_parse_type(shader_preset); + wiiu_gfx_set_shader(wiiu, type, shader_preset); } return wiiu; @@ -1435,15 +1432,15 @@ static bool wiiu_gfx_set_shader(void *data, GX2DrawDone(); wiiu_free_shader_preset(wiiu); - if (type != RARCH_SHADER_SLANG && path) - { - RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); - path = NULL; - } - - if (!path) + if (string_is_empty(path)) return true; + if (type != RARCH_SHADER_SLANG) + { + RARCH_WARN("[GX2] Only Slang shaders are supported. Falling back to stock.\n"); + return false; + } + if (!(conf = config_file_new(path))) return false; @@ -1458,15 +1455,15 @@ static bool wiiu_gfx_set_shader(void *data, video_shader_resolve_relative(wiiu->shader_preset, path); - #if 0 - video_shader_resolve_parameters(conf, wiiu->shader_preset); - #else - for (int i = 0; i < wiiu->shader_preset->passes; i++) - slang_preprocess_parse_parameters(wiiu->shader_preset->pass[i].source.path, wiiu->shader_preset); +#if 0 + video_shader_resolve_parameters(conf, wiiu->shader_preset); +#else + for (int i = 0; i < wiiu->shader_preset->passes; i++) + slang_preprocess_parse_parameters(wiiu->shader_preset->pass[i].source.path, wiiu->shader_preset); - video_shader_resolve_current_parameters(conf, wiiu->shader_preset); - #endif - config_file_free(conf); + video_shader_resolve_current_parameters(conf, wiiu->shader_preset); +#endif + config_file_free(conf); for (int i = 0; i < wiiu->shader_preset->passes; i++) { @@ -1546,7 +1543,6 @@ static bool wiiu_gfx_set_shader(void *data, } return true; - } static struct video_shader *wiiu_gfx_get_current_shader(void *data) diff --git a/gfx/drivers/metal.m b/gfx/drivers/metal.m index 4eedef45f1..57f536ca06 100644 --- a/gfx/drivers/metal.m +++ b/gfx/drivers/metal.m @@ -69,12 +69,10 @@ static void *metal_init(const video_info_t *video, return NULL; } - const char *shader_path = retroarch_get_shader_preset(); - - if (shader_path) { + const char *shader_path = retroarch_get_shader_preset(); enum rarch_shader_type type = video_shader_parse_type(shader_path); - metal_set_shader(((__bridge void *)md), type, shader_path); + metal_set_shader((__bridge void *)md, type, shader_path); } return (__bridge_retained void *)md; @@ -127,15 +125,14 @@ static bool metal_set_shader(void *data, { #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) MetalDriver *md = (__bridge MetalDriver *)data; + if (!md) return false; - if (!path) - return true; - if (type != RARCH_SHADER_SLANG) + if (!string_is_empty(path) && type != RARCH_SHADER_SLANG) { - RARCH_WARN("[Metal] Only .slang or .slangp shaders are supported. Falling back to stock.\n"); - return false; + RARCH_WARN("[Metal] Only Slang shaders are supported. Falling back to stock.\n"); + path = NULL; } return [md.frameView setShaderFromPath:[NSString stringWithUTF8String:path]]; diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 44028d8825..1a66d65472 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -829,10 +829,9 @@ static bool vulkan_init_filter_chain_preset(vk_t *vk, const char *shader_path) static bool vulkan_init_filter_chain(vk_t *vk) { const char *shader_path = retroarch_get_shader_preset(); - enum rarch_shader_type type = video_shader_parse_type(shader_path); - if (type == RARCH_SHADER_NONE) + if (string_is_empty(shader_path)) { RARCH_LOG("[Vulkan]: Loading stock shader.\n"); return vulkan_init_default_filter_chain(vk); @@ -840,7 +839,7 @@ static bool vulkan_init_filter_chain(vk_t *vk) if (type != RARCH_SHADER_SLANG) { - RARCH_LOG("[Vulkan]: Only SLANG shaders are supported, falling back to stock.\n"); + RARCH_LOG("[Vulkan]: Only Slang shaders are supported, falling back to stock.\n"); return vulkan_init_default_filter_chain(vk); } @@ -1359,17 +1358,17 @@ static bool vulkan_set_shader(void *data, if (!vk) return false; - if (type != RARCH_SHADER_SLANG && path) - { - RARCH_WARN("[Vulkan]: Only .slang or .slangp shaders are supported. Falling back to stock.\n"); - path = NULL; - } - if (vk->filter_chain) vulkan_filter_chain_free((vulkan_filter_chain_t*)vk->filter_chain); vk->filter_chain = NULL; - if (!path) + if (!string_is_empty(path) && type != RARCH_SHADER_SLANG) + { + RARCH_WARN("[Vulkan]: Only Slang shaders are supported. Falling back to stock.\n"); + path = NULL; + } + + if (string_is_empty(path)) { vulkan_init_default_filter_chain(vk); return true; diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index b19a41a5c5..8627ca3f37 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -1171,11 +1171,11 @@ static uint32_t gfx_ctx_x_get_flags(void *data) } if (string_is_equal(video_driver_get_ident(), "gl1")) { } else if (string_is_equal(video_driver_get_ident(), "glcore")) - { + { #ifdef HAVE_SLANG - BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); + BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); #endif - } + } else { #ifdef HAVE_CG diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 00304c0560..44821d3bb8 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -1074,16 +1074,27 @@ static void *gl_cg_init(void *data, const char *path) memset(cg->alias_define, 0, sizeof(cg->alias_define)); - if ( !string_is_empty(path) - && string_is_equal(path_get_extension(path), "cgp")) { - if (!gl_cg_load_preset(cg, path)) - goto error; - } - else - { - if (!gl_cg_load_plain(cg, path)) - goto error; + bool is_preset; + enum rarch_shader_type type = + video_shader_get_type_from_ext(path_get_extension(path), &is_preset); + + if (!string_is_empty(path) && type != RARCH_SHADER_CG) + { + RARCH_ERR("[CG]: Invalid shader type, falling back to stock.\n"); + path = NULL; + } + + if (!string_is_empty(path) && is_preset) + { + if (!gl_cg_load_preset(cg, path)) + goto error; + } + else + { + if (!gl_cg_load_plain(cg, path)) + goto error; + } } cg->prg[0].mvp = cgGetNamedParameter(cg->prg[0].vprg, "IN.mvp_matrix"); @@ -1099,7 +1110,7 @@ static void *gl_cg_init(void *data, const char *path) cg->prg[cg->shader->passes + 1] = cg->prg[0]; /* No need to apply Android hack in Cg. */ - cg->prg[VIDEO_SHADER_STOCK_BLEND] = cg->prg[0]; + cg->prg[VIDEO_SHADER_STOCK_BLEND] = cg->prg[0]; gl_cg_set_shaders(cg->prg[1].fprg, cg->prg[1].vprg); diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index e282582b9f..947bc7c241 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -888,44 +888,55 @@ static void *gl_glsl_init(void *data, const char *path) if (!glsl->shader) goto error; - if (!string_is_empty(path)) { - bool ret = false; - const char *path_ext = path_get_extension(path); + bool is_preset; + enum rarch_shader_type type = + video_shader_get_type_from_ext(path_get_extension(path), &is_preset); - if (string_is_equal(path_ext, "glslp")) + if (!string_is_empty(path) && type != RARCH_SHADER_GLSL) { - conf = config_file_new(path); - if (conf) + RARCH_ERR("[GL]: Invalid shader type, falling back to stock.\n"); + path = NULL; + } + + if (!string_is_empty(path)) + { + bool ret = false; + + if (is_preset) { - ret = video_shader_read_conf_preset(conf, glsl->shader); + conf = config_file_new(path); + if (conf) + { + ret = video_shader_read_conf_preset(conf, glsl->shader); + glsl->shader->modern = true; + } + } + else + { + strlcpy(glsl->shader->pass[0].source.path, path, + sizeof(glsl->shader->pass[0].source.path)); + glsl->shader->passes = 1; glsl->shader->modern = true; + ret = true; + } + + if (!ret) + { + RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); + goto error; } } - else if (string_is_equal(path_ext, "glsl")) + else { - strlcpy(glsl->shader->pass[0].source.path, path, - sizeof(glsl->shader->pass[0].source.path)); + RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); glsl->shader->passes = 1; + glsl->shader->pass[0].source.string.vertex = + strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); + glsl->shader->pass[0].source.string.fragment = + strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); glsl->shader->modern = true; - ret = true; } - - if (!ret) - { - RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); - goto error; - } - } - else - { - RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); - glsl->shader->passes = 1; - glsl->shader->pass[0].source.string.vertex = - strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); - glsl->shader->pass[0].source.string.fragment = - strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); - glsl->shader->modern = true; } if (!string_is_empty(path)) diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index 2090883dff..397b6e02e4 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -482,7 +482,7 @@ bool slang_process( } else #endif - if (dst_type == RARCH_SHADER_METAL) + if (dst_type == RARCH_SHADER_METAL) { CompilerMSL::Options options; CompilerMSL* vs = (CompilerMSL*)vs_compiler; @@ -502,7 +502,7 @@ bool slang_process( vs_code = vs->compile(); ps_code = ps->compile(); } - else if (shader_info->type == RARCH_SHADER_GLSL) + else if (dst_type == RARCH_SHADER_GLSL) { CompilerGLSL::Options options; CompilerGLSL* vs = (CompilerGLSL*)vs_compiler; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index d154fc247c..bc35299649 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -730,7 +730,6 @@ bool video_shader_read_conf_preset(config_file_t *conf, (void)file_list; memset(shader, 0, sizeof(*shader)); - shader->type = RARCH_SHADER_CG; if (!config_get_uint(conf, "shaders", &shaders)) { @@ -1128,6 +1127,29 @@ void video_shader_write_conf_preset(config_file_t *conf, } } +const char *video_shader_to_str(enum rarch_shader_type type) +{ + switch (type) + { + case RARCH_SHADER_CG: + return "Cg"; + case RARCH_SHADER_HLSL: + return "HLSL"; + case RARCH_SHADER_GLSL: + return "GLSL"; + case RARCH_SHADER_SLANG: + return "Slang"; + case RARCH_SHADER_METAL: + return "Metal"; + case RARCH_SHADER_NONE: + return "none"; + default: + break; + } + + return "???"; +} + bool video_shader_is_supported(enum rarch_shader_type type) { enum display_flags flag = GFX_CTX_FLAGS_NONE; @@ -1156,14 +1178,11 @@ bool video_shader_is_supported(enum rarch_shader_type type) bool video_shader_any_supported(void) { - if ( - video_shader_is_supported(RARCH_SHADER_SLANG) || - video_shader_is_supported(RARCH_SHADER_HLSL) || - video_shader_is_supported(RARCH_SHADER_GLSL) || - video_shader_is_supported(RARCH_SHADER_CG) - ) - return true; - return false; + return + video_shader_is_supported(RARCH_SHADER_SLANG) || + video_shader_is_supported(RARCH_SHADER_HLSL) || + video_shader_is_supported(RARCH_SHADER_GLSL) || + video_shader_is_supported(RARCH_SHADER_CG); } enum rarch_shader_type video_shader_get_type_from_ext(const char *ext, @@ -1175,38 +1194,25 @@ enum rarch_shader_type video_shader_get_type_from_ext(const char *ext, if (strlen(ext) > 1 && ext[0] == '.') ext++; - if ( - string_is_equal_case_insensitive(ext, "cgp") || - string_is_equal_case_insensitive(ext, "glslp") || - string_is_equal_case_insensitive(ext, "slangp") + *is_preset = + string_is_equal_case_insensitive(ext, "cgp") || + string_is_equal_case_insensitive(ext, "glslp") || + string_is_equal_case_insensitive(ext, "slangp"); + + if (string_is_equal_case_insensitive(ext, "cgp") || + string_is_equal_case_insensitive(ext, "cg") ) - *is_preset = true; - else - *is_preset = false; + return RARCH_SHADER_CG; - { - gfx_ctx_flags_t flags; - if (string_is_equal_case_insensitive(ext, "cgp") || - string_is_equal_case_insensitive(ext, "cg") - ) - return RARCH_SHADER_CG; - } + if (string_is_equal_case_insensitive(ext, "glslp") || + string_is_equal_case_insensitive(ext, "glsl") + ) + return RARCH_SHADER_GLSL; - { - gfx_ctx_flags_t flags; - if (string_is_equal_case_insensitive(ext, "glslp") || - string_is_equal_case_insensitive(ext, "glsl") - ) - return RARCH_SHADER_GLSL; - } - - { - gfx_ctx_flags_t flags; - if (string_is_equal_case_insensitive(ext, "slangp") || - string_is_equal_case_insensitive(ext, "slang") - ) - return RARCH_SHADER_SLANG; - } + if (string_is_equal_case_insensitive(ext, "slangp") || + string_is_equal_case_insensitive(ext, "slang") + ) + return RARCH_SHADER_SLANG; return RARCH_SHADER_NONE; } diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index 42df1534f8..aca13746d6 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -141,8 +141,6 @@ struct video_shader_lut * Avoid lots of allocation for convenience. */ struct video_shader { - enum rarch_shader_type type; - char prefix[64]; char script_class[512]; char script_path[PATH_MAX_LENGTH]; @@ -250,6 +248,8 @@ bool video_shader_any_supported(void); bool video_shader_check_for_changes(void); +const char *video_shader_to_str(enum rarch_shader_type type); + RETRO_END_DECLS #endif diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 0ff5504da1..14d8f5c727 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5685,7 +5685,7 @@ void general_write_handler(rarch_setting_t *setting) menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); } - else if (!*setting->value.target.boolean) + else { bool refresh = false; settings_t *settings = config_get_ptr(); diff --git a/menu/menu_shader.c b/menu/menu_shader.c index d5791cd14f..143aa9a758 100644 --- a/menu/menu_shader.c +++ b/menu/menu_shader.c @@ -147,14 +147,14 @@ bool menu_shader_manager_init(void) * Sets shader preset. **/ bool menu_shader_manager_set_preset(void *data, - unsigned type, const char *preset_path) + enum rarch_shader_type type, const char *preset_path) { struct video_shader *shader = (struct video_shader*)data; config_file_t *conf = NULL; bool refresh = false; settings_t *settings = config_get_ptr(); - if (!video_driver_set_shader((enum rarch_shader_type)type, preset_path)) + if (!video_driver_set_shader(type, preset_path)) { configuration_set_bool(settings, settings->bools.video_shader_enable, false); return false; @@ -225,7 +225,8 @@ bool menu_shader_manager_save_preset( char preset_path[PATH_MAX_LENGTH]; char config_directory[PATH_MAX_LENGTH]; bool ret = false; - unsigned d, type = RARCH_SHADER_NONE; + unsigned d; + enum rarch_shader_type type = RARCH_SHADER_NONE; const char *dirs[3] = {0}; config_file_t *conf = NULL; struct video_shader *shader = menu_shader_get(); @@ -265,7 +266,7 @@ bool menu_shader_manager_save_preset( default_preset[0] = '\0'; - if (video_shader_is_supported((enum rarch_shader_type)type)) + if (video_shader_is_supported(type)) { const char *config_path = path_get(RARCH_PATH_CONFIG); /* In a multi-config setting, we can't have @@ -449,16 +450,18 @@ void menu_shader_manager_clear_pass_path(unsigned i) * * Returns: type of shader. **/ -unsigned menu_shader_manager_get_type(const void *data) +enum rarch_shader_type menu_shader_manager_get_type(const void *data) { unsigned type = RARCH_SHADER_NONE; const struct video_shader *shader = (const struct video_shader*)data; /* All shader types must be the same, or we cannot use it. */ - uint8_t i = 0; + unsigned i = 0; if (!shader) return RARCH_SHADER_NONE; + type = video_shader_parse_type(shader->path); + for (i = 0; i < shader->passes; i++) { enum rarch_shader_type pass_type = @@ -469,9 +472,7 @@ unsigned menu_shader_manager_get_type(const void *data) case RARCH_SHADER_CG: case RARCH_SHADER_GLSL: case RARCH_SHADER_SLANG: - if (type == RARCH_SHADER_NONE) - type = pass_type; - else if (type != pass_type) + if (type != pass_type) return RARCH_SHADER_NONE; break; default: @@ -489,7 +490,7 @@ unsigned menu_shader_manager_get_type(const void *data) **/ void menu_shader_manager_apply_changes(void) { - unsigned shader_type; + enum rarch_shader_type shader_type; struct video_shader *shader = menu_shader_get(); if (!shader) diff --git a/menu/menu_shader.h b/menu/menu_shader.h index ca6bfdcef0..21c237581c 100644 --- a/menu/menu_shader.h +++ b/menu/menu_shader.h @@ -20,6 +20,7 @@ #include #include "../retroarch.h" +#include "../gfx/video_shader_parse.h" RETRO_BEGIN_DECLS @@ -43,7 +44,7 @@ bool menu_shader_manager_init(void); * Sets shader preset. **/ bool menu_shader_manager_set_preset( - void *data, unsigned type, const char *preset_path); + void *data, enum rarch_shader_type type, const char *preset_path); /** * menu_shader_manager_save_preset: @@ -63,7 +64,7 @@ bool menu_shader_manager_save_preset( * * Returns: type of shader. **/ -unsigned menu_shader_manager_get_type(const void *data); +enum rarch_shader_type menu_shader_manager_get_type(const void *data); /** * menu_shader_manager_apply_changes: diff --git a/retroarch.c b/retroarch.c index 7fad954710..a862b3e4f5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -10176,7 +10176,7 @@ static bool video_driver_get_flags(gfx_ctx_flags_t *flags) * @testflag : flag to test * * Poll both the video and context driver's flags and test - * whether testflag is set or not. + * whether @testflag is set or not. **/ bool video_driver_test_all_flags(enum display_flags testflag) {