diff --git a/Makefile.common b/Makefile.common
index df6ced6b21..0679d05574 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1248,6 +1248,20 @@ ifeq ($(HAVE_VULKAN), 1)
HAVE_SPIRV_CROSS = 1
endif
+ifeq ($(HAVE_OPENGL_CORE), 1)
+ OBJ += gfx/drivers/gl_core.o \
+ gfx/drivers_font/gl_core_raster_font.o \
+ gfx/drivers_shader/shader_gl_core.o
+ ifeq ($(HAVE_MENU_COMMON), 1)
+ OBJ += menu/drivers_display/menu_display_gl_core.o
+ endif
+
+ DEFINES += -DHAVE_OPENGL_CORE
+ HAVE_SLANG = 1
+ HAVE_GLSLANG = 1
+ HAVE_SPIRV_CROSS = 1
+endif
+
ifeq ($(HAVE_OMAP), 1)
OBJ += gfx/drivers/omap_gfx.o
endif
diff --git a/configuration.c b/configuration.c
index 1e8b0b4f06..dfbda1b737 100644
--- a/configuration.c
+++ b/configuration.c
@@ -2509,6 +2509,7 @@ static bool check_menu_driver_compatibility(void)
string_is_equal(video_driver, "gl1") ||
string_is_equal(video_driver, "gx2") ||
string_is_equal(video_driver, "vulkan") ||
+ string_is_equal(video_driver, "glcore") ||
string_is_equal(video_driver, "metal") ||
string_is_equal(video_driver, "ctr") ||
string_is_equal(video_driver, "vita2d"))
@@ -2622,6 +2623,7 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx)
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"))
diff --git a/dynamic.c b/dynamic.c
index 6f899eabde..0cf7bd830c 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -1157,8 +1157,11 @@ static bool dynamic_verify_hw_context(enum retro_hw_context_type type,
case RETRO_HW_CONTEXT_OPENGLES_VERSION:
case RETRO_HW_CONTEXT_OPENGL:
case RETRO_HW_CONTEXT_OPENGL_CORE:
- if (!string_is_equal(video_ident, "gl"))
+ if (!string_is_equal(video_ident, "gl") &&
+ !string_is_equal(video_ident, "glcore"))
+ {
return false;
+ }
break;
case RETRO_HW_CONTEXT_DIRECT3D:
if (!(string_is_equal(video_ident, "d3d11") && major == 11))
diff --git a/gfx/common/gl_core_common.h b/gfx/common/gl_core_common.h
new file mode 100644
index 0000000000..c2c5fcd4c8
--- /dev/null
+++ b/gfx/common/gl_core_common.h
@@ -0,0 +1,141 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2019 - Hans-Kristian Arntzen
+ * copyright (c) 2011-2017 - Daniel De Matteis
+ *
+ * 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 .
+ */
+
+#ifndef __GL_CORE_COMMON_H
+#define __GL_CORE_COMMON_H
+
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "../video_coord_array.h"
+#include "../video_driver.h"
+#include "../drivers_shader/shader_gl_core.h"
+
+RETRO_BEGIN_DECLS
+
+#define GL_CORE_NUM_TEXTURES 4
+#define GL_CORE_NUM_PBOS 4
+#define GL_CORE_NUM_VBOS 256
+#define GL_CORE_NUM_FENCES 8
+struct gl_core_streamed_texture
+{
+ GLuint tex;
+ unsigned width;
+ unsigned height;
+};
+
+typedef struct gl_core
+{
+ const gfx_ctx_driver_t *ctx_driver;
+ void *ctx_data;
+ gl_core_filter_chain_t *filter_chain;
+
+ video_info_t video_info;
+
+ bool vsync;
+ bool fullscreen;
+ bool quitting;
+ bool should_resize;
+ bool keep_aspect;
+ unsigned version_major;
+ unsigned version_minor;
+
+ video_viewport_t vp;
+ struct gl_core_viewport filter_chain_vp;
+ unsigned vp_out_width;
+ unsigned vp_out_height;
+
+ math_matrix_4x4 mvp;
+ math_matrix_4x4 mvp_yflip;
+ math_matrix_4x4 mvp_no_rot;
+ math_matrix_4x4 mvp_no_rot_yflip;
+ unsigned rotation;
+
+ GLuint vao;
+ struct gl_core_streamed_texture textures[GL_CORE_NUM_TEXTURES];
+ unsigned textures_index;
+
+ GLuint menu_texture;
+ float menu_texture_alpha;
+ bool menu_texture_enable;
+ bool menu_texture_full_screen;
+
+ struct
+ {
+ GLuint alpha_blend;
+ GLuint font;
+ GLuint ribbon;
+ GLuint ribbon_simple;
+ GLuint snow_simple;
+ GLuint snow;
+ GLuint bokeh;
+ struct gl_core_buffer_locations alpha_blend_loc;
+ struct gl_core_buffer_locations font_loc;
+ struct gl_core_buffer_locations ribbon_loc;
+ struct gl_core_buffer_locations ribbon_simple_loc;
+ struct gl_core_buffer_locations snow_simple_loc;
+ struct gl_core_buffer_locations snow_loc;
+ struct gl_core_buffer_locations bokeh_loc;
+ } pipelines;
+
+ GLuint *overlay_tex;
+ float *overlay_vertex_coord;
+ float *overlay_tex_coord;
+ float *overlay_color_coord;
+ unsigned overlays;
+ bool overlay_enable;
+ bool overlay_full_screen;
+
+ GLuint scratch_vbos[GL_CORE_NUM_VBOS];
+ unsigned scratch_vbo_index;
+
+ bool use_shared_context;
+ GLuint hw_render_texture;
+ GLuint hw_render_fbo;
+ GLuint hw_render_rb_ds;
+ bool hw_render_enable;
+ unsigned hw_render_max_width;
+ unsigned hw_render_max_height;
+ bool hw_render_bottom_left;
+
+ GLsync fences[GL_CORE_NUM_FENCES];
+ unsigned fence_count;
+
+ void *readback_buffer_screenshot;
+ struct scaler_ctx pbo_readback_scaler;
+ bool pbo_readback_enable;
+ unsigned pbo_readback_index;
+ bool pbo_readback_valid[GL_CORE_NUM_PBOS];
+ GLuint pbo_readback[GL_CORE_NUM_PBOS];
+} gl_core_t;
+
+void gl_core_bind_scratch_vbo(gl_core_t *gl, const void *data, size_t size);
+
+RETRO_END_DECLS
+
+#endif
diff --git a/gfx/drivers/gl_core.c b/gfx/drivers/gl_core.c
new file mode 100644
index 0000000000..f0776c0b8d
--- /dev/null
+++ b/gfx/drivers/gl_core.c
@@ -0,0 +1,2001 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2019 - 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 .
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../common/gl_core_common.h"
+
+#include
+#include
+#include
+#include
+
+#include "../../configuration.h"
+#include "../../dynamic.h"
+#include "../../record/record_driver.h"
+
+#include "../../retroarch.h"
+#include "../../verbosity.h"
+
+#ifdef HAVE_THREADS
+#include "../video_thread_wrapper.h"
+#endif
+
+#include "../font_driver.h"
+
+#ifdef HAVE_MENU
+#include "../../menu/menu_driver.h"
+#ifdef HAVE_MENU_WIDGETS
+#include "../../menu/widgets/menu_widgets.h"
+#endif
+#endif
+
+static const struct video_ortho gl_core_default_ortho = {0, 1, 0, 1, -1, 1};
+
+static void gl_core_deinit_fences(gl_core_t *gl)
+{
+ unsigned i;
+ for (i = 0; i < gl->fence_count; i++)
+ {
+ if (gl->fences[i])
+ glDeleteSync(gl->fences[i]);
+ }
+ gl->fence_count = 0;
+ memset(gl->fences, 0, sizeof(gl->fences));
+}
+
+static bool gl_core_init_pbo_readback(gl_core_t *gl)
+{
+ int i;
+ glGenBuffers(GL_CORE_NUM_PBOS, gl->pbo_readback);
+
+ for (i = 0; i < GL_CORE_NUM_PBOS; i++)
+ {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, gl->pbo_readback[i]);
+ glBufferData(GL_PIXEL_PACK_BUFFER, gl->vp.width * gl->vp.height * sizeof(uint32_t), NULL, GL_STREAM_READ);
+ }
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+ struct scaler_ctx *scaler = &gl->pbo_readback_scaler;
+ scaler->in_width = gl->vp.width;
+ scaler->in_height = gl->vp.height;
+ scaler->out_width = gl->vp.width;
+ scaler->out_height = gl->vp.height;
+ scaler->in_stride = gl->vp.width * sizeof(uint32_t);
+ scaler->out_stride = gl->vp.width * 3;
+ scaler->in_fmt = SCALER_FMT_ABGR8888;
+ scaler->out_fmt = SCALER_FMT_BGR24;
+ scaler->scaler_type = SCALER_TYPE_POINT;
+
+ if (!scaler_ctx_gen_filter(scaler))
+ {
+ gl->pbo_readback_enable = false;
+ RARCH_ERR("[GLCore]: Failed to initialize pixel conversion for PBO.\n");
+ glDeleteBuffers(4, gl->pbo_readback);
+ memset(gl->pbo_readback, 0, sizeof(gl->pbo_readback));
+ return false;
+ }
+
+ return true;
+}
+
+static void gl_core_deinit_pbo_readback(gl_core_t *gl)
+{
+ int i;
+ for (i = 0; i < GL_CORE_NUM_PBOS; i++)
+ if (gl->pbo_readback[i] != 0)
+ glDeleteBuffers(1, &gl->pbo_readback[i]);
+ memset(gl->pbo_readback, 0, sizeof(gl->pbo_readback));
+ scaler_ctx_gen_reset(&gl->pbo_readback_scaler);
+}
+
+#ifdef HAVE_OVERLAY
+static void gl_core_free_overlay(gl_core_t *gl)
+{
+ if (gl->overlay_tex)
+ glDeleteTextures(gl->overlays, gl->overlay_tex);
+
+ free(gl->overlay_tex);
+ free(gl->overlay_vertex_coord);
+ free(gl->overlay_tex_coord);
+ free(gl->overlay_color_coord);
+ gl->overlay_tex = NULL;
+ gl->overlay_vertex_coord = NULL;
+ gl->overlay_tex_coord = NULL;
+ gl->overlay_color_coord = NULL;
+ gl->overlays = 0;
+}
+
+static void gl_core_free_scratch_vbos(gl_core_t *gl)
+{
+ int i;
+ for (i = 0; i < GL_CORE_NUM_VBOS; i++)
+ if (gl->scratch_vbos[i])
+ glDeleteBuffers(1, &gl->scratch_vbos[i]);
+}
+
+static void gl_core_slow_readback(gl_core_t *gl, void *buffer)
+{
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+#ifndef HAVE_OPENGLES
+ glReadBuffer(GL_BACK);
+#endif
+
+ glReadPixels(gl->vp.x, gl->vp.y,
+ gl->vp.width, gl->vp.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+}
+
+static void gl_core_pbo_async_readback(gl_core_t *gl)
+{
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, gl->pbo_readback[gl->pbo_readback_index++]);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+#ifndef HAVE_OPENGLES
+ glReadBuffer(GL_BACK);
+#endif
+ if (gl->pbo_readback_index >= GL_CORE_NUM_PBOS)
+ gl->pbo_readback_index = 0;
+ gl->pbo_readback_valid[gl->pbo_readback_index] = true;
+
+ glReadPixels(gl->vp.x, gl->vp.y,
+ gl->vp.width, gl->vp.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+}
+
+static void gl_core_fence_iterate(gl_core_t *gl, unsigned hard_sync_frames)
+{
+ if (gl->fence_count < GL_CORE_NUM_FENCES)
+ {
+ /*
+ * We need to do some work after the flip, or we risk fencing too early.
+ * Do as little work as possible.
+ */
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0, 0, 1, 1);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_SCISSOR_TEST);
+
+ gl->fences[gl->fence_count++] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ }
+
+ while (gl->fence_count > hard_sync_frames)
+ {
+ glClientWaitSync(gl->fences[0], GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
+ glDeleteSync(gl->fences[0]);
+ gl->fence_count--;
+ memmove(gl->fences, gl->fences + 1, gl->fence_count * sizeof(GLsync));
+ }
+}
+
+void gl_core_bind_scratch_vbo(gl_core_t *gl, const void *data, size_t size)
+{
+ if (!gl->scratch_vbos[gl->scratch_vbo_index])
+ glGenBuffers(1, &gl->scratch_vbos[gl->scratch_vbo_index]);
+ glBindBuffer(GL_ARRAY_BUFFER, gl->scratch_vbos[gl->scratch_vbo_index]);
+ glBufferData(GL_ARRAY_BUFFER, size, data, GL_STREAM_DRAW);
+ gl->scratch_vbo_index++;
+ if (gl->scratch_vbo_index >= GL_CORE_NUM_VBOS)
+ gl->scratch_vbo_index = 0;
+}
+
+static void gl_core_overlay_vertex_geom(void *data,
+ unsigned image,
+ float x, float y,
+ float w, float h)
+{
+ GLfloat *vertex = NULL;
+ gl_core_t *gl = (gl_core_t*)data;
+
+ if (!gl)
+ return;
+
+ if (image > gl->overlays)
+ {
+ RARCH_ERR("[GLCore]: Invalid overlay id: %u\n", image);
+ return;
+ }
+
+ vertex = (GLfloat*)&gl->overlay_vertex_coord[image * 8];
+
+ /* Flipped, so we preserve top-down semantics. */
+ y = 1.0f - y;
+ h = -h;
+
+ vertex[0] = x;
+ vertex[1] = y;
+ vertex[2] = x + w;
+ vertex[3] = y;
+ vertex[4] = x;
+ vertex[5] = y + h;
+ vertex[6] = x + w;
+ vertex[7] = y + h;
+}
+
+static void gl_core_overlay_tex_geom(void *data,
+ unsigned image,
+ GLfloat x, GLfloat y,
+ GLfloat w, GLfloat h)
+{
+ GLfloat *tex = NULL;
+ gl_core_t *gl = (gl_core_t*)data;
+
+ if (!gl)
+ return;
+
+ tex = (GLfloat*)&gl->overlay_tex_coord[image * 8];
+
+ tex[0] = x;
+ tex[1] = y;
+ tex[2] = x + w;
+ tex[3] = y;
+ tex[4] = x;
+ tex[5] = y + h;
+ tex[6] = x + w;
+ tex[7] = y + h;
+}
+
+static void gl_core_render_overlay(gl_core_t *gl, video_frame_info_t *video_info)
+{
+ unsigned i;
+ unsigned width = video_info->width;
+ unsigned height = video_info->height;
+
+ glEnable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
+ if (gl->overlay_full_screen)
+ glViewport(0, 0, width, height);
+
+ /* Ensure that we reset the attrib array. */
+ glUseProgram(gl->pipelines.alpha_blend);
+ if (gl->pipelines.alpha_blend_loc.flat_ubo_vertex >= 0)
+ glUniform4fv(gl->pipelines.alpha_blend_loc.flat_ubo_vertex, 4, gl->mvp_no_rot.data);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
+
+ gl_core_bind_scratch_vbo(gl, gl->overlay_vertex_coord, 8 * sizeof(float) * gl->overlays);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0);
+ gl_core_bind_scratch_vbo(gl, gl->overlay_tex_coord, 8 * sizeof(float) * gl->overlays);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0);
+ gl_core_bind_scratch_vbo(gl, gl->overlay_color_coord, 16 * sizeof(float) * gl->overlays);
+ glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(uintptr_t)0);
+
+ for (i = 0; i < gl->overlays; i++)
+ {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, gl->overlay_tex[i]);
+ glDrawArrays(GL_TRIANGLE_STRIP, 4 * i, 4);
+ }
+
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(2);
+
+ glDisable(GL_BLEND);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (gl->overlay_full_screen)
+ glViewport(gl->vp.x, gl->vp.y, gl->vp.width, gl->vp.height);
+}
+#endif
+
+static void gl_core_context_bind_hw_render(gl_core_t *gl, bool enable)
+{
+ if (gl->use_shared_context && gl->ctx_driver->bind_hw_render)
+ gl->ctx_driver->bind_hw_render(gl->ctx_data, enable);
+}
+
+static void gl_core_deinit_hw_render(gl_core_t *gl)
+{
+ gl_core_context_bind_hw_render(gl, true);
+
+ if (gl->hw_render_fbo)
+ glDeleteFramebuffers(1, &gl->hw_render_fbo);
+ if (gl->hw_render_rb_ds)
+ glDeleteRenderbuffers(1, &gl->hw_render_rb_ds);
+ if (gl->hw_render_texture)
+ glDeleteTextures(1, &gl->hw_render_texture);
+
+ gl->hw_render_fbo = 0;
+ gl->hw_render_rb_ds = 0;
+ gl->hw_render_texture = 0;
+ gl_core_context_bind_hw_render(gl, false);
+ gl->hw_render_enable = false;
+}
+
+static void gl_core_destroy_resources(gl_core_t *gl)
+{
+ int i;
+ if (!gl)
+ return;
+
+ if (gl->filter_chain)
+ gl_core_filter_chain_free(gl->filter_chain);
+ gl->filter_chain = NULL;
+
+ glBindVertexArray(0);
+ if (gl->vao != 0)
+ glDeleteVertexArrays(1, &gl->vao);
+
+ for (i = 0; i < GL_CORE_NUM_TEXTURES; i++)
+ {
+ if (gl->textures[i].tex != 0)
+ glDeleteTextures(1, &gl->textures[i].tex);
+ }
+ memset(gl->textures, 0, sizeof(gl->textures));
+
+ if (gl->menu_texture != 0)
+ glDeleteTextures(1, &gl->menu_texture);
+
+ if (gl->pipelines.alpha_blend)
+ glDeleteProgram(gl->pipelines.alpha_blend);
+ if (gl->pipelines.font)
+ glDeleteProgram(gl->pipelines.font);
+ if (gl->pipelines.ribbon)
+ glDeleteProgram(gl->pipelines.ribbon);
+ if (gl->pipelines.ribbon_simple)
+ glDeleteProgram(gl->pipelines.ribbon_simple);
+ if (gl->pipelines.snow_simple)
+ glDeleteProgram(gl->pipelines.snow_simple);
+ if (gl->pipelines.snow)
+ glDeleteProgram(gl->pipelines.snow);
+ if (gl->pipelines.bokeh)
+ glDeleteProgram(gl->pipelines.bokeh);
+
+ gl_core_free_overlay(gl);
+ gl_core_free_scratch_vbos(gl);
+ gl_core_deinit_fences(gl);
+ gl_core_deinit_pbo_readback(gl);
+ gl_core_deinit_hw_render(gl);
+ free(gl);
+}
+
+static bool gl_core_init_hw_render(gl_core_t *gl, unsigned width, unsigned height)
+{
+ GLint max_fbo_size;
+ GLint max_rb_size;
+ GLenum status;
+ struct retro_hw_render_callback *hwr = video_driver_get_hw_context();
+ gl_core_context_bind_hw_render(gl, true);
+
+ RARCH_LOG("[GLCore]: Initializing HW render (%u x %u).\n", width, height);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_fbo_size);
+ glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_rb_size);
+ RARCH_LOG("[GLCore]: Max texture size: %d px, renderbuffer size: %d px.\n",
+ max_fbo_size, max_rb_size);
+
+ glGenFramebuffers(1, &gl->hw_render_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, gl->hw_render_fbo);
+ glGenTextures(1, &gl->hw_render_texture);
+ glBindTexture(GL_TEXTURE_2D, gl->hw_render_texture);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->hw_render_texture, 0);
+
+ gl->hw_render_rb_ds = 0;
+ gl->hw_render_bottom_left = hwr->bottom_left_origin;
+ if (hwr->depth)
+ {
+ glGenRenderbuffers(1, &gl->hw_render_rb_ds);
+ glRenderbufferStorage(GL_RENDERBUFFER, hwr->stencil ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16,
+ width, height);
+
+ if (hwr->stencil)
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gl->hw_render_rb_ds);
+ else
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl->hw_render_rb_ds);
+ }
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ RARCH_ERR("[GLCore]: Framebuffer is not complete.\n");
+ gl_core_context_bind_hw_render(gl, false);
+ return false;
+ }
+
+ gl->hw_render_enable = true;
+ gl->hw_render_max_width = width;
+ gl->hw_render_max_height = height;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_core_context_bind_hw_render(gl, false);
+
+ return true;
+}
+
+static const gfx_ctx_driver_t *gl_core_get_context(gl_core_t *gl)
+{
+ enum gfx_ctx_api api;
+ const gfx_ctx_driver_t *gfx_ctx = NULL;
+ void *ctx_data = NULL;
+ settings_t *settings = config_get_ptr();
+ unsigned major;
+ unsigned minor;
+ gfx_ctx_flags_t flags;
+ struct retro_hw_render_callback *hwr = video_driver_get_hw_context();
+
+#ifdef HAVE_OPENGLES3
+ api = GFX_CTX_OPENGL_ES_API;
+ major = 3;
+ minor = 0;
+ if (hwr && hwr->context_type == RETRO_HW_CONTEXT_OPENGLES_VERSION)
+ {
+ major = hwr->version_major;
+ minor = hwr->version_minor;
+ }
+#else
+ api = GFX_CTX_OPENGL_API;
+ if (hwr)
+ {
+ major = hwr->version_major;
+ minor = hwr->version_minor;
+ gl_query_core_context_set(hwr->context_type == RETRO_HW_CONTEXT_OPENGL_CORE);
+ if (hwr->context_type == RETRO_HW_CONTEXT_OPENGL_CORE)
+ {
+ flags.flags = 0;
+ BIT32_SET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT);
+ video_context_driver_set_flags(&flags);
+ }
+ }
+ else
+ {
+ major = 3;
+ minor = 2;
+ gl_query_core_context_set(true);
+ flags.flags = 0;
+ BIT32_SET(flags.flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT);
+ video_context_driver_set_flags(&flags);
+ }
+#endif
+
+ /* Force shared context. */
+ gl->use_shared_context = hwr->context_type != RETRO_HW_CONTEXT_NONE;
+
+ gfx_ctx = video_context_driver_init_first(gl,
+ settings->arrays.video_context_driver,
+ api, major, minor, gl->use_shared_context, &ctx_data);
+
+ if (ctx_data)
+ gl->ctx_data = ctx_data;
+
+ /* Need to force here since video_context_driver_init also checks for global option. */
+ if (gfx_ctx->bind_hw_render)
+ gfx_ctx->bind_hw_render(ctx_data, gl->use_shared_context);
+ return gfx_ctx;
+}
+
+static void gl_core_set_projection(gl_core_t *gl,
+ const struct video_ortho *ortho, bool allow_rotate)
+{
+ math_matrix_4x4 rot;
+
+ /* Calculate projection. */
+ matrix_4x4_ortho(gl->mvp_no_rot, ortho->left, ortho->right,
+ ortho->bottom, ortho->top, ortho->znear, ortho->zfar);
+
+ if (!allow_rotate)
+ {
+ gl->mvp = gl->mvp_no_rot;
+ return;
+ }
+
+ matrix_4x4_rotate_z(rot, M_PI * gl->rotation / 180.0f);
+ matrix_4x4_multiply(gl->mvp, rot, gl->mvp_no_rot);
+
+ memcpy(gl->mvp_no_rot_yflip.data, gl->mvp_no_rot.data, sizeof(gl->mvp_no_rot.data));
+ MAT_ELEM_4X4(gl->mvp_no_rot_yflip, 1, 0) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_no_rot_yflip, 1, 1) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_no_rot_yflip, 1, 2) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_no_rot_yflip, 1, 3) *= -1.0f;
+
+ memcpy(gl->mvp_yflip.data, gl->mvp.data, sizeof(gl->mvp.data));
+ MAT_ELEM_4X4(gl->mvp_yflip, 1, 0) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_yflip, 1, 1) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_yflip, 1, 2) *= -1.0f;
+ MAT_ELEM_4X4(gl->mvp_yflip, 1, 3) *= -1.0f;
+}
+
+static void gl_core_set_viewport(gl_core_t *gl,
+ unsigned viewport_width,
+ unsigned viewport_height,
+ bool force_full, bool allow_rotate)
+{
+ gfx_ctx_aspect_t aspect_data;
+ unsigned width, height;
+ int x = 0;
+ int y = 0;
+ float device_aspect = (float)viewport_width / viewport_height;
+ settings_t *settings = config_get_ptr();
+
+ video_driver_get_size(&width, &height);
+
+ aspect_data.aspect = &device_aspect;
+ aspect_data.width = viewport_width;
+ aspect_data.height = viewport_height;
+
+ video_context_driver_translate_aspect(&aspect_data);
+
+ if (settings->bools.video_scale_integer && !force_full)
+ {
+ video_viewport_get_scaled_integer(&gl->vp,
+ viewport_width, viewport_height,
+ video_driver_get_aspect_ratio(), gl->keep_aspect);
+ viewport_width = gl->vp.width;
+ viewport_height = gl->vp.height;
+ }
+ else if (gl->keep_aspect && !force_full)
+ {
+ float desired_aspect = video_driver_get_aspect_ratio();
+
+#if defined(HAVE_MENU)
+ if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
+ {
+ const struct video_viewport *custom = video_viewport_get_custom();
+ /* GL has bottom-left origin viewport. */
+ x = custom->x;
+ y = height - custom->y - custom->height;
+ viewport_width = custom->width;
+ viewport_height = custom->height;
+ }
+ else
+#endif
+ {
+ float delta;
+
+ if (fabsf(device_aspect - desired_aspect) < 0.0001f)
+ {
+ /* If the aspect ratios of screen and desired aspect
+ * ratio are sufficiently equal (floating point stuff),
+ * assume they are actually equal.
+ */
+ }
+ else if (device_aspect > desired_aspect)
+ {
+ delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
+ x = (int)roundf(viewport_width * (0.5f - delta));
+ viewport_width = (unsigned)roundf(2.0f * viewport_width * delta);
+ }
+ else
+ {
+ delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
+ y = (int)roundf(viewport_height * (0.5f - delta));
+ viewport_height = (unsigned)roundf(2.0f * viewport_height * delta);
+ }
+ }
+
+ gl->vp.x = x;
+ gl->vp.y = y;
+ gl->vp.width = viewport_width;
+ gl->vp.height = viewport_height;
+ }
+ else
+ {
+ gl->vp.x = gl->vp.y = 0;
+ gl->vp.width = viewport_width;
+ gl->vp.height = viewport_height;
+ }
+
+#if defined(RARCH_MOBILE)
+ /* In portrait mode, we want viewport to gravitate to top of screen. */
+ if (device_aspect < 1.0f)
+ gl->vp.y *= 2;
+#endif
+
+ glViewport(gl->vp.x, gl->vp.y, gl->vp.width, gl->vp.height);
+ gl_core_set_projection(gl, &gl_core_default_ortho, allow_rotate);
+
+ /* Set last backbuffer viewport. */
+ if (!force_full)
+ {
+ gl->vp_out_width = viewport_width;
+ gl->vp_out_height = viewport_height;
+ }
+
+ gl->filter_chain_vp.x = gl->vp.x;
+ gl->filter_chain_vp.y = gl->vp.y;
+ gl->filter_chain_vp.width = gl->vp.width;
+ gl->filter_chain_vp.height = gl->vp.height;
+
+#if 0
+ RARCH_LOG("Setting viewport @ %ux%u\n", viewport_width, viewport_height);
+#endif
+}
+
+static bool gl_core_init_pipelines(gl_core_t *gl)
+{
+ static const uint32_t alpha_blend_vert[] =
+#include "vulkan_shaders/alpha_blend.vert.inc"
+ ;
+
+ static const uint32_t alpha_blend_frag[] =
+#include "vulkan_shaders/alpha_blend.frag.inc"
+ ;
+
+ static const uint32_t font_frag[] =
+#include "vulkan_shaders/font.frag.inc"
+ ;
+
+ static const uint32_t pipeline_ribbon_vert[] =
+#include "vulkan_shaders/pipeline_ribbon.vert.inc"
+ ;
+
+ static const uint32_t pipeline_ribbon_frag[] =
+#include "vulkan_shaders/pipeline_ribbon.frag.inc"
+ ;
+
+ static const uint32_t pipeline_ribbon_simple_vert[] =
+#include "vulkan_shaders/pipeline_ribbon_simple.vert.inc"
+ ;
+
+ static const uint32_t pipeline_ribbon_simple_frag[] =
+#include "vulkan_shaders/pipeline_ribbon_simple.frag.inc"
+ ;
+
+ static const uint32_t pipeline_snow_simple_frag[] =
+#include "vulkan_shaders/pipeline_snow_simple.frag.inc"
+ ;
+
+ static const uint32_t pipeline_snow_frag[] =
+#include "vulkan_shaders/pipeline_snow.frag.inc"
+ ;
+
+ static const uint32_t pipeline_bokeh_frag[] =
+#include "vulkan_shaders/pipeline_bokeh.frag.inc"
+ ;
+
+ gl->pipelines.alpha_blend = gl_core_cross_compile_program(alpha_blend_vert, sizeof(alpha_blend_vert),
+ alpha_blend_frag, sizeof(alpha_blend_frag),
+ &gl->pipelines.alpha_blend_loc, true);
+ if (!gl->pipelines.alpha_blend)
+ return false;
+
+ gl->pipelines.font = gl_core_cross_compile_program(alpha_blend_vert, sizeof(alpha_blend_vert),
+ font_frag, sizeof(font_frag),
+ &gl->pipelines.font_loc, true);
+ if (!gl->pipelines.font)
+ return false;
+
+ gl->pipelines.ribbon_simple = gl_core_cross_compile_program(pipeline_ribbon_simple_vert, sizeof(pipeline_ribbon_simple_vert),
+ pipeline_ribbon_simple_frag, sizeof(pipeline_ribbon_simple_frag),
+ &gl->pipelines.ribbon_simple_loc, true);
+ if (!gl->pipelines.ribbon_simple)
+ return false;
+
+ gl->pipelines.ribbon = gl_core_cross_compile_program(pipeline_ribbon_vert, sizeof(pipeline_ribbon_vert),
+ pipeline_ribbon_frag, sizeof(pipeline_ribbon_frag),
+ &gl->pipelines.ribbon_loc, true);
+ if (!gl->pipelines.ribbon)
+ return false;
+
+ gl->pipelines.bokeh = gl_core_cross_compile_program(alpha_blend_vert, sizeof(alpha_blend_vert),
+ pipeline_bokeh_frag, sizeof(pipeline_bokeh_frag),
+ &gl->pipelines.bokeh_loc, true);
+ if (!gl->pipelines.bokeh)
+ return false;
+
+ gl->pipelines.snow_simple = gl_core_cross_compile_program(alpha_blend_vert, sizeof(alpha_blend_vert),
+ pipeline_snow_simple_frag, sizeof(pipeline_snow_simple_frag),
+ &gl->pipelines.snow_simple_loc, true);
+ if (!gl->pipelines.snow_simple)
+ return false;
+
+ gl->pipelines.snow = gl_core_cross_compile_program(alpha_blend_vert, sizeof(alpha_blend_vert),
+ pipeline_snow_frag, sizeof(pipeline_snow_frag),
+ &gl->pipelines.snow_loc, true);
+ if (!gl->pipelines.snow)
+ return false;
+
+ return true;
+}
+
+static bool gl_core_init_default_filter_chain(gl_core_t *gl)
+{
+ if (!gl->ctx_driver)
+ return false;
+
+ gl->filter_chain = gl_core_filter_chain_create_default(
+ gl->video_info.smooth ?
+ GL_CORE_FILTER_CHAIN_LINEAR : GL_CORE_FILTER_CHAIN_NEAREST);
+
+ if (!gl->filter_chain)
+ {
+ RARCH_ERR("Failed to create filter chain.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool gl_core_init_filter_chain_preset(gl_core_t *gl, const char *shader_path)
+{
+ gl->filter_chain = gl_core_filter_chain_create_from_preset(
+ shader_path,
+ gl->video_info.smooth ?
+ GL_CORE_FILTER_CHAIN_LINEAR : GL_CORE_FILTER_CHAIN_NEAREST);
+
+ if (!gl->filter_chain)
+ {
+ RARCH_ERR("[GLCore]: Failed to create preset: \"%s\".\n", shader_path);
+ return false;
+ }
+
+ return true;
+}
+
+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, RARCH_SHADER_NONE);
+
+ if (type == RARCH_SHADER_NONE)
+ {
+ RARCH_LOG("[GLCore]: Loading stock shader.\n");
+ return gl_core_init_default_filter_chain(gl);
+ }
+
+ if (type != RARCH_SHADER_SLANG)
+ {
+ RARCH_LOG("[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))
+ gl_core_init_default_filter_chain(gl);
+
+ return true;
+}
+
+#ifdef GL_DEBUG
+#ifdef HAVE_OPENGLES3
+#define DEBUG_CALLBACK_TYPE GL_APIENTRY
+#define GL_DEBUG_SOURCE_API GL_DEBUG_SOURCE_API_KHR
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR
+#define GL_DEBUG_SOURCE_SHADER_COMPILER GL_DEBUG_SOURCE_SHADER_COMPILER_KHR
+#define GL_DEBUG_SOURCE_THIRD_PARTY GL_DEBUG_SOURCE_THIRD_PARTY_KHR
+#define GL_DEBUG_SOURCE_APPLICATION GL_DEBUG_SOURCE_APPLICATION_KHR
+#define GL_DEBUG_SOURCE_OTHER GL_DEBUG_SOURCE_OTHER_KHR
+#define GL_DEBUG_TYPE_ERROR GL_DEBUG_TYPE_ERROR_KHR
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR
+#define GL_DEBUG_TYPE_PORTABILITY GL_DEBUG_TYPE_PORTABILITY_KHR
+#define GL_DEBUG_TYPE_PERFORMANCE GL_DEBUG_TYPE_PERFORMANCE_KHR
+#define GL_DEBUG_TYPE_MARKER GL_DEBUG_TYPE_MARKER_KHR
+#define GL_DEBUG_TYPE_PUSH_GROUP GL_DEBUG_TYPE_PUSH_GROUP_KHR
+#define GL_DEBUG_TYPE_POP_GROUP GL_DEBUG_TYPE_POP_GROUP_KHR
+#define GL_DEBUG_TYPE_OTHER GL_DEBUG_TYPE_OTHER_KHR
+#define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
+#define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
+#define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
+#else
+#define DEBUG_CALLBACK_TYPE APIENTRY
+#endif
+static void DEBUG_CALLBACK_TYPE gl_core_debug_cb(GLenum source, GLenum type,
+ GLuint id, GLenum severity, GLsizei length,
+ const GLchar *message, void *userParam)
+{
+ const char *src = NULL;
+ const char *typestr = NULL;
+ gl_core_t *gl = (gl_core_t*)userParam; /* Useful for debugger. */
+
+ (void)gl;
+ (void)id;
+ (void)length;
+
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API:
+ src = "API";
+ break;
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ src = "Window system";
+ break;
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ src = "Shader compiler";
+ break;
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ src = "3rd party";
+ break;
+ case GL_DEBUG_SOURCE_APPLICATION:
+ src = "Application";
+ break;
+ case GL_DEBUG_SOURCE_OTHER:
+ src = "Other";
+ break;
+ default:
+ src = "Unknown";
+ break;
+ }
+
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR:
+ typestr = "Error";
+ break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ typestr = "Deprecated behavior";
+ break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ typestr = "Undefined behavior";
+ break;
+ case GL_DEBUG_TYPE_PORTABILITY:
+ typestr = "Portability";
+ break;
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ typestr = "Performance";
+ break;
+ case GL_DEBUG_TYPE_MARKER:
+ typestr = "Marker";
+ break;
+ case GL_DEBUG_TYPE_PUSH_GROUP:
+ typestr = "Push group";
+ break;
+ case GL_DEBUG_TYPE_POP_GROUP:
+ typestr = "Pop group";
+ break;
+ case GL_DEBUG_TYPE_OTHER:
+ typestr = "Other";
+ break;
+ default:
+ typestr = "Unknown";
+ break;
+ }
+
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH:
+ RARCH_ERR("[GL debug (High, %s, %s)]: %s\n", src, typestr, message);
+ break;
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ RARCH_WARN("[GL debug (Medium, %s, %s)]: %s\n", src, typestr, message);
+ break;
+ case GL_DEBUG_SEVERITY_LOW:
+ RARCH_LOG("[GL debug (Low, %s, %s)]: %s\n", src, typestr, message);
+ break;
+ }
+}
+
+static void gl_core_begin_debug(gl_core_t *gl)
+{
+ if (gl_check_capability(GL_CAPS_DEBUG))
+ {
+#ifdef HAVE_OPENGLES3
+ glDebugMessageCallbackKHR(gl_core_debug_cb, gl);
+ glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
+ glEnable(GL_DEBUG_OUTPUT_KHR);
+#else
+ glDebugMessageCallback(gl_core_debug_cb, gl);
+ glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ glEnable(GL_DEBUG_OUTPUT);
+#endif
+ }
+ else
+ RARCH_ERR("[GLCore]: Neither GL_KHR_debug nor GL_ARB_debug_output are implemented. Cannot start GL debugging.\n");
+}
+#endif
+
+static void *gl_core_init(const video_info_t *video,
+ const input_driver_t **input, void **input_data)
+{
+ gfx_ctx_mode_t mode;
+ gfx_ctx_input_t inp;
+ unsigned full_x, full_y;
+ settings_t *settings = config_get_ptr();
+ int interval = 0;
+ unsigned win_width = 0;
+ unsigned win_height = 0;
+ unsigned temp_width = 0;
+ unsigned temp_height = 0;
+ const char *vendor = NULL;
+ const char *renderer = NULL;
+ const char *version = NULL;
+ char *error_string = NULL;
+ gl_core_t *gl = (gl_core_t*)calloc(1, sizeof(gl_core_t));
+ const gfx_ctx_driver_t *ctx_driver = gl_core_get_context(gl);
+ struct retro_hw_render_callback *hwr = video_driver_get_hw_context();
+
+ if (!gl || !ctx_driver)
+ goto error;
+
+ video_context_driver_set(ctx_driver);
+
+ gl->ctx_driver = ctx_driver;
+ gl->video_info = *video;
+
+ RARCH_LOG("[GLCore]: Found GL context: %s\n", ctx_driver->ident);
+
+ video_context_driver_get_video_size(&mode);
+
+ full_x = mode.width;
+ full_y = mode.height;
+ mode.width = 0;
+ mode.height = 0;
+ interval = 0;
+
+ RARCH_LOG("[GLCore]: Detecting screen resolution %ux%u.\n", full_x, full_y);
+
+ if (video->vsync)
+ interval = video->swap_interval;
+
+ video_context_driver_swap_interval(&interval);
+
+ win_width = video->width;
+ win_height = video->height;
+
+ if (video->fullscreen && (win_width == 0) && (win_height == 0))
+ {
+ win_width = full_x;
+ win_height = full_y;
+ }
+
+ mode.width = win_width;
+ mode.height = win_height;
+ mode.fullscreen = video->fullscreen;
+
+ if (!video_context_driver_set_video_mode(&mode))
+ goto error;
+
+ rglgen_resolve_symbols(ctx_driver->get_proc_address);
+
+ if (hwr && hwr->context_type != RETRO_HW_CONTEXT_NONE)
+ gl_core_init_hw_render(gl, RARCH_SCALE_BASE * video->input_scale, RARCH_SCALE_BASE * video->input_scale);
+
+#ifdef GL_DEBUG
+ gl_core_begin_debug(gl);
+ if (gl->hw_render_enable)
+ {
+ gl_core_context_bind_hw_render(gl, true);
+ gl_core_begin_debug(gl);
+ gl_core_context_bind_hw_render(gl, false);
+ }
+#endif
+
+ /* Clear out potential error flags in case we use cached context. */
+ glGetError();
+
+ vendor = (const char*)glGetString(GL_VENDOR);
+ renderer = (const char*)glGetString(GL_RENDERER);
+ version = (const char*)glGetString(GL_VERSION);
+
+ RARCH_LOG("[GLCore]: Vendor: %s, Renderer: %s.\n", vendor, renderer);
+ RARCH_LOG("[GLCore]: Version: %s.\n", version);
+
+ if (string_is_equal(ctx_driver->ident, "null"))
+ goto error;
+
+ if (!gl_core_init_pipelines(gl))
+ {
+ RARCH_ERR("[GLCore]: Failed to cross-compile menu pipelines.\n");
+ goto error;
+ }
+
+ if (!string_is_empty(version))
+ sscanf(version, "%d.%d", &gl->version_major, &gl->version_minor);
+
+ gl->vsync = video->vsync;
+ gl->fullscreen = video->fullscreen;
+ gl->keep_aspect = video->force_aspect;
+
+ mode.width = 0;
+ mode.height = 0;
+
+ video_context_driver_get_video_size(&mode);
+ temp_width = mode.width;
+ temp_height = mode.height;
+
+ mode.width = 0;
+ mode.height = 0;
+
+ /* Get real known video size, which might have been altered by context. */
+
+ if (temp_width != 0 && temp_height != 0)
+ video_driver_set_size(&temp_width, &temp_height);
+ video_driver_get_size(&temp_width, &temp_height);
+
+ RARCH_LOG("[GLCore]: Using resolution %ux%u\n", temp_width, temp_height);
+
+ /* Set the viewport to fix recording, since it needs to know
+ * the viewport sizes before we start running. */
+ gl_core_set_viewport(gl, temp_width, temp_height, false, true);
+
+ inp.input = input;
+ inp.input_data = input_data;
+ video_context_driver_input_driver(&inp);
+
+ if (!gl_core_init_filter_chain(gl))
+ {
+ RARCH_ERR("[GLCore]: Failed to init filter chain.\n");
+ goto error;
+ }
+
+ if (video->font_enable)
+ {
+ font_driver_init_osd(gl, false,
+ video->is_threaded,
+ FONT_DRIVER_RENDER_OPENGL_CORE_API);
+ }
+
+ gl->pbo_readback_enable = settings->bools.video_gpu_record
+ && recording_is_enabled();
+
+ if (gl->pbo_readback_enable && gl_core_init_pbo_readback(gl))
+ {
+ RARCH_LOG("[GLCore]: Async PBO readback enabled.\n");
+ }
+
+ if (!gl_check_error(&error_string))
+ {
+ RARCH_ERR("%s\n", error_string);
+ free(error_string);
+ goto error;
+ }
+
+ glGenVertexArrays(1, &gl->vao);
+ glBindVertexArray(gl->vao);
+ glBindVertexArray(0);
+
+ gl_core_context_bind_hw_render(gl, true);
+ return gl;
+
+error:
+ video_context_driver_destroy();
+ gl_core_destroy_resources(gl);
+ return NULL;
+}
+
+static unsigned gl_core_num_miplevels(unsigned width, unsigned height)
+{
+ unsigned levels = 1;
+ if (width < height)
+ width = height;
+ while (width > 1)
+ {
+ levels++;
+ width >>= 1;
+ }
+ return levels;
+}
+
+static void video_texture_load_gl_core(
+ const struct texture_image *ti,
+ enum texture_filter_type filter_type,
+ uintptr_t *idptr)
+{
+ /* Generate the OpenGL texture object */
+ GLuint id;
+ unsigned levels;
+ GLenum mag_filter, min_filter;
+
+ glGenTextures(1, &id);
+ *idptr = id;
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ levels = 1;
+ if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || filter_type == TEXTURE_FILTER_MIPMAP_NEAREST)
+ levels = gl_core_num_miplevels(ti->width, ti->height);
+
+ glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, ti->width, ti->height);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ switch (filter_type)
+ {
+ case TEXTURE_FILTER_LINEAR:
+ mag_filter = GL_LINEAR;
+ min_filter = GL_LINEAR;
+ break;
+
+ case TEXTURE_FILTER_NEAREST:
+ mag_filter = GL_NEAREST;
+ min_filter = GL_NEAREST;
+ break;
+
+ case TEXTURE_FILTER_MIPMAP_NEAREST:
+ mag_filter = GL_LINEAR;
+ min_filter = GL_LINEAR_MIPMAP_NEAREST;
+ break;
+
+ case TEXTURE_FILTER_MIPMAP_LINEAR:
+ default:
+ mag_filter = GL_LINEAR;
+ min_filter = GL_LINEAR_MIPMAP_LINEAR;
+ break;
+ }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ ti->width, ti->height, GL_RGBA, GL_UNSIGNED_BYTE, ti->pixels);
+
+ if (levels > 1)
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+#ifdef HAVE_OVERLAY
+static bool gl_core_overlay_load(void *data,
+ const void *image_data, unsigned num_images)
+{
+ unsigned i, j;
+ uintptr_t id;
+ gl_core_t *gl = (gl_core_t*)data;
+ const struct texture_image *images =
+ (const struct texture_image*)image_data;
+
+ if (!gl)
+ return false;
+
+ gl_core_free_overlay(gl);
+ gl->overlay_tex = (GLuint*)
+ calloc(num_images, sizeof(*gl->overlay_tex));
+
+ if (!gl->overlay_tex)
+ return false;
+
+ gl->overlay_vertex_coord = (GLfloat*)
+ calloc(2 * 4 * num_images, sizeof(GLfloat));
+ gl->overlay_tex_coord = (GLfloat*)
+ calloc(2 * 4 * num_images, sizeof(GLfloat));
+ gl->overlay_color_coord = (GLfloat*)
+ calloc(4 * 4 * num_images, sizeof(GLfloat));
+
+ if ( !gl->overlay_vertex_coord
+ || !gl->overlay_tex_coord
+ || !gl->overlay_color_coord)
+ return false;
+
+ gl->overlays = num_images;
+ glGenTextures(num_images, gl->overlay_tex);
+
+ for (i = 0; i < num_images; i++)
+ {
+ unsigned alignment = video_pixel_get_alignment(images[i].width
+ * sizeof(uint32_t));
+
+ video_texture_load_gl_core(&images[i], TEXTURE_FILTER_LINEAR, &id);
+ gl->overlay_tex[i] = id;
+
+ /* Default. Stretch to whole screen. */
+ gl_core_overlay_tex_geom(gl, i, 0, 0, 1, 1);
+ gl_core_overlay_vertex_geom(gl, i, 0, 0, 1, 1);
+
+ for (j = 0; j < 16; j++)
+ gl->overlay_color_coord[16 * i + j] = 1.0f;
+ }
+
+ return true;
+}
+
+static void gl_core_overlay_enable(void *data, bool state)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+
+ if (!gl)
+ return;
+
+ gl->overlay_enable = state;
+
+ if (gl->fullscreen)
+ video_context_driver_show_mouse(&state);
+}
+
+static void gl_core_overlay_full_screen(void *data, bool enable)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ if (gl)
+ gl->overlay_full_screen = enable;
+}
+
+static void gl_core_overlay_set_alpha(void *data, unsigned image, float mod)
+{
+ GLfloat *color = NULL;
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl)
+ return;
+
+ color = (GLfloat*)&gl->overlay_color_coord[image * 16];
+
+ color[ 0 + 3] = mod;
+ color[ 4 + 3] = mod;
+ color[ 8 + 3] = mod;
+ color[12 + 3] = mod;
+}
+
+static const video_overlay_interface_t gl_core_overlay_interface = {
+ gl_core_overlay_enable,
+ gl_core_overlay_load,
+ gl_core_overlay_tex_geom,
+ gl_core_overlay_vertex_geom,
+ gl_core_overlay_full_screen,
+ gl_core_overlay_set_alpha,
+};
+
+static void gl_core_get_overlay_interface(void *data,
+ const video_overlay_interface_t **iface)
+{
+ (void)data;
+ *iface = &gl_core_overlay_interface;
+}
+#endif
+
+static void gl_core_free(void *data)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl)
+ return;
+
+ gl_core_context_bind_hw_render(gl, false);
+ font_driver_free_osd();
+ video_context_driver_free();
+ gl_core_destroy_resources(gl);
+}
+
+static bool gl_core_alive(void *data)
+{
+ unsigned temp_width = 0;
+ unsigned temp_height = 0;
+ bool ret = false;
+ bool quit = false;
+ bool resize = false;
+ gl_core_t *gl = (gl_core_t*)data;
+ bool is_shutdown = rarch_ctl(RARCH_CTL_IS_SHUTDOWN, NULL);
+
+ /* Needed because some context drivers don't track their sizes */
+ video_driver_get_size(&temp_width, &temp_height);
+
+ gl->ctx_driver->check_window(gl->ctx_data,
+ &quit, &resize, &temp_width, &temp_height, is_shutdown);
+
+ if (quit)
+ gl->quitting = true;
+ else if (resize)
+ gl->should_resize = true;
+
+ ret = !gl->quitting;
+
+ if (temp_width != 0 && temp_height != 0)
+ video_driver_set_size(&temp_width, &temp_height);
+
+ return ret;
+}
+
+static void gl_core_set_nonblock_state(void *data, bool state)
+{
+ int interval = 0;
+ gl_core_t *gl = (gl_core_t*)data;
+ settings_t *settings = config_get_ptr();
+
+ if (!gl)
+ return;
+
+ RARCH_LOG("[GLCore]: VSync => %s\n", state ? "off" : "on");
+
+ gl_core_context_bind_hw_render(gl, false);
+ if (!state)
+ interval = settings->uints.video_swap_interval;
+
+ video_context_driver_swap_interval(&interval);
+ gl_core_context_bind_hw_render(gl, true);
+}
+
+static bool gl_core_suppress_screensaver(void *data, bool enable)
+{
+ bool enabled = enable;
+ return video_context_driver_suppress_screensaver(&enabled);
+}
+
+static bool gl_core_set_shader(void *data,
+ enum rarch_shader_type type, const char *path)
+{
+ gl_core_t *gl = (gl_core_t *)data;
+ if (!gl)
+ 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)
+ {
+ gl_core_init_default_filter_chain(gl);
+ gl_core_context_bind_hw_render(gl, true);
+ return true;
+ }
+
+ if (!gl_core_init_filter_chain_preset(gl, path))
+ {
+ RARCH_ERR("[GLCore]: Failed to create filter chain: \"%s\". Falling back to stock.\n", path);
+ gl_core_init_default_filter_chain(gl);
+ gl_core_context_bind_hw_render(gl, true);
+ return false;
+ }
+
+ gl_core_context_bind_hw_render(gl, true);
+ return true;
+}
+
+static void gl_core_set_viewport_wrapper(void *data, unsigned viewport_width,
+ unsigned viewport_height, bool force_full, bool allow_rotate)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ gl_core_set_viewport(gl, viewport_width, viewport_height, force_full, allow_rotate);
+}
+
+static void gl_core_set_rotation(void *data, unsigned rotation)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+
+ if (!gl)
+ return;
+
+ gl->rotation = 90 * rotation;
+ gl_core_set_projection(gl, &gl_core_default_ortho, true);
+}
+
+static void gl_core_viewport_info(void *data, struct video_viewport *vp)
+{
+ unsigned width, height;
+ unsigned top_y, top_dist;
+ gl_core_t *gl = (gl_core_t*)data;
+
+ video_driver_get_size(&width, &height);
+
+ *vp = gl->vp;
+ vp->full_width = width;
+ vp->full_height = height;
+
+ /* Adjust as GL viewport is bottom-up. */
+ top_y = vp->y + vp->height;
+ top_dist = height - top_y;
+ vp->y = top_dist;
+}
+
+static bool gl_core_read_viewport(void *data, uint8_t *buffer, bool is_idle)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ unsigned num_pixels = 0;
+
+ if (!gl)
+ return false;
+
+ gl_core_context_bind_hw_render(gl, false);
+ num_pixels = gl->vp.width * gl->vp.height;
+
+ if (gl->pbo_readback_enable)
+ {
+ const void *ptr = NULL;
+ struct scaler_ctx *ctx = &gl->pbo_readback_scaler;
+
+ /* Don't readback if we're in menu mode.
+ * We haven't buffered up enough frames yet, come back later. */
+ if (!gl->pbo_readback_valid[gl->pbo_readback_index])
+ goto error;
+
+ gl->pbo_readback_valid[gl->pbo_readback_index] = false;
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, gl->pbo_readback[gl->pbo_readback_index]);
+
+ ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, num_pixels * sizeof(uint32_t), GL_MAP_READ_BIT);
+ scaler_ctx_scale_direct(ctx, buffer, ptr);
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ }
+ else
+ {
+ /* Use slow synchronous readbacks. Use this with plain screenshots
+ as we don't really care about performance in this case. */
+
+ /* GLES only guarantees GL_RGBA/GL_UNSIGNED_BYTE
+ * readbacks so do just that.
+ * GLES also doesn't support reading back data
+ * from front buffer, so render a cached frame
+ * and have gl_frame() do the readback while it's
+ * in the back buffer.
+ *
+ * Keep codepath similar for GLES and desktop GL.
+ */
+ gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t));
+
+ if (!gl->readback_buffer_screenshot)
+ goto error;
+
+ if (!is_idle)
+ video_driver_cached_frame();
+
+ video_frame_convert_rgba_to_bgr(
+ (const void*)gl->readback_buffer_screenshot,
+ buffer,
+ num_pixels);
+
+ free(gl->readback_buffer_screenshot);
+ gl->readback_buffer_screenshot = NULL;
+ }
+
+ gl_core_context_bind_hw_render(gl, true);
+ return true;
+
+error:
+ gl_core_context_bind_hw_render(gl, true);
+ return false;
+}
+
+static void gl_core_update_cpu_texture(gl_core_t *gl,
+ struct gl_core_streamed_texture *streamed,
+ const void *frame, unsigned width, unsigned height, unsigned pitch)
+{
+ if (width != streamed->width || height != streamed->height)
+ {
+ if (streamed->tex != 0)
+ glDeleteTextures(1, &streamed->tex);
+ glGenTextures(1, &streamed->tex);
+ glBindTexture(GL_TEXTURE_2D, streamed->tex);
+ glTexStorage2D(GL_TEXTURE_2D, 1, gl->video_info.rgb32 ? GL_RGBA8 : GL_RGB565,
+ width, height);
+ streamed->width = width;
+ streamed->height = height;
+
+ if (gl->video_info.rgb32)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ }
+ }
+ else
+ glBindTexture(GL_TEXTURE_2D, streamed->tex);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ if (gl->video_info.rgb32)
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch >> 2);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ width, height, GL_RGBA, GL_UNSIGNED_BYTE, frame);
+ }
+ else
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch >> 1);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame);
+ }
+}
+
+static void gl_core_draw_menu_texture(gl_core_t *gl, video_frame_info_t *video_info)
+{
+ glEnable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
+ if (gl->menu_texture_full_screen)
+ glViewport(0, 0, video_info->width, video_info->height);
+
+ glActiveTexture(GL_TEXTURE0 + 1);
+ glBindTexture(GL_TEXTURE_2D, gl->menu_texture);
+
+ glUseProgram(gl->pipelines.alpha_blend);
+ if (gl->pipelines.alpha_blend_loc.flat_ubo_vertex >= 0)
+ glUniform4fv(gl->pipelines.alpha_blend_loc.flat_ubo_vertex, 4, gl->mvp_no_rot_yflip.data);
+
+ const float vbo_data[] = {
+ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, gl->menu_texture_alpha,
+ 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, gl->menu_texture_alpha,
+ 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, gl->menu_texture_alpha,
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, gl->menu_texture_alpha,
+ };
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
+ gl_core_bind_scratch_vbo(gl, vbo_data, sizeof(vbo_data));
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(uintptr_t)0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(uintptr_t)(2 * sizeof(float)));
+ glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(uintptr_t)(4 * sizeof(float)));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(2);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisable(GL_BLEND);
+}
+
+static bool gl_core_frame(void *data, const void *frame,
+ unsigned frame_width, unsigned frame_height,
+ uint64_t frame_count,
+ unsigned pitch, const char *msg,
+ video_frame_info_t *video_info)
+{
+ struct gl_core_filter_chain_texture texture;
+ struct gl_core_streamed_texture *streamed;
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl)
+ return false;
+
+ gl_core_context_bind_hw_render(gl, false);
+ glBindVertexArray(gl->vao);
+
+ if (frame)
+ gl->textures_index = (gl->textures_index + 1) & (GL_CORE_NUM_TEXTURES - 1);
+
+ streamed = &gl->textures[gl->textures_index];
+ if (frame)
+ {
+ if (!gl->hw_render_enable)
+ {
+ gl_core_update_cpu_texture(gl, streamed, frame, frame_width, frame_height, pitch);
+ }
+ else
+ {
+ streamed->width = frame_width;
+ streamed->height = frame_height;
+ }
+ }
+
+ if (gl->should_resize)
+ {
+ video_info->cb_set_resize(video_info->context_data, video_info->width, video_info->height);
+ gl->should_resize = false;
+ }
+
+ gl_core_set_viewport(gl, video_info->width, video_info->height, false, true);
+
+ memset(&texture, 0, sizeof(texture));
+
+ texture.width = streamed->width;
+ texture.height = streamed->height;
+ if (gl->hw_render_enable)
+ {
+ texture.image = gl->hw_render_texture;
+ texture.format = GL_RGBA8;
+ texture.padded_width = gl->hw_render_max_width;
+ texture.padded_height = gl->hw_render_max_height;
+
+ if (texture.width == 0)
+ texture.width = 1;
+ if (texture.height == 0)
+ texture.height = 1;
+ }
+ else
+ {
+ texture.image = streamed->tex;
+ texture.format = gl->video_info.rgb32 ? GL_RGBA8 : GL_RGB565;
+ texture.padded_width = streamed->width;
+ texture.padded_height = streamed->height;
+ }
+ gl_core_filter_chain_set_input_texture(gl->filter_chain, &texture);
+ gl_core_filter_chain_build_offscreen_passes(gl->filter_chain, &gl->filter_chain_vp);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ gl_core_filter_chain_build_viewport_pass(gl->filter_chain, &gl->filter_chain_vp,
+ gl->hw_render_bottom_left ? gl->mvp.data : gl->mvp_yflip.data);
+ gl_core_filter_chain_end_frame(gl->filter_chain);
+
+#if defined(HAVE_MENU)
+ if (gl->menu_texture_enable)
+ {
+ menu_driver_frame(video_info);
+ if (gl->menu_texture_enable && gl->menu_texture)
+ gl_core_draw_menu_texture(gl, video_info);
+ }
+ else if (video_info->statistics_show)
+ {
+ struct font_params *osd_params = (struct font_params*)
+ &video_info->osd_stat_params;
+
+ if (osd_params)
+ {
+ font_driver_render_msg(video_info, NULL, video_info->stat_text,
+ (const struct font_params*)&video_info->osd_stat_params);
+ }
+ }
+
+#ifdef HAVE_MENU_WIDGETS
+ menu_widgets_frame(video_info);
+#endif
+#endif
+
+#ifdef HAVE_OVERLAY
+ if (gl->overlay_enable)
+ gl_core_render_overlay(gl, video_info);
+#endif
+
+ if (!string_is_empty(msg))
+ {
+ //if (video_info->msg_bgcolor_enable)
+ // gl_core_render_osd_background(gl, video_info, msg);
+ font_driver_render_msg(video_info, NULL, msg, NULL);
+ }
+
+ video_info->cb_update_window_title(
+ video_info->context_data, video_info);
+
+ if (gl->readback_buffer_screenshot)
+ {
+ /* For screenshots, just do the regular slow readback. */
+ gl_core_slow_readback(gl, gl->readback_buffer_screenshot);
+ }
+ else if (gl->pbo_readback_enable)
+ {
+#ifdef HAVE_MENU
+ /* Don't readback if we're in menu mode. */
+ if (!gl->menu_texture_enable)
+#endif
+ gl_core_pbo_async_readback(gl);
+ }
+
+ /* Disable BFI during fast forward, slow-motion,
+ * and pause to prevent flicker. */
+ if (
+ video_info->black_frame_insertion
+ && !video_info->input_driver_nonblock_state
+ && !video_info->runloop_is_slowmotion
+ && !video_info->runloop_is_paused)
+ {
+ video_info->cb_swap_buffers(video_info->context_data, video_info);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ video_info->cb_swap_buffers(video_info->context_data, video_info);
+
+ if (video_info->hard_sync &&
+ video_info->input_driver_nonblock_state &&
+ !gl->menu_texture_enable)
+ {
+ gl_core_fence_iterate(gl, video_info->hard_sync_frames);
+ }
+
+ glBindVertexArray(0);
+ gl_core_context_bind_hw_render(gl, true);
+ return true;
+}
+
+static uint32_t gl_core_get_flags(void *data)
+{
+ uint32_t flags = 0;
+
+ BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES);
+ BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION);
+ BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING);
+
+ return flags;
+}
+
+static float gl_core_get_refresh_rate(void *data)
+{
+ float refresh_rate;
+ if (video_context_driver_get_refresh_rate(&refresh_rate))
+ return refresh_rate;
+ return 0.0f;
+}
+
+static void gl_core_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+
+ switch (aspect_ratio_idx)
+ {
+ case ASPECT_RATIO_SQUARE:
+ video_driver_set_viewport_square_pixel();
+ break;
+
+ case ASPECT_RATIO_CORE:
+ video_driver_set_viewport_core();
+ break;
+
+ case ASPECT_RATIO_CONFIG:
+ video_driver_set_viewport_config();
+ break;
+
+ default:
+ break;
+ }
+
+ video_driver_set_aspect_ratio_value(
+ aspectratio_lut[aspect_ratio_idx].value);
+
+ if (!gl)
+ return;
+
+ gl->keep_aspect = true;
+ gl->should_resize = true;
+}
+
+static void gl_core_apply_state_changes(void *data)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ if (gl)
+ gl->should_resize = true;
+}
+
+static struct video_shader *gl_core_get_current_shader(void *data)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl || !gl->filter_chain)
+ return NULL;
+
+ return gl_core_filter_chain_get_preset(gl->filter_chain);
+}
+
+#ifdef HAVE_THREADS
+static int video_texture_load_wrap_gl_core_mipmap(void *data)
+{
+ uintptr_t id = 0;
+
+ if (!data)
+ return 0;
+ video_texture_load_gl_core((struct texture_image*)data,
+ TEXTURE_FILTER_MIPMAP_LINEAR, &id);
+ return (int)id;
+}
+
+static int video_texture_load_wrap_gl_core(void *data)
+{
+ uintptr_t id = 0;
+
+ if (!data)
+ return 0;
+ video_texture_load_gl_core((struct texture_image*)data,
+ TEXTURE_FILTER_LINEAR, &id);
+ return (int)id;
+}
+#endif
+
+static uintptr_t gl_core_load_texture(void *video_data, void *data,
+ bool threaded, enum texture_filter_type filter_type)
+{
+ uintptr_t id = 0;
+
+#ifdef HAVE_THREADS
+ if (threaded)
+ {
+ custom_command_method_t func = video_texture_load_wrap_gl_core;
+
+ switch (filter_type)
+ {
+ case TEXTURE_FILTER_MIPMAP_LINEAR:
+ case TEXTURE_FILTER_MIPMAP_NEAREST:
+ func = video_texture_load_wrap_gl_core_mipmap;
+ break;
+ default:
+ break;
+ }
+ return video_thread_texture_load(data, func);
+ }
+#endif
+
+ video_texture_load_gl_core((struct texture_image*)data, filter_type, &id);
+ return id;
+}
+
+static void gl_core_unload_texture(void *data, uintptr_t id)
+{
+ GLuint glid;
+ if (!id)
+ return;
+
+ glid = (GLuint)id;
+ glDeleteTextures(1, &glid);
+}
+
+static void gl_core_set_video_mode(void *data, unsigned width, unsigned height,
+ bool fullscreen)
+{
+ gfx_ctx_mode_t mode;
+
+ mode.width = width;
+ mode.height = height;
+ mode.fullscreen = fullscreen;
+
+ video_context_driver_set_video_mode(&mode);
+}
+
+static void gl_core_show_mouse(void *data, bool state)
+{
+ video_context_driver_show_mouse(&state);
+}
+
+static void gl_core_set_osd_msg(void *data,
+ video_frame_info_t *video_info,
+ const char *msg,
+ const void *params, void *font)
+{
+ font_driver_render_msg(video_info, font, msg, (const struct font_params *)params);
+}
+
+static void gl_core_set_texture_frame(void *data,
+ const void *frame, bool rgb32, unsigned width, unsigned height,
+ float alpha)
+{
+ GLenum menu_filter;
+ settings_t *settings = config_get_ptr();
+ unsigned base_size = rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl)
+ return;
+
+ gl_core_context_bind_hw_render(gl, false);
+ menu_filter = settings->bools.menu_linear_filter ? GL_LINEAR : GL_NEAREST;
+
+ if (gl->menu_texture)
+ glDeleteTextures(1, &gl->menu_texture);
+ glGenTextures(1, &gl->menu_texture);
+ glBindTexture(GL_TEXTURE_2D, gl->menu_texture);
+ glTexStorage2D(GL_TEXTURE_2D, 1, rgb32 ? GL_RGBA8 : GL_RGBA4, width, height);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, base_size);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ width, height, GL_RGBA, rgb32 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_4_4_4_4, frame);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, menu_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, menu_filter);
+
+ if (rgb32)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ gl->menu_texture_alpha = alpha;
+ gl_core_context_bind_hw_render(gl, true);
+}
+
+static void gl_core_set_texture_enable(void *data, bool state, bool full_screen)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+
+ if (!gl)
+ return;
+
+ gl->menu_texture_enable = state;
+ gl->menu_texture_full_screen = full_screen;
+}
+
+static void gl_core_get_video_output_size(void *data,
+ unsigned *width, unsigned *height)
+{
+ gfx_ctx_size_t size_data;
+ size_data.width = width;
+ size_data.height = height;
+ video_context_driver_get_video_output_size(&size_data);
+}
+
+static void gl_core_get_video_output_prev(void *data)
+{
+ video_context_driver_get_video_output_prev();
+}
+
+static void gl_core_get_video_output_next(void *data)
+{
+ video_context_driver_get_video_output_next();
+}
+
+static uintptr_t gl_core_get_current_framebuffer(void *data)
+{
+ gl_core_t *gl = (gl_core_t*)data;
+ if (!gl || !gl->hw_render_enable)
+ return 0;
+ return gl->hw_render_fbo;
+}
+
+static retro_proc_address_t gl_core_get_proc_address(void *data, const char *sym)
+{
+ gfx_ctx_proc_address_t proc_address;
+ proc_address.addr = NULL;
+ proc_address.sym = sym;
+ video_context_driver_get_proc_address(&proc_address);
+ return proc_address.addr;
+}
+
+static const video_poke_interface_t gl_core_poke_interface = {
+ gl_core_get_flags,
+ NULL, /* set_coords */
+ NULL, /* set_mvp */
+ gl_core_load_texture,
+ gl_core_unload_texture,
+ gl_core_set_video_mode,
+ gl_core_get_refresh_rate, /* get_refresh_rate */
+ NULL,
+ gl_core_get_video_output_size,
+ gl_core_get_video_output_prev,
+ gl_core_get_video_output_next,
+ gl_core_get_current_framebuffer,
+ gl_core_get_proc_address,
+ gl_core_set_aspect_ratio,
+ gl_core_apply_state_changes,
+ gl_core_set_texture_frame,
+ gl_core_set_texture_enable,
+ gl_core_set_osd_msg,
+ gl_core_show_mouse,
+ NULL, /* grab_mouse_toggle */
+ gl_core_get_current_shader,
+ NULL,
+ NULL,
+};
+
+static void gl_core_get_poke_interface(void *data,
+ const video_poke_interface_t **iface)
+{
+ (void)data;
+ *iface = &gl_core_poke_interface;
+}
+
+video_driver_t video_gl_core = {
+ gl_core_init,
+ gl_core_frame,
+ gl_core_set_nonblock_state,
+ gl_core_alive,
+ NULL, /* focus */
+ gl_core_suppress_screensaver,
+ NULL, /* has_windowed */
+
+ gl_core_set_shader,
+
+ gl_core_free,
+ "glcore",
+
+ gl_core_set_viewport_wrapper,
+ gl_core_set_rotation,
+
+ gl_core_viewport_info,
+
+ gl_core_read_viewport,
+#if defined(READ_RAW_GL_FRAME_TEST)
+ gl_core_read_frame_raw,
+#else
+ NULL,
+#endif
+
+#ifdef HAVE_OVERLAY
+ gl_core_get_overlay_interface,
+#endif
+ gl_core_get_poke_interface,
+ /*gl_core_wrap_type_to_enum,*/NULL,
+#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS)
+ gl_core_menu_widgets_enabled
+#endif
+};
diff --git a/gfx/drivers/vulkan_shaders/alpha_blend.frag.inc b/gfx/drivers/vulkan_shaders/alpha_blend.frag.inc
index 991c5cab8b..843c146753 100644
--- a/gfx/drivers/vulkan_shaders/alpha_blend.frag.inc
+++ b/gfx/drivers/vulkan_shaders/alpha_blend.frag.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x00000018,
+{0x07230203,0x00010000,0x000d0007,0x00000018,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/alpha_blend.vert.inc b/gfx/drivers/vulkan_shaders/alpha_blend.vert.inc
index c86dbe4473..085bf82ca8 100644
--- a/gfx/drivers/vulkan_shaders/alpha_blend.vert.inc
+++ b/gfx/drivers/vulkan_shaders/alpha_blend.vert.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x00000023,
+{0x07230203,0x00010000,0x000d0007,0x00000023,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/font.frag.inc b/gfx/drivers/vulkan_shaders/font.frag.inc
index 82536685b1..8456b5c661 100644
--- a/gfx/drivers/vulkan_shaders/font.frag.inc
+++ b/gfx/drivers/vulkan_shaders/font.frag.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x00000025,
+{0x07230203,0x00010000,0x000d0007,0x00000025,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/opaque.frag.inc b/gfx/drivers/vulkan_shaders/opaque.frag.inc
index 6db1daab16..3332d7fc3f 100644
--- a/gfx/drivers/vulkan_shaders/opaque.frag.inc
+++ b/gfx/drivers/vulkan_shaders/opaque.frag.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x0000001b,
+{0x07230203,0x00010000,0x000d0007,0x0000001b,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/opaque.vert.inc b/gfx/drivers/vulkan_shaders/opaque.vert.inc
index 793d6ed637..93f18afd36 100644
--- a/gfx/drivers/vulkan_shaders/opaque.vert.inc
+++ b/gfx/drivers/vulkan_shaders/opaque.vert.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x00000020,
+{0x07230203,0x00010000,0x000d0007,0x00000020,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag b/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag
index fae65b9eaf..60fb3db5cb 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag
+++ b/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag
@@ -6,6 +6,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
mat4 MVP;
vec2 OutputSize;
float time;
+ float yflip;
} constants;
layout(location = 0) out vec4 FragColor;
@@ -15,6 +16,7 @@ void main(void)
float speed = constants.time * 4.0;
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / constants.OutputSize;
+ uv.y *= constants.yflip;
uv.x *= constants.OutputSize.x / constants.OutputSize.y;
vec3 color = vec3(0.0);
diff --git a/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag.inc b/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag.inc
index 5be8214581..a65510fdaa 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_bokeh.frag.inc
@@ -1,9 +1,9 @@
-{0x07230203,0x00010000,0x000d0001,0x000000da,
+{0x07230203,0x00010000,0x000d0007,0x000000e1,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
-0x00000000,0x0000001b,0x000000d1,0x00030010,
+0x00000000,0x0000001b,0x000000d8,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
@@ -16,140 +16,146 @@
0x00000000,0x0050564d,0x00060006,0x0000000c,
0x00000001,0x7074754f,0x69537475,0x0000657a,
0x00050006,0x0000000c,0x00000002,0x656d6974,
-0x00000000,0x00050005,0x0000000e,0x736e6f63,
-0x746e6174,0x00000073,0x00030005,0x00000017,
-0x00007675,0x00060005,0x0000001b,0x465f6c67,
-0x43676172,0x64726f6f,0x00000000,0x00040005,
-0x00000034,0x6f6c6f63,0x00000072,0x00030005,
-0x00000038,0x00000069,0x00030005,0x00000043,
-0x00616870,0x00030005,0x0000004e,0x007a6973,
-0x00030005,0x00000059,0x00786f70,0x00030005,
-0x00000067,0x00646172,0x00030005,0x00000072,
-0x00736f70,0x00030005,0x00000093,0x00736964,
-0x00030005,0x0000009d,0x006c6f63,0x00050005,
-0x000000d1,0x67617246,0x6f6c6f43,0x00000072,
-0x00030047,0x00000008,0x00000000,0x00040048,
-0x0000000c,0x00000000,0x00000005,0x00040048,
-0x0000000c,0x00000000,0x00000000,0x00050048,
-0x0000000c,0x00000000,0x00000023,0x00000000,
-0x00050048,0x0000000c,0x00000000,0x00000007,
-0x00000010,0x00040048,0x0000000c,0x00000001,
-0x00000000,0x00050048,0x0000000c,0x00000001,
-0x00000023,0x00000040,0x00040048,0x0000000c,
-0x00000002,0x00000000,0x00050048,0x0000000c,
-0x00000002,0x00000023,0x00000048,0x00030047,
-0x0000000c,0x00000002,0x00040047,0x0000000e,
-0x00000022,0x00000000,0x00040047,0x0000000e,
-0x00000021,0x00000000,0x00030047,0x00000013,
-0x00000000,0x00030047,0x00000015,0x00000000,
-0x00030047,0x00000017,0x00000000,0x00040047,
-0x0000001b,0x0000000b,0x0000000f,0x00030047,
-0x00000022,0x00000000,0x00030047,0x00000029,
-0x00000000,0x00030047,0x0000002c,0x00000000,
-0x00030047,0x0000002d,0x00000000,0x00030047,
-0x0000002f,0x00000000,0x00030047,0x00000030,
-0x00000000,0x00030047,0x00000034,0x00000000,
-0x00030047,0x00000038,0x00000000,0x00030047,
-0x0000003f,0x00000000,0x00030047,0x00000043,
-0x00000000,0x00030047,0x00000044,0x00000000,
-0x00030047,0x00000045,0x00000000,0x00030047,
-0x00000047,0x00000000,0x00030047,0x00000049,
+0x00000000,0x00050006,0x0000000c,0x00000003,
+0x696c6679,0x00000070,0x00050005,0x0000000e,
+0x736e6f63,0x746e6174,0x00000073,0x00030005,
+0x00000017,0x00007675,0x00060005,0x0000001b,
+0x465f6c67,0x43676172,0x64726f6f,0x00000000,
+0x00040005,0x0000003b,0x6f6c6f63,0x00000072,
+0x00030005,0x0000003f,0x00000069,0x00030005,
+0x0000004a,0x00616870,0x00030005,0x00000055,
+0x007a6973,0x00030005,0x00000060,0x00786f70,
+0x00030005,0x0000006e,0x00646172,0x00030005,
+0x00000079,0x00736f70,0x00030005,0x0000009a,
+0x00736964,0x00030005,0x000000a4,0x006c6f63,
+0x00050005,0x000000d8,0x67617246,0x6f6c6f43,
+0x00000072,0x00030047,0x00000008,0x00000000,
+0x00040048,0x0000000c,0x00000000,0x00000005,
+0x00040048,0x0000000c,0x00000000,0x00000000,
+0x00050048,0x0000000c,0x00000000,0x00000023,
+0x00000000,0x00050048,0x0000000c,0x00000000,
+0x00000007,0x00000010,0x00040048,0x0000000c,
+0x00000001,0x00000000,0x00050048,0x0000000c,
+0x00000001,0x00000023,0x00000040,0x00040048,
+0x0000000c,0x00000002,0x00000000,0x00050048,
+0x0000000c,0x00000002,0x00000023,0x00000048,
+0x00040048,0x0000000c,0x00000003,0x00000000,
+0x00050048,0x0000000c,0x00000003,0x00000023,
+0x0000004c,0x00030047,0x0000000c,0x00000002,
+0x00040047,0x0000000e,0x00000022,0x00000000,
+0x00040047,0x0000000e,0x00000021,0x00000000,
+0x00030047,0x00000013,0x00000000,0x00030047,
+0x00000015,0x00000000,0x00030047,0x00000017,
+0x00000000,0x00040047,0x0000001b,0x0000000b,
+0x0000000f,0x00030047,0x00000022,0x00000000,
+0x00030047,0x00000028,0x00000000,0x00030047,
+0x0000002c,0x00000000,0x00030047,0x0000002d,
+0x00000000,0x00030047,0x00000031,0x00000000,
+0x00030047,0x00000033,0x00000000,0x00030047,
+0x00000034,0x00000000,0x00030047,0x00000036,
+0x00000000,0x00030047,0x00000037,0x00000000,
+0x00030047,0x0000003b,0x00000000,0x00030047,
+0x0000003f,0x00000000,0x00030047,0x00000046,
0x00000000,0x00030047,0x0000004a,0x00000000,
-0x00030047,0x0000004c,0x00000000,0x00030047,
-0x0000004d,0x00000000,0x00030047,0x0000004e,
-0x00000000,0x00030047,0x0000004f,0x00000000,
-0x00030047,0x00000050,0x00000000,0x00030047,
-0x00000052,0x00000000,0x00030047,0x00000054,
+0x00030047,0x0000004b,0x00000000,0x00030047,
+0x0000004c,0x00000000,0x00030047,0x0000004e,
+0x00000000,0x00030047,0x00000050,0x00000000,
+0x00030047,0x00000051,0x00000000,0x00030047,
+0x00000053,0x00000000,0x00030047,0x00000054,
0x00000000,0x00030047,0x00000055,0x00000000,
0x00030047,0x00000056,0x00000000,0x00030047,
-0x00000057,0x00000000,0x00030047,0x00000058,
-0x00000000,0x00030047,0x00000059,0x00000000,
-0x00030047,0x0000005a,0x00000000,0x00030047,
-0x0000005b,0x00000000,0x00030047,0x0000005d,
+0x00000057,0x00000000,0x00030047,0x00000059,
+0x00000000,0x00030047,0x0000005b,0x00000000,
+0x00030047,0x0000005c,0x00000000,0x00030047,
+0x0000005d,0x00000000,0x00030047,0x0000005e,
0x00000000,0x00030047,0x0000005f,0x00000000,
0x00030047,0x00000060,0x00000000,0x00030047,
-0x00000062,0x00000000,0x00030047,0x00000063,
-0x00000000,0x00030047,0x00000065,0x00000000,
+0x00000061,0x00000000,0x00030047,0x00000062,
+0x00000000,0x00030047,0x00000064,0x00000000,
0x00030047,0x00000066,0x00000000,0x00030047,
0x00000067,0x00000000,0x00030047,0x00000069,
0x00000000,0x00030047,0x0000006a,0x00000000,
-0x00030047,0x0000006b,0x00000000,0x00030047,
-0x0000006c,0x00000000,0x00030047,0x0000006d,
-0x00000000,0x00030047,0x0000006e,0x00000000,
-0x00030047,0x0000006f,0x00000000,0x00030047,
-0x00000070,0x00000000,0x00030047,0x00000071,
-0x00000000,0x00030047,0x00000072,0x00000000,
-0x00030047,0x00000073,0x00000000,0x00030047,
-0x00000074,0x00000000,0x00030047,0x00000076,
-0x00000000,0x00030047,0x00000077,0x00000000,
-0x00030047,0x00000078,0x00000000,0x00030047,
-0x00000079,0x00000000,0x00030047,0x0000007a,
-0x00000000,0x00030047,0x0000007b,0x00000000,
-0x00030047,0x0000007c,0x00000000,0x00030047,
-0x0000007d,0x00000000,0x00030047,0x0000007e,
-0x00000000,0x00030047,0x0000007f,0x00000000,
-0x00030047,0x00000080,0x00000000,0x00030047,
-0x00000081,0x00000000,0x00030047,0x00000082,
-0x00000000,0x00030047,0x00000084,0x00000000,
+0x00030047,0x0000006c,0x00000000,0x00030047,
+0x0000006d,0x00000000,0x00030047,0x0000006e,
+0x00000000,0x00030047,0x00000070,0x00000000,
+0x00030047,0x00000071,0x00000000,0x00030047,
+0x00000072,0x00000000,0x00030047,0x00000073,
+0x00000000,0x00030047,0x00000074,0x00000000,
+0x00030047,0x00000075,0x00000000,0x00030047,
+0x00000076,0x00000000,0x00030047,0x00000077,
+0x00000000,0x00030047,0x00000078,0x00000000,
+0x00030047,0x00000079,0x00000000,0x00030047,
+0x0000007a,0x00000000,0x00030047,0x0000007b,
+0x00000000,0x00030047,0x0000007d,0x00000000,
+0x00030047,0x0000007e,0x00000000,0x00030047,
+0x0000007f,0x00000000,0x00030047,0x00000080,
+0x00000000,0x00030047,0x00000081,0x00000000,
+0x00030047,0x00000082,0x00000000,0x00030047,
+0x00000083,0x00000000,0x00030047,0x00000084,
+0x00000000,0x00030047,0x00000085,0x00000000,
0x00030047,0x00000086,0x00000000,0x00030047,
-0x00000087,0x00000000,0x00030047,0x0000008a,
-0x00000000,0x00030047,0x0000008b,0x00000000,
-0x00030047,0x0000008c,0x00000000,0x00030047,
+0x00000087,0x00000000,0x00030047,0x00000088,
+0x00000000,0x00030047,0x00000089,0x00000000,
+0x00030047,0x0000008b,0x00000000,0x00030047,
0x0000008d,0x00000000,0x00030047,0x0000008e,
-0x00000000,0x00030047,0x0000008f,0x00000000,
-0x00030047,0x00000090,0x00000000,0x00030047,
-0x00000091,0x00000000,0x00030047,0x00000092,
-0x00000000,0x00030047,0x00000093,0x00000000,
-0x00030047,0x00000094,0x00000000,0x00030047,
-0x00000095,0x00000000,0x00030047,0x00000096,
-0x00000000,0x00030047,0x00000097,0x00000000,
-0x00030047,0x00000098,0x00000000,0x00030047,
-0x00000099,0x00000000,0x00030047,0x0000009d,
-0x00000000,0x00030047,0x0000009f,0x00000000,
-0x00030047,0x000000a1,0x00000000,0x00030047,
-0x000000a2,0x00000000,0x00030047,0x000000a3,
+0x00000000,0x00030047,0x00000091,0x00000000,
+0x00030047,0x00000092,0x00000000,0x00030047,
+0x00000093,0x00000000,0x00030047,0x00000094,
+0x00000000,0x00030047,0x00000095,0x00000000,
+0x00030047,0x00000096,0x00000000,0x00030047,
+0x00000097,0x00000000,0x00030047,0x00000098,
+0x00000000,0x00030047,0x00000099,0x00000000,
+0x00030047,0x0000009a,0x00000000,0x00030047,
+0x0000009b,0x00000000,0x00030047,0x0000009c,
+0x00000000,0x00030047,0x0000009d,0x00000000,
+0x00030047,0x0000009e,0x00000000,0x00030047,
+0x0000009f,0x00000000,0x00030047,0x000000a0,
0x00000000,0x00030047,0x000000a4,0x00000000,
-0x00030047,0x000000a5,0x00000000,0x00030047,
-0x000000a6,0x00000000,0x00030047,0x000000a7,
-0x00000000,0x00030047,0x000000a9,0x00000000,
+0x00030047,0x000000a6,0x00000000,0x00030047,
+0x000000a8,0x00000000,0x00030047,0x000000a9,
+0x00000000,0x00030047,0x000000aa,0x00000000,
0x00030047,0x000000ab,0x00000000,0x00030047,
0x000000ac,0x00000000,0x00030047,0x000000ad,
0x00000000,0x00030047,0x000000ae,0x00000000,
-0x00030047,0x000000af,0x00000000,0x00030047,
-0x000000b0,0x00000000,0x00030047,0x000000b2,
-0x00000000,0x00030047,0x000000b3,0x00000000,
-0x00030047,0x000000b4,0x00000000,0x00030047,
-0x000000b5,0x00000000,0x00030047,0x000000b6,
-0x00000000,0x00030047,0x000000b7,0x00000000,
-0x00030047,0x000000b8,0x00000000,0x00030047,
-0x000000b9,0x00000000,0x00030047,0x000000ba,
-0x00000000,0x00030047,0x000000bb,0x00000000,
-0x00030047,0x000000bc,0x00000000,0x00030047,
-0x000000be,0x00000000,0x00030047,0x000000bf,
-0x00000000,0x00030047,0x000000c0,0x00000000,
-0x00030047,0x000000c1,0x00000000,0x00030047,
-0x000000c2,0x00000000,0x00030047,0x000000c3,
-0x00000000,0x00030047,0x000000c4,0x00000000,
-0x00030047,0x000000c5,0x00000000,0x00030047,
-0x000000c6,0x00000000,0x00030047,0x000000c7,
-0x00000000,0x00030047,0x000000c9,0x00000000,
-0x00030047,0x000000ca,0x00000000,0x00030047,
-0x000000cb,0x00000000,0x00030047,0x000000cc,
-0x00000000,0x00030047,0x000000cd,0x00000000,
-0x00030047,0x000000ce,0x00000000,0x00030047,
-0x000000cf,0x00000000,0x00030047,0x000000d1,
-0x00000000,0x00040047,0x000000d1,0x0000001e,
+0x00030047,0x000000b0,0x00000000,0x00030047,
+0x000000b2,0x00000000,0x00030047,0x000000b3,
+0x00000000,0x00030047,0x000000b4,0x00000000,
+0x00030047,0x000000b5,0x00000000,0x00030047,
+0x000000b6,0x00000000,0x00030047,0x000000b7,
+0x00000000,0x00030047,0x000000b9,0x00000000,
+0x00030047,0x000000ba,0x00000000,0x00030047,
+0x000000bb,0x00000000,0x00030047,0x000000bc,
+0x00000000,0x00030047,0x000000bd,0x00000000,
+0x00030047,0x000000be,0x00000000,0x00030047,
+0x000000bf,0x00000000,0x00030047,0x000000c0,
+0x00000000,0x00030047,0x000000c1,0x00000000,
+0x00030047,0x000000c2,0x00000000,0x00030047,
+0x000000c3,0x00000000,0x00030047,0x000000c5,
+0x00000000,0x00030047,0x000000c6,0x00000000,
+0x00030047,0x000000c7,0x00000000,0x00030047,
+0x000000c8,0x00000000,0x00030047,0x000000c9,
+0x00000000,0x00030047,0x000000ca,0x00000000,
+0x00030047,0x000000cb,0x00000000,0x00030047,
+0x000000cc,0x00000000,0x00030047,0x000000cd,
+0x00000000,0x00030047,0x000000ce,0x00000000,
+0x00030047,0x000000d0,0x00000000,0x00030047,
+0x000000d1,0x00000000,0x00030047,0x000000d2,
0x00000000,0x00030047,0x000000d3,0x00000000,
-0x00030047,0x000000d5,0x00000000,0x00030047,
-0x000000d8,0x00000000,0x00030047,0x000000d9,
-0x00000000,0x00020013,0x00000002,0x00030021,
-0x00000003,0x00000002,0x00030016,0x00000006,
-0x00000020,0x00040020,0x00000007,0x00000007,
-0x00000006,0x00040017,0x00000009,0x00000006,
-0x00000004,0x00040018,0x0000000a,0x00000009,
-0x00000004,0x00040017,0x0000000b,0x00000006,
-0x00000002,0x0005001e,0x0000000c,0x0000000a,
-0x0000000b,0x00000006,0x00040020,0x0000000d,
+0x00030047,0x000000d4,0x00000000,0x00030047,
+0x000000d5,0x00000000,0x00030047,0x000000d6,
+0x00000000,0x00030047,0x000000d8,0x00000000,
+0x00040047,0x000000d8,0x0000001e,0x00000000,
+0x00030047,0x000000da,0x00000000,0x00030047,
+0x000000dc,0x00000000,0x00030047,0x000000df,
+0x00000000,0x00030047,0x000000e0,0x00000000,
+0x00020013,0x00000002,0x00030021,0x00000003,
+0x00000002,0x00030016,0x00000006,0x00000020,
+0x00040020,0x00000007,0x00000007,0x00000006,
+0x00040017,0x00000009,0x00000006,0x00000004,
+0x00040018,0x0000000a,0x00000009,0x00000004,
+0x00040017,0x0000000b,0x00000006,0x00000002,
+0x0006001e,0x0000000c,0x0000000a,0x0000000b,
+0x00000006,0x00000006,0x00040020,0x0000000d,
0x00000002,0x0000000c,0x0004003b,0x0000000d,
0x0000000e,0x00000002,0x00040015,0x0000000f,
0x00000020,0x00000001,0x0004002b,0x0000000f,
@@ -162,53 +168,54 @@
0x00000001,0x00000009,0x0004003b,0x0000001a,
0x0000001b,0x00000001,0x0004002b,0x0000000f,
0x0000001f,0x00000001,0x00040020,0x00000020,
-0x00000002,0x0000000b,0x00040015,0x00000026,
-0x00000020,0x00000000,0x0004002b,0x00000026,
-0x00000027,0x00000000,0x0004002b,0x00000026,
-0x0000002a,0x00000001,0x00040017,0x00000032,
-0x00000006,0x00000003,0x00040020,0x00000033,
-0x00000007,0x00000032,0x0004002b,0x00000006,
-0x00000035,0x00000000,0x0006002c,0x00000032,
-0x00000036,0x00000035,0x00000035,0x00000035,
-0x00040020,0x00000037,0x00000007,0x0000000f,
-0x0004002b,0x0000000f,0x00000039,0x00000000,
-0x0004002b,0x0000000f,0x00000040,0x00000008,
-0x00020014,0x00000041,0x0004002b,0x00000006,
-0x00000046,0x44088852,0x0004002b,0x00000006,
-0x00000048,0x3f800000,0x0004002b,0x00000006,
-0x0000004b,0x3f000000,0x0004002b,0x00000006,
-0x00000051,0x4422ef5c,0x0004002b,0x00000006,
-0x00000053,0x40a00000,0x0004002b,0x00000006,
-0x0000005c,0x43a0c666,0x0004002b,0x00000006,
-0x0000005e,0x40833333,0x0004002b,0x00000006,
-0x00000068,0x3dcccccd,0x0004002b,0x00000006,
-0x00000075,0x41700000,0x0004002b,0x00000006,
-0x00000083,0x3e99999a,0x0004002b,0x00000006,
-0x00000085,0x40e00000,0x0004002b,0x00000006,
-0x00000088,0x3e4ccccd,0x0004002b,0x00000006,
-0x00000089,0x3f4ccccd,0x0004002b,0x00000006,
-0x0000009e,0x3e46a7f0,0x0004002b,0x00000006,
-0x000000a0,0x40c00000,0x0004002b,0x00000006,
-0x000000a8,0x3f8ccccd,0x0004002b,0x00000006,
-0x000000aa,0x41100000,0x0004002b,0x00000006,
-0x000000b1,0x3ecccccd,0x0004002b,0x00000006,
-0x000000bd,0x3e19999a,0x0004002b,0x00000006,
-0x000000c8,0x3fc00000,0x00040020,0x000000d0,
-0x00000003,0x00000009,0x0004003b,0x000000d0,
-0x000000d1,0x00000003,0x0004002b,0x00000026,
-0x000000d6,0x00000002,0x00050036,0x00000002,
+0x00000002,0x0000000b,0x0004002b,0x0000000f,
+0x00000026,0x00000003,0x00040015,0x00000029,
+0x00000020,0x00000000,0x0004002b,0x00000029,
+0x0000002a,0x00000001,0x0004002b,0x00000029,
+0x0000002f,0x00000000,0x00040017,0x00000039,
+0x00000006,0x00000003,0x00040020,0x0000003a,
+0x00000007,0x00000039,0x0004002b,0x00000006,
+0x0000003c,0x00000000,0x0006002c,0x00000039,
+0x0000003d,0x0000003c,0x0000003c,0x0000003c,
+0x00040020,0x0000003e,0x00000007,0x0000000f,
+0x0004002b,0x0000000f,0x00000040,0x00000000,
+0x0004002b,0x0000000f,0x00000047,0x00000008,
+0x00020014,0x00000048,0x0004002b,0x00000006,
+0x0000004d,0x44088852,0x0004002b,0x00000006,
+0x0000004f,0x3f800000,0x0004002b,0x00000006,
+0x00000052,0x3f000000,0x0004002b,0x00000006,
+0x00000058,0x4422ef5c,0x0004002b,0x00000006,
+0x0000005a,0x40a00000,0x0004002b,0x00000006,
+0x00000063,0x43a0c666,0x0004002b,0x00000006,
+0x00000065,0x40833333,0x0004002b,0x00000006,
+0x0000006f,0x3dcccccd,0x0004002b,0x00000006,
+0x0000007c,0x41700000,0x0004002b,0x00000006,
+0x0000008a,0x3e99999a,0x0004002b,0x00000006,
+0x0000008c,0x40e00000,0x0004002b,0x00000006,
+0x0000008f,0x3e4ccccd,0x0004002b,0x00000006,
+0x00000090,0x3f4ccccd,0x0004002b,0x00000006,
+0x000000a5,0x3e46a7f0,0x0004002b,0x00000006,
+0x000000a7,0x40c00000,0x0004002b,0x00000006,
+0x000000af,0x3f8ccccd,0x0004002b,0x00000006,
+0x000000b1,0x41100000,0x0004002b,0x00000006,
+0x000000b8,0x3ecccccd,0x0004002b,0x00000006,
+0x000000c4,0x3e19999a,0x0004002b,0x00000006,
+0x000000cf,0x3fc00000,0x00040020,0x000000d7,
+0x00000003,0x00000009,0x0004003b,0x000000d7,
+0x000000d8,0x00000003,0x0004002b,0x00000029,
+0x000000dd,0x00000002,0x00050036,0x00000002,
0x00000004,0x00000000,0x00000003,0x000200f8,
0x00000005,0x0004003b,0x00000007,0x00000008,
0x00000007,0x0004003b,0x00000016,0x00000017,
-0x00000007,0x0004003b,0x00000033,0x00000034,
-0x00000007,0x0004003b,0x00000037,0x00000038,
-0x00000007,0x0004003b,0x00000007,0x00000043,
-0x00000007,0x0004003b,0x00000007,0x0000004e,
-0x00000007,0x0004003b,0x00000007,0x00000059,
-0x00000007,0x0004003b,0x00000007,0x00000067,
-0x00000007,0x0004003b,0x00000016,0x00000072,
-0x00000007,0x0004003b,0x00000007,0x00000093,
-0x00000007,0x0004003b,0x00000033,0x0000009d,
+0x00000007,0x0004003b,0x0000003a,0x0000003b,
+0x00000007,0x0004003b,0x0000003e,0x0000003f,
+0x00000007,0x0004003b,0x00000007,0x0000004a,
+0x00000007,0x0004003b,0x00000007,0x00000055,
+0x00000007,0x0004003b,0x00000007,0x00000060,
+0x00000007,0x0004003b,0x00000007,0x0000006e,
+0x00000007,0x0004003b,0x00000016,0x00000079,
+0x00000007,0x0004003b,0x00000007,0x0000009a,
+0x00000007,0x0004003b,0x0000003a,0x000000a4,
0x00000007,0x00050041,0x00000011,0x00000012,
0x0000000e,0x00000010,0x0004003d,0x00000006,
0x00000013,0x00000012,0x00050085,0x00000006,
@@ -224,184 +231,191 @@
0x00050050,0x0000000b,0x00000024,0x00000018,
0x00000018,0x00050081,0x0000000b,0x00000025,
0x00000024,0x00000023,0x0003003e,0x00000017,
-0x00000025,0x00060041,0x00000011,0x00000028,
-0x0000000e,0x0000001f,0x00000027,0x0004003d,
-0x00000006,0x00000029,0x00000028,0x00060041,
-0x00000011,0x0000002b,0x0000000e,0x0000001f,
-0x0000002a,0x0004003d,0x00000006,0x0000002c,
-0x0000002b,0x00050088,0x00000006,0x0000002d,
-0x00000029,0x0000002c,0x00050041,0x00000007,
-0x0000002e,0x00000017,0x00000027,0x0004003d,
-0x00000006,0x0000002f,0x0000002e,0x00050085,
-0x00000006,0x00000030,0x0000002f,0x0000002d,
-0x00050041,0x00000007,0x00000031,0x00000017,
-0x00000027,0x0003003e,0x00000031,0x00000030,
-0x0003003e,0x00000034,0x00000036,0x0003003e,
-0x00000038,0x00000039,0x000200f9,0x0000003a,
-0x000200f8,0x0000003a,0x000400f6,0x0000003c,
-0x0000003d,0x00000000,0x000200f9,0x0000003e,
-0x000200f8,0x0000003e,0x0004003d,0x0000000f,
-0x0000003f,0x00000038,0x000500b1,0x00000041,
-0x00000042,0x0000003f,0x00000040,0x000400fa,
-0x00000042,0x0000003b,0x0000003c,0x000200f8,
-0x0000003b,0x0004003d,0x0000000f,0x00000044,
-0x00000038,0x0004006f,0x00000006,0x00000045,
-0x00000044,0x00050085,0x00000006,0x00000047,
-0x00000045,0x00000046,0x00050081,0x00000006,
-0x00000049,0x00000047,0x00000048,0x0006000c,
-0x00000006,0x0000004a,0x00000001,0x0000000d,
-0x00000049,0x00050085,0x00000006,0x0000004c,
-0x0000004a,0x0000004b,0x00050081,0x00000006,
-0x0000004d,0x0000004c,0x0000004b,0x0003003e,
-0x00000043,0x0000004d,0x0004003d,0x0000000f,
-0x0000004f,0x00000038,0x0004006f,0x00000006,
-0x00000050,0x0000004f,0x00050085,0x00000006,
-0x00000052,0x00000050,0x00000051,0x00050081,
-0x00000006,0x00000054,0x00000052,0x00000053,
-0x0006000c,0x00000006,0x00000055,0x00000001,
-0x0000000d,0x00000054,0x00050085,0x00000006,
-0x00000056,0x00000055,0x0000004b,0x00050081,
-0x00000006,0x00000057,0x00000056,0x0000004b,
-0x0007000c,0x00000006,0x00000058,0x00000001,
-0x0000001a,0x00000057,0x00000014,0x0003003e,
-0x0000004e,0x00000058,0x0004003d,0x0000000f,
-0x0000005a,0x00000038,0x0004006f,0x00000006,
-0x0000005b,0x0000005a,0x00050085,0x00000006,
-0x0000005d,0x0000005b,0x0000005c,0x00050081,
-0x00000006,0x0000005f,0x0000005d,0x0000005e,
-0x0006000c,0x00000006,0x00000060,0x00000001,
-0x0000000d,0x0000005f,0x00060041,0x00000011,
-0x00000061,0x0000000e,0x0000001f,0x00000027,
-0x0004003d,0x00000006,0x00000062,0x00000061,
-0x00050085,0x00000006,0x00000063,0x00000060,
-0x00000062,0x00060041,0x00000011,0x00000064,
-0x0000000e,0x0000001f,0x0000002a,0x0004003d,
-0x00000006,0x00000065,0x00000064,0x00050088,
-0x00000006,0x00000066,0x00000063,0x00000065,
-0x0003003e,0x00000059,0x00000066,0x0004003d,
-0x00000006,0x00000069,0x0000004e,0x00050085,
-0x00000006,0x0000006a,0x0000004b,0x00000069,
-0x00050081,0x00000006,0x0000006b,0x00000068,
-0x0000006a,0x0004003d,0x00000006,0x0000006c,
-0x00000043,0x0004003d,0x00000006,0x0000006d,
-0x0000004e,0x00050081,0x00000006,0x0000006e,
-0x0000006c,0x0000006d,0x0006000c,0x00000006,
-0x0000006f,0x00000001,0x0000000d,0x0000006e,
-0x00050088,0x00000006,0x00000070,0x0000006f,
-0x00000014,0x00050081,0x00000006,0x00000071,
-0x0000006b,0x00000070,0x0003003e,0x00000067,
-0x00000071,0x0004003d,0x00000006,0x00000073,
-0x00000059,0x0004003d,0x00000006,0x00000074,
-0x00000008,0x00050088,0x00000006,0x00000076,
-0x00000074,0x00000075,0x0004003d,0x00000006,
-0x00000077,0x00000043,0x00050081,0x00000006,
-0x00000078,0x00000076,0x00000077,0x0004003d,
-0x00000006,0x00000079,0x0000004e,0x00050081,
-0x00000006,0x0000007a,0x00000078,0x00000079,
-0x0006000c,0x00000006,0x0000007b,0x00000001,
-0x0000000d,0x0000007a,0x00050081,0x00000006,
-0x0000007c,0x00000073,0x0000007b,0x0004003d,
-0x00000006,0x0000007d,0x00000067,0x00050083,
-0x00000006,0x0000007e,0x00000018,0x0000007d,
-0x0004003d,0x00000006,0x0000007f,0x00000067,
-0x00050085,0x00000006,0x00000080,0x00000019,
-0x0000007f,0x00050081,0x00000006,0x00000081,
-0x00000019,0x00000080,0x0004003d,0x00000006,
-0x00000082,0x00000043,0x0004003d,0x00000006,
-0x00000084,0x00000008,0x00050088,0x00000006,
-0x00000086,0x00000084,0x00000085,0x00050085,
-0x00000006,0x00000087,0x00000083,0x00000086,
-0x0004003d,0x00000006,0x0000008a,0x0000004e,
-0x00050085,0x00000006,0x0000008b,0x00000089,
-0x0000008a,0x00050081,0x00000006,0x0000008c,
-0x00000088,0x0000008b,0x00050085,0x00000006,
-0x0000008d,0x00000087,0x0000008c,0x00050081,
-0x00000006,0x0000008e,0x00000082,0x0000008d,
-0x0006000c,0x00000006,0x0000008f,0x00000001,
-0x0000000a,0x0000008e,0x00050085,0x00000006,
-0x00000090,0x00000081,0x0000008f,0x00050081,
-0x00000006,0x00000091,0x0000007e,0x00000090,
-0x00050050,0x0000000b,0x00000092,0x0000007c,
-0x00000091,0x0003003e,0x00000072,0x00000092,
-0x0004003d,0x0000000b,0x00000094,0x00000017,
-0x0004003d,0x0000000b,0x00000095,0x00000072,
-0x00050083,0x0000000b,0x00000096,0x00000094,
-0x00000095,0x0006000c,0x00000006,0x00000097,
-0x00000001,0x00000042,0x00000096,0x0003003e,
-0x00000093,0x00000097,0x0004003d,0x00000006,
-0x00000098,0x00000093,0x0004003d,0x00000006,
-0x00000099,0x00000067,0x000500b8,0x00000041,
-0x0000009a,0x00000098,0x00000099,0x000300f7,
-0x0000009c,0x00000000,0x000400fa,0x0000009a,
-0x0000009b,0x0000009c,0x000200f8,0x0000009b,
-0x0004003d,0x00000006,0x0000009f,0x00000008,
-0x00050088,0x00000006,0x000000a1,0x0000009f,
-0x000000a0,0x0006000c,0x00000006,0x000000a2,
-0x00000001,0x0000000d,0x000000a1,0x00050085,
-0x00000006,0x000000a3,0x0000009e,0x000000a2,
-0x00050081,0x00000006,0x000000a4,0x000000a3,
-0x00000083,0x0004003d,0x00000006,0x000000a5,
-0x00000043,0x00050085,0x00000006,0x000000a6,
-0x00000083,0x000000a5,0x00060050,0x00000032,
-0x000000a7,0x000000a4,0x00000088,0x000000a6,
-0x0004003d,0x00000006,0x000000a9,0x00000008,
-0x00050088,0x00000006,0x000000ab,0x000000a9,
-0x000000aa,0x0006000c,0x00000006,0x000000ac,
-0x00000001,0x0000000d,0x000000ab,0x00050085,
-0x00000006,0x000000ad,0x000000a8,0x000000ac,
-0x00050081,0x00000006,0x000000ae,0x000000ad,
-0x00000083,0x0004003d,0x00000006,0x000000af,
-0x00000043,0x00050085,0x00000006,0x000000b0,
-0x00000088,0x000000af,0x00060050,0x00000032,
-0x000000b2,0x000000ae,0x000000b0,0x000000b1,
-0x0004003d,0x0000000f,0x000000b3,0x00000038,
-0x0004006f,0x00000006,0x000000b4,0x000000b3,
-0x0006000c,0x00000006,0x000000b5,0x00000001,
-0x0000000d,0x000000b4,0x00050085,0x00000006,
-0x000000b6,0x0000004b,0x000000b5,0x00050081,
-0x00000006,0x000000b7,0x0000004b,0x000000b6,
-0x00060050,0x00000032,0x000000b8,0x000000b7,
-0x000000b7,0x000000b7,0x0008000c,0x00000032,
-0x000000b9,0x00000001,0x0000002e,0x000000a7,
-0x000000b2,0x000000b8,0x0003003e,0x0000009d,
-0x000000b9,0x0004003d,0x00000032,0x000000ba,
-0x0000009d,0x0008004f,0x00000032,0x000000bb,
-0x000000ba,0x000000ba,0x00000002,0x00000001,
-0x00000000,0x0004003d,0x00000006,0x000000bc,
-0x00000067,0x00050085,0x00000006,0x000000be,
-0x000000bc,0x000000bd,0x0004003d,0x00000006,
-0x000000bf,0x00000067,0x0004003d,0x00000006,
-0x000000c0,0x00000093,0x0008000c,0x00000006,
-0x000000c1,0x00000001,0x00000031,0x000000be,
-0x000000bf,0x000000c0,0x00050083,0x00000006,
-0x000000c2,0x00000048,0x000000c1,0x0005008e,
-0x00000032,0x000000c3,0x000000bb,0x000000c2,
-0x0004003d,0x00000032,0x000000c4,0x00000034,
-0x00050081,0x00000032,0x000000c5,0x000000c4,
-0x000000c3,0x0003003e,0x00000034,0x000000c5,
-0x000200f9,0x0000009c,0x000200f8,0x0000009c,
-0x000200f9,0x0000003d,0x000200f8,0x0000003d,
-0x0004003d,0x0000000f,0x000000c6,0x00000038,
-0x00050080,0x0000000f,0x000000c7,0x000000c6,
-0x0000001f,0x0003003e,0x00000038,0x000000c7,
-0x000200f9,0x0000003a,0x000200f8,0x0000003c,
-0x0004003d,0x0000000b,0x000000c9,0x00000017,
-0x0006000c,0x00000006,0x000000ca,0x00000001,
-0x00000042,0x000000c9,0x00050085,0x00000006,
-0x000000cb,0x0000004b,0x000000ca,0x00050083,
-0x00000006,0x000000cc,0x000000c8,0x000000cb,
-0x0006000c,0x00000006,0x000000cd,0x00000001,
-0x0000001f,0x000000cc,0x0004003d,0x00000032,
-0x000000ce,0x00000034,0x0005008e,0x00000032,
-0x000000cf,0x000000ce,0x000000cd,0x0003003e,
-0x00000034,0x000000cf,0x00050041,0x00000007,
-0x000000d2,0x00000034,0x00000027,0x0004003d,
-0x00000006,0x000000d3,0x000000d2,0x00050041,
-0x00000007,0x000000d4,0x00000034,0x0000002a,
-0x0004003d,0x00000006,0x000000d5,0x000000d4,
-0x00050041,0x00000007,0x000000d7,0x00000034,
-0x000000d6,0x0004003d,0x00000006,0x000000d8,
-0x000000d7,0x00070050,0x00000009,0x000000d9,
-0x000000d3,0x000000d5,0x000000d8,0x0000004b,
-0x0003003e,0x000000d1,0x000000d9,0x000100fd,
-0x00010038}
+0x00000025,0x00050041,0x00000011,0x00000027,
+0x0000000e,0x00000026,0x0004003d,0x00000006,
+0x00000028,0x00000027,0x00050041,0x00000007,
+0x0000002b,0x00000017,0x0000002a,0x0004003d,
+0x00000006,0x0000002c,0x0000002b,0x00050085,
+0x00000006,0x0000002d,0x0000002c,0x00000028,
+0x00050041,0x00000007,0x0000002e,0x00000017,
+0x0000002a,0x0003003e,0x0000002e,0x0000002d,
+0x00060041,0x00000011,0x00000030,0x0000000e,
+0x0000001f,0x0000002f,0x0004003d,0x00000006,
+0x00000031,0x00000030,0x00060041,0x00000011,
+0x00000032,0x0000000e,0x0000001f,0x0000002a,
+0x0004003d,0x00000006,0x00000033,0x00000032,
+0x00050088,0x00000006,0x00000034,0x00000031,
+0x00000033,0x00050041,0x00000007,0x00000035,
+0x00000017,0x0000002f,0x0004003d,0x00000006,
+0x00000036,0x00000035,0x00050085,0x00000006,
+0x00000037,0x00000036,0x00000034,0x00050041,
+0x00000007,0x00000038,0x00000017,0x0000002f,
+0x0003003e,0x00000038,0x00000037,0x0003003e,
+0x0000003b,0x0000003d,0x0003003e,0x0000003f,
+0x00000040,0x000200f9,0x00000041,0x000200f8,
+0x00000041,0x000400f6,0x00000043,0x00000044,
+0x00000000,0x000200f9,0x00000045,0x000200f8,
+0x00000045,0x0004003d,0x0000000f,0x00000046,
+0x0000003f,0x000500b1,0x00000048,0x00000049,
+0x00000046,0x00000047,0x000400fa,0x00000049,
+0x00000042,0x00000043,0x000200f8,0x00000042,
+0x0004003d,0x0000000f,0x0000004b,0x0000003f,
+0x0004006f,0x00000006,0x0000004c,0x0000004b,
+0x00050085,0x00000006,0x0000004e,0x0000004c,
+0x0000004d,0x00050081,0x00000006,0x00000050,
+0x0000004e,0x0000004f,0x0006000c,0x00000006,
+0x00000051,0x00000001,0x0000000d,0x00000050,
+0x00050085,0x00000006,0x00000053,0x00000051,
+0x00000052,0x00050081,0x00000006,0x00000054,
+0x00000053,0x00000052,0x0003003e,0x0000004a,
+0x00000054,0x0004003d,0x0000000f,0x00000056,
+0x0000003f,0x0004006f,0x00000006,0x00000057,
+0x00000056,0x00050085,0x00000006,0x00000059,
+0x00000057,0x00000058,0x00050081,0x00000006,
+0x0000005b,0x00000059,0x0000005a,0x0006000c,
+0x00000006,0x0000005c,0x00000001,0x0000000d,
+0x0000005b,0x00050085,0x00000006,0x0000005d,
+0x0000005c,0x00000052,0x00050081,0x00000006,
+0x0000005e,0x0000005d,0x00000052,0x0007000c,
+0x00000006,0x0000005f,0x00000001,0x0000001a,
+0x0000005e,0x00000014,0x0003003e,0x00000055,
+0x0000005f,0x0004003d,0x0000000f,0x00000061,
+0x0000003f,0x0004006f,0x00000006,0x00000062,
+0x00000061,0x00050085,0x00000006,0x00000064,
+0x00000062,0x00000063,0x00050081,0x00000006,
+0x00000066,0x00000064,0x00000065,0x0006000c,
+0x00000006,0x00000067,0x00000001,0x0000000d,
+0x00000066,0x00060041,0x00000011,0x00000068,
+0x0000000e,0x0000001f,0x0000002f,0x0004003d,
+0x00000006,0x00000069,0x00000068,0x00050085,
+0x00000006,0x0000006a,0x00000067,0x00000069,
+0x00060041,0x00000011,0x0000006b,0x0000000e,
+0x0000001f,0x0000002a,0x0004003d,0x00000006,
+0x0000006c,0x0000006b,0x00050088,0x00000006,
+0x0000006d,0x0000006a,0x0000006c,0x0003003e,
+0x00000060,0x0000006d,0x0004003d,0x00000006,
+0x00000070,0x00000055,0x00050085,0x00000006,
+0x00000071,0x00000052,0x00000070,0x00050081,
+0x00000006,0x00000072,0x0000006f,0x00000071,
+0x0004003d,0x00000006,0x00000073,0x0000004a,
+0x0004003d,0x00000006,0x00000074,0x00000055,
+0x00050081,0x00000006,0x00000075,0x00000073,
+0x00000074,0x0006000c,0x00000006,0x00000076,
+0x00000001,0x0000000d,0x00000075,0x00050088,
+0x00000006,0x00000077,0x00000076,0x00000014,
+0x00050081,0x00000006,0x00000078,0x00000072,
+0x00000077,0x0003003e,0x0000006e,0x00000078,
+0x0004003d,0x00000006,0x0000007a,0x00000060,
+0x0004003d,0x00000006,0x0000007b,0x00000008,
+0x00050088,0x00000006,0x0000007d,0x0000007b,
+0x0000007c,0x0004003d,0x00000006,0x0000007e,
+0x0000004a,0x00050081,0x00000006,0x0000007f,
+0x0000007d,0x0000007e,0x0004003d,0x00000006,
+0x00000080,0x00000055,0x00050081,0x00000006,
+0x00000081,0x0000007f,0x00000080,0x0006000c,
+0x00000006,0x00000082,0x00000001,0x0000000d,
+0x00000081,0x00050081,0x00000006,0x00000083,
+0x0000007a,0x00000082,0x0004003d,0x00000006,
+0x00000084,0x0000006e,0x00050083,0x00000006,
+0x00000085,0x00000018,0x00000084,0x0004003d,
+0x00000006,0x00000086,0x0000006e,0x00050085,
+0x00000006,0x00000087,0x00000019,0x00000086,
+0x00050081,0x00000006,0x00000088,0x00000019,
+0x00000087,0x0004003d,0x00000006,0x00000089,
+0x0000004a,0x0004003d,0x00000006,0x0000008b,
+0x00000008,0x00050088,0x00000006,0x0000008d,
+0x0000008b,0x0000008c,0x00050085,0x00000006,
+0x0000008e,0x0000008a,0x0000008d,0x0004003d,
+0x00000006,0x00000091,0x00000055,0x00050085,
+0x00000006,0x00000092,0x00000090,0x00000091,
+0x00050081,0x00000006,0x00000093,0x0000008f,
+0x00000092,0x00050085,0x00000006,0x00000094,
+0x0000008e,0x00000093,0x00050081,0x00000006,
+0x00000095,0x00000089,0x00000094,0x0006000c,
+0x00000006,0x00000096,0x00000001,0x0000000a,
+0x00000095,0x00050085,0x00000006,0x00000097,
+0x00000088,0x00000096,0x00050081,0x00000006,
+0x00000098,0x00000085,0x00000097,0x00050050,
+0x0000000b,0x00000099,0x00000083,0x00000098,
+0x0003003e,0x00000079,0x00000099,0x0004003d,
+0x0000000b,0x0000009b,0x00000017,0x0004003d,
+0x0000000b,0x0000009c,0x00000079,0x00050083,
+0x0000000b,0x0000009d,0x0000009b,0x0000009c,
+0x0006000c,0x00000006,0x0000009e,0x00000001,
+0x00000042,0x0000009d,0x0003003e,0x0000009a,
+0x0000009e,0x0004003d,0x00000006,0x0000009f,
+0x0000009a,0x0004003d,0x00000006,0x000000a0,
+0x0000006e,0x000500b8,0x00000048,0x000000a1,
+0x0000009f,0x000000a0,0x000300f7,0x000000a3,
+0x00000000,0x000400fa,0x000000a1,0x000000a2,
+0x000000a3,0x000200f8,0x000000a2,0x0004003d,
+0x00000006,0x000000a6,0x00000008,0x00050088,
+0x00000006,0x000000a8,0x000000a6,0x000000a7,
+0x0006000c,0x00000006,0x000000a9,0x00000001,
+0x0000000d,0x000000a8,0x00050085,0x00000006,
+0x000000aa,0x000000a5,0x000000a9,0x00050081,
+0x00000006,0x000000ab,0x000000aa,0x0000008a,
+0x0004003d,0x00000006,0x000000ac,0x0000004a,
+0x00050085,0x00000006,0x000000ad,0x0000008a,
+0x000000ac,0x00060050,0x00000039,0x000000ae,
+0x000000ab,0x0000008f,0x000000ad,0x0004003d,
+0x00000006,0x000000b0,0x00000008,0x00050088,
+0x00000006,0x000000b2,0x000000b0,0x000000b1,
+0x0006000c,0x00000006,0x000000b3,0x00000001,
+0x0000000d,0x000000b2,0x00050085,0x00000006,
+0x000000b4,0x000000af,0x000000b3,0x00050081,
+0x00000006,0x000000b5,0x000000b4,0x0000008a,
+0x0004003d,0x00000006,0x000000b6,0x0000004a,
+0x00050085,0x00000006,0x000000b7,0x0000008f,
+0x000000b6,0x00060050,0x00000039,0x000000b9,
+0x000000b5,0x000000b7,0x000000b8,0x0004003d,
+0x0000000f,0x000000ba,0x0000003f,0x0004006f,
+0x00000006,0x000000bb,0x000000ba,0x0006000c,
+0x00000006,0x000000bc,0x00000001,0x0000000d,
+0x000000bb,0x00050085,0x00000006,0x000000bd,
+0x00000052,0x000000bc,0x00050081,0x00000006,
+0x000000be,0x00000052,0x000000bd,0x00060050,
+0x00000039,0x000000bf,0x000000be,0x000000be,
+0x000000be,0x0008000c,0x00000039,0x000000c0,
+0x00000001,0x0000002e,0x000000ae,0x000000b9,
+0x000000bf,0x0003003e,0x000000a4,0x000000c0,
+0x0004003d,0x00000039,0x000000c1,0x000000a4,
+0x0008004f,0x00000039,0x000000c2,0x000000c1,
+0x000000c1,0x00000002,0x00000001,0x00000000,
+0x0004003d,0x00000006,0x000000c3,0x0000006e,
+0x00050085,0x00000006,0x000000c5,0x000000c3,
+0x000000c4,0x0004003d,0x00000006,0x000000c6,
+0x0000006e,0x0004003d,0x00000006,0x000000c7,
+0x0000009a,0x0008000c,0x00000006,0x000000c8,
+0x00000001,0x00000031,0x000000c5,0x000000c6,
+0x000000c7,0x00050083,0x00000006,0x000000c9,
+0x0000004f,0x000000c8,0x0005008e,0x00000039,
+0x000000ca,0x000000c2,0x000000c9,0x0004003d,
+0x00000039,0x000000cb,0x0000003b,0x00050081,
+0x00000039,0x000000cc,0x000000cb,0x000000ca,
+0x0003003e,0x0000003b,0x000000cc,0x000200f9,
+0x000000a3,0x000200f8,0x000000a3,0x000200f9,
+0x00000044,0x000200f8,0x00000044,0x0004003d,
+0x0000000f,0x000000cd,0x0000003f,0x00050080,
+0x0000000f,0x000000ce,0x000000cd,0x0000001f,
+0x0003003e,0x0000003f,0x000000ce,0x000200f9,
+0x00000041,0x000200f8,0x00000043,0x0004003d,
+0x0000000b,0x000000d0,0x00000017,0x0006000c,
+0x00000006,0x000000d1,0x00000001,0x00000042,
+0x000000d0,0x00050085,0x00000006,0x000000d2,
+0x00000052,0x000000d1,0x00050083,0x00000006,
+0x000000d3,0x000000cf,0x000000d2,0x0006000c,
+0x00000006,0x000000d4,0x00000001,0x0000001f,
+0x000000d3,0x0004003d,0x00000039,0x000000d5,
+0x0000003b,0x0005008e,0x00000039,0x000000d6,
+0x000000d5,0x000000d4,0x0003003e,0x0000003b,
+0x000000d6,0x00050041,0x00000007,0x000000d9,
+0x0000003b,0x0000002f,0x0004003d,0x00000006,
+0x000000da,0x000000d9,0x00050041,0x00000007,
+0x000000db,0x0000003b,0x0000002a,0x0004003d,
+0x00000006,0x000000dc,0x000000db,0x00050041,
+0x00000007,0x000000de,0x0000003b,0x000000dd,
+0x0004003d,0x00000006,0x000000df,0x000000de,
+0x00070050,0x00000009,0x000000e0,0x000000da,
+0x000000dc,0x000000df,0x00000052,0x0003003e,
+0x000000d8,0x000000e0,0x000100fd,0x00010038}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag b/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag
index 043dab856b..d9d009ed2c 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag
@@ -4,6 +4,7 @@ precision highp float;
layout(std140, set = 0, binding = 0) uniform UBO
{
float time;
+ float yflip;
} constants;
layout(location = 0) in vec3 vEC;
@@ -14,6 +15,7 @@ void main()
const vec3 up = vec3(0.0, 0.0, 1.0);
vec3 x = dFdx(vEC);
vec3 y = dFdy(vEC);
+ y *= constants.yflip;
vec3 normal = normalize(cross(x, y));
float c = 1.0 - dot(normal, up);
c = (1.0 - cos(c * c)) / 3.0;
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag.inc b/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag.inc
index 9311131fce..4ec1180998 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon.frag.inc
@@ -1,9 +1,9 @@
-{0x07230203,0x00010000,0x000d0001,0x0000002f,
+{0x07230203,0x00010000,0x000d0007,0x00000036,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
-0x00000000,0x0000000b,0x00000027,0x00030010,
+0x00000000,0x0000000b,0x00000031,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
@@ -13,68 +13,79 @@
0x00000004,0x6e69616d,0x00000000,0x00030005,
0x00000009,0x00000078,0x00030005,0x0000000b,
0x00434576,0x00030005,0x0000000e,0x00000079,
-0x00040005,0x00000011,0x6d726f6e,0x00006c61,
-0x00030005,0x00000017,0x00000063,0x00050005,
-0x00000027,0x67617246,0x6f6c6f43,0x00000072,
-0x00030005,0x0000002c,0x004f4255,0x00050006,
-0x0000002c,0x00000000,0x656d6974,0x00000000,
-0x00050005,0x0000002e,0x736e6f63,0x746e6174,
-0x00000073,0x00040047,0x0000000b,0x0000001e,
-0x00000000,0x00040047,0x00000027,0x0000001e,
-0x00000000,0x00050048,0x0000002c,0x00000000,
-0x00000023,0x00000000,0x00030047,0x0000002c,
-0x00000002,0x00040047,0x0000002e,0x00000022,
-0x00000000,0x00040047,0x0000002e,0x00000021,
-0x00000000,0x00020013,0x00000002,0x00030021,
-0x00000003,0x00000002,0x00030016,0x00000006,
-0x00000020,0x00040017,0x00000007,0x00000006,
-0x00000003,0x00040020,0x00000008,0x00000007,
-0x00000007,0x00040020,0x0000000a,0x00000001,
-0x00000007,0x0004003b,0x0000000a,0x0000000b,
-0x00000001,0x00040020,0x00000016,0x00000007,
-0x00000006,0x0004002b,0x00000006,0x00000018,
-0x3f800000,0x0004002b,0x00000006,0x0000001a,
-0x00000000,0x0006002c,0x00000007,0x0000001b,
-0x0000001a,0x0000001a,0x00000018,0x0004002b,
-0x00000006,0x00000023,0x40400000,0x00040017,
-0x00000025,0x00000006,0x00000004,0x00040020,
-0x00000026,0x00000003,0x00000025,0x0004003b,
-0x00000026,0x00000027,0x00000003,0x0003001e,
-0x0000002c,0x00000006,0x00040020,0x0000002d,
-0x00000002,0x0000002c,0x0004003b,0x0000002d,
-0x0000002e,0x00000002,0x00050036,0x00000002,
-0x00000004,0x00000000,0x00000003,0x000200f8,
-0x00000005,0x0004003b,0x00000008,0x00000009,
-0x00000007,0x0004003b,0x00000008,0x0000000e,
-0x00000007,0x0004003b,0x00000008,0x00000011,
-0x00000007,0x0004003b,0x00000016,0x00000017,
-0x00000007,0x0004003d,0x00000007,0x0000000c,
-0x0000000b,0x000400cf,0x00000007,0x0000000d,
-0x0000000c,0x0003003e,0x00000009,0x0000000d,
-0x0004003d,0x00000007,0x0000000f,0x0000000b,
-0x000400d0,0x00000007,0x00000010,0x0000000f,
-0x0003003e,0x0000000e,0x00000010,0x0004003d,
-0x00000007,0x00000012,0x00000009,0x0004003d,
-0x00000007,0x00000013,0x0000000e,0x0007000c,
-0x00000007,0x00000014,0x00000001,0x00000044,
-0x00000012,0x00000013,0x0006000c,0x00000007,
-0x00000015,0x00000001,0x00000045,0x00000014,
-0x0003003e,0x00000011,0x00000015,0x0004003d,
-0x00000007,0x00000019,0x00000011,0x00050094,
-0x00000006,0x0000001c,0x00000019,0x0000001b,
-0x00050083,0x00000006,0x0000001d,0x00000018,
-0x0000001c,0x0003003e,0x00000017,0x0000001d,
-0x0004003d,0x00000006,0x0000001e,0x00000017,
-0x0004003d,0x00000006,0x0000001f,0x00000017,
-0x00050085,0x00000006,0x00000020,0x0000001e,
-0x0000001f,0x0006000c,0x00000006,0x00000021,
-0x00000001,0x0000000e,0x00000020,0x00050083,
-0x00000006,0x00000022,0x00000018,0x00000021,
-0x00050088,0x00000006,0x00000024,0x00000022,
-0x00000023,0x0003003e,0x00000017,0x00000024,
-0x0004003d,0x00000006,0x00000028,0x00000017,
-0x0004003d,0x00000006,0x00000029,0x00000017,
-0x0004003d,0x00000006,0x0000002a,0x00000017,
-0x00070050,0x00000025,0x0000002b,0x00000028,
-0x00000029,0x0000002a,0x00000018,0x0003003e,
-0x00000027,0x0000002b,0x000100fd,0x00010038}
+0x00030005,0x00000011,0x004f4255,0x00050006,
+0x00000011,0x00000000,0x656d6974,0x00000000,
+0x00050006,0x00000011,0x00000001,0x696c6679,
+0x00000070,0x00050005,0x00000013,0x736e6f63,
+0x746e6174,0x00000073,0x00040005,0x0000001b,
+0x6d726f6e,0x00006c61,0x00030005,0x00000021,
+0x00000063,0x00050005,0x00000031,0x67617246,
+0x6f6c6f43,0x00000072,0x00040047,0x0000000b,
+0x0000001e,0x00000000,0x00050048,0x00000011,
+0x00000000,0x00000023,0x00000000,0x00050048,
+0x00000011,0x00000001,0x00000023,0x00000004,
+0x00030047,0x00000011,0x00000002,0x00040047,
+0x00000013,0x00000022,0x00000000,0x00040047,
+0x00000013,0x00000021,0x00000000,0x00040047,
+0x00000031,0x0000001e,0x00000000,0x00020013,
+0x00000002,0x00030021,0x00000003,0x00000002,
+0x00030016,0x00000006,0x00000020,0x00040017,
+0x00000007,0x00000006,0x00000003,0x00040020,
+0x00000008,0x00000007,0x00000007,0x00040020,
+0x0000000a,0x00000001,0x00000007,0x0004003b,
+0x0000000a,0x0000000b,0x00000001,0x0004001e,
+0x00000011,0x00000006,0x00000006,0x00040020,
+0x00000012,0x00000002,0x00000011,0x0004003b,
+0x00000012,0x00000013,0x00000002,0x00040015,
+0x00000014,0x00000020,0x00000001,0x0004002b,
+0x00000014,0x00000015,0x00000001,0x00040020,
+0x00000016,0x00000002,0x00000006,0x00040020,
+0x00000020,0x00000007,0x00000006,0x0004002b,
+0x00000006,0x00000022,0x3f800000,0x0004002b,
+0x00000006,0x00000024,0x00000000,0x0006002c,
+0x00000007,0x00000025,0x00000024,0x00000024,
+0x00000022,0x0004002b,0x00000006,0x0000002d,
+0x40400000,0x00040017,0x0000002f,0x00000006,
+0x00000004,0x00040020,0x00000030,0x00000003,
+0x0000002f,0x0004003b,0x00000030,0x00000031,
+0x00000003,0x00050036,0x00000002,0x00000004,
+0x00000000,0x00000003,0x000200f8,0x00000005,
+0x0004003b,0x00000008,0x00000009,0x00000007,
+0x0004003b,0x00000008,0x0000000e,0x00000007,
+0x0004003b,0x00000008,0x0000001b,0x00000007,
+0x0004003b,0x00000020,0x00000021,0x00000007,
+0x0004003d,0x00000007,0x0000000c,0x0000000b,
+0x000400cf,0x00000007,0x0000000d,0x0000000c,
+0x0003003e,0x00000009,0x0000000d,0x0004003d,
+0x00000007,0x0000000f,0x0000000b,0x000400d0,
+0x00000007,0x00000010,0x0000000f,0x0003003e,
+0x0000000e,0x00000010,0x00050041,0x00000016,
+0x00000017,0x00000013,0x00000015,0x0004003d,
+0x00000006,0x00000018,0x00000017,0x0004003d,
+0x00000007,0x00000019,0x0000000e,0x0005008e,
+0x00000007,0x0000001a,0x00000019,0x00000018,
+0x0003003e,0x0000000e,0x0000001a,0x0004003d,
+0x00000007,0x0000001c,0x00000009,0x0004003d,
+0x00000007,0x0000001d,0x0000000e,0x0007000c,
+0x00000007,0x0000001e,0x00000001,0x00000044,
+0x0000001c,0x0000001d,0x0006000c,0x00000007,
+0x0000001f,0x00000001,0x00000045,0x0000001e,
+0x0003003e,0x0000001b,0x0000001f,0x0004003d,
+0x00000007,0x00000023,0x0000001b,0x00050094,
+0x00000006,0x00000026,0x00000023,0x00000025,
+0x00050083,0x00000006,0x00000027,0x00000022,
+0x00000026,0x0003003e,0x00000021,0x00000027,
+0x0004003d,0x00000006,0x00000028,0x00000021,
+0x0004003d,0x00000006,0x00000029,0x00000021,
+0x00050085,0x00000006,0x0000002a,0x00000028,
+0x00000029,0x0006000c,0x00000006,0x0000002b,
+0x00000001,0x0000000e,0x0000002a,0x00050083,
+0x00000006,0x0000002c,0x00000022,0x0000002b,
+0x00050088,0x00000006,0x0000002e,0x0000002c,
+0x0000002d,0x0003003e,0x00000021,0x0000002e,
+0x0004003d,0x00000006,0x00000032,0x00000021,
+0x0004003d,0x00000006,0x00000033,0x00000021,
+0x0004003d,0x00000006,0x00000034,0x00000021,
+0x00070050,0x0000002f,0x00000035,0x00000032,
+0x00000033,0x00000034,0x00000022,0x0003003e,
+0x00000031,0x00000035,0x000100fd,0x00010038}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert b/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert
index c5a95f5340..705c5e8be9 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert
@@ -6,6 +6,7 @@ layout(location = 0) out vec3 vEC;
layout(std140, set = 0, binding = 0) uniform UBO
{
float time;
+ float yflip;
} constants;
float iqhash(float n)
@@ -49,4 +50,5 @@ void main()
vEC = v;
gl_Position = vec4(v, 1.0);
+ gl_Position.y *= constants.yflip;
}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert.inc b/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert.inc
index b38583984f..4282d54a3d 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon.vert.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x000d0001,0x000000ee,
+{0x07230203,0x00010000,0x000d0007,0x000000f6,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
@@ -28,179 +28,192 @@
0x00000066,0x61726170,0x0000006d,0x00040005,
0x0000006b,0x61726170,0x0000006d,0x00030005,
0x0000007f,0x004f4255,0x00050006,0x0000007f,
-0x00000000,0x656d6974,0x00000000,0x00050005,
-0x00000081,0x736e6f63,0x746e6174,0x00000073,
-0x00030005,0x00000091,0x00000076,0x00050005,
-0x00000093,0x74726556,0x6f437865,0x0064726f,
-0x00030005,0x0000009b,0x00003276,0x00030005,
-0x0000009d,0x00003376,0x00040005,0x0000009f,
-0x61726170,0x0000006d,0x00040005,0x000000c3,
-0x61726170,0x0000006d,0x00040005,0x000000cd,
-0x61726170,0x0000006d,0x00030005,0x000000e1,
-0x00434576,0x00060005,0x000000e4,0x505f6c67,
-0x65567265,0x78657472,0x00000000,0x00060006,
-0x000000e4,0x00000000,0x505f6c67,0x7469736f,
-0x006e6f69,0x00070006,0x000000e4,0x00000001,
-0x505f6c67,0x746e696f,0x657a6953,0x00000000,
-0x00030005,0x000000e6,0x00000000,0x00050048,
-0x0000007f,0x00000000,0x00000023,0x00000000,
-0x00030047,0x0000007f,0x00000002,0x00040047,
-0x00000081,0x00000022,0x00000000,0x00040047,
-0x00000081,0x00000021,0x00000000,0x00040047,
-0x00000093,0x0000001e,0x00000000,0x00040047,
-0x000000e1,0x0000001e,0x00000000,0x00050048,
-0x000000e4,0x00000000,0x0000000b,0x00000000,
-0x00050048,0x000000e4,0x00000001,0x0000000b,
-0x00000001,0x00030047,0x000000e4,0x00000002,
-0x00020013,0x00000002,0x00030021,0x00000003,
-0x00000002,0x00030016,0x00000006,0x00000020,
-0x00040020,0x00000007,0x00000007,0x00000006,
-0x00040021,0x00000008,0x00000006,0x00000007,
-0x00040017,0x0000000c,0x00000006,0x00000003,
-0x00040020,0x0000000d,0x00000007,0x0000000c,
-0x00040021,0x0000000e,0x00000006,0x0000000d,
-0x0004002b,0x00000006,0x00000017,0x472aee8c,
-0x0004002b,0x00000006,0x00000025,0x40400000,
-0x0004002b,0x00000006,0x00000026,0x40000000,
-0x00040015,0x0000002d,0x00000020,0x00000000,
-0x0004002b,0x0000002d,0x0000002e,0x00000000,
-0x0004002b,0x0000002d,0x00000031,0x00000001,
-0x0004002b,0x00000006,0x00000034,0x42640000,
-0x0004002b,0x00000006,0x00000037,0x42e20000,
-0x0004002b,0x0000002d,0x00000038,0x00000002,
-0x0004002b,0x00000006,0x00000041,0x3f800000,
-0x0004002b,0x00000006,0x0000004d,0x42680000,
-0x0004002b,0x00000006,0x0000005c,0x42e40000,
-0x0004002b,0x00000006,0x00000064,0x432a0000,
-0x0004002b,0x00000006,0x00000069,0x432b0000,
-0x0004002b,0x00000006,0x0000007a,0x40800000,
-0x0003001e,0x0000007f,0x00000006,0x00040020,
-0x00000080,0x00000002,0x0000007f,0x0004003b,
-0x00000080,0x00000081,0x00000002,0x00040015,
-0x00000082,0x00000020,0x00000001,0x0004002b,
-0x00000082,0x00000083,0x00000000,0x00040020,
-0x00000084,0x00000002,0x00000006,0x0004002b,
-0x00000006,0x00000087,0x41200000,0x00040020,
-0x00000092,0x00000001,0x0000000c,0x0004003b,
-0x00000092,0x00000093,0x00000001,0x00040020,
-0x00000094,0x00000001,0x00000006,0x0004002b,
-0x00000006,0x00000097,0x00000000,0x0004002b,
-0x00000006,0x000000a2,0x41000000,0x0004002b,
-0x00000006,0x000000a7,0x40a00000,0x0004002b,
-0x00000006,0x000000ba,0x42c80000,0x0004002b,
-0x00000006,0x000000c1,0x40e00000,0x0004002b,
-0x00000006,0x000000c5,0x41700000,0x0004002b,
-0x00000006,0x000000da,0x3e99999a,0x00040020,
-0x000000e0,0x00000003,0x0000000c,0x0004003b,
-0x000000e0,0x000000e1,0x00000003,0x00040017,
-0x000000e3,0x00000006,0x00000004,0x0004001e,
-0x000000e4,0x000000e3,0x00000006,0x00040020,
-0x000000e5,0x00000003,0x000000e4,0x0004003b,
-0x000000e5,0x000000e6,0x00000003,0x00040020,
-0x000000ec,0x00000003,0x000000e3,0x00050036,
-0x00000002,0x00000004,0x00000000,0x00000003,
-0x000200f8,0x00000005,0x0004003b,0x0000000d,
-0x00000091,0x00000007,0x0004003b,0x0000000d,
-0x0000009b,0x00000007,0x0004003b,0x0000000d,
-0x0000009d,0x00000007,0x0004003b,0x0000000d,
-0x0000009f,0x00000007,0x0004003b,0x0000000d,
-0x000000c3,0x00000007,0x0004003b,0x0000000d,
-0x000000cd,0x00000007,0x00050041,0x00000094,
-0x00000095,0x00000093,0x0000002e,0x0004003d,
-0x00000006,0x00000096,0x00000095,0x00050041,
-0x00000094,0x00000098,0x00000093,0x00000031,
-0x0004003d,0x00000006,0x00000099,0x00000098,
-0x00060050,0x0000000c,0x0000009a,0x00000096,
-0x00000097,0x00000099,0x0003003e,0x00000091,
-0x0000009a,0x0004003d,0x0000000c,0x0000009c,
-0x00000091,0x0003003e,0x0000009b,0x0000009c,
-0x0004003d,0x0000000c,0x0000009e,0x00000091,
-0x0003003e,0x0000009d,0x0000009e,0x0004003d,
-0x0000000c,0x000000a0,0x0000009b,0x0003003e,
-0x0000009f,0x000000a0,0x00050039,0x00000006,
-0x000000a1,0x00000013,0x0000009f,0x00050088,
-0x00000006,0x000000a3,0x000000a1,0x000000a2,
-0x00050041,0x00000007,0x000000a4,0x00000091,
-0x00000031,0x0003003e,0x000000a4,0x000000a3,
-0x00050041,0x00000084,0x000000a5,0x00000081,
-0x00000083,0x0004003d,0x00000006,0x000000a6,
-0x000000a5,0x00050088,0x00000006,0x000000a8,
-0x000000a6,0x000000a7,0x00050041,0x00000007,
-0x000000a9,0x0000009d,0x0000002e,0x0004003d,
-0x00000006,0x000000aa,0x000000a9,0x00050083,
-0x00000006,0x000000ab,0x000000aa,0x000000a8,
-0x00050041,0x00000007,0x000000ac,0x0000009d,
-0x0000002e,0x0003003e,0x000000ac,0x000000ab,
-0x00050041,0x00000007,0x000000ad,0x0000009d,
-0x0000002e,0x0004003d,0x00000006,0x000000ae,
-0x000000ad,0x00050088,0x00000006,0x000000af,
-0x000000ae,0x0000007a,0x00050041,0x00000007,
-0x000000b0,0x0000009d,0x0000002e,0x0003003e,
-0x000000b0,0x000000af,0x00050041,0x00000084,
-0x000000b1,0x00000081,0x00000083,0x0004003d,
-0x00000006,0x000000b2,0x000000b1,0x00050088,
-0x00000006,0x000000b3,0x000000b2,0x00000087,
-0x00050041,0x00000007,0x000000b4,0x0000009d,
-0x00000038,0x0004003d,0x00000006,0x000000b5,
-0x000000b4,0x00050083,0x00000006,0x000000b6,
-0x000000b5,0x000000b3,0x00050041,0x00000007,
-0x000000b7,0x0000009d,0x00000038,0x0003003e,
-0x000000b7,0x000000b6,0x00050041,0x00000084,
-0x000000b8,0x00000081,0x00000083,0x0004003d,
-0x00000006,0x000000b9,0x000000b8,0x00050088,
-0x00000006,0x000000bb,0x000000b9,0x000000ba,
-0x00050041,0x00000007,0x000000bc,0x0000009d,
-0x00000031,0x0004003d,0x00000006,0x000000bd,
-0x000000bc,0x00050083,0x00000006,0x000000be,
-0x000000bd,0x000000bb,0x00050041,0x00000007,
-0x000000bf,0x0000009d,0x00000031,0x0003003e,
-0x000000bf,0x000000be,0x0004003d,0x0000000c,
-0x000000c0,0x0000009d,0x0005008e,0x0000000c,
-0x000000c2,0x000000c0,0x000000c1,0x0003003e,
-0x000000c3,0x000000c2,0x00050039,0x00000006,
-0x000000c4,0x00000010,0x000000c3,0x00050088,
-0x00000006,0x000000c6,0x000000c4,0x000000c5,
-0x00050041,0x00000007,0x000000c7,0x00000091,
-0x00000038,0x0004003d,0x00000006,0x000000c8,
-0x000000c7,0x00050083,0x00000006,0x000000c9,
-0x000000c8,0x000000c6,0x00050041,0x00000007,
-0x000000ca,0x00000091,0x00000038,0x0003003e,
-0x000000ca,0x000000c9,0x0004003d,0x0000000c,
-0x000000cb,0x0000009d,0x0005008e,0x0000000c,
-0x000000cc,0x000000cb,0x000000c1,0x0003003e,
-0x000000cd,0x000000cc,0x00050039,0x00000006,
-0x000000ce,0x00000010,0x000000cd,0x00050088,
-0x00000006,0x000000cf,0x000000ce,0x000000c5,
-0x00050041,0x00000007,0x000000d0,0x00000091,
-0x0000002e,0x0004003d,0x00000006,0x000000d1,
-0x000000d0,0x00050085,0x00000006,0x000000d2,
-0x000000d1,0x00000026,0x00050041,0x00000084,
-0x000000d3,0x00000081,0x00000083,0x0004003d,
-0x00000006,0x000000d4,0x000000d3,0x00050088,
-0x00000006,0x000000d5,0x000000d4,0x00000026,
-0x00050083,0x00000006,0x000000d6,0x000000d2,
-0x000000d5,0x0006000c,0x00000006,0x000000d7,
-0x00000001,0x0000000e,0x000000d6,0x00050088,
-0x00000006,0x000000d8,0x000000d7,0x000000a7,
-0x00050081,0x00000006,0x000000d9,0x000000cf,
-0x000000d8,0x00050083,0x00000006,0x000000db,
-0x000000d9,0x000000da,0x00050041,0x00000007,
-0x000000dc,0x00000091,0x00000031,0x0004003d,
-0x00000006,0x000000dd,0x000000dc,0x00050083,
-0x00000006,0x000000de,0x000000dd,0x000000db,
-0x00050041,0x00000007,0x000000df,0x00000091,
-0x00000031,0x0003003e,0x000000df,0x000000de,
-0x0004003d,0x0000000c,0x000000e2,0x00000091,
-0x0003003e,0x000000e1,0x000000e2,0x0004003d,
-0x0000000c,0x000000e7,0x00000091,0x00050051,
-0x00000006,0x000000e8,0x000000e7,0x00000000,
-0x00050051,0x00000006,0x000000e9,0x000000e7,
-0x00000001,0x00050051,0x00000006,0x000000ea,
-0x000000e7,0x00000002,0x00070050,0x000000e3,
-0x000000eb,0x000000e8,0x000000e9,0x000000ea,
-0x00000041,0x00050041,0x000000ec,0x000000ed,
-0x000000e6,0x00000083,0x0003003e,0x000000ed,
-0x000000eb,0x000100fd,0x00010038,0x00050036,
+0x00000000,0x656d6974,0x00000000,0x00050006,
+0x0000007f,0x00000001,0x696c6679,0x00000070,
+0x00050005,0x00000081,0x736e6f63,0x746e6174,
+0x00000073,0x00030005,0x00000091,0x00000076,
+0x00050005,0x00000093,0x74726556,0x6f437865,
+0x0064726f,0x00030005,0x0000009b,0x00003276,
+0x00030005,0x0000009d,0x00003376,0x00040005,
+0x0000009f,0x61726170,0x0000006d,0x00040005,
+0x000000c3,0x61726170,0x0000006d,0x00040005,
+0x000000cd,0x61726170,0x0000006d,0x00030005,
+0x000000e1,0x00434576,0x00060005,0x000000e4,
+0x505f6c67,0x65567265,0x78657472,0x00000000,
+0x00060006,0x000000e4,0x00000000,0x505f6c67,
+0x7469736f,0x006e6f69,0x00070006,0x000000e4,
+0x00000001,0x505f6c67,0x746e696f,0x657a6953,
+0x00000000,0x00030005,0x000000e6,0x00000000,
+0x00050048,0x0000007f,0x00000000,0x00000023,
+0x00000000,0x00050048,0x0000007f,0x00000001,
+0x00000023,0x00000004,0x00030047,0x0000007f,
+0x00000002,0x00040047,0x00000081,0x00000022,
+0x00000000,0x00040047,0x00000081,0x00000021,
+0x00000000,0x00040047,0x00000093,0x0000001e,
+0x00000000,0x00040047,0x000000e1,0x0000001e,
+0x00000000,0x00050048,0x000000e4,0x00000000,
+0x0000000b,0x00000000,0x00050048,0x000000e4,
+0x00000001,0x0000000b,0x00000001,0x00030047,
+0x000000e4,0x00000002,0x00020013,0x00000002,
+0x00030021,0x00000003,0x00000002,0x00030016,
+0x00000006,0x00000020,0x00040020,0x00000007,
+0x00000007,0x00000006,0x00040021,0x00000008,
+0x00000006,0x00000007,0x00040017,0x0000000c,
+0x00000006,0x00000003,0x00040020,0x0000000d,
+0x00000007,0x0000000c,0x00040021,0x0000000e,
+0x00000006,0x0000000d,0x0004002b,0x00000006,
+0x00000017,0x472aee8c,0x0004002b,0x00000006,
+0x00000025,0x40400000,0x0004002b,0x00000006,
+0x00000026,0x40000000,0x00040015,0x0000002d,
+0x00000020,0x00000000,0x0004002b,0x0000002d,
+0x0000002e,0x00000000,0x0004002b,0x0000002d,
+0x00000031,0x00000001,0x0004002b,0x00000006,
+0x00000034,0x42640000,0x0004002b,0x00000006,
+0x00000037,0x42e20000,0x0004002b,0x0000002d,
+0x00000038,0x00000002,0x0004002b,0x00000006,
+0x00000041,0x3f800000,0x0004002b,0x00000006,
+0x0000004d,0x42680000,0x0004002b,0x00000006,
+0x0000005c,0x42e40000,0x0004002b,0x00000006,
+0x00000064,0x432a0000,0x0004002b,0x00000006,
+0x00000069,0x432b0000,0x0004002b,0x00000006,
+0x0000007a,0x40800000,0x0004001e,0x0000007f,
+0x00000006,0x00000006,0x00040020,0x00000080,
+0x00000002,0x0000007f,0x0004003b,0x00000080,
+0x00000081,0x00000002,0x00040015,0x00000082,
+0x00000020,0x00000001,0x0004002b,0x00000082,
+0x00000083,0x00000000,0x00040020,0x00000084,
+0x00000002,0x00000006,0x0004002b,0x00000006,
+0x00000087,0x41200000,0x00040020,0x00000092,
+0x00000001,0x0000000c,0x0004003b,0x00000092,
+0x00000093,0x00000001,0x00040020,0x00000094,
+0x00000001,0x00000006,0x0004002b,0x00000006,
+0x00000097,0x00000000,0x0004002b,0x00000006,
+0x000000a2,0x41000000,0x0004002b,0x00000006,
+0x000000a7,0x40a00000,0x0004002b,0x00000006,
+0x000000ba,0x42c80000,0x0004002b,0x00000006,
+0x000000c1,0x40e00000,0x0004002b,0x00000006,
+0x000000c5,0x41700000,0x0004002b,0x00000006,
+0x000000da,0x3e99999a,0x00040020,0x000000e0,
+0x00000003,0x0000000c,0x0004003b,0x000000e0,
+0x000000e1,0x00000003,0x00040017,0x000000e3,
+0x00000006,0x00000004,0x0004001e,0x000000e4,
+0x000000e3,0x00000006,0x00040020,0x000000e5,
+0x00000003,0x000000e4,0x0004003b,0x000000e5,
+0x000000e6,0x00000003,0x00040020,0x000000ec,
+0x00000003,0x000000e3,0x0004002b,0x00000082,
+0x000000ee,0x00000001,0x00040020,0x000000f1,
+0x00000003,0x00000006,0x00050036,0x00000002,
+0x00000004,0x00000000,0x00000003,0x000200f8,
+0x00000005,0x0004003b,0x0000000d,0x00000091,
+0x00000007,0x0004003b,0x0000000d,0x0000009b,
+0x00000007,0x0004003b,0x0000000d,0x0000009d,
+0x00000007,0x0004003b,0x0000000d,0x0000009f,
+0x00000007,0x0004003b,0x0000000d,0x000000c3,
+0x00000007,0x0004003b,0x0000000d,0x000000cd,
+0x00000007,0x00050041,0x00000094,0x00000095,
+0x00000093,0x0000002e,0x0004003d,0x00000006,
+0x00000096,0x00000095,0x00050041,0x00000094,
+0x00000098,0x00000093,0x00000031,0x0004003d,
+0x00000006,0x00000099,0x00000098,0x00060050,
+0x0000000c,0x0000009a,0x00000096,0x00000097,
+0x00000099,0x0003003e,0x00000091,0x0000009a,
+0x0004003d,0x0000000c,0x0000009c,0x00000091,
+0x0003003e,0x0000009b,0x0000009c,0x0004003d,
+0x0000000c,0x0000009e,0x00000091,0x0003003e,
+0x0000009d,0x0000009e,0x0004003d,0x0000000c,
+0x000000a0,0x0000009b,0x0003003e,0x0000009f,
+0x000000a0,0x00050039,0x00000006,0x000000a1,
+0x00000013,0x0000009f,0x00050088,0x00000006,
+0x000000a3,0x000000a1,0x000000a2,0x00050041,
+0x00000007,0x000000a4,0x00000091,0x00000031,
+0x0003003e,0x000000a4,0x000000a3,0x00050041,
+0x00000084,0x000000a5,0x00000081,0x00000083,
+0x0004003d,0x00000006,0x000000a6,0x000000a5,
+0x00050088,0x00000006,0x000000a8,0x000000a6,
+0x000000a7,0x00050041,0x00000007,0x000000a9,
+0x0000009d,0x0000002e,0x0004003d,0x00000006,
+0x000000aa,0x000000a9,0x00050083,0x00000006,
+0x000000ab,0x000000aa,0x000000a8,0x00050041,
+0x00000007,0x000000ac,0x0000009d,0x0000002e,
+0x0003003e,0x000000ac,0x000000ab,0x00050041,
+0x00000007,0x000000ad,0x0000009d,0x0000002e,
+0x0004003d,0x00000006,0x000000ae,0x000000ad,
+0x00050088,0x00000006,0x000000af,0x000000ae,
+0x0000007a,0x00050041,0x00000007,0x000000b0,
+0x0000009d,0x0000002e,0x0003003e,0x000000b0,
+0x000000af,0x00050041,0x00000084,0x000000b1,
+0x00000081,0x00000083,0x0004003d,0x00000006,
+0x000000b2,0x000000b1,0x00050088,0x00000006,
+0x000000b3,0x000000b2,0x00000087,0x00050041,
+0x00000007,0x000000b4,0x0000009d,0x00000038,
+0x0004003d,0x00000006,0x000000b5,0x000000b4,
+0x00050083,0x00000006,0x000000b6,0x000000b5,
+0x000000b3,0x00050041,0x00000007,0x000000b7,
+0x0000009d,0x00000038,0x0003003e,0x000000b7,
+0x000000b6,0x00050041,0x00000084,0x000000b8,
+0x00000081,0x00000083,0x0004003d,0x00000006,
+0x000000b9,0x000000b8,0x00050088,0x00000006,
+0x000000bb,0x000000b9,0x000000ba,0x00050041,
+0x00000007,0x000000bc,0x0000009d,0x00000031,
+0x0004003d,0x00000006,0x000000bd,0x000000bc,
+0x00050083,0x00000006,0x000000be,0x000000bd,
+0x000000bb,0x00050041,0x00000007,0x000000bf,
+0x0000009d,0x00000031,0x0003003e,0x000000bf,
+0x000000be,0x0004003d,0x0000000c,0x000000c0,
+0x0000009d,0x0005008e,0x0000000c,0x000000c2,
+0x000000c0,0x000000c1,0x0003003e,0x000000c3,
+0x000000c2,0x00050039,0x00000006,0x000000c4,
+0x00000010,0x000000c3,0x00050088,0x00000006,
+0x000000c6,0x000000c4,0x000000c5,0x00050041,
+0x00000007,0x000000c7,0x00000091,0x00000038,
+0x0004003d,0x00000006,0x000000c8,0x000000c7,
+0x00050083,0x00000006,0x000000c9,0x000000c8,
+0x000000c6,0x00050041,0x00000007,0x000000ca,
+0x00000091,0x00000038,0x0003003e,0x000000ca,
+0x000000c9,0x0004003d,0x0000000c,0x000000cb,
+0x0000009d,0x0005008e,0x0000000c,0x000000cc,
+0x000000cb,0x000000c1,0x0003003e,0x000000cd,
+0x000000cc,0x00050039,0x00000006,0x000000ce,
+0x00000010,0x000000cd,0x00050088,0x00000006,
+0x000000cf,0x000000ce,0x000000c5,0x00050041,
+0x00000007,0x000000d0,0x00000091,0x0000002e,
+0x0004003d,0x00000006,0x000000d1,0x000000d0,
+0x00050085,0x00000006,0x000000d2,0x000000d1,
+0x00000026,0x00050041,0x00000084,0x000000d3,
+0x00000081,0x00000083,0x0004003d,0x00000006,
+0x000000d4,0x000000d3,0x00050088,0x00000006,
+0x000000d5,0x000000d4,0x00000026,0x00050083,
+0x00000006,0x000000d6,0x000000d2,0x000000d5,
+0x0006000c,0x00000006,0x000000d7,0x00000001,
+0x0000000e,0x000000d6,0x00050088,0x00000006,
+0x000000d8,0x000000d7,0x000000a7,0x00050081,
+0x00000006,0x000000d9,0x000000cf,0x000000d8,
+0x00050083,0x00000006,0x000000db,0x000000d9,
+0x000000da,0x00050041,0x00000007,0x000000dc,
+0x00000091,0x00000031,0x0004003d,0x00000006,
+0x000000dd,0x000000dc,0x00050083,0x00000006,
+0x000000de,0x000000dd,0x000000db,0x00050041,
+0x00000007,0x000000df,0x00000091,0x00000031,
+0x0003003e,0x000000df,0x000000de,0x0004003d,
+0x0000000c,0x000000e2,0x00000091,0x0003003e,
+0x000000e1,0x000000e2,0x0004003d,0x0000000c,
+0x000000e7,0x00000091,0x00050051,0x00000006,
+0x000000e8,0x000000e7,0x00000000,0x00050051,
+0x00000006,0x000000e9,0x000000e7,0x00000001,
+0x00050051,0x00000006,0x000000ea,0x000000e7,
+0x00000002,0x00070050,0x000000e3,0x000000eb,
+0x000000e8,0x000000e9,0x000000ea,0x00000041,
+0x00050041,0x000000ec,0x000000ed,0x000000e6,
+0x00000083,0x0003003e,0x000000ed,0x000000eb,
+0x00050041,0x00000084,0x000000ef,0x00000081,
+0x000000ee,0x0004003d,0x00000006,0x000000f0,
+0x000000ef,0x00060041,0x000000f1,0x000000f2,
+0x000000e6,0x00000083,0x00000031,0x0004003d,
+0x00000006,0x000000f3,0x000000f2,0x00050085,
+0x00000006,0x000000f4,0x000000f3,0x000000f0,
+0x00060041,0x000000f1,0x000000f5,0x000000e6,
+0x00000083,0x00000031,0x0003003e,0x000000f5,
+0x000000f4,0x000100fd,0x00010038,0x00050036,
0x00000006,0x0000000a,0x00000000,0x00000008,
0x00030037,0x00000007,0x00000009,0x000200f8,
0x0000000b,0x0004003d,0x00000006,0x00000015,
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.frag.inc b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.frag.inc
index bec3d8ed0f..86ab83fe8c 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.frag.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.frag.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x000d0001,0x0000000d,
+{0x07230203,0x00010000,0x000d0007,0x0000000d,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert
index a7bee379e8..af607a7640 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert
@@ -5,6 +5,7 @@ layout(location = 0) in vec3 VertexCoord;
layout(std140, set = 0, binding = 0) uniform UBO
{
float time;
+ float yflip;
} constants;
float iqhash(float n)
@@ -32,4 +33,5 @@ void main()
v2.z = v.z * 3.0;
v.y = cos((v.x + v.z / 3.0 + constants.time) * 2.0) / 10.0 + noise(v2.xyz) / 4.0;
gl_Position = vec4(v, 1.0);
+ gl_Position.y *= constants.yflip;
}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert.inc b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert.inc
index 6e12fa9062..1d8c19bf0b 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_ribbon_simple.vert.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x000000b1,
+{0x07230203,0x00010000,0x000d0007,0x000000b9,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
@@ -29,118 +29,131 @@
0x0064726f,0x00030005,0x0000007f,0x00003276,
0x00030005,0x00000083,0x004f4255,0x00050006,
0x00000083,0x00000000,0x656d6974,0x00000000,
-0x00050005,0x00000085,0x736e6f63,0x746e6174,
-0x00000073,0x00040005,0x0000009f,0x61726170,
-0x0000006d,0x00060005,0x000000a7,0x505f6c67,
-0x65567265,0x78657472,0x00000000,0x00060006,
-0x000000a7,0x00000000,0x505f6c67,0x7469736f,
-0x006e6f69,0x00070006,0x000000a7,0x00000001,
-0x505f6c67,0x746e696f,0x657a6953,0x00000000,
-0x00030005,0x000000a9,0x00000000,0x00040047,
-0x00000077,0x0000001e,0x00000000,0x00050048,
-0x00000083,0x00000000,0x00000023,0x00000000,
-0x00030047,0x00000083,0x00000002,0x00040047,
-0x00000085,0x00000022,0x00000000,0x00040047,
-0x00000085,0x00000021,0x00000000,0x00050048,
-0x000000a7,0x00000000,0x0000000b,0x00000000,
-0x00050048,0x000000a7,0x00000001,0x0000000b,
-0x00000001,0x00030047,0x000000a7,0x00000002,
-0x00020013,0x00000002,0x00030021,0x00000003,
-0x00000002,0x00030016,0x00000006,0x00000020,
-0x00040020,0x00000007,0x00000007,0x00000006,
-0x00040021,0x00000008,0x00000006,0x00000007,
-0x00040017,0x0000000c,0x00000006,0x00000003,
-0x00040020,0x0000000d,0x00000007,0x0000000c,
-0x00040021,0x0000000e,0x00000006,0x0000000d,
-0x0004002b,0x00000006,0x00000014,0x472aee8c,
-0x0004002b,0x00000006,0x00000022,0x40400000,
-0x0004002b,0x00000006,0x00000023,0x40000000,
-0x00040015,0x0000002a,0x00000020,0x00000000,
-0x0004002b,0x0000002a,0x0000002b,0x00000000,
-0x0004002b,0x0000002a,0x0000002e,0x00000001,
-0x0004002b,0x00000006,0x00000031,0x42640000,
-0x0004002b,0x00000006,0x00000034,0x42e20000,
-0x0004002b,0x0000002a,0x00000035,0x00000002,
-0x0004002b,0x00000006,0x0000003e,0x3f800000,
-0x0004002b,0x00000006,0x0000004a,0x42680000,
-0x0004002b,0x00000006,0x00000059,0x42e40000,
-0x0004002b,0x00000006,0x00000061,0x432a0000,
-0x0004002b,0x00000006,0x00000066,0x432b0000,
-0x00040020,0x00000076,0x00000001,0x0000000c,
-0x0004003b,0x00000076,0x00000077,0x00000001,
-0x00040020,0x00000078,0x00000001,0x00000006,
-0x0004002b,0x00000006,0x0000007b,0x00000000,
-0x0003001e,0x00000083,0x00000006,0x00040020,
-0x00000084,0x00000002,0x00000083,0x0004003b,
-0x00000084,0x00000085,0x00000002,0x00040015,
-0x00000086,0x00000020,0x00000001,0x0004002b,
-0x00000086,0x00000087,0x00000000,0x00040020,
-0x00000088,0x00000002,0x00000006,0x0004002b,
-0x00000006,0x0000009d,0x41200000,0x0004002b,
-0x00000006,0x000000a2,0x40800000,0x00040017,
-0x000000a6,0x00000006,0x00000004,0x0004001e,
-0x000000a7,0x000000a6,0x00000006,0x00040020,
-0x000000a8,0x00000003,0x000000a7,0x0004003b,
-0x000000a8,0x000000a9,0x00000003,0x00040020,
-0x000000af,0x00000003,0x000000a6,0x00050036,
-0x00000002,0x00000004,0x00000000,0x00000003,
-0x000200f8,0x00000005,0x0004003b,0x0000000d,
-0x00000075,0x00000007,0x0004003b,0x0000000d,
-0x0000007f,0x00000007,0x0004003b,0x0000000d,
-0x0000009f,0x00000007,0x00050041,0x00000078,
-0x00000079,0x00000077,0x0000002b,0x0004003d,
-0x00000006,0x0000007a,0x00000079,0x00050041,
-0x00000078,0x0000007c,0x00000077,0x0000002e,
-0x0004003d,0x00000006,0x0000007d,0x0000007c,
-0x00060050,0x0000000c,0x0000007e,0x0000007a,
-0x0000007b,0x0000007d,0x0003003e,0x00000075,
-0x0000007e,0x0004003d,0x0000000c,0x00000080,
-0x00000075,0x0003003e,0x0000007f,0x00000080,
-0x00050041,0x00000007,0x00000081,0x0000007f,
-0x0000002b,0x0004003d,0x00000006,0x00000082,
-0x00000081,0x00050041,0x00000088,0x00000089,
+0x00050006,0x00000083,0x00000001,0x696c6679,
+0x00000070,0x00050005,0x00000085,0x736e6f63,
+0x746e6174,0x00000073,0x00040005,0x0000009f,
+0x61726170,0x0000006d,0x00060005,0x000000a7,
+0x505f6c67,0x65567265,0x78657472,0x00000000,
+0x00060006,0x000000a7,0x00000000,0x505f6c67,
+0x7469736f,0x006e6f69,0x00070006,0x000000a7,
+0x00000001,0x505f6c67,0x746e696f,0x657a6953,
+0x00000000,0x00030005,0x000000a9,0x00000000,
+0x00040047,0x00000077,0x0000001e,0x00000000,
+0x00050048,0x00000083,0x00000000,0x00000023,
+0x00000000,0x00050048,0x00000083,0x00000001,
+0x00000023,0x00000004,0x00030047,0x00000083,
+0x00000002,0x00040047,0x00000085,0x00000022,
+0x00000000,0x00040047,0x00000085,0x00000021,
+0x00000000,0x00050048,0x000000a7,0x00000000,
+0x0000000b,0x00000000,0x00050048,0x000000a7,
+0x00000001,0x0000000b,0x00000001,0x00030047,
+0x000000a7,0x00000002,0x00020013,0x00000002,
+0x00030021,0x00000003,0x00000002,0x00030016,
+0x00000006,0x00000020,0x00040020,0x00000007,
+0x00000007,0x00000006,0x00040021,0x00000008,
+0x00000006,0x00000007,0x00040017,0x0000000c,
+0x00000006,0x00000003,0x00040020,0x0000000d,
+0x00000007,0x0000000c,0x00040021,0x0000000e,
+0x00000006,0x0000000d,0x0004002b,0x00000006,
+0x00000014,0x472aee8c,0x0004002b,0x00000006,
+0x00000022,0x40400000,0x0004002b,0x00000006,
+0x00000023,0x40000000,0x00040015,0x0000002a,
+0x00000020,0x00000000,0x0004002b,0x0000002a,
+0x0000002b,0x00000000,0x0004002b,0x0000002a,
+0x0000002e,0x00000001,0x0004002b,0x00000006,
+0x00000031,0x42640000,0x0004002b,0x00000006,
+0x00000034,0x42e20000,0x0004002b,0x0000002a,
+0x00000035,0x00000002,0x0004002b,0x00000006,
+0x0000003e,0x3f800000,0x0004002b,0x00000006,
+0x0000004a,0x42680000,0x0004002b,0x00000006,
+0x00000059,0x42e40000,0x0004002b,0x00000006,
+0x00000061,0x432a0000,0x0004002b,0x00000006,
+0x00000066,0x432b0000,0x00040020,0x00000076,
+0x00000001,0x0000000c,0x0004003b,0x00000076,
+0x00000077,0x00000001,0x00040020,0x00000078,
+0x00000001,0x00000006,0x0004002b,0x00000006,
+0x0000007b,0x00000000,0x0004001e,0x00000083,
+0x00000006,0x00000006,0x00040020,0x00000084,
+0x00000002,0x00000083,0x0004003b,0x00000084,
+0x00000085,0x00000002,0x00040015,0x00000086,
+0x00000020,0x00000001,0x0004002b,0x00000086,
+0x00000087,0x00000000,0x00040020,0x00000088,
+0x00000002,0x00000006,0x0004002b,0x00000006,
+0x0000009d,0x41200000,0x0004002b,0x00000006,
+0x000000a2,0x40800000,0x00040017,0x000000a6,
+0x00000006,0x00000004,0x0004001e,0x000000a7,
+0x000000a6,0x00000006,0x00040020,0x000000a8,
+0x00000003,0x000000a7,0x0004003b,0x000000a8,
+0x000000a9,0x00000003,0x00040020,0x000000af,
+0x00000003,0x000000a6,0x0004002b,0x00000086,
+0x000000b1,0x00000001,0x00040020,0x000000b4,
+0x00000003,0x00000006,0x00050036,0x00000002,
+0x00000004,0x00000000,0x00000003,0x000200f8,
+0x00000005,0x0004003b,0x0000000d,0x00000075,
+0x00000007,0x0004003b,0x0000000d,0x0000007f,
+0x00000007,0x0004003b,0x0000000d,0x0000009f,
+0x00000007,0x00050041,0x00000078,0x00000079,
+0x00000077,0x0000002b,0x0004003d,0x00000006,
+0x0000007a,0x00000079,0x00050041,0x00000078,
+0x0000007c,0x00000077,0x0000002e,0x0004003d,
+0x00000006,0x0000007d,0x0000007c,0x00060050,
+0x0000000c,0x0000007e,0x0000007a,0x0000007b,
+0x0000007d,0x0003003e,0x00000075,0x0000007e,
+0x0004003d,0x0000000c,0x00000080,0x00000075,
+0x0003003e,0x0000007f,0x00000080,0x00050041,
+0x00000007,0x00000081,0x0000007f,0x0000002b,
+0x0004003d,0x00000006,0x00000082,0x00000081,
+0x00050041,0x00000088,0x00000089,0x00000085,
+0x00000087,0x0004003d,0x00000006,0x0000008a,
+0x00000089,0x00050088,0x00000006,0x0000008b,
+0x0000008a,0x00000023,0x00050081,0x00000006,
+0x0000008c,0x00000082,0x0000008b,0x00050041,
+0x00000007,0x0000008d,0x0000007f,0x0000002b,
+0x0003003e,0x0000008d,0x0000008c,0x00050041,
+0x00000007,0x0000008e,0x00000075,0x00000035,
+0x0004003d,0x00000006,0x0000008f,0x0000008e,
+0x00050085,0x00000006,0x00000090,0x0000008f,
+0x00000022,0x00050041,0x00000007,0x00000091,
+0x0000007f,0x00000035,0x0003003e,0x00000091,
+0x00000090,0x00050041,0x00000007,0x00000092,
+0x00000075,0x0000002b,0x0004003d,0x00000006,
+0x00000093,0x00000092,0x00050041,0x00000007,
+0x00000094,0x00000075,0x00000035,0x0004003d,
+0x00000006,0x00000095,0x00000094,0x00050088,
+0x00000006,0x00000096,0x00000095,0x00000022,
+0x00050081,0x00000006,0x00000097,0x00000093,
+0x00000096,0x00050041,0x00000088,0x00000098,
0x00000085,0x00000087,0x0004003d,0x00000006,
-0x0000008a,0x00000089,0x00050088,0x00000006,
-0x0000008b,0x0000008a,0x00000023,0x00050081,
-0x00000006,0x0000008c,0x00000082,0x0000008b,
-0x00050041,0x00000007,0x0000008d,0x0000007f,
-0x0000002b,0x0003003e,0x0000008d,0x0000008c,
-0x00050041,0x00000007,0x0000008e,0x00000075,
-0x00000035,0x0004003d,0x00000006,0x0000008f,
-0x0000008e,0x00050085,0x00000006,0x00000090,
-0x0000008f,0x00000022,0x00050041,0x00000007,
-0x00000091,0x0000007f,0x00000035,0x0003003e,
-0x00000091,0x00000090,0x00050041,0x00000007,
-0x00000092,0x00000075,0x0000002b,0x0004003d,
-0x00000006,0x00000093,0x00000092,0x00050041,
-0x00000007,0x00000094,0x00000075,0x00000035,
-0x0004003d,0x00000006,0x00000095,0x00000094,
-0x00050088,0x00000006,0x00000096,0x00000095,
-0x00000022,0x00050081,0x00000006,0x00000097,
-0x00000093,0x00000096,0x00050041,0x00000088,
-0x00000098,0x00000085,0x00000087,0x0004003d,
-0x00000006,0x00000099,0x00000098,0x00050081,
-0x00000006,0x0000009a,0x00000097,0x00000099,
-0x00050085,0x00000006,0x0000009b,0x0000009a,
-0x00000023,0x0006000c,0x00000006,0x0000009c,
-0x00000001,0x0000000e,0x0000009b,0x00050088,
-0x00000006,0x0000009e,0x0000009c,0x0000009d,
-0x0004003d,0x0000000c,0x000000a0,0x0000007f,
-0x0003003e,0x0000009f,0x000000a0,0x00050039,
-0x00000006,0x000000a1,0x00000010,0x0000009f,
-0x00050088,0x00000006,0x000000a3,0x000000a1,
-0x000000a2,0x00050081,0x00000006,0x000000a4,
-0x0000009e,0x000000a3,0x00050041,0x00000007,
-0x000000a5,0x00000075,0x0000002e,0x0003003e,
-0x000000a5,0x000000a4,0x0004003d,0x0000000c,
-0x000000aa,0x00000075,0x00050051,0x00000006,
-0x000000ab,0x000000aa,0x00000000,0x00050051,
-0x00000006,0x000000ac,0x000000aa,0x00000001,
-0x00050051,0x00000006,0x000000ad,0x000000aa,
-0x00000002,0x00070050,0x000000a6,0x000000ae,
-0x000000ab,0x000000ac,0x000000ad,0x0000003e,
-0x00050041,0x000000af,0x000000b0,0x000000a9,
-0x00000087,0x0003003e,0x000000b0,0x000000ae,
+0x00000099,0x00000098,0x00050081,0x00000006,
+0x0000009a,0x00000097,0x00000099,0x00050085,
+0x00000006,0x0000009b,0x0000009a,0x00000023,
+0x0006000c,0x00000006,0x0000009c,0x00000001,
+0x0000000e,0x0000009b,0x00050088,0x00000006,
+0x0000009e,0x0000009c,0x0000009d,0x0004003d,
+0x0000000c,0x000000a0,0x0000007f,0x0003003e,
+0x0000009f,0x000000a0,0x00050039,0x00000006,
+0x000000a1,0x00000010,0x0000009f,0x00050088,
+0x00000006,0x000000a3,0x000000a1,0x000000a2,
+0x00050081,0x00000006,0x000000a4,0x0000009e,
+0x000000a3,0x00050041,0x00000007,0x000000a5,
+0x00000075,0x0000002e,0x0003003e,0x000000a5,
+0x000000a4,0x0004003d,0x0000000c,0x000000aa,
+0x00000075,0x00050051,0x00000006,0x000000ab,
+0x000000aa,0x00000000,0x00050051,0x00000006,
+0x000000ac,0x000000aa,0x00000001,0x00050051,
+0x00000006,0x000000ad,0x000000aa,0x00000002,
+0x00070050,0x000000a6,0x000000ae,0x000000ab,
+0x000000ac,0x000000ad,0x0000003e,0x00050041,
+0x000000af,0x000000b0,0x000000a9,0x00000087,
+0x0003003e,0x000000b0,0x000000ae,0x00050041,
+0x00000088,0x000000b2,0x00000085,0x000000b1,
+0x0004003d,0x00000006,0x000000b3,0x000000b2,
+0x00060041,0x000000b4,0x000000b5,0x000000a9,
+0x00000087,0x0000002e,0x0004003d,0x00000006,
+0x000000b6,0x000000b5,0x00050085,0x00000006,
+0x000000b7,0x000000b6,0x000000b3,0x00060041,
+0x000000b4,0x000000b8,0x000000a9,0x00000087,
+0x0000002e,0x0003003e,0x000000b8,0x000000b7,
0x000100fd,0x00010038,0x00050036,0x00000006,
0x0000000a,0x00000000,0x00000008,0x00030037,
0x00000007,0x00000009,0x000200f8,0x0000000b,
diff --git a/gfx/drivers/vulkan_shaders/pipeline_snow.frag b/gfx/drivers/vulkan_shaders/pipeline_snow.frag
index eeb2c0d81c..9e4f0196aa 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_snow.frag
+++ b/gfx/drivers/vulkan_shaders/pipeline_snow.frag
@@ -6,6 +6,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
mat4 MVP;
vec2 OutputSize;
float time;
+ float yflip;
} constants;
layout(location = 0) out vec4 FragColor;
@@ -56,7 +57,7 @@ void main(void)
{
float tim = constants.time * 0.4 * speed;
vec2 pos = gl_FragCoord.xy / constants.OutputSize.xx;
- pos.y = 1.0 - pos.y; // Flip Y
+ pos.y = mix(pos.y, 1.0 - pos.y, constants.yflip); // Flip Y
float a = 0.0;
// Each of these is a layer of snow
// Remove some for better performance
diff --git a/gfx/drivers/vulkan_shaders/pipeline_snow.frag.inc b/gfx/drivers/vulkan_shaders/pipeline_snow.frag.inc
index fffb3c3771..78ce6c0271 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_snow.frag.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_snow.frag.inc
@@ -1,9 +1,9 @@
-{0x07230203,0x00010000,0x00080001,0x00000109,
+{0x07230203,0x00010000,0x000d0007,0x0000010f,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
-0x00000000,0x000000ac,0x00000105,0x00030010,
+0x00000000,0x000000ac,0x0000010b,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
@@ -36,201 +36,207 @@
0x00040006,0x0000009f,0x00000000,0x0050564d,
0x00060006,0x0000009f,0x00000001,0x7074754f,
0x69537475,0x0000657a,0x00050006,0x0000009f,
-0x00000002,0x656d6974,0x00000000,0x00050005,
-0x000000a1,0x736e6f63,0x746e6174,0x00000073,
-0x00030005,0x000000aa,0x00736f70,0x00060005,
-0x000000ac,0x465f6c67,0x43676172,0x64726f6f,
-0x00000000,0x00030005,0x000000b9,0x00000061,
-0x00040005,0x000000ba,0x61726170,0x0000006d,
-0x00040005,0x000000bc,0x61726170,0x0000006d,
-0x00040005,0x000000be,0x61726170,0x0000006d,
-0x00040005,0x000000c3,0x61726170,0x0000006d,
-0x00040005,0x000000c5,0x61726170,0x0000006d,
-0x00040005,0x000000c7,0x61726170,0x0000006d,
-0x00040005,0x000000cc,0x61726170,0x0000006d,
-0x00040005,0x000000ce,0x61726170,0x0000006d,
-0x00040005,0x000000d0,0x61726170,0x0000006d,
-0x00040005,0x000000d4,0x61726170,0x0000006d,
-0x00040005,0x000000d6,0x61726170,0x0000006d,
-0x00040005,0x000000d8,0x61726170,0x0000006d,
-0x00040005,0x000000dc,0x61726170,0x0000006d,
-0x00040005,0x000000de,0x61726170,0x0000006d,
-0x00040005,0x000000e0,0x61726170,0x0000006d,
-0x00040005,0x000000e5,0x61726170,0x0000006d,
-0x00040005,0x000000e7,0x61726170,0x0000006d,
-0x00040005,0x000000e9,0x61726170,0x0000006d,
-0x00040005,0x000000ed,0x61726170,0x0000006d,
-0x00040005,0x000000ef,0x61726170,0x0000006d,
-0x00040005,0x000000f1,0x61726170,0x0000006d,
-0x00040005,0x000000f6,0x61726170,0x0000006d,
-0x00040005,0x000000f8,0x61726170,0x0000006d,
-0x00040005,0x000000fa,0x61726170,0x0000006d,
-0x00050005,0x00000105,0x67617246,0x6f6c6f43,
-0x00000072,0x00030047,0x0000000b,0x00000000,
-0x00030047,0x0000000a,0x00000000,0x00030047,
-0x0000000e,0x00000000,0x00030047,0x0000000d,
-0x00000000,0x00030047,0x00000011,0x00000000,
-0x00030047,0x00000010,0x00000000,0x00030047,
-0x00000018,0x00000000,0x00030047,0x00000015,
-0x00000000,0x00030047,0x00000016,0x00000000,
-0x00030047,0x00000017,0x00000000,0x00030047,
-0x0000001a,0x00000000,0x00030047,0x0000001e,
-0x00000000,0x00030047,0x0000001f,0x00000000,
-0x00030047,0x00000021,0x00000000,0x00030047,
-0x00000022,0x00000000,0x00030047,0x00000025,
-0x00000000,0x00030047,0x00000029,0x00000000,
-0x00030047,0x0000002b,0x00000000,0x00030047,
-0x0000002c,0x00000000,0x00030047,0x0000002f,
-0x00000000,0x00030047,0x00000031,0x00000000,
-0x00030047,0x00000032,0x00000000,0x00030047,
-0x00000033,0x00000000,0x00030047,0x00000034,
-0x00000000,0x00030047,0x00000036,0x00000000,
-0x00030047,0x00000037,0x00000000,0x00030047,
-0x0000003a,0x00000000,0x00030047,0x0000003b,
-0x00000000,0x00030047,0x0000003d,0x00000000,
-0x00030047,0x0000003e,0x00000000,0x00030047,
-0x00000040,0x00000000,0x00030047,0x00000043,
-0x00000000,0x00030047,0x00000045,0x00000000,
-0x00030047,0x00000046,0x00000000,0x00030047,
-0x00000047,0x00000000,0x00030047,0x00000048,
-0x00000000,0x00030047,0x00000049,0x00000000,
-0x00030047,0x0000004a,0x00000000,0x00030047,
-0x0000004b,0x00000000,0x00030047,0x0000004d,
-0x00000000,0x00030047,0x0000004e,0x00000000,
-0x00030047,0x0000004f,0x00000000,0x00030047,
-0x00000056,0x00000000,0x00030047,0x00000057,
-0x00000000,0x00030047,0x00000059,0x00000000,
-0x00030047,0x0000005a,0x00000000,0x00030047,
-0x0000005b,0x00000000,0x00030047,0x0000005c,
-0x00000000,0x00030047,0x0000005e,0x00000000,
-0x00030047,0x00000060,0x00000000,0x00030047,
-0x00000061,0x00000000,0x00030047,0x00000062,
-0x00000000,0x00030047,0x00000063,0x00000000,
-0x00030047,0x00000064,0x00000000,0x00030047,
-0x00000065,0x00000000,0x00030047,0x00000066,
-0x00000000,0x00030047,0x00000067,0x00000000,
-0x00030047,0x00000068,0x00000000,0x00030047,
-0x00000069,0x00000000,0x00030047,0x0000006a,
-0x00000000,0x00030047,0x0000006c,0x00000000,
-0x00030047,0x0000006d,0x00000000,0x00030047,
-0x00000071,0x00000000,0x00030047,0x00000073,
-0x00000000,0x00030047,0x00000074,0x00000000,
-0x00030047,0x00000076,0x00000000,0x00030047,
-0x00000077,0x00000000,0x00030047,0x00000078,
-0x00000000,0x00030047,0x00000079,0x00000000,
-0x00030047,0x0000007a,0x00000000,0x00030047,
-0x0000007b,0x00000000,0x00030047,0x0000007c,
-0x00000000,0x00030047,0x0000007e,0x00000000,
-0x00030047,0x0000007f,0x00000000,0x00030047,
-0x00000080,0x00000000,0x00030047,0x00000082,
-0x00000000,0x00030047,0x00000084,0x00000000,
-0x00030047,0x00000085,0x00000000,0x00030047,
-0x00000087,0x00000000,0x00030047,0x00000088,
-0x00000000,0x00030047,0x00000089,0x00000000,
-0x00030047,0x0000008c,0x00000000,0x00030047,
-0x0000008d,0x00000000,0x00030047,0x0000008e,
-0x00000000,0x00030047,0x0000008f,0x00000000,
-0x00030047,0x00000090,0x00000000,0x00030047,
-0x00000091,0x00000000,0x00030047,0x00000092,
-0x00000000,0x00030047,0x00000093,0x00000000,
-0x00030047,0x00000095,0x00000000,0x00030047,
-0x00000096,0x00000000,0x00030047,0x00000097,
-0x00000000,0x00030047,0x00000098,0x00000000,
-0x00030047,0x00000099,0x00000000,0x00030047,
-0x0000009c,0x00000000,0x00040048,0x0000009f,
-0x00000000,0x00000005,0x00040048,0x0000009f,
-0x00000000,0x00000000,0x00050048,0x0000009f,
-0x00000000,0x00000023,0x00000000,0x00050048,
-0x0000009f,0x00000000,0x00000007,0x00000010,
-0x00040048,0x0000009f,0x00000001,0x00000000,
-0x00050048,0x0000009f,0x00000001,0x00000023,
-0x00000040,0x00040048,0x0000009f,0x00000002,
-0x00000000,0x00050048,0x0000009f,0x00000002,
-0x00000023,0x00000048,0x00030047,0x0000009f,
-0x00000002,0x00040047,0x000000a1,0x00000022,
-0x00000000,0x00040047,0x000000a1,0x00000021,
-0x00000000,0x00030047,0x000000a6,0x00000000,
-0x00030047,0x000000a8,0x00000000,0x00030047,
-0x000000a9,0x00000000,0x00030047,0x000000aa,
-0x00000000,0x00040047,0x000000ac,0x0000000b,
-0x0000000f,0x00030047,0x000000b2,0x00000000,
-0x00030047,0x000000b3,0x00000000,0x00030047,
-0x000000b6,0x00000000,0x00030047,0x000000b7,
-0x00000000,0x00030047,0x000000b9,0x00000000,
-0x00030047,0x000000bb,0x00000000,0x00030047,
-0x000000bd,0x00000000,0x00030047,0x000000bf,
-0x00000000,0x00030047,0x000000c0,0x00000000,
-0x00030047,0x000000c1,0x00000000,0x00030047,
-0x000000c4,0x00000000,0x00030047,0x000000c6,
-0x00000000,0x00030047,0x000000c8,0x00000000,
-0x00030047,0x000000c9,0x00000000,0x00030047,
-0x000000ca,0x00000000,0x00030047,0x000000cd,
-0x00000000,0x00030047,0x000000cf,0x00000000,
-0x00030047,0x000000d1,0x00000000,0x00030047,
-0x000000d2,0x00000000,0x00030047,0x000000d3,
-0x00000000,0x00030047,0x000000d5,0x00000000,
-0x00030047,0x000000d7,0x00000000,0x00030047,
-0x000000d9,0x00000000,0x00030047,0x000000da,
-0x00000000,0x00030047,0x000000db,0x00000000,
-0x00030047,0x000000dd,0x00000000,0x00030047,
-0x000000df,0x00000000,0x00030047,0x000000e1,
-0x00000000,0x00030047,0x000000e2,0x00000000,
-0x00030047,0x000000e3,0x00000000,0x00030047,
-0x000000e6,0x00000000,0x00030047,0x000000e8,
-0x00000000,0x00030047,0x000000ea,0x00000000,
-0x00030047,0x000000eb,0x00000000,0x00030047,
-0x000000ec,0x00000000,0x00030047,0x000000ee,
-0x00000000,0x00030047,0x000000f0,0x00000000,
-0x00030047,0x000000f2,0x00000000,0x00030047,
-0x000000f3,0x00000000,0x00030047,0x000000f4,
-0x00000000,0x00030047,0x000000f7,0x00000000,
-0x00030047,0x000000f9,0x00000000,0x00030047,
-0x000000fb,0x00000000,0x00030047,0x000000fc,
-0x00000000,0x00030047,0x000000fd,0x00000000,
-0x00030047,0x000000fe,0x00000000,0x00030047,
-0x00000100,0x00000000,0x00030047,0x00000101,
+0x00000002,0x656d6974,0x00000000,0x00050006,
+0x0000009f,0x00000003,0x696c6679,0x00000070,
+0x00050005,0x000000a1,0x736e6f63,0x746e6174,
+0x00000073,0x00030005,0x000000aa,0x00736f70,
+0x00060005,0x000000ac,0x465f6c67,0x43676172,
+0x64726f6f,0x00000000,0x00030005,0x000000bf,
+0x00000061,0x00040005,0x000000c0,0x61726170,
+0x0000006d,0x00040005,0x000000c2,0x61726170,
+0x0000006d,0x00040005,0x000000c4,0x61726170,
+0x0000006d,0x00040005,0x000000c9,0x61726170,
+0x0000006d,0x00040005,0x000000cb,0x61726170,
+0x0000006d,0x00040005,0x000000cd,0x61726170,
+0x0000006d,0x00040005,0x000000d2,0x61726170,
+0x0000006d,0x00040005,0x000000d4,0x61726170,
+0x0000006d,0x00040005,0x000000d6,0x61726170,
+0x0000006d,0x00040005,0x000000da,0x61726170,
+0x0000006d,0x00040005,0x000000dc,0x61726170,
+0x0000006d,0x00040005,0x000000de,0x61726170,
+0x0000006d,0x00040005,0x000000e2,0x61726170,
+0x0000006d,0x00040005,0x000000e4,0x61726170,
+0x0000006d,0x00040005,0x000000e6,0x61726170,
+0x0000006d,0x00040005,0x000000eb,0x61726170,
+0x0000006d,0x00040005,0x000000ed,0x61726170,
+0x0000006d,0x00040005,0x000000ef,0x61726170,
+0x0000006d,0x00040005,0x000000f3,0x61726170,
+0x0000006d,0x00040005,0x000000f5,0x61726170,
+0x0000006d,0x00040005,0x000000f7,0x61726170,
+0x0000006d,0x00040005,0x000000fc,0x61726170,
+0x0000006d,0x00040005,0x000000fe,0x61726170,
+0x0000006d,0x00040005,0x00000100,0x61726170,
+0x0000006d,0x00050005,0x0000010b,0x67617246,
+0x6f6c6f43,0x00000072,0x00030047,0x0000000b,
+0x00000000,0x00030047,0x0000000a,0x00000000,
+0x00030047,0x0000000e,0x00000000,0x00030047,
+0x0000000d,0x00000000,0x00030047,0x00000011,
+0x00000000,0x00030047,0x00000010,0x00000000,
+0x00030047,0x00000018,0x00000000,0x00030047,
+0x00000015,0x00000000,0x00030047,0x00000016,
+0x00000000,0x00030047,0x00000017,0x00000000,
+0x00030047,0x0000001a,0x00000000,0x00030047,
+0x0000001e,0x00000000,0x00030047,0x0000001f,
+0x00000000,0x00030047,0x00000021,0x00000000,
+0x00030047,0x00000022,0x00000000,0x00030047,
+0x00000025,0x00000000,0x00030047,0x00000029,
+0x00000000,0x00030047,0x0000002b,0x00000000,
+0x00030047,0x0000002c,0x00000000,0x00030047,
+0x0000002f,0x00000000,0x00030047,0x00000031,
+0x00000000,0x00030047,0x00000032,0x00000000,
+0x00030047,0x00000033,0x00000000,0x00030047,
+0x00000034,0x00000000,0x00030047,0x00000036,
+0x00000000,0x00030047,0x00000037,0x00000000,
+0x00030047,0x0000003a,0x00000000,0x00030047,
+0x0000003b,0x00000000,0x00030047,0x0000003d,
+0x00000000,0x00030047,0x0000003e,0x00000000,
+0x00030047,0x00000040,0x00000000,0x00030047,
+0x00000043,0x00000000,0x00030047,0x00000045,
+0x00000000,0x00030047,0x00000046,0x00000000,
+0x00030047,0x00000047,0x00000000,0x00030047,
+0x00000048,0x00000000,0x00030047,0x00000049,
+0x00000000,0x00030047,0x0000004a,0x00000000,
+0x00030047,0x0000004b,0x00000000,0x00030047,
+0x0000004d,0x00000000,0x00030047,0x0000004e,
+0x00000000,0x00030047,0x0000004f,0x00000000,
+0x00030047,0x00000056,0x00000000,0x00030047,
+0x00000057,0x00000000,0x00030047,0x00000059,
+0x00000000,0x00030047,0x0000005a,0x00000000,
+0x00030047,0x0000005b,0x00000000,0x00030047,
+0x0000005c,0x00000000,0x00030047,0x0000005e,
+0x00000000,0x00030047,0x00000060,0x00000000,
+0x00030047,0x00000061,0x00000000,0x00030047,
+0x00000062,0x00000000,0x00030047,0x00000063,
+0x00000000,0x00030047,0x00000064,0x00000000,
+0x00030047,0x00000065,0x00000000,0x00030047,
+0x00000066,0x00000000,0x00030047,0x00000067,
+0x00000000,0x00030047,0x00000068,0x00000000,
+0x00030047,0x00000069,0x00000000,0x00030047,
+0x0000006a,0x00000000,0x00030047,0x0000006c,
+0x00000000,0x00030047,0x0000006d,0x00000000,
+0x00030047,0x00000071,0x00000000,0x00030047,
+0x00000073,0x00000000,0x00030047,0x00000074,
+0x00000000,0x00030047,0x00000076,0x00000000,
+0x00030047,0x00000077,0x00000000,0x00030047,
+0x00000078,0x00000000,0x00030047,0x00000079,
+0x00000000,0x00030047,0x0000007a,0x00000000,
+0x00030047,0x0000007b,0x00000000,0x00030047,
+0x0000007c,0x00000000,0x00030047,0x0000007e,
+0x00000000,0x00030047,0x0000007f,0x00000000,
+0x00030047,0x00000080,0x00000000,0x00030047,
+0x00000082,0x00000000,0x00030047,0x00000084,
+0x00000000,0x00030047,0x00000085,0x00000000,
+0x00030047,0x00000087,0x00000000,0x00030047,
+0x00000088,0x00000000,0x00030047,0x00000089,
+0x00000000,0x00030047,0x0000008c,0x00000000,
+0x00030047,0x0000008d,0x00000000,0x00030047,
+0x0000008e,0x00000000,0x00030047,0x0000008f,
+0x00000000,0x00030047,0x00000090,0x00000000,
+0x00030047,0x00000091,0x00000000,0x00030047,
+0x00000092,0x00000000,0x00030047,0x00000093,
+0x00000000,0x00030047,0x00000095,0x00000000,
+0x00030047,0x00000096,0x00000000,0x00030047,
+0x00000097,0x00000000,0x00030047,0x00000098,
+0x00000000,0x00030047,0x00000099,0x00000000,
+0x00030047,0x0000009c,0x00000000,0x00040048,
+0x0000009f,0x00000000,0x00000005,0x00040048,
+0x0000009f,0x00000000,0x00000000,0x00050048,
+0x0000009f,0x00000000,0x00000023,0x00000000,
+0x00050048,0x0000009f,0x00000000,0x00000007,
+0x00000010,0x00040048,0x0000009f,0x00000001,
+0x00000000,0x00050048,0x0000009f,0x00000001,
+0x00000023,0x00000040,0x00040048,0x0000009f,
+0x00000002,0x00000000,0x00050048,0x0000009f,
+0x00000002,0x00000023,0x00000048,0x00040048,
+0x0000009f,0x00000003,0x00000000,0x00050048,
+0x0000009f,0x00000003,0x00000023,0x0000004c,
+0x00030047,0x0000009f,0x00000002,0x00040047,
+0x000000a1,0x00000022,0x00000000,0x00040047,
+0x000000a1,0x00000021,0x00000000,0x00030047,
+0x000000a6,0x00000000,0x00030047,0x000000a8,
+0x00000000,0x00030047,0x000000a9,0x00000000,
+0x00030047,0x000000aa,0x00000000,0x00040047,
+0x000000ac,0x0000000b,0x0000000f,0x00030047,
+0x000000b2,0x00000000,0x00030047,0x000000b3,
+0x00000000,0x00030047,0x000000b6,0x00000000,
+0x00030047,0x000000b8,0x00000000,0x00030047,
+0x000000b9,0x00000000,0x00030047,0x000000bc,
+0x00000000,0x00030047,0x000000bd,0x00000000,
+0x00030047,0x000000bf,0x00000000,0x00030047,
+0x000000c1,0x00000000,0x00030047,0x000000c3,
+0x00000000,0x00030047,0x000000c5,0x00000000,
+0x00030047,0x000000c6,0x00000000,0x00030047,
+0x000000c7,0x00000000,0x00030047,0x000000ca,
+0x00000000,0x00030047,0x000000cc,0x00000000,
+0x00030047,0x000000ce,0x00000000,0x00030047,
+0x000000cf,0x00000000,0x00030047,0x000000d0,
+0x00000000,0x00030047,0x000000d3,0x00000000,
+0x00030047,0x000000d5,0x00000000,0x00030047,
+0x000000d7,0x00000000,0x00030047,0x000000d8,
+0x00000000,0x00030047,0x000000d9,0x00000000,
+0x00030047,0x000000db,0x00000000,0x00030047,
+0x000000dd,0x00000000,0x00030047,0x000000df,
+0x00000000,0x00030047,0x000000e0,0x00000000,
+0x00030047,0x000000e1,0x00000000,0x00030047,
+0x000000e3,0x00000000,0x00030047,0x000000e5,
+0x00000000,0x00030047,0x000000e7,0x00000000,
+0x00030047,0x000000e8,0x00000000,0x00030047,
+0x000000e9,0x00000000,0x00030047,0x000000ec,
+0x00000000,0x00030047,0x000000ee,0x00000000,
+0x00030047,0x000000f0,0x00000000,0x00030047,
+0x000000f1,0x00000000,0x00030047,0x000000f2,
+0x00000000,0x00030047,0x000000f4,0x00000000,
+0x00030047,0x000000f6,0x00000000,0x00030047,
+0x000000f8,0x00000000,0x00030047,0x000000f9,
+0x00000000,0x00030047,0x000000fa,0x00000000,
+0x00030047,0x000000fd,0x00000000,0x00030047,
+0x000000ff,0x00000000,0x00030047,0x00000101,
0x00000000,0x00030047,0x00000102,0x00000000,
0x00030047,0x00000103,0x00000000,0x00030047,
-0x00000105,0x00000000,0x00040047,0x00000105,
-0x0000001e,0x00000000,0x00030047,0x00000106,
+0x00000104,0x00000000,0x00030047,0x00000106,
0x00000000,0x00030047,0x00000107,0x00000000,
0x00030047,0x00000108,0x00000000,0x00030047,
-0x000000c2,0x00000000,0x00030047,0x0000005f,
-0x00000000,0x00020013,0x00000002,0x00030021,
-0x00000003,0x00000002,0x00030016,0x00000006,
-0x00000020,0x00040017,0x00000007,0x00000006,
-0x00000002,0x00040020,0x00000008,0x00000007,
-0x00000007,0x00040021,0x00000009,0x00000006,
-0x00000008,0x00040020,0x00000013,0x00000007,
-0x00000006,0x00060021,0x00000014,0x00000006,
-0x00000008,0x00000013,0x00000013,0x0004002b,
-0x00000006,0x0000001b,0x414fd639,0x0004002b,
-0x00000006,0x0000001c,0x429c774c,0x0005002c,
-0x00000007,0x0000001d,0x0000001b,0x0000001c,
-0x0004002b,0x00000006,0x00000020,0x472aee8c,
-0x00040015,0x00000026,0x00000020,0x00000000,
-0x0004002b,0x00000026,0x00000027,0x00000000,
-0x0004002b,0x00000026,0x0000002d,0x00000001,
-0x0004002b,0x00000006,0x00000035,0x4136db6e,
-0x0004002b,0x00000006,0x00000038,0x00000000,
-0x0004002b,0x00000006,0x00000039,0x3f800000,
-0x0004002b,0x00000006,0x0000003c,0x3fc90fdb,
-0x0004002b,0x00000006,0x0000003f,0x3f000000,
-0x0004002b,0x00000006,0x00000044,0x3d4ccccd,
-0x0004002b,0x00000006,0x00000050,0x3e0f5c29,
-0x00020014,0x00000051,0x0004002b,0x00000006,
-0x00000058,0x40000000,0x0005002c,0x00000007,
-0x0000005d,0x00000058,0x00000058,0x0004002b,
-0x00000006,0x0000005f,0x3e800000,0x0004002b,
-0x00000006,0x00000072,0x3f99999a,0x0004002b,
-0x00000006,0x00000075,0x40490fd0,0x0004002b,
-0x00000006,0x0000007d,0x41000000,0x0004002b,
-0x00000006,0x00000081,0x40800000,0x0004002b,
-0x00000006,0x0000008a,0xbf000000,0x0005002c,
-0x00000007,0x0000008b,0x0000008a,0x00000039,
-0x00040017,0x0000009d,0x00000006,0x00000004,
-0x00040018,0x0000009e,0x0000009d,0x00000004,
-0x0005001e,0x0000009f,0x0000009e,0x00000007,
+0x00000109,0x00000000,0x00030047,0x0000010b,
+0x00000000,0x00040047,0x0000010b,0x0000001e,
+0x00000000,0x00030047,0x0000010c,0x00000000,
+0x00030047,0x0000010d,0x00000000,0x00030047,
+0x0000010e,0x00000000,0x00030047,0x000000c8,
+0x00000000,0x00030047,0x0000005f,0x00000000,
+0x00020013,0x00000002,0x00030021,0x00000003,
+0x00000002,0x00030016,0x00000006,0x00000020,
+0x00040017,0x00000007,0x00000006,0x00000002,
+0x00040020,0x00000008,0x00000007,0x00000007,
+0x00040021,0x00000009,0x00000006,0x00000008,
+0x00040020,0x00000013,0x00000007,0x00000006,
+0x00060021,0x00000014,0x00000006,0x00000008,
+0x00000013,0x00000013,0x0004002b,0x00000006,
+0x0000001b,0x414fd639,0x0004002b,0x00000006,
+0x0000001c,0x429c774c,0x0005002c,0x00000007,
+0x0000001d,0x0000001b,0x0000001c,0x0004002b,
+0x00000006,0x00000020,0x472aee8c,0x00040015,
+0x00000026,0x00000020,0x00000000,0x0004002b,
+0x00000026,0x00000027,0x00000000,0x0004002b,
+0x00000026,0x0000002d,0x00000001,0x0004002b,
+0x00000006,0x00000035,0x4136db6e,0x0004002b,
+0x00000006,0x00000038,0x00000000,0x0004002b,
+0x00000006,0x00000039,0x3f800000,0x0004002b,
+0x00000006,0x0000003c,0x3fc90fdb,0x0004002b,
+0x00000006,0x0000003f,0x3f000000,0x0004002b,
+0x00000006,0x00000044,0x3d4ccccd,0x0004002b,
+0x00000006,0x00000050,0x3e0f5c29,0x00020014,
+0x00000051,0x0004002b,0x00000006,0x00000058,
+0x40000000,0x0005002c,0x00000007,0x0000005d,
+0x00000058,0x00000058,0x0004002b,0x00000006,
+0x0000005f,0x3e800000,0x0004002b,0x00000006,
+0x00000072,0x3f99999a,0x0004002b,0x00000006,
+0x00000075,0x40490fd0,0x0004002b,0x00000006,
+0x0000007d,0x41000000,0x0004002b,0x00000006,
+0x00000081,0x40800000,0x0004002b,0x00000006,
+0x0000008a,0xbf000000,0x0005002c,0x00000007,
+0x0000008b,0x0000008a,0x00000039,0x00040017,
+0x0000009d,0x00000006,0x00000004,0x00040018,
+0x0000009e,0x0000009d,0x00000004,0x0006001e,
+0x0000009f,0x0000009e,0x00000007,0x00000006,
0x00000006,0x00040020,0x000000a0,0x00000002,
0x0000009f,0x0004003b,0x000000a0,0x000000a1,
0x00000002,0x00040015,0x000000a2,0x00000020,
@@ -241,42 +247,43 @@
0x0000009d,0x0004003b,0x000000ab,0x000000ac,
0x00000001,0x0004002b,0x000000a2,0x000000af,
0x00000001,0x00040020,0x000000b0,0x00000002,
-0x00000007,0x0004002b,0x00000006,0x000000c2,
-0x3f333333,0x0004002b,0x00000006,0x000000cb,
-0x3f19999a,0x0004002b,0x00000006,0x000000e4,
-0x3e99999a,0x0004002b,0x00000006,0x000000f5,
-0x3e000000,0x00040020,0x00000104,0x00000003,
-0x0000009d,0x0004003b,0x00000104,0x00000105,
-0x00000003,0x0004002b,0x00000006,0x00000108,
+0x00000007,0x0004002b,0x000000a2,0x000000ba,
+0x00000003,0x0004002b,0x00000006,0x000000c8,
+0x3f333333,0x0004002b,0x00000006,0x000000d1,
+0x3f19999a,0x0004002b,0x00000006,0x000000ea,
+0x3e99999a,0x0004002b,0x00000006,0x000000fb,
+0x3e000000,0x00040020,0x0000010a,0x00000003,
+0x0000009d,0x0004003b,0x0000010a,0x0000010b,
+0x00000003,0x0004002b,0x00000006,0x0000010e,
0x40600000,0x00050036,0x00000002,0x00000004,
0x00000000,0x00000003,0x000200f8,0x00000005,
0x0004003b,0x00000013,0x0000009c,0x00000007,
0x0004003b,0x00000008,0x000000aa,0x00000007,
-0x0004003b,0x00000013,0x000000b9,0x00000007,
-0x0004003b,0x00000008,0x000000ba,0x00000007,
-0x0004003b,0x00000013,0x000000bc,0x00000007,
-0x0004003b,0x00000013,0x000000be,0x00000007,
-0x0004003b,0x00000008,0x000000c3,0x00000007,
-0x0004003b,0x00000013,0x000000c5,0x00000007,
-0x0004003b,0x00000013,0x000000c7,0x00000007,
-0x0004003b,0x00000008,0x000000cc,0x00000007,
-0x0004003b,0x00000013,0x000000ce,0x00000007,
-0x0004003b,0x00000013,0x000000d0,0x00000007,
-0x0004003b,0x00000008,0x000000d4,0x00000007,
+0x0004003b,0x00000013,0x000000bf,0x00000007,
+0x0004003b,0x00000008,0x000000c0,0x00000007,
+0x0004003b,0x00000013,0x000000c2,0x00000007,
+0x0004003b,0x00000013,0x000000c4,0x00000007,
+0x0004003b,0x00000008,0x000000c9,0x00000007,
+0x0004003b,0x00000013,0x000000cb,0x00000007,
+0x0004003b,0x00000013,0x000000cd,0x00000007,
+0x0004003b,0x00000008,0x000000d2,0x00000007,
+0x0004003b,0x00000013,0x000000d4,0x00000007,
0x0004003b,0x00000013,0x000000d6,0x00000007,
-0x0004003b,0x00000013,0x000000d8,0x00000007,
-0x0004003b,0x00000008,0x000000dc,0x00000007,
+0x0004003b,0x00000008,0x000000da,0x00000007,
+0x0004003b,0x00000013,0x000000dc,0x00000007,
0x0004003b,0x00000013,0x000000de,0x00000007,
-0x0004003b,0x00000013,0x000000e0,0x00000007,
-0x0004003b,0x00000008,0x000000e5,0x00000007,
-0x0004003b,0x00000013,0x000000e7,0x00000007,
-0x0004003b,0x00000013,0x000000e9,0x00000007,
-0x0004003b,0x00000008,0x000000ed,0x00000007,
+0x0004003b,0x00000008,0x000000e2,0x00000007,
+0x0004003b,0x00000013,0x000000e4,0x00000007,
+0x0004003b,0x00000013,0x000000e6,0x00000007,
+0x0004003b,0x00000008,0x000000eb,0x00000007,
+0x0004003b,0x00000013,0x000000ed,0x00000007,
0x0004003b,0x00000013,0x000000ef,0x00000007,
-0x0004003b,0x00000013,0x000000f1,0x00000007,
-0x0004003b,0x00000008,0x000000f6,0x00000007,
-0x0004003b,0x00000013,0x000000f8,0x00000007,
-0x0004003b,0x00000013,0x000000fa,0x00000007,
+0x0004003b,0x00000008,0x000000f3,0x00000007,
+0x0004003b,0x00000013,0x000000f5,0x00000007,
+0x0004003b,0x00000013,0x000000f7,0x00000007,
+0x0004003b,0x00000008,0x000000fc,0x00000007,
+0x0004003b,0x00000013,0x000000fe,0x00000007,
+0x0004003b,0x00000013,0x00000100,0x00000007,
0x00050041,0x000000a4,0x000000a5,0x000000a1,
0x000000a3,0x0004003d,0x00000006,0x000000a6,
0x000000a5,0x00050085,0x00000006,0x000000a8,
@@ -293,231 +300,238 @@
0x000000ae,0x000000b3,0x0003003e,0x000000aa,
0x000000b4,0x00050041,0x00000013,0x000000b5,
0x000000aa,0x0000002d,0x0004003d,0x00000006,
-0x000000b6,0x000000b5,0x00050083,0x00000006,
-0x000000b7,0x00000039,0x000000b6,0x00050041,
-0x00000013,0x000000b8,0x000000aa,0x0000002d,
-0x0003003e,0x000000b8,0x000000b7,0x0003003e,
-0x000000b9,0x00000038,0x0004003d,0x00000007,
-0x000000bb,0x000000aa,0x0003003e,0x000000ba,
-0x000000bb,0x0004003d,0x00000006,0x000000bd,
-0x0000009c,0x0003003e,0x000000bc,0x000000bd,
-0x0003003e,0x000000be,0x00000039,0x00070039,
-0x00000006,0x000000bf,0x00000018,0x000000ba,
-0x000000bc,0x000000be,0x0004003d,0x00000006,
-0x000000c0,0x000000b9,0x00050081,0x00000006,
-0x000000c1,0x000000c0,0x000000bf,0x0003003e,
-0x000000b9,0x000000c1,0x0004003d,0x00000007,
-0x000000c4,0x000000aa,0x0003003e,0x000000c3,
-0x000000c4,0x0004003d,0x00000006,0x000000c6,
-0x0000009c,0x0003003e,0x000000c5,0x000000c6,
-0x0003003e,0x000000c7,0x000000c2,0x00070039,
-0x00000006,0x000000c8,0x00000018,0x000000c3,
-0x000000c5,0x000000c7,0x0004003d,0x00000006,
-0x000000c9,0x000000b9,0x00050081,0x00000006,
-0x000000ca,0x000000c9,0x000000c8,0x0003003e,
-0x000000b9,0x000000ca,0x0004003d,0x00000007,
-0x000000cd,0x000000aa,0x0003003e,0x000000cc,
-0x000000cd,0x0004003d,0x00000006,0x000000cf,
-0x0000009c,0x0003003e,0x000000ce,0x000000cf,
-0x0003003e,0x000000d0,0x000000cb,0x00070039,
-0x00000006,0x000000d1,0x00000018,0x000000cc,
-0x000000ce,0x000000d0,0x0004003d,0x00000006,
-0x000000d2,0x000000b9,0x00050081,0x00000006,
-0x000000d3,0x000000d2,0x000000d1,0x0003003e,
-0x000000b9,0x000000d3,0x0004003d,0x00000007,
-0x000000d5,0x000000aa,0x0003003e,0x000000d4,
-0x000000d5,0x0004003d,0x00000006,0x000000d7,
-0x0000009c,0x0003003e,0x000000d6,0x000000d7,
-0x0003003e,0x000000d8,0x0000003f,0x00070039,
-0x00000006,0x000000d9,0x00000018,0x000000d4,
-0x000000d6,0x000000d8,0x0004003d,0x00000006,
-0x000000da,0x000000b9,0x00050081,0x00000006,
-0x000000db,0x000000da,0x000000d9,0x0003003e,
-0x000000b9,0x000000db,0x0004003d,0x00000007,
-0x000000dd,0x000000aa,0x0003003e,0x000000dc,
-0x000000dd,0x0004003d,0x00000006,0x000000df,
-0x0000009c,0x0003003e,0x000000de,0x000000df,
-0x0003003e,0x000000e0,0x000000a7,0x00070039,
-0x00000006,0x000000e1,0x00000018,0x000000dc,
-0x000000de,0x000000e0,0x0004003d,0x00000006,
-0x000000e2,0x000000b9,0x00050081,0x00000006,
-0x000000e3,0x000000e2,0x000000e1,0x0003003e,
-0x000000b9,0x000000e3,0x0004003d,0x00000007,
-0x000000e6,0x000000aa,0x0003003e,0x000000e5,
-0x000000e6,0x0004003d,0x00000006,0x000000e8,
-0x0000009c,0x0003003e,0x000000e7,0x000000e8,
-0x0003003e,0x000000e9,0x000000e4,0x00070039,
-0x00000006,0x000000ea,0x00000018,0x000000e5,
-0x000000e7,0x000000e9,0x0004003d,0x00000006,
-0x000000eb,0x000000b9,0x00050081,0x00000006,
-0x000000ec,0x000000eb,0x000000ea,0x0003003e,
-0x000000b9,0x000000ec,0x0004003d,0x00000007,
-0x000000ee,0x000000aa,0x0003003e,0x000000ed,
-0x000000ee,0x0004003d,0x00000006,0x000000f0,
-0x0000009c,0x0003003e,0x000000ef,0x000000f0,
-0x0003003e,0x000000f1,0x0000005f,0x00070039,
-0x00000006,0x000000f2,0x00000018,0x000000ed,
-0x000000ef,0x000000f1,0x0004003d,0x00000006,
-0x000000f3,0x000000b9,0x00050081,0x00000006,
-0x000000f4,0x000000f3,0x000000f2,0x0003003e,
-0x000000b9,0x000000f4,0x0004003d,0x00000007,
-0x000000f7,0x000000aa,0x0003003e,0x000000f6,
-0x000000f7,0x0004003d,0x00000006,0x000000f9,
-0x0000009c,0x0003003e,0x000000f8,0x000000f9,
-0x0003003e,0x000000fa,0x000000f5,0x00070039,
-0x00000006,0x000000fb,0x00000018,0x000000f6,
-0x000000f8,0x000000fa,0x0004003d,0x00000006,
-0x000000fc,0x000000b9,0x00050081,0x00000006,
-0x000000fd,0x000000fc,0x000000fb,0x0003003e,
-0x000000b9,0x000000fd,0x0004003d,0x00000006,
-0x000000fe,0x000000b9,0x00050041,0x00000013,
-0x000000ff,0x000000aa,0x0000002d,0x0004003d,
-0x00000006,0x00000100,0x000000ff,0x00050085,
-0x00000006,0x00000101,0x00000100,0x00000081,
-0x0007000c,0x00000006,0x00000102,0x00000001,
-0x00000025,0x00000101,0x00000039,0x00050085,
-0x00000006,0x00000103,0x000000fe,0x00000102,
-0x0003003e,0x000000b9,0x00000103,0x0004003d,
-0x00000006,0x00000106,0x000000b9,0x00070050,
-0x0000009d,0x00000107,0x00000039,0x00000039,
-0x00000039,0x00000106,0x0003003e,0x00000105,
-0x00000107,0x000100fd,0x00010038,0x00050036,
-0x00000006,0x0000000b,0x00000000,0x00000009,
-0x00030037,0x00000008,0x0000000a,0x000200f8,
-0x0000000c,0x0004003d,0x00000007,0x0000001a,
-0x0000000a,0x00050094,0x00000006,0x0000001e,
-0x0000001a,0x0000001d,0x0006000c,0x00000006,
-0x0000001f,0x00000001,0x0000000d,0x0000001e,
-0x00050085,0x00000006,0x00000021,0x0000001f,
-0x00000020,0x0006000c,0x00000006,0x00000022,
-0x00000001,0x0000000a,0x00000021,0x000200fe,
-0x00000022,0x00010038,0x00050036,0x00000006,
-0x0000000e,0x00000000,0x00000009,0x00030037,
-0x00000008,0x0000000d,0x000200f8,0x0000000f,
-0x0004003b,0x00000013,0x00000025,0x00000007,
-0x00050041,0x00000013,0x00000028,0x0000000d,
-0x00000027,0x0004003d,0x00000006,0x00000029,
-0x00000028,0x00050041,0x00000013,0x0000002a,
-0x0000000d,0x00000027,0x0004003d,0x00000006,
-0x0000002b,0x0000002a,0x00050085,0x00000006,
-0x0000002c,0x00000029,0x0000002b,0x00050041,
-0x00000013,0x0000002e,0x0000000d,0x0000002d,
-0x0004003d,0x00000006,0x0000002f,0x0000002e,
-0x00050041,0x00000013,0x00000030,0x0000000d,
-0x0000002d,0x0004003d,0x00000006,0x00000031,
-0x00000030,0x00050085,0x00000006,0x00000032,
-0x0000002f,0x00000031,0x00050081,0x00000006,
-0x00000033,0x0000002c,0x00000032,0x0006000c,
-0x00000006,0x00000034,0x00000001,0x0000001f,
-0x00000033,0x00050085,0x00000006,0x00000036,
-0x00000034,0x00000035,0x0003003e,0x00000025,
-0x00000036,0x0004003d,0x00000006,0x00000037,
-0x00000025,0x0008000c,0x00000006,0x0000003a,
-0x00000001,0x0000002b,0x00000037,0x00000038,
-0x00000039,0x0003003e,0x00000025,0x0000003a,
-0x0004003d,0x00000006,0x0000003b,0x00000025,
-0x00050085,0x00000006,0x0000003d,0x0000003b,
-0x0000003c,0x0006000c,0x00000006,0x0000003e,
-0x00000001,0x0000000e,0x0000003d,0x00050085,
-0x00000006,0x00000040,0x0000003e,0x0000003f,
-0x000200fe,0x00000040,0x00010038,0x00050036,
-0x00000006,0x00000011,0x00000000,0x00000009,
-0x00030037,0x00000008,0x00000010,0x000200f8,
-0x00000012,0x0004003b,0x00000013,0x00000043,
-0x00000007,0x0004003b,0x00000008,0x00000045,
-0x00000007,0x0004003b,0x00000013,0x0000004b,
-0x00000007,0x0004003b,0x00000008,0x0000004c,
-0x00000007,0x0004003b,0x00000008,0x00000056,
-0x00000007,0x0004003b,0x00000008,0x00000061,
-0x00000007,0x0004003b,0x00000008,0x00000067,
-0x00000007,0x0004003b,0x00000008,0x0000006b,
-0x00000007,0x0003003e,0x00000043,0x00000044,
-0x0004003d,0x00000007,0x00000046,0x00000010,
-0x0004003d,0x00000006,0x00000047,0x00000043,
-0x00050050,0x00000007,0x00000048,0x00000047,
-0x00000047,0x00050088,0x00000007,0x00000049,
-0x00000046,0x00000048,0x0006000c,0x00000007,
-0x0000004a,0x00000001,0x00000008,0x00000049,
-0x0003003e,0x00000045,0x0000004a,0x0004003d,
-0x00000007,0x0000004d,0x00000045,0x0003003e,
-0x0000004c,0x0000004d,0x00050039,0x00000006,
-0x0000004e,0x0000000b,0x0000004c,0x0003003e,
-0x0000004b,0x0000004e,0x0004003d,0x00000006,
-0x0000004f,0x0000004b,0x000500ba,0x00000051,
-0x00000052,0x0000004f,0x00000050,0x000300f7,
-0x00000054,0x00000000,0x000400fa,0x00000052,
-0x00000053,0x00000054,0x000200f8,0x00000053,
-0x000200fe,0x00000038,0x000200f8,0x00000054,
-0x0004003d,0x00000006,0x00000057,0x0000004b,
-0x00050085,0x00000006,0x00000059,0x00000057,
-0x00000058,0x0006000c,0x00000006,0x0000005a,
-0x00000001,0x0000000a,0x00000059,0x0004003d,
-0x00000006,0x0000005b,0x0000004b,0x00050050,
-0x00000007,0x0000005c,0x0000005a,0x0000005b,
-0x00050081,0x00000007,0x0000005e,0x0000005c,
-0x0000005d,0x0005008e,0x00000007,0x00000060,
-0x0000005e,0x0000005f,0x0003003e,0x00000056,
-0x00000060,0x0004003d,0x00000007,0x00000062,
-0x00000010,0x0004003d,0x00000006,0x00000063,
-0x00000043,0x00050050,0x00000007,0x00000064,
-0x00000063,0x00000063,0x00050088,0x00000007,
-0x00000065,0x00000062,0x00000064,0x0006000c,
-0x00000007,0x00000066,0x00000001,0x0000000a,
-0x00000065,0x0003003e,0x00000061,0x00000066,
-0x0004003d,0x00000007,0x00000068,0x00000061,
-0x0004003d,0x00000007,0x00000069,0x00000056,
-0x00050083,0x00000007,0x0000006a,0x00000068,
-0x00000069,0x0003003e,0x00000067,0x0000006a,
-0x0004003d,0x00000007,0x0000006c,0x00000067,
-0x0003003e,0x0000006b,0x0000006c,0x00050039,
-0x00000006,0x0000006d,0x0000000e,0x0000006b,
-0x000200fe,0x0000006d,0x00010038,0x00050036,
-0x00000006,0x00000018,0x00000000,0x00000014,
-0x00030037,0x00000008,0x00000015,0x00030037,
-0x00000013,0x00000016,0x00030037,0x00000013,
-0x00000017,0x000200f8,0x00000019,0x0004003b,
-0x00000008,0x00000094,0x00000007,0x00050041,
-0x00000013,0x00000070,0x00000015,0x0000002d,
-0x0004003d,0x00000006,0x00000071,0x00000070,
-0x00050085,0x00000006,0x00000073,0x00000071,
-0x00000072,0x0004003d,0x00000006,0x00000074,
-0x00000016,0x00050085,0x00000006,0x00000076,
-0x00000074,0x00000075,0x00050085,0x00000006,
-0x00000077,0x00000076,0x00000058,0x00050081,
-0x00000006,0x00000078,0x00000073,0x00000077,
-0x0004003d,0x00000006,0x00000079,0x00000017,
-0x00050088,0x00000006,0x0000007a,0x00000039,
-0x00000079,0x00050081,0x00000006,0x0000007b,
-0x00000078,0x0000007a,0x0006000c,0x00000006,
-0x0000007c,0x00000001,0x0000000e,0x0000007b,
-0x0004003d,0x00000006,0x0000007e,0x00000017,
-0x00050088,0x00000006,0x0000007f,0x0000007d,
-0x0000007e,0x00050088,0x00000006,0x00000080,
-0x0000007c,0x0000007f,0x00050085,0x00000006,
-0x00000082,0x00000080,0x00000081,0x00050041,
-0x00000013,0x00000083,0x00000015,0x00000027,
-0x0004003d,0x00000006,0x00000084,0x00000083,
-0x00050081,0x00000006,0x00000085,0x00000084,
-0x00000082,0x00050041,0x00000013,0x00000086,
-0x00000015,0x00000027,0x0003003e,0x00000086,
-0x00000085,0x0004003d,0x00000006,0x00000087,
-0x00000016,0x0004003d,0x00000006,0x00000088,
-0x00000017,0x00050085,0x00000006,0x00000089,
-0x00000087,0x00000088,0x0005008e,0x00000007,
-0x0000008c,0x0000008b,0x00000089,0x0005008e,
-0x00000007,0x0000008d,0x0000008c,0x00000081,
-0x0004003d,0x00000007,0x0000008e,0x00000015,
-0x00050081,0x00000007,0x0000008f,0x0000008e,
-0x0000008d,0x0003003e,0x00000015,0x0000008f,
-0x0004003d,0x00000007,0x00000090,0x00000015,
-0x0004003d,0x00000006,0x00000091,0x00000017,
-0x00050050,0x00000007,0x00000092,0x00000091,
-0x00000091,0x00050088,0x00000007,0x00000093,
-0x00000090,0x00000092,0x0003003e,0x00000094,
-0x00000093,0x00050039,0x00000006,0x00000095,
-0x00000011,0x00000094,0x0004003d,0x00000006,
-0x00000096,0x00000017,0x00050085,0x00000006,
-0x00000097,0x00000096,0x0000003f,0x00050081,
-0x00000006,0x00000098,0x00000097,0x0000003f,
-0x00050085,0x00000006,0x00000099,0x00000095,
-0x00000098,0x000200fe,0x00000099,0x00010038}
+0x000000b6,0x000000b5,0x00050041,0x00000013,
+0x000000b7,0x000000aa,0x0000002d,0x0004003d,
+0x00000006,0x000000b8,0x000000b7,0x00050083,
+0x00000006,0x000000b9,0x00000039,0x000000b8,
+0x00050041,0x000000a4,0x000000bb,0x000000a1,
+0x000000ba,0x0004003d,0x00000006,0x000000bc,
+0x000000bb,0x0008000c,0x00000006,0x000000bd,
+0x00000001,0x0000002e,0x000000b6,0x000000b9,
+0x000000bc,0x00050041,0x00000013,0x000000be,
+0x000000aa,0x0000002d,0x0003003e,0x000000be,
+0x000000bd,0x0003003e,0x000000bf,0x00000038,
+0x0004003d,0x00000007,0x000000c1,0x000000aa,
+0x0003003e,0x000000c0,0x000000c1,0x0004003d,
+0x00000006,0x000000c3,0x0000009c,0x0003003e,
+0x000000c2,0x000000c3,0x0003003e,0x000000c4,
+0x00000039,0x00070039,0x00000006,0x000000c5,
+0x00000018,0x000000c0,0x000000c2,0x000000c4,
+0x0004003d,0x00000006,0x000000c6,0x000000bf,
+0x00050081,0x00000006,0x000000c7,0x000000c6,
+0x000000c5,0x0003003e,0x000000bf,0x000000c7,
+0x0004003d,0x00000007,0x000000ca,0x000000aa,
+0x0003003e,0x000000c9,0x000000ca,0x0004003d,
+0x00000006,0x000000cc,0x0000009c,0x0003003e,
+0x000000cb,0x000000cc,0x0003003e,0x000000cd,
+0x000000c8,0x00070039,0x00000006,0x000000ce,
+0x00000018,0x000000c9,0x000000cb,0x000000cd,
+0x0004003d,0x00000006,0x000000cf,0x000000bf,
+0x00050081,0x00000006,0x000000d0,0x000000cf,
+0x000000ce,0x0003003e,0x000000bf,0x000000d0,
+0x0004003d,0x00000007,0x000000d3,0x000000aa,
+0x0003003e,0x000000d2,0x000000d3,0x0004003d,
+0x00000006,0x000000d5,0x0000009c,0x0003003e,
+0x000000d4,0x000000d5,0x0003003e,0x000000d6,
+0x000000d1,0x00070039,0x00000006,0x000000d7,
+0x00000018,0x000000d2,0x000000d4,0x000000d6,
+0x0004003d,0x00000006,0x000000d8,0x000000bf,
+0x00050081,0x00000006,0x000000d9,0x000000d8,
+0x000000d7,0x0003003e,0x000000bf,0x000000d9,
+0x0004003d,0x00000007,0x000000db,0x000000aa,
+0x0003003e,0x000000da,0x000000db,0x0004003d,
+0x00000006,0x000000dd,0x0000009c,0x0003003e,
+0x000000dc,0x000000dd,0x0003003e,0x000000de,
+0x0000003f,0x00070039,0x00000006,0x000000df,
+0x00000018,0x000000da,0x000000dc,0x000000de,
+0x0004003d,0x00000006,0x000000e0,0x000000bf,
+0x00050081,0x00000006,0x000000e1,0x000000e0,
+0x000000df,0x0003003e,0x000000bf,0x000000e1,
+0x0004003d,0x00000007,0x000000e3,0x000000aa,
+0x0003003e,0x000000e2,0x000000e3,0x0004003d,
+0x00000006,0x000000e5,0x0000009c,0x0003003e,
+0x000000e4,0x000000e5,0x0003003e,0x000000e6,
+0x000000a7,0x00070039,0x00000006,0x000000e7,
+0x00000018,0x000000e2,0x000000e4,0x000000e6,
+0x0004003d,0x00000006,0x000000e8,0x000000bf,
+0x00050081,0x00000006,0x000000e9,0x000000e8,
+0x000000e7,0x0003003e,0x000000bf,0x000000e9,
+0x0004003d,0x00000007,0x000000ec,0x000000aa,
+0x0003003e,0x000000eb,0x000000ec,0x0004003d,
+0x00000006,0x000000ee,0x0000009c,0x0003003e,
+0x000000ed,0x000000ee,0x0003003e,0x000000ef,
+0x000000ea,0x00070039,0x00000006,0x000000f0,
+0x00000018,0x000000eb,0x000000ed,0x000000ef,
+0x0004003d,0x00000006,0x000000f1,0x000000bf,
+0x00050081,0x00000006,0x000000f2,0x000000f1,
+0x000000f0,0x0003003e,0x000000bf,0x000000f2,
+0x0004003d,0x00000007,0x000000f4,0x000000aa,
+0x0003003e,0x000000f3,0x000000f4,0x0004003d,
+0x00000006,0x000000f6,0x0000009c,0x0003003e,
+0x000000f5,0x000000f6,0x0003003e,0x000000f7,
+0x0000005f,0x00070039,0x00000006,0x000000f8,
+0x00000018,0x000000f3,0x000000f5,0x000000f7,
+0x0004003d,0x00000006,0x000000f9,0x000000bf,
+0x00050081,0x00000006,0x000000fa,0x000000f9,
+0x000000f8,0x0003003e,0x000000bf,0x000000fa,
+0x0004003d,0x00000007,0x000000fd,0x000000aa,
+0x0003003e,0x000000fc,0x000000fd,0x0004003d,
+0x00000006,0x000000ff,0x0000009c,0x0003003e,
+0x000000fe,0x000000ff,0x0003003e,0x00000100,
+0x000000fb,0x00070039,0x00000006,0x00000101,
+0x00000018,0x000000fc,0x000000fe,0x00000100,
+0x0004003d,0x00000006,0x00000102,0x000000bf,
+0x00050081,0x00000006,0x00000103,0x00000102,
+0x00000101,0x0003003e,0x000000bf,0x00000103,
+0x0004003d,0x00000006,0x00000104,0x000000bf,
+0x00050041,0x00000013,0x00000105,0x000000aa,
+0x0000002d,0x0004003d,0x00000006,0x00000106,
+0x00000105,0x00050085,0x00000006,0x00000107,
+0x00000106,0x00000081,0x0007000c,0x00000006,
+0x00000108,0x00000001,0x00000025,0x00000107,
+0x00000039,0x00050085,0x00000006,0x00000109,
+0x00000104,0x00000108,0x0003003e,0x000000bf,
+0x00000109,0x0004003d,0x00000006,0x0000010c,
+0x000000bf,0x00070050,0x0000009d,0x0000010d,
+0x00000039,0x00000039,0x00000039,0x0000010c,
+0x0003003e,0x0000010b,0x0000010d,0x000100fd,
+0x00010038,0x00050036,0x00000006,0x0000000b,
+0x00000000,0x00000009,0x00030037,0x00000008,
+0x0000000a,0x000200f8,0x0000000c,0x0004003d,
+0x00000007,0x0000001a,0x0000000a,0x00050094,
+0x00000006,0x0000001e,0x0000001a,0x0000001d,
+0x0006000c,0x00000006,0x0000001f,0x00000001,
+0x0000000d,0x0000001e,0x00050085,0x00000006,
+0x00000021,0x0000001f,0x00000020,0x0006000c,
+0x00000006,0x00000022,0x00000001,0x0000000a,
+0x00000021,0x000200fe,0x00000022,0x00010038,
+0x00050036,0x00000006,0x0000000e,0x00000000,
+0x00000009,0x00030037,0x00000008,0x0000000d,
+0x000200f8,0x0000000f,0x0004003b,0x00000013,
+0x00000025,0x00000007,0x00050041,0x00000013,
+0x00000028,0x0000000d,0x00000027,0x0004003d,
+0x00000006,0x00000029,0x00000028,0x00050041,
+0x00000013,0x0000002a,0x0000000d,0x00000027,
+0x0004003d,0x00000006,0x0000002b,0x0000002a,
+0x00050085,0x00000006,0x0000002c,0x00000029,
+0x0000002b,0x00050041,0x00000013,0x0000002e,
+0x0000000d,0x0000002d,0x0004003d,0x00000006,
+0x0000002f,0x0000002e,0x00050041,0x00000013,
+0x00000030,0x0000000d,0x0000002d,0x0004003d,
+0x00000006,0x00000031,0x00000030,0x00050085,
+0x00000006,0x00000032,0x0000002f,0x00000031,
+0x00050081,0x00000006,0x00000033,0x0000002c,
+0x00000032,0x0006000c,0x00000006,0x00000034,
+0x00000001,0x0000001f,0x00000033,0x00050085,
+0x00000006,0x00000036,0x00000034,0x00000035,
+0x0003003e,0x00000025,0x00000036,0x0004003d,
+0x00000006,0x00000037,0x00000025,0x0008000c,
+0x00000006,0x0000003a,0x00000001,0x0000002b,
+0x00000037,0x00000038,0x00000039,0x0003003e,
+0x00000025,0x0000003a,0x0004003d,0x00000006,
+0x0000003b,0x00000025,0x00050085,0x00000006,
+0x0000003d,0x0000003b,0x0000003c,0x0006000c,
+0x00000006,0x0000003e,0x00000001,0x0000000e,
+0x0000003d,0x00050085,0x00000006,0x00000040,
+0x0000003e,0x0000003f,0x000200fe,0x00000040,
+0x00010038,0x00050036,0x00000006,0x00000011,
+0x00000000,0x00000009,0x00030037,0x00000008,
+0x00000010,0x000200f8,0x00000012,0x0004003b,
+0x00000013,0x00000043,0x00000007,0x0004003b,
+0x00000008,0x00000045,0x00000007,0x0004003b,
+0x00000013,0x0000004b,0x00000007,0x0004003b,
+0x00000008,0x0000004c,0x00000007,0x0004003b,
+0x00000008,0x00000056,0x00000007,0x0004003b,
+0x00000008,0x00000061,0x00000007,0x0004003b,
+0x00000008,0x00000067,0x00000007,0x0004003b,
+0x00000008,0x0000006b,0x00000007,0x0003003e,
+0x00000043,0x00000044,0x0004003d,0x00000007,
+0x00000046,0x00000010,0x0004003d,0x00000006,
+0x00000047,0x00000043,0x00050050,0x00000007,
+0x00000048,0x00000047,0x00000047,0x00050088,
+0x00000007,0x00000049,0x00000046,0x00000048,
+0x0006000c,0x00000007,0x0000004a,0x00000001,
+0x00000008,0x00000049,0x0003003e,0x00000045,
+0x0000004a,0x0004003d,0x00000007,0x0000004d,
+0x00000045,0x0003003e,0x0000004c,0x0000004d,
+0x00050039,0x00000006,0x0000004e,0x0000000b,
+0x0000004c,0x0003003e,0x0000004b,0x0000004e,
+0x0004003d,0x00000006,0x0000004f,0x0000004b,
+0x000500ba,0x00000051,0x00000052,0x0000004f,
+0x00000050,0x000300f7,0x00000054,0x00000000,
+0x000400fa,0x00000052,0x00000053,0x00000054,
+0x000200f8,0x00000053,0x000200fe,0x00000038,
+0x000200f8,0x00000054,0x0004003d,0x00000006,
+0x00000057,0x0000004b,0x00050085,0x00000006,
+0x00000059,0x00000057,0x00000058,0x0006000c,
+0x00000006,0x0000005a,0x00000001,0x0000000a,
+0x00000059,0x0004003d,0x00000006,0x0000005b,
+0x0000004b,0x00050050,0x00000007,0x0000005c,
+0x0000005a,0x0000005b,0x00050081,0x00000007,
+0x0000005e,0x0000005c,0x0000005d,0x0005008e,
+0x00000007,0x00000060,0x0000005e,0x0000005f,
+0x0003003e,0x00000056,0x00000060,0x0004003d,
+0x00000007,0x00000062,0x00000010,0x0004003d,
+0x00000006,0x00000063,0x00000043,0x00050050,
+0x00000007,0x00000064,0x00000063,0x00000063,
+0x00050088,0x00000007,0x00000065,0x00000062,
+0x00000064,0x0006000c,0x00000007,0x00000066,
+0x00000001,0x0000000a,0x00000065,0x0003003e,
+0x00000061,0x00000066,0x0004003d,0x00000007,
+0x00000068,0x00000061,0x0004003d,0x00000007,
+0x00000069,0x00000056,0x00050083,0x00000007,
+0x0000006a,0x00000068,0x00000069,0x0003003e,
+0x00000067,0x0000006a,0x0004003d,0x00000007,
+0x0000006c,0x00000067,0x0003003e,0x0000006b,
+0x0000006c,0x00050039,0x00000006,0x0000006d,
+0x0000000e,0x0000006b,0x000200fe,0x0000006d,
+0x00010038,0x00050036,0x00000006,0x00000018,
+0x00000000,0x00000014,0x00030037,0x00000008,
+0x00000015,0x00030037,0x00000013,0x00000016,
+0x00030037,0x00000013,0x00000017,0x000200f8,
+0x00000019,0x0004003b,0x00000008,0x00000094,
+0x00000007,0x00050041,0x00000013,0x00000070,
+0x00000015,0x0000002d,0x0004003d,0x00000006,
+0x00000071,0x00000070,0x00050085,0x00000006,
+0x00000073,0x00000071,0x00000072,0x0004003d,
+0x00000006,0x00000074,0x00000016,0x00050085,
+0x00000006,0x00000076,0x00000074,0x00000075,
+0x00050085,0x00000006,0x00000077,0x00000076,
+0x00000058,0x00050081,0x00000006,0x00000078,
+0x00000073,0x00000077,0x0004003d,0x00000006,
+0x00000079,0x00000017,0x00050088,0x00000006,
+0x0000007a,0x00000039,0x00000079,0x00050081,
+0x00000006,0x0000007b,0x00000078,0x0000007a,
+0x0006000c,0x00000006,0x0000007c,0x00000001,
+0x0000000e,0x0000007b,0x0004003d,0x00000006,
+0x0000007e,0x00000017,0x00050088,0x00000006,
+0x0000007f,0x0000007d,0x0000007e,0x00050088,
+0x00000006,0x00000080,0x0000007c,0x0000007f,
+0x00050085,0x00000006,0x00000082,0x00000080,
+0x00000081,0x00050041,0x00000013,0x00000083,
+0x00000015,0x00000027,0x0004003d,0x00000006,
+0x00000084,0x00000083,0x00050081,0x00000006,
+0x00000085,0x00000084,0x00000082,0x00050041,
+0x00000013,0x00000086,0x00000015,0x00000027,
+0x0003003e,0x00000086,0x00000085,0x0004003d,
+0x00000006,0x00000087,0x00000016,0x0004003d,
+0x00000006,0x00000088,0x00000017,0x00050085,
+0x00000006,0x00000089,0x00000087,0x00000088,
+0x0005008e,0x00000007,0x0000008c,0x0000008b,
+0x00000089,0x0005008e,0x00000007,0x0000008d,
+0x0000008c,0x00000081,0x0004003d,0x00000007,
+0x0000008e,0x00000015,0x00050081,0x00000007,
+0x0000008f,0x0000008e,0x0000008d,0x0003003e,
+0x00000015,0x0000008f,0x0004003d,0x00000007,
+0x00000090,0x00000015,0x0004003d,0x00000006,
+0x00000091,0x00000017,0x00050050,0x00000007,
+0x00000092,0x00000091,0x00000091,0x00050088,
+0x00000007,0x00000093,0x00000090,0x00000092,
+0x0003003e,0x00000094,0x00000093,0x00050039,
+0x00000006,0x00000095,0x00000011,0x00000094,
+0x0004003d,0x00000006,0x00000096,0x00000017,
+0x00050085,0x00000006,0x00000097,0x00000096,
+0x0000003f,0x00050081,0x00000006,0x00000098,
+0x00000097,0x0000003f,0x00050085,0x00000006,
+0x00000099,0x00000095,0x00000098,0x000200fe,
+0x00000099,0x00010038}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag
index c0e242d9a8..52c929aa21 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag
+++ b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag
@@ -6,6 +6,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
mat4 MVP;
vec2 OutputSize;
float time;
+ float yflip;
} constants;
layout(location = 0) out vec4 FragColor;
@@ -56,7 +57,7 @@ void main(void)
{
float tim = constants.time * 0.4 * speed;
vec2 pos = gl_FragCoord.xy / constants.OutputSize.xx;
- pos.y = 1.0 - pos.y; // Flip Y
+ pos.y = mix(pos.y, 1.0 - pos.y, constants.yflip); // Flip Y
float a = 0.0;
// Each of these is a layer of snow
// Remove some for better performance
diff --git a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag.inc b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag.inc
index a415621896..6eae853da1 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.frag.inc
@@ -1,9 +1,9 @@
-{0x07230203,0x00010000,0x00080001,0x0000010a,
+{0x07230203,0x00010000,0x000d0007,0x00000110,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
-0x00000000,0x000000ad,0x00000106,0x00030010,
+0x00000000,0x000000ad,0x0000010c,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
@@ -36,201 +36,207 @@
0x00040006,0x0000009f,0x00000000,0x0050564d,
0x00060006,0x0000009f,0x00000001,0x7074754f,
0x69537475,0x0000657a,0x00050006,0x0000009f,
-0x00000002,0x656d6974,0x00000000,0x00050005,
-0x000000a1,0x736e6f63,0x746e6174,0x00000073,
-0x00030005,0x000000ab,0x00736f70,0x00060005,
-0x000000ad,0x465f6c67,0x43676172,0x64726f6f,
-0x00000000,0x00030005,0x000000ba,0x00000061,
-0x00040005,0x000000bb,0x61726170,0x0000006d,
-0x00040005,0x000000bd,0x61726170,0x0000006d,
-0x00040005,0x000000bf,0x61726170,0x0000006d,
-0x00040005,0x000000c4,0x61726170,0x0000006d,
-0x00040005,0x000000c6,0x61726170,0x0000006d,
-0x00040005,0x000000c8,0x61726170,0x0000006d,
-0x00040005,0x000000cd,0x61726170,0x0000006d,
-0x00040005,0x000000cf,0x61726170,0x0000006d,
-0x00040005,0x000000d1,0x61726170,0x0000006d,
-0x00040005,0x000000d5,0x61726170,0x0000006d,
-0x00040005,0x000000d7,0x61726170,0x0000006d,
-0x00040005,0x000000d9,0x61726170,0x0000006d,
-0x00040005,0x000000dd,0x61726170,0x0000006d,
-0x00040005,0x000000df,0x61726170,0x0000006d,
-0x00040005,0x000000e1,0x61726170,0x0000006d,
-0x00040005,0x000000e6,0x61726170,0x0000006d,
-0x00040005,0x000000e8,0x61726170,0x0000006d,
-0x00040005,0x000000ea,0x61726170,0x0000006d,
-0x00040005,0x000000ee,0x61726170,0x0000006d,
-0x00040005,0x000000f0,0x61726170,0x0000006d,
-0x00040005,0x000000f2,0x61726170,0x0000006d,
-0x00040005,0x000000f7,0x61726170,0x0000006d,
-0x00040005,0x000000f9,0x61726170,0x0000006d,
-0x00040005,0x000000fb,0x61726170,0x0000006d,
-0x00050005,0x00000106,0x67617246,0x6f6c6f43,
-0x00000072,0x00030047,0x0000000b,0x00000000,
-0x00030047,0x0000000a,0x00000000,0x00030047,
-0x0000000e,0x00000000,0x00030047,0x0000000d,
-0x00000000,0x00030047,0x00000011,0x00000000,
-0x00030047,0x00000010,0x00000000,0x00030047,
-0x00000018,0x00000000,0x00030047,0x00000015,
-0x00000000,0x00030047,0x00000016,0x00000000,
-0x00030047,0x00000017,0x00000000,0x00030047,
-0x0000001a,0x00000000,0x00030047,0x0000001e,
-0x00000000,0x00030047,0x0000001f,0x00000000,
-0x00030047,0x00000021,0x00000000,0x00030047,
-0x00000022,0x00000000,0x00030047,0x00000025,
-0x00000000,0x00030047,0x00000029,0x00000000,
-0x00030047,0x0000002b,0x00000000,0x00030047,
-0x0000002c,0x00000000,0x00030047,0x0000002f,
-0x00000000,0x00030047,0x00000031,0x00000000,
-0x00030047,0x00000032,0x00000000,0x00030047,
-0x00000033,0x00000000,0x00030047,0x00000034,
-0x00000000,0x00030047,0x00000036,0x00000000,
-0x00030047,0x00000037,0x00000000,0x00030047,
-0x0000003a,0x00000000,0x00030047,0x0000003b,
-0x00000000,0x00030047,0x0000003d,0x00000000,
-0x00030047,0x0000003e,0x00000000,0x00030047,
-0x00000040,0x00000000,0x00030047,0x00000043,
-0x00000000,0x00030047,0x00000045,0x00000000,
-0x00030047,0x00000046,0x00000000,0x00030047,
-0x00000047,0x00000000,0x00030047,0x00000048,
-0x00000000,0x00030047,0x00000049,0x00000000,
-0x00030047,0x0000004a,0x00000000,0x00030047,
-0x0000004b,0x00000000,0x00030047,0x0000004d,
-0x00000000,0x00030047,0x0000004e,0x00000000,
-0x00030047,0x0000004f,0x00000000,0x00030047,
-0x00000056,0x00000000,0x00030047,0x00000057,
-0x00000000,0x00030047,0x00000059,0x00000000,
-0x00030047,0x0000005a,0x00000000,0x00030047,
-0x0000005b,0x00000000,0x00030047,0x0000005c,
-0x00000000,0x00030047,0x0000005e,0x00000000,
-0x00030047,0x00000060,0x00000000,0x00030047,
-0x00000061,0x00000000,0x00030047,0x00000062,
-0x00000000,0x00030047,0x00000063,0x00000000,
-0x00030047,0x00000064,0x00000000,0x00030047,
-0x00000065,0x00000000,0x00030047,0x00000066,
-0x00000000,0x00030047,0x00000067,0x00000000,
-0x00030047,0x00000068,0x00000000,0x00030047,
-0x00000069,0x00000000,0x00030047,0x0000006a,
-0x00000000,0x00030047,0x0000006c,0x00000000,
-0x00030047,0x0000006d,0x00000000,0x00030047,
-0x00000071,0x00000000,0x00030047,0x00000073,
-0x00000000,0x00030047,0x00000074,0x00000000,
-0x00030047,0x00000076,0x00000000,0x00030047,
-0x00000077,0x00000000,0x00030047,0x00000078,
-0x00000000,0x00030047,0x00000079,0x00000000,
-0x00030047,0x0000007a,0x00000000,0x00030047,
-0x0000007b,0x00000000,0x00030047,0x0000007c,
-0x00000000,0x00030047,0x0000007e,0x00000000,
-0x00030047,0x0000007f,0x00000000,0x00030047,
-0x00000080,0x00000000,0x00030047,0x00000082,
-0x00000000,0x00030047,0x00000084,0x00000000,
-0x00030047,0x00000085,0x00000000,0x00030047,
-0x00000087,0x00000000,0x00030047,0x00000088,
-0x00000000,0x00030047,0x00000089,0x00000000,
-0x00030047,0x0000008c,0x00000000,0x00030047,
-0x0000008d,0x00000000,0x00030047,0x0000008e,
-0x00000000,0x00030047,0x0000008f,0x00000000,
-0x00030047,0x00000090,0x00000000,0x00030047,
-0x00000091,0x00000000,0x00030047,0x00000092,
-0x00000000,0x00030047,0x00000093,0x00000000,
-0x00030047,0x00000095,0x00000000,0x00030047,
-0x00000096,0x00000000,0x00030047,0x00000097,
-0x00000000,0x00030047,0x00000098,0x00000000,
-0x00030047,0x00000099,0x00000000,0x00030047,
-0x0000009c,0x00000000,0x00040048,0x0000009f,
-0x00000000,0x00000005,0x00040048,0x0000009f,
-0x00000000,0x00000000,0x00050048,0x0000009f,
-0x00000000,0x00000023,0x00000000,0x00050048,
-0x0000009f,0x00000000,0x00000007,0x00000010,
-0x00040048,0x0000009f,0x00000001,0x00000000,
-0x00050048,0x0000009f,0x00000001,0x00000023,
-0x00000040,0x00040048,0x0000009f,0x00000002,
-0x00000000,0x00050048,0x0000009f,0x00000002,
-0x00000023,0x00000048,0x00030047,0x0000009f,
-0x00000002,0x00040047,0x000000a1,0x00000022,
-0x00000000,0x00040047,0x000000a1,0x00000021,
-0x00000000,0x00030047,0x000000a6,0x00000000,
-0x00030047,0x000000a8,0x00000000,0x00030047,
-0x000000aa,0x00000000,0x00030047,0x000000ab,
-0x00000000,0x00040047,0x000000ad,0x0000000b,
-0x0000000f,0x00030047,0x000000b3,0x00000000,
-0x00030047,0x000000b4,0x00000000,0x00030047,
-0x000000b7,0x00000000,0x00030047,0x000000b8,
-0x00000000,0x00030047,0x000000ba,0x00000000,
-0x00030047,0x000000bc,0x00000000,0x00030047,
-0x000000be,0x00000000,0x00030047,0x000000c0,
-0x00000000,0x00030047,0x000000c1,0x00000000,
-0x00030047,0x000000c2,0x00000000,0x00030047,
-0x000000c5,0x00000000,0x00030047,0x000000c7,
-0x00000000,0x00030047,0x000000c9,0x00000000,
-0x00030047,0x000000ca,0x00000000,0x00030047,
-0x000000cb,0x00000000,0x00030047,0x000000ce,
-0x00000000,0x00030047,0x000000d0,0x00000000,
-0x00030047,0x000000d2,0x00000000,0x00030047,
-0x000000d3,0x00000000,0x00030047,0x000000d4,
-0x00000000,0x00030047,0x000000d6,0x00000000,
-0x00030047,0x000000d8,0x00000000,0x00030047,
-0x000000da,0x00000000,0x00030047,0x000000db,
-0x00000000,0x00030047,0x000000dc,0x00000000,
-0x00030047,0x000000de,0x00000000,0x00030047,
-0x000000e0,0x00000000,0x00030047,0x000000e2,
-0x00000000,0x00030047,0x000000e3,0x00000000,
-0x00030047,0x000000e4,0x00000000,0x00030047,
-0x000000e7,0x00000000,0x00030047,0x000000e9,
-0x00000000,0x00030047,0x000000eb,0x00000000,
-0x00030047,0x000000ec,0x00000000,0x00030047,
-0x000000ed,0x00000000,0x00030047,0x000000ef,
-0x00000000,0x00030047,0x000000f1,0x00000000,
-0x00030047,0x000000f3,0x00000000,0x00030047,
-0x000000f4,0x00000000,0x00030047,0x000000f5,
-0x00000000,0x00030047,0x000000f8,0x00000000,
-0x00030047,0x000000fa,0x00000000,0x00030047,
-0x000000fc,0x00000000,0x00030047,0x000000fd,
-0x00000000,0x00030047,0x000000fe,0x00000000,
-0x00030047,0x000000ff,0x00000000,0x00030047,
-0x00000101,0x00000000,0x00030047,0x00000102,
+0x00000002,0x656d6974,0x00000000,0x00050006,
+0x0000009f,0x00000003,0x696c6679,0x00000070,
+0x00050005,0x000000a1,0x736e6f63,0x746e6174,
+0x00000073,0x00030005,0x000000ab,0x00736f70,
+0x00060005,0x000000ad,0x465f6c67,0x43676172,
+0x64726f6f,0x00000000,0x00030005,0x000000c0,
+0x00000061,0x00040005,0x000000c1,0x61726170,
+0x0000006d,0x00040005,0x000000c3,0x61726170,
+0x0000006d,0x00040005,0x000000c5,0x61726170,
+0x0000006d,0x00040005,0x000000ca,0x61726170,
+0x0000006d,0x00040005,0x000000cc,0x61726170,
+0x0000006d,0x00040005,0x000000ce,0x61726170,
+0x0000006d,0x00040005,0x000000d3,0x61726170,
+0x0000006d,0x00040005,0x000000d5,0x61726170,
+0x0000006d,0x00040005,0x000000d7,0x61726170,
+0x0000006d,0x00040005,0x000000db,0x61726170,
+0x0000006d,0x00040005,0x000000dd,0x61726170,
+0x0000006d,0x00040005,0x000000df,0x61726170,
+0x0000006d,0x00040005,0x000000e3,0x61726170,
+0x0000006d,0x00040005,0x000000e5,0x61726170,
+0x0000006d,0x00040005,0x000000e7,0x61726170,
+0x0000006d,0x00040005,0x000000ec,0x61726170,
+0x0000006d,0x00040005,0x000000ee,0x61726170,
+0x0000006d,0x00040005,0x000000f0,0x61726170,
+0x0000006d,0x00040005,0x000000f4,0x61726170,
+0x0000006d,0x00040005,0x000000f6,0x61726170,
+0x0000006d,0x00040005,0x000000f8,0x61726170,
+0x0000006d,0x00040005,0x000000fd,0x61726170,
+0x0000006d,0x00040005,0x000000ff,0x61726170,
+0x0000006d,0x00040005,0x00000101,0x61726170,
+0x0000006d,0x00050005,0x0000010c,0x67617246,
+0x6f6c6f43,0x00000072,0x00030047,0x0000000b,
+0x00000000,0x00030047,0x0000000a,0x00000000,
+0x00030047,0x0000000e,0x00000000,0x00030047,
+0x0000000d,0x00000000,0x00030047,0x00000011,
+0x00000000,0x00030047,0x00000010,0x00000000,
+0x00030047,0x00000018,0x00000000,0x00030047,
+0x00000015,0x00000000,0x00030047,0x00000016,
+0x00000000,0x00030047,0x00000017,0x00000000,
+0x00030047,0x0000001a,0x00000000,0x00030047,
+0x0000001e,0x00000000,0x00030047,0x0000001f,
+0x00000000,0x00030047,0x00000021,0x00000000,
+0x00030047,0x00000022,0x00000000,0x00030047,
+0x00000025,0x00000000,0x00030047,0x00000029,
+0x00000000,0x00030047,0x0000002b,0x00000000,
+0x00030047,0x0000002c,0x00000000,0x00030047,
+0x0000002f,0x00000000,0x00030047,0x00000031,
+0x00000000,0x00030047,0x00000032,0x00000000,
+0x00030047,0x00000033,0x00000000,0x00030047,
+0x00000034,0x00000000,0x00030047,0x00000036,
+0x00000000,0x00030047,0x00000037,0x00000000,
+0x00030047,0x0000003a,0x00000000,0x00030047,
+0x0000003b,0x00000000,0x00030047,0x0000003d,
+0x00000000,0x00030047,0x0000003e,0x00000000,
+0x00030047,0x00000040,0x00000000,0x00030047,
+0x00000043,0x00000000,0x00030047,0x00000045,
+0x00000000,0x00030047,0x00000046,0x00000000,
+0x00030047,0x00000047,0x00000000,0x00030047,
+0x00000048,0x00000000,0x00030047,0x00000049,
+0x00000000,0x00030047,0x0000004a,0x00000000,
+0x00030047,0x0000004b,0x00000000,0x00030047,
+0x0000004d,0x00000000,0x00030047,0x0000004e,
+0x00000000,0x00030047,0x0000004f,0x00000000,
+0x00030047,0x00000056,0x00000000,0x00030047,
+0x00000057,0x00000000,0x00030047,0x00000059,
+0x00000000,0x00030047,0x0000005a,0x00000000,
+0x00030047,0x0000005b,0x00000000,0x00030047,
+0x0000005c,0x00000000,0x00030047,0x0000005e,
+0x00000000,0x00030047,0x00000060,0x00000000,
+0x00030047,0x00000061,0x00000000,0x00030047,
+0x00000062,0x00000000,0x00030047,0x00000063,
+0x00000000,0x00030047,0x00000064,0x00000000,
+0x00030047,0x00000065,0x00000000,0x00030047,
+0x00000066,0x00000000,0x00030047,0x00000067,
+0x00000000,0x00030047,0x00000068,0x00000000,
+0x00030047,0x00000069,0x00000000,0x00030047,
+0x0000006a,0x00000000,0x00030047,0x0000006c,
+0x00000000,0x00030047,0x0000006d,0x00000000,
+0x00030047,0x00000071,0x00000000,0x00030047,
+0x00000073,0x00000000,0x00030047,0x00000074,
+0x00000000,0x00030047,0x00000076,0x00000000,
+0x00030047,0x00000077,0x00000000,0x00030047,
+0x00000078,0x00000000,0x00030047,0x00000079,
+0x00000000,0x00030047,0x0000007a,0x00000000,
+0x00030047,0x0000007b,0x00000000,0x00030047,
+0x0000007c,0x00000000,0x00030047,0x0000007e,
+0x00000000,0x00030047,0x0000007f,0x00000000,
+0x00030047,0x00000080,0x00000000,0x00030047,
+0x00000082,0x00000000,0x00030047,0x00000084,
+0x00000000,0x00030047,0x00000085,0x00000000,
+0x00030047,0x00000087,0x00000000,0x00030047,
+0x00000088,0x00000000,0x00030047,0x00000089,
+0x00000000,0x00030047,0x0000008c,0x00000000,
+0x00030047,0x0000008d,0x00000000,0x00030047,
+0x0000008e,0x00000000,0x00030047,0x0000008f,
+0x00000000,0x00030047,0x00000090,0x00000000,
+0x00030047,0x00000091,0x00000000,0x00030047,
+0x00000092,0x00000000,0x00030047,0x00000093,
+0x00000000,0x00030047,0x00000095,0x00000000,
+0x00030047,0x00000096,0x00000000,0x00030047,
+0x00000097,0x00000000,0x00030047,0x00000098,
+0x00000000,0x00030047,0x00000099,0x00000000,
+0x00030047,0x0000009c,0x00000000,0x00040048,
+0x0000009f,0x00000000,0x00000005,0x00040048,
+0x0000009f,0x00000000,0x00000000,0x00050048,
+0x0000009f,0x00000000,0x00000023,0x00000000,
+0x00050048,0x0000009f,0x00000000,0x00000007,
+0x00000010,0x00040048,0x0000009f,0x00000001,
+0x00000000,0x00050048,0x0000009f,0x00000001,
+0x00000023,0x00000040,0x00040048,0x0000009f,
+0x00000002,0x00000000,0x00050048,0x0000009f,
+0x00000002,0x00000023,0x00000048,0x00040048,
+0x0000009f,0x00000003,0x00000000,0x00050048,
+0x0000009f,0x00000003,0x00000023,0x0000004c,
+0x00030047,0x0000009f,0x00000002,0x00040047,
+0x000000a1,0x00000022,0x00000000,0x00040047,
+0x000000a1,0x00000021,0x00000000,0x00030047,
+0x000000a6,0x00000000,0x00030047,0x000000a8,
+0x00000000,0x00030047,0x000000aa,0x00000000,
+0x00030047,0x000000ab,0x00000000,0x00040047,
+0x000000ad,0x0000000b,0x0000000f,0x00030047,
+0x000000b3,0x00000000,0x00030047,0x000000b4,
+0x00000000,0x00030047,0x000000b7,0x00000000,
+0x00030047,0x000000b9,0x00000000,0x00030047,
+0x000000ba,0x00000000,0x00030047,0x000000bd,
+0x00000000,0x00030047,0x000000be,0x00000000,
+0x00030047,0x000000c0,0x00000000,0x00030047,
+0x000000c2,0x00000000,0x00030047,0x000000c4,
+0x00000000,0x00030047,0x000000c6,0x00000000,
+0x00030047,0x000000c7,0x00000000,0x00030047,
+0x000000c8,0x00000000,0x00030047,0x000000cb,
+0x00000000,0x00030047,0x000000cd,0x00000000,
+0x00030047,0x000000cf,0x00000000,0x00030047,
+0x000000d0,0x00000000,0x00030047,0x000000d1,
+0x00000000,0x00030047,0x000000d4,0x00000000,
+0x00030047,0x000000d6,0x00000000,0x00030047,
+0x000000d8,0x00000000,0x00030047,0x000000d9,
+0x00000000,0x00030047,0x000000da,0x00000000,
+0x00030047,0x000000dc,0x00000000,0x00030047,
+0x000000de,0x00000000,0x00030047,0x000000e0,
+0x00000000,0x00030047,0x000000e1,0x00000000,
+0x00030047,0x000000e2,0x00000000,0x00030047,
+0x000000e4,0x00000000,0x00030047,0x000000e6,
+0x00000000,0x00030047,0x000000e8,0x00000000,
+0x00030047,0x000000e9,0x00000000,0x00030047,
+0x000000ea,0x00000000,0x00030047,0x000000ed,
+0x00000000,0x00030047,0x000000ef,0x00000000,
+0x00030047,0x000000f1,0x00000000,0x00030047,
+0x000000f2,0x00000000,0x00030047,0x000000f3,
+0x00000000,0x00030047,0x000000f5,0x00000000,
+0x00030047,0x000000f7,0x00000000,0x00030047,
+0x000000f9,0x00000000,0x00030047,0x000000fa,
+0x00000000,0x00030047,0x000000fb,0x00000000,
+0x00030047,0x000000fe,0x00000000,0x00030047,
+0x00000100,0x00000000,0x00030047,0x00000102,
0x00000000,0x00030047,0x00000103,0x00000000,
0x00030047,0x00000104,0x00000000,0x00030047,
-0x00000106,0x00000000,0x00040047,0x00000106,
-0x0000001e,0x00000000,0x00030047,0x00000107,
+0x00000105,0x00000000,0x00030047,0x00000107,
0x00000000,0x00030047,0x00000108,0x00000000,
0x00030047,0x00000109,0x00000000,0x00030047,
-0x0000003f,0x00000000,0x00030047,0x000000a9,
-0x00000000,0x00020013,0x00000002,0x00030021,
-0x00000003,0x00000002,0x00030016,0x00000006,
-0x00000020,0x00040017,0x00000007,0x00000006,
-0x00000002,0x00040020,0x00000008,0x00000007,
-0x00000007,0x00040021,0x00000009,0x00000006,
-0x00000008,0x00040020,0x00000013,0x00000007,
-0x00000006,0x00060021,0x00000014,0x00000006,
-0x00000008,0x00000013,0x00000013,0x0004002b,
-0x00000006,0x0000001b,0x414fd639,0x0004002b,
-0x00000006,0x0000001c,0x429c774c,0x0005002c,
-0x00000007,0x0000001d,0x0000001b,0x0000001c,
-0x0004002b,0x00000006,0x00000020,0x472aee8c,
-0x00040015,0x00000026,0x00000020,0x00000000,
-0x0004002b,0x00000026,0x00000027,0x00000000,
-0x0004002b,0x00000026,0x0000002d,0x00000001,
-0x0004002b,0x00000006,0x00000035,0x42000000,
-0x0004002b,0x00000006,0x00000038,0x00000000,
-0x0004002b,0x00000006,0x00000039,0x3f800000,
-0x0004002b,0x00000006,0x0000003c,0x3fc90fdb,
-0x0004002b,0x00000006,0x0000003f,0x3f000000,
-0x0004002b,0x00000006,0x00000044,0x3d4ccccd,
-0x0004002b,0x00000006,0x00000050,0x3dcccccd,
-0x00020014,0x00000051,0x0004002b,0x00000006,
-0x00000058,0x40000000,0x0005002c,0x00000007,
-0x0000005d,0x00000058,0x00000058,0x0004002b,
-0x00000006,0x0000005f,0x3e800000,0x0004002b,
-0x00000006,0x00000072,0x3f99999a,0x0004002b,
-0x00000006,0x00000075,0x40490fd0,0x0004002b,
-0x00000006,0x0000007d,0x41000000,0x0004002b,
-0x00000006,0x00000081,0x40800000,0x0004002b,
-0x00000006,0x0000008a,0xbf000000,0x0005002c,
-0x00000007,0x0000008b,0x0000008a,0x00000039,
-0x00040017,0x0000009d,0x00000006,0x00000004,
-0x00040018,0x0000009e,0x0000009d,0x00000004,
-0x0005001e,0x0000009f,0x0000009e,0x00000007,
+0x0000010a,0x00000000,0x00030047,0x0000010c,
+0x00000000,0x00040047,0x0000010c,0x0000001e,
+0x00000000,0x00030047,0x0000010d,0x00000000,
+0x00030047,0x0000010e,0x00000000,0x00030047,
+0x0000010f,0x00000000,0x00030047,0x0000003f,
+0x00000000,0x00030047,0x000000a9,0x00000000,
+0x00020013,0x00000002,0x00030021,0x00000003,
+0x00000002,0x00030016,0x00000006,0x00000020,
+0x00040017,0x00000007,0x00000006,0x00000002,
+0x00040020,0x00000008,0x00000007,0x00000007,
+0x00040021,0x00000009,0x00000006,0x00000008,
+0x00040020,0x00000013,0x00000007,0x00000006,
+0x00060021,0x00000014,0x00000006,0x00000008,
+0x00000013,0x00000013,0x0004002b,0x00000006,
+0x0000001b,0x414fd639,0x0004002b,0x00000006,
+0x0000001c,0x429c774c,0x0005002c,0x00000007,
+0x0000001d,0x0000001b,0x0000001c,0x0004002b,
+0x00000006,0x00000020,0x472aee8c,0x00040015,
+0x00000026,0x00000020,0x00000000,0x0004002b,
+0x00000026,0x00000027,0x00000000,0x0004002b,
+0x00000026,0x0000002d,0x00000001,0x0004002b,
+0x00000006,0x00000035,0x42000000,0x0004002b,
+0x00000006,0x00000038,0x00000000,0x0004002b,
+0x00000006,0x00000039,0x3f800000,0x0004002b,
+0x00000006,0x0000003c,0x3fc90fdb,0x0004002b,
+0x00000006,0x0000003f,0x3f000000,0x0004002b,
+0x00000006,0x00000044,0x3d4ccccd,0x0004002b,
+0x00000006,0x00000050,0x3dcccccd,0x00020014,
+0x00000051,0x0004002b,0x00000006,0x00000058,
+0x40000000,0x0005002c,0x00000007,0x0000005d,
+0x00000058,0x00000058,0x0004002b,0x00000006,
+0x0000005f,0x3e800000,0x0004002b,0x00000006,
+0x00000072,0x3f99999a,0x0004002b,0x00000006,
+0x00000075,0x40490fd0,0x0004002b,0x00000006,
+0x0000007d,0x41000000,0x0004002b,0x00000006,
+0x00000081,0x40800000,0x0004002b,0x00000006,
+0x0000008a,0xbf000000,0x0005002c,0x00000007,
+0x0000008b,0x0000008a,0x00000039,0x00040017,
+0x0000009d,0x00000006,0x00000004,0x00040018,
+0x0000009e,0x0000009d,0x00000004,0x0006001e,
+0x0000009f,0x0000009e,0x00000007,0x00000006,
0x00000006,0x00040020,0x000000a0,0x00000002,
0x0000009f,0x0004003b,0x000000a0,0x000000a1,
0x00000002,0x00040015,0x000000a2,0x00000020,
@@ -242,42 +248,43 @@
0x0000009d,0x0004003b,0x000000ac,0x000000ad,
0x00000001,0x0004002b,0x000000a2,0x000000b0,
0x00000001,0x00040020,0x000000b1,0x00000002,
-0x00000007,0x0004002b,0x00000006,0x000000c3,
-0x3f333333,0x0004002b,0x00000006,0x000000cc,
-0x3f19999a,0x0004002b,0x00000006,0x000000e5,
-0x3e99999a,0x0004002b,0x00000006,0x000000f6,
-0x3e000000,0x00040020,0x00000105,0x00000003,
-0x0000009d,0x0004003b,0x00000105,0x00000106,
-0x00000003,0x0004002b,0x00000006,0x00000109,
+0x00000007,0x0004002b,0x000000a2,0x000000bb,
+0x00000003,0x0004002b,0x00000006,0x000000c9,
+0x3f333333,0x0004002b,0x00000006,0x000000d2,
+0x3f19999a,0x0004002b,0x00000006,0x000000eb,
+0x3e99999a,0x0004002b,0x00000006,0x000000fc,
+0x3e000000,0x00040020,0x0000010b,0x00000003,
+0x0000009d,0x0004003b,0x0000010b,0x0000010c,
+0x00000003,0x0004002b,0x00000006,0x0000010f,
0x3fa00000,0x00050036,0x00000002,0x00000004,
0x00000000,0x00000003,0x000200f8,0x00000005,
0x0004003b,0x00000013,0x0000009c,0x00000007,
0x0004003b,0x00000008,0x000000ab,0x00000007,
-0x0004003b,0x00000013,0x000000ba,0x00000007,
-0x0004003b,0x00000008,0x000000bb,0x00000007,
-0x0004003b,0x00000013,0x000000bd,0x00000007,
-0x0004003b,0x00000013,0x000000bf,0x00000007,
-0x0004003b,0x00000008,0x000000c4,0x00000007,
-0x0004003b,0x00000013,0x000000c6,0x00000007,
-0x0004003b,0x00000013,0x000000c8,0x00000007,
-0x0004003b,0x00000008,0x000000cd,0x00000007,
-0x0004003b,0x00000013,0x000000cf,0x00000007,
-0x0004003b,0x00000013,0x000000d1,0x00000007,
-0x0004003b,0x00000008,0x000000d5,0x00000007,
+0x0004003b,0x00000013,0x000000c0,0x00000007,
+0x0004003b,0x00000008,0x000000c1,0x00000007,
+0x0004003b,0x00000013,0x000000c3,0x00000007,
+0x0004003b,0x00000013,0x000000c5,0x00000007,
+0x0004003b,0x00000008,0x000000ca,0x00000007,
+0x0004003b,0x00000013,0x000000cc,0x00000007,
+0x0004003b,0x00000013,0x000000ce,0x00000007,
+0x0004003b,0x00000008,0x000000d3,0x00000007,
+0x0004003b,0x00000013,0x000000d5,0x00000007,
0x0004003b,0x00000013,0x000000d7,0x00000007,
-0x0004003b,0x00000013,0x000000d9,0x00000007,
-0x0004003b,0x00000008,0x000000dd,0x00000007,
+0x0004003b,0x00000008,0x000000db,0x00000007,
+0x0004003b,0x00000013,0x000000dd,0x00000007,
0x0004003b,0x00000013,0x000000df,0x00000007,
-0x0004003b,0x00000013,0x000000e1,0x00000007,
-0x0004003b,0x00000008,0x000000e6,0x00000007,
-0x0004003b,0x00000013,0x000000e8,0x00000007,
-0x0004003b,0x00000013,0x000000ea,0x00000007,
-0x0004003b,0x00000008,0x000000ee,0x00000007,
+0x0004003b,0x00000008,0x000000e3,0x00000007,
+0x0004003b,0x00000013,0x000000e5,0x00000007,
+0x0004003b,0x00000013,0x000000e7,0x00000007,
+0x0004003b,0x00000008,0x000000ec,0x00000007,
+0x0004003b,0x00000013,0x000000ee,0x00000007,
0x0004003b,0x00000013,0x000000f0,0x00000007,
-0x0004003b,0x00000013,0x000000f2,0x00000007,
-0x0004003b,0x00000008,0x000000f7,0x00000007,
-0x0004003b,0x00000013,0x000000f9,0x00000007,
-0x0004003b,0x00000013,0x000000fb,0x00000007,
+0x0004003b,0x00000008,0x000000f4,0x00000007,
+0x0004003b,0x00000013,0x000000f6,0x00000007,
+0x0004003b,0x00000013,0x000000f8,0x00000007,
+0x0004003b,0x00000008,0x000000fd,0x00000007,
+0x0004003b,0x00000013,0x000000ff,0x00000007,
+0x0004003b,0x00000013,0x00000101,0x00000007,
0x00050041,0x000000a4,0x000000a5,0x000000a1,
0x000000a3,0x0004003d,0x00000006,0x000000a6,
0x000000a5,0x00050085,0x00000006,0x000000a8,
@@ -294,231 +301,238 @@
0x000000af,0x000000b4,0x0003003e,0x000000ab,
0x000000b5,0x00050041,0x00000013,0x000000b6,
0x000000ab,0x0000002d,0x0004003d,0x00000006,
-0x000000b7,0x000000b6,0x00050083,0x00000006,
-0x000000b8,0x00000039,0x000000b7,0x00050041,
-0x00000013,0x000000b9,0x000000ab,0x0000002d,
-0x0003003e,0x000000b9,0x000000b8,0x0003003e,
-0x000000ba,0x00000038,0x0004003d,0x00000007,
-0x000000bc,0x000000ab,0x0003003e,0x000000bb,
-0x000000bc,0x0004003d,0x00000006,0x000000be,
-0x0000009c,0x0003003e,0x000000bd,0x000000be,
-0x0003003e,0x000000bf,0x00000039,0x00070039,
-0x00000006,0x000000c0,0x00000018,0x000000bb,
-0x000000bd,0x000000bf,0x0004003d,0x00000006,
-0x000000c1,0x000000ba,0x00050081,0x00000006,
-0x000000c2,0x000000c1,0x000000c0,0x0003003e,
-0x000000ba,0x000000c2,0x0004003d,0x00000007,
-0x000000c5,0x000000ab,0x0003003e,0x000000c4,
-0x000000c5,0x0004003d,0x00000006,0x000000c7,
-0x0000009c,0x0003003e,0x000000c6,0x000000c7,
-0x0003003e,0x000000c8,0x000000c3,0x00070039,
-0x00000006,0x000000c9,0x00000018,0x000000c4,
-0x000000c6,0x000000c8,0x0004003d,0x00000006,
-0x000000ca,0x000000ba,0x00050081,0x00000006,
-0x000000cb,0x000000ca,0x000000c9,0x0003003e,
-0x000000ba,0x000000cb,0x0004003d,0x00000007,
-0x000000ce,0x000000ab,0x0003003e,0x000000cd,
-0x000000ce,0x0004003d,0x00000006,0x000000d0,
-0x0000009c,0x0003003e,0x000000cf,0x000000d0,
-0x0003003e,0x000000d1,0x000000cc,0x00070039,
-0x00000006,0x000000d2,0x00000018,0x000000cd,
-0x000000cf,0x000000d1,0x0004003d,0x00000006,
-0x000000d3,0x000000ba,0x00050081,0x00000006,
-0x000000d4,0x000000d3,0x000000d2,0x0003003e,
-0x000000ba,0x000000d4,0x0004003d,0x00000007,
-0x000000d6,0x000000ab,0x0003003e,0x000000d5,
-0x000000d6,0x0004003d,0x00000006,0x000000d8,
-0x0000009c,0x0003003e,0x000000d7,0x000000d8,
-0x0003003e,0x000000d9,0x0000003f,0x00070039,
-0x00000006,0x000000da,0x00000018,0x000000d5,
-0x000000d7,0x000000d9,0x0004003d,0x00000006,
-0x000000db,0x000000ba,0x00050081,0x00000006,
-0x000000dc,0x000000db,0x000000da,0x0003003e,
-0x000000ba,0x000000dc,0x0004003d,0x00000007,
-0x000000de,0x000000ab,0x0003003e,0x000000dd,
-0x000000de,0x0004003d,0x00000006,0x000000e0,
-0x0000009c,0x0003003e,0x000000df,0x000000e0,
-0x0003003e,0x000000e1,0x000000a7,0x00070039,
-0x00000006,0x000000e2,0x00000018,0x000000dd,
-0x000000df,0x000000e1,0x0004003d,0x00000006,
-0x000000e3,0x000000ba,0x00050081,0x00000006,
-0x000000e4,0x000000e3,0x000000e2,0x0003003e,
-0x000000ba,0x000000e4,0x0004003d,0x00000007,
-0x000000e7,0x000000ab,0x0003003e,0x000000e6,
-0x000000e7,0x0004003d,0x00000006,0x000000e9,
-0x0000009c,0x0003003e,0x000000e8,0x000000e9,
-0x0003003e,0x000000ea,0x000000e5,0x00070039,
-0x00000006,0x000000eb,0x00000018,0x000000e6,
-0x000000e8,0x000000ea,0x0004003d,0x00000006,
-0x000000ec,0x000000ba,0x00050081,0x00000006,
-0x000000ed,0x000000ec,0x000000eb,0x0003003e,
-0x000000ba,0x000000ed,0x0004003d,0x00000007,
-0x000000ef,0x000000ab,0x0003003e,0x000000ee,
-0x000000ef,0x0004003d,0x00000006,0x000000f1,
-0x0000009c,0x0003003e,0x000000f0,0x000000f1,
-0x0003003e,0x000000f2,0x0000005f,0x00070039,
-0x00000006,0x000000f3,0x00000018,0x000000ee,
-0x000000f0,0x000000f2,0x0004003d,0x00000006,
-0x000000f4,0x000000ba,0x00050081,0x00000006,
-0x000000f5,0x000000f4,0x000000f3,0x0003003e,
-0x000000ba,0x000000f5,0x0004003d,0x00000007,
-0x000000f8,0x000000ab,0x0003003e,0x000000f7,
-0x000000f8,0x0004003d,0x00000006,0x000000fa,
-0x0000009c,0x0003003e,0x000000f9,0x000000fa,
-0x0003003e,0x000000fb,0x000000f6,0x00070039,
-0x00000006,0x000000fc,0x00000018,0x000000f7,
-0x000000f9,0x000000fb,0x0004003d,0x00000006,
-0x000000fd,0x000000ba,0x00050081,0x00000006,
-0x000000fe,0x000000fd,0x000000fc,0x0003003e,
-0x000000ba,0x000000fe,0x0004003d,0x00000006,
-0x000000ff,0x000000ba,0x00050041,0x00000013,
-0x00000100,0x000000ab,0x0000002d,0x0004003d,
-0x00000006,0x00000101,0x00000100,0x00050085,
-0x00000006,0x00000102,0x00000101,0x00000081,
-0x0007000c,0x00000006,0x00000103,0x00000001,
-0x00000025,0x00000102,0x00000039,0x00050085,
-0x00000006,0x00000104,0x000000ff,0x00000103,
-0x0003003e,0x000000ba,0x00000104,0x0004003d,
-0x00000006,0x00000107,0x000000ba,0x00070050,
-0x0000009d,0x00000108,0x00000039,0x00000039,
-0x00000039,0x00000107,0x0003003e,0x00000106,
-0x00000108,0x000100fd,0x00010038,0x00050036,
-0x00000006,0x0000000b,0x00000000,0x00000009,
-0x00030037,0x00000008,0x0000000a,0x000200f8,
-0x0000000c,0x0004003d,0x00000007,0x0000001a,
-0x0000000a,0x00050094,0x00000006,0x0000001e,
-0x0000001a,0x0000001d,0x0006000c,0x00000006,
-0x0000001f,0x00000001,0x0000000d,0x0000001e,
-0x00050085,0x00000006,0x00000021,0x0000001f,
-0x00000020,0x0006000c,0x00000006,0x00000022,
-0x00000001,0x0000000a,0x00000021,0x000200fe,
-0x00000022,0x00010038,0x00050036,0x00000006,
-0x0000000e,0x00000000,0x00000009,0x00030037,
-0x00000008,0x0000000d,0x000200f8,0x0000000f,
-0x0004003b,0x00000013,0x00000025,0x00000007,
-0x00050041,0x00000013,0x00000028,0x0000000d,
-0x00000027,0x0004003d,0x00000006,0x00000029,
-0x00000028,0x00050041,0x00000013,0x0000002a,
-0x0000000d,0x00000027,0x0004003d,0x00000006,
-0x0000002b,0x0000002a,0x00050085,0x00000006,
-0x0000002c,0x00000029,0x0000002b,0x00050041,
-0x00000013,0x0000002e,0x0000000d,0x0000002d,
-0x0004003d,0x00000006,0x0000002f,0x0000002e,
-0x00050041,0x00000013,0x00000030,0x0000000d,
-0x0000002d,0x0004003d,0x00000006,0x00000031,
-0x00000030,0x00050085,0x00000006,0x00000032,
-0x0000002f,0x00000031,0x00050081,0x00000006,
-0x00000033,0x0000002c,0x00000032,0x0006000c,
-0x00000006,0x00000034,0x00000001,0x0000001f,
-0x00000033,0x00050085,0x00000006,0x00000036,
-0x00000034,0x00000035,0x0003003e,0x00000025,
-0x00000036,0x0004003d,0x00000006,0x00000037,
-0x00000025,0x0008000c,0x00000006,0x0000003a,
-0x00000001,0x0000002b,0x00000037,0x00000038,
-0x00000039,0x0003003e,0x00000025,0x0000003a,
-0x0004003d,0x00000006,0x0000003b,0x00000025,
-0x00050085,0x00000006,0x0000003d,0x0000003b,
-0x0000003c,0x0006000c,0x00000006,0x0000003e,
-0x00000001,0x0000000e,0x0000003d,0x00050085,
-0x00000006,0x00000040,0x0000003e,0x0000003f,
-0x000200fe,0x00000040,0x00010038,0x00050036,
-0x00000006,0x00000011,0x00000000,0x00000009,
-0x00030037,0x00000008,0x00000010,0x000200f8,
-0x00000012,0x0004003b,0x00000013,0x00000043,
-0x00000007,0x0004003b,0x00000008,0x00000045,
-0x00000007,0x0004003b,0x00000013,0x0000004b,
-0x00000007,0x0004003b,0x00000008,0x0000004c,
-0x00000007,0x0004003b,0x00000008,0x00000056,
-0x00000007,0x0004003b,0x00000008,0x00000061,
-0x00000007,0x0004003b,0x00000008,0x00000067,
-0x00000007,0x0004003b,0x00000008,0x0000006b,
-0x00000007,0x0003003e,0x00000043,0x00000044,
-0x0004003d,0x00000007,0x00000046,0x00000010,
-0x0004003d,0x00000006,0x00000047,0x00000043,
-0x00050050,0x00000007,0x00000048,0x00000047,
-0x00000047,0x00050088,0x00000007,0x00000049,
-0x00000046,0x00000048,0x0006000c,0x00000007,
-0x0000004a,0x00000001,0x00000008,0x00000049,
-0x0003003e,0x00000045,0x0000004a,0x0004003d,
-0x00000007,0x0000004d,0x00000045,0x0003003e,
-0x0000004c,0x0000004d,0x00050039,0x00000006,
-0x0000004e,0x0000000b,0x0000004c,0x0003003e,
-0x0000004b,0x0000004e,0x0004003d,0x00000006,
-0x0000004f,0x0000004b,0x000500ba,0x00000051,
-0x00000052,0x0000004f,0x00000050,0x000300f7,
-0x00000054,0x00000000,0x000400fa,0x00000052,
-0x00000053,0x00000054,0x000200f8,0x00000053,
-0x000200fe,0x00000038,0x000200f8,0x00000054,
-0x0004003d,0x00000006,0x00000057,0x0000004b,
-0x00050085,0x00000006,0x00000059,0x00000057,
-0x00000058,0x0006000c,0x00000006,0x0000005a,
-0x00000001,0x0000000a,0x00000059,0x0004003d,
-0x00000006,0x0000005b,0x0000004b,0x00050050,
-0x00000007,0x0000005c,0x0000005a,0x0000005b,
-0x00050081,0x00000007,0x0000005e,0x0000005c,
-0x0000005d,0x0005008e,0x00000007,0x00000060,
-0x0000005e,0x0000005f,0x0003003e,0x00000056,
-0x00000060,0x0004003d,0x00000007,0x00000062,
-0x00000010,0x0004003d,0x00000006,0x00000063,
-0x00000043,0x00050050,0x00000007,0x00000064,
-0x00000063,0x00000063,0x00050088,0x00000007,
-0x00000065,0x00000062,0x00000064,0x0006000c,
-0x00000007,0x00000066,0x00000001,0x0000000a,
-0x00000065,0x0003003e,0x00000061,0x00000066,
-0x0004003d,0x00000007,0x00000068,0x00000061,
-0x0004003d,0x00000007,0x00000069,0x00000056,
-0x00050083,0x00000007,0x0000006a,0x00000068,
-0x00000069,0x0003003e,0x00000067,0x0000006a,
-0x0004003d,0x00000007,0x0000006c,0x00000067,
-0x0003003e,0x0000006b,0x0000006c,0x00050039,
-0x00000006,0x0000006d,0x0000000e,0x0000006b,
-0x000200fe,0x0000006d,0x00010038,0x00050036,
-0x00000006,0x00000018,0x00000000,0x00000014,
-0x00030037,0x00000008,0x00000015,0x00030037,
-0x00000013,0x00000016,0x00030037,0x00000013,
-0x00000017,0x000200f8,0x00000019,0x0004003b,
-0x00000008,0x00000094,0x00000007,0x00050041,
-0x00000013,0x00000070,0x00000015,0x0000002d,
-0x0004003d,0x00000006,0x00000071,0x00000070,
-0x00050085,0x00000006,0x00000073,0x00000071,
-0x00000072,0x0004003d,0x00000006,0x00000074,
-0x00000016,0x00050085,0x00000006,0x00000076,
-0x00000074,0x00000075,0x00050085,0x00000006,
-0x00000077,0x00000076,0x00000058,0x00050081,
-0x00000006,0x00000078,0x00000073,0x00000077,
-0x0004003d,0x00000006,0x00000079,0x00000017,
-0x00050088,0x00000006,0x0000007a,0x00000039,
-0x00000079,0x00050081,0x00000006,0x0000007b,
-0x00000078,0x0000007a,0x0006000c,0x00000006,
-0x0000007c,0x00000001,0x0000000e,0x0000007b,
-0x0004003d,0x00000006,0x0000007e,0x00000017,
-0x00050088,0x00000006,0x0000007f,0x0000007d,
-0x0000007e,0x00050088,0x00000006,0x00000080,
-0x0000007c,0x0000007f,0x00050085,0x00000006,
-0x00000082,0x00000080,0x00000081,0x00050041,
-0x00000013,0x00000083,0x00000015,0x00000027,
-0x0004003d,0x00000006,0x00000084,0x00000083,
-0x00050081,0x00000006,0x00000085,0x00000084,
-0x00000082,0x00050041,0x00000013,0x00000086,
-0x00000015,0x00000027,0x0003003e,0x00000086,
-0x00000085,0x0004003d,0x00000006,0x00000087,
-0x00000016,0x0004003d,0x00000006,0x00000088,
-0x00000017,0x00050085,0x00000006,0x00000089,
-0x00000087,0x00000088,0x0005008e,0x00000007,
-0x0000008c,0x0000008b,0x00000089,0x0005008e,
-0x00000007,0x0000008d,0x0000008c,0x00000081,
-0x0004003d,0x00000007,0x0000008e,0x00000015,
-0x00050081,0x00000007,0x0000008f,0x0000008e,
-0x0000008d,0x0003003e,0x00000015,0x0000008f,
-0x0004003d,0x00000007,0x00000090,0x00000015,
-0x0004003d,0x00000006,0x00000091,0x00000017,
-0x00050050,0x00000007,0x00000092,0x00000091,
-0x00000091,0x00050088,0x00000007,0x00000093,
-0x00000090,0x00000092,0x0003003e,0x00000094,
-0x00000093,0x00050039,0x00000006,0x00000095,
-0x00000011,0x00000094,0x0004003d,0x00000006,
-0x00000096,0x00000017,0x00050085,0x00000006,
-0x00000097,0x00000096,0x0000003f,0x00050081,
-0x00000006,0x00000098,0x00000097,0x0000003f,
-0x00050085,0x00000006,0x00000099,0x00000095,
-0x00000098,0x000200fe,0x00000099,0x00010038}
+0x000000b7,0x000000b6,0x00050041,0x00000013,
+0x000000b8,0x000000ab,0x0000002d,0x0004003d,
+0x00000006,0x000000b9,0x000000b8,0x00050083,
+0x00000006,0x000000ba,0x00000039,0x000000b9,
+0x00050041,0x000000a4,0x000000bc,0x000000a1,
+0x000000bb,0x0004003d,0x00000006,0x000000bd,
+0x000000bc,0x0008000c,0x00000006,0x000000be,
+0x00000001,0x0000002e,0x000000b7,0x000000ba,
+0x000000bd,0x00050041,0x00000013,0x000000bf,
+0x000000ab,0x0000002d,0x0003003e,0x000000bf,
+0x000000be,0x0003003e,0x000000c0,0x00000038,
+0x0004003d,0x00000007,0x000000c2,0x000000ab,
+0x0003003e,0x000000c1,0x000000c2,0x0004003d,
+0x00000006,0x000000c4,0x0000009c,0x0003003e,
+0x000000c3,0x000000c4,0x0003003e,0x000000c5,
+0x00000039,0x00070039,0x00000006,0x000000c6,
+0x00000018,0x000000c1,0x000000c3,0x000000c5,
+0x0004003d,0x00000006,0x000000c7,0x000000c0,
+0x00050081,0x00000006,0x000000c8,0x000000c7,
+0x000000c6,0x0003003e,0x000000c0,0x000000c8,
+0x0004003d,0x00000007,0x000000cb,0x000000ab,
+0x0003003e,0x000000ca,0x000000cb,0x0004003d,
+0x00000006,0x000000cd,0x0000009c,0x0003003e,
+0x000000cc,0x000000cd,0x0003003e,0x000000ce,
+0x000000c9,0x00070039,0x00000006,0x000000cf,
+0x00000018,0x000000ca,0x000000cc,0x000000ce,
+0x0004003d,0x00000006,0x000000d0,0x000000c0,
+0x00050081,0x00000006,0x000000d1,0x000000d0,
+0x000000cf,0x0003003e,0x000000c0,0x000000d1,
+0x0004003d,0x00000007,0x000000d4,0x000000ab,
+0x0003003e,0x000000d3,0x000000d4,0x0004003d,
+0x00000006,0x000000d6,0x0000009c,0x0003003e,
+0x000000d5,0x000000d6,0x0003003e,0x000000d7,
+0x000000d2,0x00070039,0x00000006,0x000000d8,
+0x00000018,0x000000d3,0x000000d5,0x000000d7,
+0x0004003d,0x00000006,0x000000d9,0x000000c0,
+0x00050081,0x00000006,0x000000da,0x000000d9,
+0x000000d8,0x0003003e,0x000000c0,0x000000da,
+0x0004003d,0x00000007,0x000000dc,0x000000ab,
+0x0003003e,0x000000db,0x000000dc,0x0004003d,
+0x00000006,0x000000de,0x0000009c,0x0003003e,
+0x000000dd,0x000000de,0x0003003e,0x000000df,
+0x0000003f,0x00070039,0x00000006,0x000000e0,
+0x00000018,0x000000db,0x000000dd,0x000000df,
+0x0004003d,0x00000006,0x000000e1,0x000000c0,
+0x00050081,0x00000006,0x000000e2,0x000000e1,
+0x000000e0,0x0003003e,0x000000c0,0x000000e2,
+0x0004003d,0x00000007,0x000000e4,0x000000ab,
+0x0003003e,0x000000e3,0x000000e4,0x0004003d,
+0x00000006,0x000000e6,0x0000009c,0x0003003e,
+0x000000e5,0x000000e6,0x0003003e,0x000000e7,
+0x000000a7,0x00070039,0x00000006,0x000000e8,
+0x00000018,0x000000e3,0x000000e5,0x000000e7,
+0x0004003d,0x00000006,0x000000e9,0x000000c0,
+0x00050081,0x00000006,0x000000ea,0x000000e9,
+0x000000e8,0x0003003e,0x000000c0,0x000000ea,
+0x0004003d,0x00000007,0x000000ed,0x000000ab,
+0x0003003e,0x000000ec,0x000000ed,0x0004003d,
+0x00000006,0x000000ef,0x0000009c,0x0003003e,
+0x000000ee,0x000000ef,0x0003003e,0x000000f0,
+0x000000eb,0x00070039,0x00000006,0x000000f1,
+0x00000018,0x000000ec,0x000000ee,0x000000f0,
+0x0004003d,0x00000006,0x000000f2,0x000000c0,
+0x00050081,0x00000006,0x000000f3,0x000000f2,
+0x000000f1,0x0003003e,0x000000c0,0x000000f3,
+0x0004003d,0x00000007,0x000000f5,0x000000ab,
+0x0003003e,0x000000f4,0x000000f5,0x0004003d,
+0x00000006,0x000000f7,0x0000009c,0x0003003e,
+0x000000f6,0x000000f7,0x0003003e,0x000000f8,
+0x0000005f,0x00070039,0x00000006,0x000000f9,
+0x00000018,0x000000f4,0x000000f6,0x000000f8,
+0x0004003d,0x00000006,0x000000fa,0x000000c0,
+0x00050081,0x00000006,0x000000fb,0x000000fa,
+0x000000f9,0x0003003e,0x000000c0,0x000000fb,
+0x0004003d,0x00000007,0x000000fe,0x000000ab,
+0x0003003e,0x000000fd,0x000000fe,0x0004003d,
+0x00000006,0x00000100,0x0000009c,0x0003003e,
+0x000000ff,0x00000100,0x0003003e,0x00000101,
+0x000000fc,0x00070039,0x00000006,0x00000102,
+0x00000018,0x000000fd,0x000000ff,0x00000101,
+0x0004003d,0x00000006,0x00000103,0x000000c0,
+0x00050081,0x00000006,0x00000104,0x00000103,
+0x00000102,0x0003003e,0x000000c0,0x00000104,
+0x0004003d,0x00000006,0x00000105,0x000000c0,
+0x00050041,0x00000013,0x00000106,0x000000ab,
+0x0000002d,0x0004003d,0x00000006,0x00000107,
+0x00000106,0x00050085,0x00000006,0x00000108,
+0x00000107,0x00000081,0x0007000c,0x00000006,
+0x00000109,0x00000001,0x00000025,0x00000108,
+0x00000039,0x00050085,0x00000006,0x0000010a,
+0x00000105,0x00000109,0x0003003e,0x000000c0,
+0x0000010a,0x0004003d,0x00000006,0x0000010d,
+0x000000c0,0x00070050,0x0000009d,0x0000010e,
+0x00000039,0x00000039,0x00000039,0x0000010d,
+0x0003003e,0x0000010c,0x0000010e,0x000100fd,
+0x00010038,0x00050036,0x00000006,0x0000000b,
+0x00000000,0x00000009,0x00030037,0x00000008,
+0x0000000a,0x000200f8,0x0000000c,0x0004003d,
+0x00000007,0x0000001a,0x0000000a,0x00050094,
+0x00000006,0x0000001e,0x0000001a,0x0000001d,
+0x0006000c,0x00000006,0x0000001f,0x00000001,
+0x0000000d,0x0000001e,0x00050085,0x00000006,
+0x00000021,0x0000001f,0x00000020,0x0006000c,
+0x00000006,0x00000022,0x00000001,0x0000000a,
+0x00000021,0x000200fe,0x00000022,0x00010038,
+0x00050036,0x00000006,0x0000000e,0x00000000,
+0x00000009,0x00030037,0x00000008,0x0000000d,
+0x000200f8,0x0000000f,0x0004003b,0x00000013,
+0x00000025,0x00000007,0x00050041,0x00000013,
+0x00000028,0x0000000d,0x00000027,0x0004003d,
+0x00000006,0x00000029,0x00000028,0x00050041,
+0x00000013,0x0000002a,0x0000000d,0x00000027,
+0x0004003d,0x00000006,0x0000002b,0x0000002a,
+0x00050085,0x00000006,0x0000002c,0x00000029,
+0x0000002b,0x00050041,0x00000013,0x0000002e,
+0x0000000d,0x0000002d,0x0004003d,0x00000006,
+0x0000002f,0x0000002e,0x00050041,0x00000013,
+0x00000030,0x0000000d,0x0000002d,0x0004003d,
+0x00000006,0x00000031,0x00000030,0x00050085,
+0x00000006,0x00000032,0x0000002f,0x00000031,
+0x00050081,0x00000006,0x00000033,0x0000002c,
+0x00000032,0x0006000c,0x00000006,0x00000034,
+0x00000001,0x0000001f,0x00000033,0x00050085,
+0x00000006,0x00000036,0x00000034,0x00000035,
+0x0003003e,0x00000025,0x00000036,0x0004003d,
+0x00000006,0x00000037,0x00000025,0x0008000c,
+0x00000006,0x0000003a,0x00000001,0x0000002b,
+0x00000037,0x00000038,0x00000039,0x0003003e,
+0x00000025,0x0000003a,0x0004003d,0x00000006,
+0x0000003b,0x00000025,0x00050085,0x00000006,
+0x0000003d,0x0000003b,0x0000003c,0x0006000c,
+0x00000006,0x0000003e,0x00000001,0x0000000e,
+0x0000003d,0x00050085,0x00000006,0x00000040,
+0x0000003e,0x0000003f,0x000200fe,0x00000040,
+0x00010038,0x00050036,0x00000006,0x00000011,
+0x00000000,0x00000009,0x00030037,0x00000008,
+0x00000010,0x000200f8,0x00000012,0x0004003b,
+0x00000013,0x00000043,0x00000007,0x0004003b,
+0x00000008,0x00000045,0x00000007,0x0004003b,
+0x00000013,0x0000004b,0x00000007,0x0004003b,
+0x00000008,0x0000004c,0x00000007,0x0004003b,
+0x00000008,0x00000056,0x00000007,0x0004003b,
+0x00000008,0x00000061,0x00000007,0x0004003b,
+0x00000008,0x00000067,0x00000007,0x0004003b,
+0x00000008,0x0000006b,0x00000007,0x0003003e,
+0x00000043,0x00000044,0x0004003d,0x00000007,
+0x00000046,0x00000010,0x0004003d,0x00000006,
+0x00000047,0x00000043,0x00050050,0x00000007,
+0x00000048,0x00000047,0x00000047,0x00050088,
+0x00000007,0x00000049,0x00000046,0x00000048,
+0x0006000c,0x00000007,0x0000004a,0x00000001,
+0x00000008,0x00000049,0x0003003e,0x00000045,
+0x0000004a,0x0004003d,0x00000007,0x0000004d,
+0x00000045,0x0003003e,0x0000004c,0x0000004d,
+0x00050039,0x00000006,0x0000004e,0x0000000b,
+0x0000004c,0x0003003e,0x0000004b,0x0000004e,
+0x0004003d,0x00000006,0x0000004f,0x0000004b,
+0x000500ba,0x00000051,0x00000052,0x0000004f,
+0x00000050,0x000300f7,0x00000054,0x00000000,
+0x000400fa,0x00000052,0x00000053,0x00000054,
+0x000200f8,0x00000053,0x000200fe,0x00000038,
+0x000200f8,0x00000054,0x0004003d,0x00000006,
+0x00000057,0x0000004b,0x00050085,0x00000006,
+0x00000059,0x00000057,0x00000058,0x0006000c,
+0x00000006,0x0000005a,0x00000001,0x0000000a,
+0x00000059,0x0004003d,0x00000006,0x0000005b,
+0x0000004b,0x00050050,0x00000007,0x0000005c,
+0x0000005a,0x0000005b,0x00050081,0x00000007,
+0x0000005e,0x0000005c,0x0000005d,0x0005008e,
+0x00000007,0x00000060,0x0000005e,0x0000005f,
+0x0003003e,0x00000056,0x00000060,0x0004003d,
+0x00000007,0x00000062,0x00000010,0x0004003d,
+0x00000006,0x00000063,0x00000043,0x00050050,
+0x00000007,0x00000064,0x00000063,0x00000063,
+0x00050088,0x00000007,0x00000065,0x00000062,
+0x00000064,0x0006000c,0x00000007,0x00000066,
+0x00000001,0x0000000a,0x00000065,0x0003003e,
+0x00000061,0x00000066,0x0004003d,0x00000007,
+0x00000068,0x00000061,0x0004003d,0x00000007,
+0x00000069,0x00000056,0x00050083,0x00000007,
+0x0000006a,0x00000068,0x00000069,0x0003003e,
+0x00000067,0x0000006a,0x0004003d,0x00000007,
+0x0000006c,0x00000067,0x0003003e,0x0000006b,
+0x0000006c,0x00050039,0x00000006,0x0000006d,
+0x0000000e,0x0000006b,0x000200fe,0x0000006d,
+0x00010038,0x00050036,0x00000006,0x00000018,
+0x00000000,0x00000014,0x00030037,0x00000008,
+0x00000015,0x00030037,0x00000013,0x00000016,
+0x00030037,0x00000013,0x00000017,0x000200f8,
+0x00000019,0x0004003b,0x00000008,0x00000094,
+0x00000007,0x00050041,0x00000013,0x00000070,
+0x00000015,0x0000002d,0x0004003d,0x00000006,
+0x00000071,0x00000070,0x00050085,0x00000006,
+0x00000073,0x00000071,0x00000072,0x0004003d,
+0x00000006,0x00000074,0x00000016,0x00050085,
+0x00000006,0x00000076,0x00000074,0x00000075,
+0x00050085,0x00000006,0x00000077,0x00000076,
+0x00000058,0x00050081,0x00000006,0x00000078,
+0x00000073,0x00000077,0x0004003d,0x00000006,
+0x00000079,0x00000017,0x00050088,0x00000006,
+0x0000007a,0x00000039,0x00000079,0x00050081,
+0x00000006,0x0000007b,0x00000078,0x0000007a,
+0x0006000c,0x00000006,0x0000007c,0x00000001,
+0x0000000e,0x0000007b,0x0004003d,0x00000006,
+0x0000007e,0x00000017,0x00050088,0x00000006,
+0x0000007f,0x0000007d,0x0000007e,0x00050088,
+0x00000006,0x00000080,0x0000007c,0x0000007f,
+0x00050085,0x00000006,0x00000082,0x00000080,
+0x00000081,0x00050041,0x00000013,0x00000083,
+0x00000015,0x00000027,0x0004003d,0x00000006,
+0x00000084,0x00000083,0x00050081,0x00000006,
+0x00000085,0x00000084,0x00000082,0x00050041,
+0x00000013,0x00000086,0x00000015,0x00000027,
+0x0003003e,0x00000086,0x00000085,0x0004003d,
+0x00000006,0x00000087,0x00000016,0x0004003d,
+0x00000006,0x00000088,0x00000017,0x00050085,
+0x00000006,0x00000089,0x00000087,0x00000088,
+0x0005008e,0x00000007,0x0000008c,0x0000008b,
+0x00000089,0x0005008e,0x00000007,0x0000008d,
+0x0000008c,0x00000081,0x0004003d,0x00000007,
+0x0000008e,0x00000015,0x00050081,0x00000007,
+0x0000008f,0x0000008e,0x0000008d,0x0003003e,
+0x00000015,0x0000008f,0x0004003d,0x00000007,
+0x00000090,0x00000015,0x0004003d,0x00000006,
+0x00000091,0x00000017,0x00050050,0x00000007,
+0x00000092,0x00000091,0x00000091,0x00050088,
+0x00000007,0x00000093,0x00000090,0x00000092,
+0x0003003e,0x00000094,0x00000093,0x00050039,
+0x00000006,0x00000095,0x00000011,0x00000094,
+0x0004003d,0x00000006,0x00000096,0x00000017,
+0x00050085,0x00000006,0x00000097,0x00000096,
+0x0000003f,0x00050081,0x00000006,0x00000098,
+0x00000097,0x0000003f,0x00050085,0x00000006,
+0x00000099,0x00000095,0x00000098,0x000200fe,
+0x00000099,0x00010038}
diff --git a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.vert.inc b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.vert.inc
index 64fe4a3ae2..3a9edfc3b9 100644
--- a/gfx/drivers/vulkan_shaders/pipeline_snow_simple.vert.inc
+++ b/gfx/drivers/vulkan_shaders/pipeline_snow_simple.vert.inc
@@ -1,4 +1,4 @@
-{0x07230203,0x00010000,0x00080001,0x00000025,
+{0x07230203,0x00010000,0x000d0007,0x00000025,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
diff --git a/gfx/drivers_font/gl_core_raster_font.c b/gfx/drivers_font/gl_core_raster_font.c
new file mode 100644
index 0000000000..28ad8c27c1
--- /dev/null
+++ b/gfx/drivers_font/gl_core_raster_font.c
@@ -0,0 +1,492 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ * Copyright (C) 2016-2019 - Brad Parker
+ *
+ * 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 .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include "../common/gl_core_common.h"
+#include "../font_driver.h"
+#include "../video_driver.h"
+#include "../../verbosity.h"
+
+/* TODO: Move viewport side effects to the caller: it's a source of bugs. */
+
+#define gl_core_raster_font_emit(c, vx, vy) do { \
+ font_vertex[ 2 * (6 * i + c) + 0] = (x + (delta_x + off_x + vx * width) * scale) * inv_win_width; \
+ font_vertex[ 2 * (6 * i + c) + 1] = (y + (delta_y - off_y - vy * height) * scale) * inv_win_height; \
+ font_tex_coords[ 2 * (6 * i + c) + 0] = (tex_x + vx * width) * inv_tex_size_x; \
+ font_tex_coords[ 2 * (6 * i + c) + 1] = (tex_y + vy * height) * inv_tex_size_y; \
+ font_color[ 4 * (6 * i + c) + 0] = color[0]; \
+ font_color[ 4 * (6 * i + c) + 1] = color[1]; \
+ font_color[ 4 * (6 * i + c) + 2] = color[2]; \
+ font_color[ 4 * (6 * i + c) + 3] = color[3]; \
+} while(0)
+
+#define MAX_MSG_LEN_CHUNK 64
+
+typedef struct
+{
+ gl_core_t *gl;
+ GLuint tex;
+
+ const font_renderer_driver_t *font_driver;
+ void *font_data;
+ struct font_atlas *atlas;
+
+ video_font_raster_block_t *block;
+} gl_core_raster_t;
+
+static void gl_core_raster_font_free_font(void *data,
+ bool is_threaded)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+ if (!font)
+ return;
+
+ if (font->font_driver && font->font_data)
+ font->font_driver->free(font->font_data);
+
+ if (is_threaded)
+ video_context_driver_make_current(true);
+
+ glDeleteTextures(1, &font->tex);
+
+ free(font);
+}
+
+static bool gl_core_raster_font_upload_atlas(gl_core_raster_t *font)
+{
+ if (font->tex)
+ glDeleteTextures(1, &font->tex);
+ glGenTextures(1, &font->tex);
+ glBindTexture(GL_TEXTURE_2D, font->tex);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, font->atlas->width, font->atlas->height);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ font->atlas->width, font->atlas->height, GL_RED, GL_UNSIGNED_BYTE, font->atlas->buffer);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+static void *gl_core_raster_font_init_font(void *data,
+ const char *font_path, float font_size,
+ bool is_threaded)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)calloc(1, sizeof(*font));
+
+ if (!font)
+ return NULL;
+
+ font->gl = (gl_core_t*)data;
+
+ if (!font_renderer_create_default(
+ &font->font_driver,
+ &font->font_data, font_path, font_size))
+ {
+ RARCH_WARN("Couldn't initialize font renderer.\n");
+ free(font);
+ return NULL;
+ }
+
+ if (is_threaded)
+ video_context_driver_make_current(false);
+
+ font->atlas = font->font_driver->get_atlas(font->font_data);
+
+ if (!gl_core_raster_font_upload_atlas(font))
+ goto error;
+
+ font->atlas->dirty = false;
+ return font;
+
+error:
+ gl_core_raster_font_free_font(font, is_threaded);
+ return NULL;
+}
+
+static int gl_core_get_message_width(void *data, const char *msg,
+ unsigned msg_len, float scale)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+ const char* msg_end = msg + msg_len;
+ int delta_x = 0;
+
+ if ( !font
+ || !font->font_driver
+ || !font->font_driver->get_glyph
+ || !font->font_data )
+ return 0;
+
+ while (msg < msg_end)
+ {
+ unsigned code = utf8_walk(&msg);
+ const struct font_glyph *glyph = font->font_driver->get_glyph(
+ font->font_data, code);
+
+ if (!glyph) /* Do something smarter here ... */
+ glyph = font->font_driver->get_glyph(font->font_data, '?');
+ if (!glyph)
+ continue;
+
+ delta_x += glyph->advance_x;
+ }
+
+ return delta_x * scale;
+}
+
+static void gl_core_raster_font_draw_vertices(gl_core_raster_t *font,
+ const video_coords_t *coords,
+ video_frame_info_t *video_info)
+{
+ if (font->atlas->dirty)
+ {
+ gl_core_raster_font_upload_atlas(font);
+ font->atlas->dirty = false;
+ }
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, font->tex);
+
+ if (font->gl->pipelines.font_loc.flat_ubo_vertex >= 0)
+ {
+ glUniform4fv(font->gl->pipelines.font_loc.flat_ubo_vertex,
+ 4, font->gl->mvp_no_rot.data);
+ }
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
+
+ gl_core_bind_scratch_vbo(font->gl, coords->vertex, 2 * sizeof(float) * coords->vertices);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0);
+
+ gl_core_bind_scratch_vbo(font->gl, coords->tex_coord, 2 * sizeof(float) * coords->vertices);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)(uintptr_t)0);
+
+ gl_core_bind_scratch_vbo(font->gl, coords->color, 4 * sizeof(float) * coords->vertices);
+ glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(uintptr_t)0);
+
+ glDrawArrays(GL_TRIANGLES, 0, coords->vertices);
+
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(2);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+static void gl_core_raster_font_render_line(
+ gl_core_raster_t *font, const char *msg, unsigned msg_len,
+ GLfloat scale, const GLfloat color[4], GLfloat pos_x,
+ GLfloat pos_y, unsigned text_align,
+ video_frame_info_t *video_info)
+{
+ unsigned i;
+ struct video_coords coords;
+ GLfloat font_tex_coords[2 * 6 * MAX_MSG_LEN_CHUNK];
+ GLfloat font_vertex[2 * 6 * MAX_MSG_LEN_CHUNK];
+ GLfloat font_color[4 * 6 * MAX_MSG_LEN_CHUNK];
+ gl_core_t *gl = font->gl;
+ const char* msg_end = msg + msg_len;
+ int x = roundf(pos_x * gl->vp.width);
+ int y = roundf(pos_y * gl->vp.height);
+ int delta_x = 0;
+ int delta_y = 0;
+ float inv_tex_size_x = 1.0f / font->atlas->width;
+ float inv_tex_size_y = 1.0f / font->atlas->height;
+ float inv_win_width = 1.0f / font->gl->vp.width;
+ float inv_win_height = 1.0f / font->gl->vp.height;
+
+ switch (text_align)
+ {
+ case TEXT_ALIGN_RIGHT:
+ x -= gl_core_get_message_width(font, msg, msg_len, scale);
+ break;
+ case TEXT_ALIGN_CENTER:
+ x -= gl_core_get_message_width(font, msg, msg_len, scale) / 2.0;
+ break;
+ }
+
+ while (msg < msg_end)
+ {
+ i = 0;
+ while ((i < MAX_MSG_LEN_CHUNK) && (msg < msg_end))
+ {
+ int off_x, off_y, tex_x, tex_y, width, height;
+ unsigned code = utf8_walk(&msg);
+ const struct font_glyph *glyph = font->font_driver->get_glyph(
+ font->font_data, code);
+
+ if (!glyph) /* Do something smarter here ... */
+ glyph = font->font_driver->get_glyph(font->font_data, '?');
+
+ if (!glyph)
+ continue;
+
+ off_x = glyph->draw_offset_x;
+ off_y = glyph->draw_offset_y;
+ tex_x = glyph->atlas_offset_x;
+ tex_y = glyph->atlas_offset_y;
+ width = glyph->width;
+ height = glyph->height;
+
+ gl_core_raster_font_emit(0, 0, 1); /* Bottom-left */
+ gl_core_raster_font_emit(1, 1, 1); /* Bottom-right */
+ gl_core_raster_font_emit(2, 0, 0); /* Top-left */
+
+ gl_core_raster_font_emit(3, 1, 0); /* Top-right */
+ gl_core_raster_font_emit(4, 0, 0); /* Top-left */
+ gl_core_raster_font_emit(5, 1, 1); /* Bottom-right */
+
+ i++;
+
+ delta_x += glyph->advance_x;
+ delta_y -= glyph->advance_y;
+ }
+
+ coords.tex_coord = font_tex_coords;
+ coords.vertex = font_vertex;
+ coords.color = font_color;
+ coords.vertices = i * 6;
+ coords.lut_tex_coord = font_tex_coords;
+
+ if (font->block)
+ video_coord_array_append(&font->block->carr, &coords, coords.vertices);
+ else
+ gl_core_raster_font_draw_vertices(font, &coords, video_info);
+ }
+}
+
+static void gl_core_raster_font_render_message(
+ gl_core_raster_t *font, const char *msg, GLfloat scale,
+ const GLfloat color[4], GLfloat pos_x, GLfloat pos_y,
+ unsigned text_align,
+ video_frame_info_t *video_info)
+{
+ float line_height;
+ int lines = 0;
+
+ /* If the font height is not supported just draw as usual */
+ if (!font->font_driver->get_line_height)
+ {
+ gl_core_raster_font_render_line(font,
+ msg, (unsigned)strlen(msg), scale, color, pos_x,
+ pos_y, text_align,
+ video_info);
+ return;
+ }
+
+ line_height = (float) font->font_driver->get_line_height(font->font_data) *
+ scale / font->gl->vp.height;
+
+ for (;;)
+ {
+ const char *delim = strchr(msg, '\n');
+ unsigned msg_len = delim
+ ? (unsigned)(delim - msg) : (unsigned)strlen(msg);
+
+ /* Draw the line */
+ gl_core_raster_font_render_line(font,
+ msg, msg_len, scale, color, pos_x,
+ pos_y - (float)lines*line_height, text_align,
+ video_info);
+
+ if (!delim)
+ break;
+
+ msg += msg_len + 1;
+ lines++;
+ }
+}
+
+static void gl_core_raster_font_setup_viewport(unsigned width, unsigned height,
+ gl_core_raster_t *font, bool full_screen)
+{
+ video_driver_set_viewport(width, height, full_screen, false);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+ glUseProgram(font->gl->pipelines.font);
+}
+
+static void gl_core_raster_font_render_msg(
+ video_frame_info_t *video_info,
+ void *data, const char *msg,
+ const struct font_params *params)
+{
+ GLfloat color[4];
+ int drop_x, drop_y;
+ GLfloat x, y, scale, drop_mod, drop_alpha;
+ enum text_alignment text_align = TEXT_ALIGN_LEFT;
+ bool full_screen = false ;
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+ unsigned width = video_info->width;
+ unsigned height = video_info->height;
+
+ if (!font || string_is_empty(msg))
+ return;
+
+ if (params)
+ {
+ x = params->x;
+ y = params->y;
+ scale = params->scale;
+ full_screen = params->full_screen;
+ text_align = params->text_align;
+ drop_x = params->drop_x;
+ drop_y = params->drop_y;
+ drop_mod = params->drop_mod;
+ drop_alpha = params->drop_alpha;
+
+ color[0] = FONT_COLOR_GET_RED(params->color) / 255.0f;
+ color[1] = FONT_COLOR_GET_GREEN(params->color) / 255.0f;
+ color[2] = FONT_COLOR_GET_BLUE(params->color) / 255.0f;
+ color[3] = FONT_COLOR_GET_ALPHA(params->color) / 255.0f;
+
+ /* If alpha is 0.0f, turn it into default 1.0f */
+ if (color[3] <= 0.0f)
+ color[3] = 1.0f;
+ }
+ else
+ {
+ x = video_info->font_msg_pos_x;
+ y = video_info->font_msg_pos_y;
+ scale = 1.0f;
+ full_screen = true;
+ text_align = TEXT_ALIGN_LEFT;
+
+ color[0] = video_info->font_msg_color_r;
+ color[1] = video_info->font_msg_color_g;
+ color[2] = video_info->font_msg_color_b;
+ color[3] = 1.0f;
+
+ drop_x = -2;
+ drop_y = -2;
+ drop_mod = 0.3f;
+ drop_alpha = 1.0f;
+ }
+
+ if (font->block)
+ font->block->fullscreen = full_screen;
+ else
+ gl_core_raster_font_setup_viewport(width, height, font, full_screen);
+
+ if (!string_is_empty(msg) && font->gl
+ && font->font_data && font->font_driver)
+ {
+ if (drop_x || drop_y)
+ {
+ GLfloat color_dark[4];
+
+ color_dark[0] = color[0] * drop_mod;
+ color_dark[1] = color[1] * drop_mod;
+ color_dark[2] = color[2] * drop_mod;
+ color_dark[3] = color[3] * drop_alpha;
+
+ if (font->gl)
+ gl_core_raster_font_render_message(font, msg, scale, color_dark,
+ x + scale * drop_x / font->gl->vp.width, y +
+ scale * drop_y / font->gl->vp.height, text_align,
+ video_info);
+ }
+
+ if (font->gl)
+ gl_core_raster_font_render_message(font, msg, scale, color,
+ x, y, text_align, video_info);
+ }
+
+ if (!font->block && font->gl)
+ {
+ glDisable(GL_BLEND);
+ video_driver_set_viewport(width, height, false, true);
+ }
+}
+
+static const struct font_glyph *gl_core_raster_font_get_glyph(
+ void *data, uint32_t code)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+
+ if (!font || !font->font_driver)
+ return NULL;
+ if (!font->font_driver->ident)
+ return NULL;
+ return font->font_driver->get_glyph((void*)font->font_driver, code);
+}
+
+static void gl_core_raster_font_flush_block(unsigned width, unsigned height,
+ void *data, video_frame_info_t *video_info)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+ video_font_raster_block_t *block = font ? font->block : NULL;
+
+ if (!font || !block || !block->carr.coords.vertices)
+ return;
+
+ gl_core_raster_font_setup_viewport(width, height, font, block->fullscreen);
+ gl_core_raster_font_draw_vertices(font, (video_coords_t*)&block->carr.coords,
+ video_info);
+
+ if (font->gl)
+ {
+ glDisable(GL_BLEND);
+ video_driver_set_viewport(width, height, block->fullscreen, true);
+ }
+}
+
+static void gl_core_raster_font_bind_block(void *data, void *userdata)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+ video_font_raster_block_t *block = (video_font_raster_block_t*)userdata;
+
+ if (font)
+ font->block = block;
+}
+
+static int gl_core_get_line_height(void *data)
+{
+ gl_core_raster_t *font = (gl_core_raster_t*)data;
+
+ if (!font || !font->font_driver || !font->font_data)
+ return -1;
+
+ return font->font_driver->get_line_height(font->font_data);
+}
+
+font_renderer_t gl_core_raster_font = {
+ gl_core_raster_font_init_font,
+ gl_core_raster_font_free_font,
+ gl_core_raster_font_render_msg,
+ "GLCore raster",
+ gl_core_raster_font_get_glyph,
+ gl_core_raster_font_bind_block,
+ gl_core_raster_font_flush_block,
+ gl_core_get_message_width,
+ gl_core_get_line_height
+};
diff --git a/gfx/drivers_shader/shader_gl_core.cpp b/gfx/drivers_shader/shader_gl_core.cpp
new file mode 100644
index 0000000000..b2d2f0ce13
--- /dev/null
+++ b/gfx/drivers_shader/shader_gl_core.cpp
@@ -0,0 +1,2586 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2019 - 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 .
+ */
+
+#include "shader_gl_core.h"
+#include "glslang_util.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "slang_reflection.h"
+#include "slang_reflection.hpp"
+#include "spirv_glsl.hpp"
+
+#include "../video_driver.h"
+#include "../../verbosity.h"
+#include "../../msg_hash.h"
+
+using namespace std;
+
+template
+static bool gl_core_shader_set_unique_map(unordered_map &m, const string &name, const P &p)
+{
+ auto itr = m.find(name);
+ if (itr != end(m))
+ {
+ RARCH_ERR("[slang]: Alias \"%s\" already exists.\n",
+ name.c_str());
+ return false;
+ }
+
+ m[name] = p;
+ return true;
+}
+
+static GLuint gl_core_compile_shader(GLenum stage, const string &source)
+{
+ GLuint shader = glCreateShader(stage);
+
+ const char *ptr = source.c_str();
+ glShaderSource(shader, 1, &ptr, nullptr);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (!status)
+ {
+ GLint length;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+ if (length > 0)
+ {
+ vector buffer(length + 1);
+ glGetShaderInfoLog(shader, length, &length, buffer.data());
+ RARCH_ERR("[GLCore]: Failed to compile shader: %s\n", buffer.data());
+ glDeleteShader(shader);
+ return 0;
+ }
+ }
+
+ return shader;
+}
+
+GLuint gl_core_cross_compile_program(const uint32_t *vertex, size_t vertex_size,
+ const uint32_t *fragment, size_t fragment_size,
+ gl_core_buffer_locations *loc, bool flatten)
+{
+ GLuint program = 0;
+ try
+ {
+ spirv_cross::CompilerGLSL vertex_compiler(vertex, vertex_size / 4);
+ spirv_cross::CompilerGLSL fragment_compiler(fragment, fragment_size / 4);
+ spirv_cross::CompilerGLSL::Options opts;
+#ifdef HAVE_OPENGLES3
+ opts.es = true;
+ opts.version = 300;
+#else
+ opts.es = false;
+ opts.version = 150;
+#endif
+ opts.fragment.default_float_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
+ opts.fragment.default_int_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
+ opts.enable_420pack_extension = false;
+ vertex_compiler.set_common_options(opts);
+ fragment_compiler.set_common_options(opts);
+
+ auto vertex_resources = vertex_compiler.get_shader_resources();
+ auto fragment_resources = fragment_compiler.get_shader_resources();
+
+ for (auto &res : vertex_resources.stage_inputs)
+ {
+ uint32_t location = vertex_compiler.get_decoration(res.id, spv::DecorationLocation);
+ vertex_compiler.set_name(res.id, string("RARCH_ATTRIBUTE_") + to_string(location));
+ vertex_compiler.unset_decoration(res.id, spv::DecorationLocation);
+ }
+
+ for (auto &res : vertex_resources.stage_outputs)
+ {
+ uint32_t location = vertex_compiler.get_decoration(res.id, spv::DecorationLocation);
+ vertex_compiler.set_name(res.id, string("RARCH_VARYING_") + to_string(location));
+ vertex_compiler.unset_decoration(res.id, spv::DecorationLocation);
+ }
+
+ for (auto &res : fragment_resources.stage_inputs)
+ {
+ uint32_t location = fragment_compiler.get_decoration(res.id, spv::DecorationLocation);
+ fragment_compiler.set_name(res.id, string("RARCH_VARYING_") + to_string(location));
+ fragment_compiler.unset_decoration(res.id, spv::DecorationLocation);
+ }
+
+ if (vertex_resources.push_constant_buffers.size() > 1)
+ {
+ RARCH_ERR("[GLCore]: Cannot have more than one push constant buffer.\n");
+ return 0;
+ }
+
+ for (auto &res : vertex_resources.push_constant_buffers)
+ {
+ vertex_compiler.set_name(res.id, "RARCH_PUSH_VERTEX_INSTANCE");
+ vertex_compiler.set_name(res.base_type_id, "RARCH_PUSH_VERTEX");
+ }
+
+ if (vertex_resources.uniform_buffers.size() > 1)
+ {
+ RARCH_ERR("[GLCore]: Cannot have more than one uniform buffer.\n");
+ return 0;
+ }
+
+ for (auto &res : vertex_resources.uniform_buffers)
+ {
+ if (flatten)
+ vertex_compiler.flatten_buffer_block(res.id);
+ vertex_compiler.set_name(res.id, "RARCH_UBO_VERTEX_INSTANCE");
+ vertex_compiler.set_name(res.base_type_id, "RARCH_UBO_VERTEX");
+ vertex_compiler.unset_decoration(res.id, spv::DecorationDescriptorSet);
+ vertex_compiler.unset_decoration(res.id, spv::DecorationBinding);
+ }
+
+ if (fragment_resources.push_constant_buffers.size() > 1)
+ {
+ RARCH_ERR("[GLCore]: Cannot have more than one push constant block.\n");
+ return 0;
+ }
+
+ for (auto &res : fragment_resources.push_constant_buffers)
+ {
+ fragment_compiler.set_name(res.id, "RARCH_PUSH_FRAGMENT_INSTANCE");
+ fragment_compiler.set_name(res.base_type_id, "RARCH_PUSH_FRAGMENT");
+ }
+
+ if (fragment_resources.uniform_buffers.size() > 1)
+ {
+ RARCH_ERR("[GLCore]: Cannot have more than one uniform buffer.\n");
+ return 0;
+ }
+
+ for (auto &res : fragment_resources.uniform_buffers)
+ {
+ if (flatten)
+ fragment_compiler.flatten_buffer_block(res.id);
+ fragment_compiler.set_name(res.id, "RARCH_UBO_FRAGMENT_INSTANCE");
+ fragment_compiler.set_name(res.base_type_id, "RARCH_UBO_FRAGMENT");
+ fragment_compiler.unset_decoration(res.id, spv::DecorationDescriptorSet);
+ fragment_compiler.unset_decoration(res.id, spv::DecorationBinding);
+ }
+
+ std::vector texture_binding_fixups;
+ for (auto &res : fragment_resources.sampled_images)
+ {
+ uint32_t binding = fragment_compiler.get_decoration(res.id, spv::DecorationBinding);
+ fragment_compiler.set_name(res.id, string("RARCH_TEXTURE_") + to_string(binding));
+ fragment_compiler.unset_decoration(res.id, spv::DecorationDescriptorSet);
+ fragment_compiler.unset_decoration(res.id, spv::DecorationBinding);
+ texture_binding_fixups.push_back(binding);
+ }
+
+ auto vertex_source = vertex_compiler.compile();
+ auto fragment_source = fragment_compiler.compile();
+ GLuint vertex_shader = gl_core_compile_shader(GL_VERTEX_SHADER, vertex_source);
+ GLuint fragment_shader = gl_core_compile_shader(GL_FRAGMENT_SHADER, fragment_source);
+
+ //RARCH_LOG("[GLCore]: Vertex shader:\n========\n%s\n=======\n", vertex_source.c_str());
+ //RARCH_LOG("[GLCore]: Fragment shader:\n========\n%s\n=======\n", fragment_source.c_str());
+
+ if (!vertex_shader || !fragment_shader)
+ {
+ RARCH_ERR("[GLCore]: One or more shaders failed to compile.\n");
+ if (vertex_shader)
+ glDeleteShader(vertex_shader);
+ if (fragment_shader)
+ glDeleteShader(fragment_shader);
+ return 0;
+ }
+
+ program = glCreateProgram();
+ glAttachShader(program, vertex_shader);
+ glAttachShader(program, fragment_shader);
+ for (auto &res : vertex_resources.stage_inputs)
+ {
+ uint32_t location = vertex_compiler.get_decoration(res.id, spv::DecorationLocation);
+ glBindAttribLocation(program, location, (string("RARCH_ATTRIBUTE_") + to_string(location)).c_str());
+ }
+ glLinkProgram(program);
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ GLint status;
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ if (!status)
+ {
+ GLint length;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
+ if (length > 0)
+ {
+ vector buffer(length + 1);
+ glGetProgramInfoLog(program, length, &length, buffer.data());
+ RARCH_ERR("[GLCore]: Failed to link program: %s\n", buffer.data());
+ glDeleteProgram(program);
+ return 0;
+ }
+ }
+
+ glUseProgram(program);
+
+ if (loc)
+ {
+ loc->flat_ubo_fragment = -1;
+ loc->flat_ubo_vertex = -1;
+ loc->flat_push_vertex = -1;
+ loc->flat_push_fragment = -1;
+ loc->buffer_index_ubo_vertex = GL_INVALID_INDEX;
+ loc->buffer_index_ubo_fragment = GL_INVALID_INDEX;
+
+ if (flatten)
+ {
+ loc->flat_ubo_vertex = glGetUniformLocation(program, "RARCH_UBO_VERTEX");
+ loc->flat_ubo_fragment = glGetUniformLocation(program, "RARCH_UBO_FRAGMENT");
+ loc->flat_push_vertex = glGetUniformLocation(program, "RARCH_PUSH_VERTEX");
+ loc->flat_push_fragment = glGetUniformLocation(program, "RARCH_PUSH_FRAGMENT");
+ }
+ else
+ {
+ loc->buffer_index_ubo_vertex = glGetUniformBlockIndex(program, "RARCH_UBO_VERTEX");
+ loc->buffer_index_ubo_fragment = glGetUniformBlockIndex(program, "RARCH_UBO_FRAGMENT");
+ }
+ }
+
+ // Force proper bindings for textures.
+ for (auto &binding : texture_binding_fixups)
+ {
+ GLint location = glGetUniformLocation(program, (string("RARCH_TEXTURE_") + to_string(binding)).c_str());
+ if (location >= 0)
+ glUniform1i(location, binding);
+ }
+
+ glUseProgram(0);
+ }
+ catch (const exception &e)
+ {
+ RARCH_ERR("[GLCore]: Failed to cross compile program: %s\n", e.what());
+ if (program != 0)
+ glDeleteProgram(program);
+ return 0;
+ }
+
+ return program;
+}
+
+namespace gl_core
+{
+static const uint32_t opaque_vert[] =
+#include "../drivers/vulkan_shaders/opaque.vert.inc"
+;
+
+static const uint32_t opaque_frag[] =
+#include "../drivers/vulkan_shaders/opaque.frag.inc"
+;
+
+struct ConfigDeleter
+{
+ void operator()(config_file_t *conf)
+ {
+ if (conf)
+ config_file_free(conf);
+ }
+};
+
+static unsigned num_miplevels(unsigned width, unsigned height)
+{
+ unsigned size = MAX(width, height);
+ unsigned levels = 0;
+ while (size) {
+ levels++;
+ size >>= 1;
+ }
+ return levels;
+}
+
+static void build_default_matrix(float *data)
+{
+ data[0] = 2.0f;
+ data[1] = 0.0f;
+ data[2] = 0.0f;
+ data[3] = 0.0f;
+ data[4] = 0.0f;
+ data[5] = 2.0f;
+ data[6] = 0.0f;
+ data[7] = 0.0f;
+ data[8] = 0.0f;
+ data[9] = 0.0f;
+ data[10] = 2.0f;
+ data[11] = 0.0f;
+ data[12] = -1.0f;
+ data[13] = -1.0f;
+ data[14] = 0.0f;
+ data[15] = 1.0f;
+}
+
+static void build_vec4(float *data, unsigned width, unsigned height)
+{
+ data[0] = float(width);
+ data[1] = float(height);
+ data[2] = 1.0f / float(width);
+ data[3] = 1.0f / float(height);
+}
+
+struct Size2D
+{
+ unsigned width, height;
+};
+
+struct Texture
+{
+ gl_core_filter_chain_texture texture;
+ gl_core_filter_chain_filter filter;
+ gl_core_filter_chain_filter mip_filter;
+ gl_core_filter_chain_address address;
+};
+
+static gl_core_filter_chain_address wrap_to_address(gfx_wrap_type type)
+{
+ switch (type)
+ {
+ default:
+ case RARCH_WRAP_EDGE:
+ return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
+
+ case RARCH_WRAP_BORDER:
+ return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER;
+
+ case RARCH_WRAP_REPEAT:
+ return GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT;
+
+ case RARCH_WRAP_MIRRORED_REPEAT:
+ return GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT;
+ }
+}
+
+static GLenum address_to_gl(gl_core_filter_chain_address type)
+{
+ switch (type)
+ {
+ default:
+ case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE:
+ return GL_CLAMP_TO_EDGE;
+
+#ifdef HAVE_OPENGLES3
+ case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
+ //RARCH_WARN("[GLCore]: No CLAMP_TO_BORDER in GLES3. Falling back to edge clamp.\n");
+ return GL_CLAMP_TO_EDGE;
+#else
+ case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
+ return GL_CLAMP_TO_BORDER;
+#endif
+
+ case GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT:
+ return GL_REPEAT;
+
+ case GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT:
+ return GL_MIRRORED_REPEAT;
+ }
+}
+
+static GLenum convert_filter_to_mag_gl(gl_core_filter_chain_filter filter)
+{
+ switch (filter)
+ {
+ case GL_CORE_FILTER_CHAIN_LINEAR:
+ return GL_LINEAR;
+
+ default:
+ case GL_CORE_FILTER_CHAIN_NEAREST:
+ return GL_NEAREST;
+ }
+}
+
+static GLenum convert_filter_to_min_gl(gl_core_filter_chain_filter filter, gl_core_filter_chain_filter mipfilter)
+{
+ if (filter == GL_CORE_FILTER_CHAIN_LINEAR && mipfilter == GL_CORE_FILTER_CHAIN_LINEAR)
+ return GL_LINEAR_MIPMAP_LINEAR;
+ else if (filter == GL_CORE_FILTER_CHAIN_LINEAR)
+ return GL_LINEAR_MIPMAP_NEAREST;
+ else if (mipfilter == GL_CORE_FILTER_CHAIN_LINEAR)
+ return GL_NEAREST_MIPMAP_LINEAR;
+ else
+ return GL_NEAREST_MIPMAP_NEAREST;
+}
+
+static GLenum convert_glslang_format(glslang_format fmt)
+{
+#undef FMT
+#define FMT(x, r) case SLANG_FORMAT_##x: return GL_##r
+ switch (fmt)
+ {
+ FMT(R8_UNORM, R8);
+ FMT(R8_SINT, R8I);
+ FMT(R8_UINT, R8UI);
+ FMT(R8G8_UNORM, RG8);
+ FMT(R8G8_SINT, RG8I);
+ FMT(R8G8_UINT, RG8UI);
+ FMT(R8G8B8A8_UNORM, RGBA8);
+ FMT(R8G8B8A8_SINT, RGBA8I);
+ FMT(R8G8B8A8_UINT, RGBA8UI);
+ FMT(R8G8B8A8_SRGB, SRGB8_ALPHA8);
+
+ FMT(A2B10G10R10_UNORM_PACK32, RGB10_A2);
+ FMT(A2B10G10R10_UINT_PACK32, RGB10_A2UI);
+
+ FMT(R16_UINT, R16UI);
+ FMT(R16_SINT, R16I);
+ FMT(R16_SFLOAT, R16F);
+ FMT(R16G16_UINT, RG16UI);
+ FMT(R16G16_SINT, RG16I);
+ FMT(R16G16_SFLOAT, RG16F);
+ FMT(R16G16B16A16_UINT, RGBA16UI);
+ FMT(R16G16B16A16_SINT, RGBA16I);
+ FMT(R16G16B16A16_SFLOAT, RGBA16F);
+
+ FMT(R32_UINT, R32UI);
+ FMT(R32_SINT, R32I);
+ FMT(R32_SFLOAT, R32F);
+ FMT(R32G32_UINT, RG32UI);
+ FMT(R32G32_SINT, RG32I);
+ FMT(R32G32_SFLOAT, RG32F);
+ FMT(R32G32B32A32_UINT, RGBA32UI);
+ FMT(R32G32B32A32_SINT, RGBA32I);
+ FMT(R32G32B32A32_SFLOAT, RGBA32F);
+
+ default:
+ return 0;
+ }
+}
+
+class StaticTexture
+{
+public:
+ StaticTexture(string id,
+ GLuint image,
+ unsigned width, unsigned height,
+ bool linear,
+ bool mipmap,
+ GLenum address);
+ ~StaticTexture();
+
+ StaticTexture(StaticTexture&&) = delete;
+ void operator=(StaticTexture&&) = delete;
+
+ void set_id(string name)
+ {
+ id = move(name);
+ }
+
+ const string &get_id() const
+ {
+ return id;
+ }
+
+ const Texture &get_texture() const
+ {
+ return texture;
+ }
+
+private:
+ string id;
+ GLuint image;
+ Texture texture;
+};
+
+StaticTexture::StaticTexture(string id_, GLuint image_, unsigned width, unsigned height, bool linear, bool mipmap,
+ GLenum address)
+ : id(std::move(id_)), image(image_)
+{
+ texture.texture.width = width;
+ texture.texture.height = height;
+ texture.texture.format = 0;
+ texture.texture.image = image;
+
+ glBindTexture(GL_TEXTURE_2D, image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, address);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, address);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
+ if (linear && mipmap)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ else if (linear)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+StaticTexture::~StaticTexture()
+{
+ if (image != 0)
+ glDeleteTextures(1, &image);
+}
+
+struct CommonResources
+{
+ CommonResources();
+ ~CommonResources();
+
+ vector original_history;
+ vector framebuffer_feedback;
+ vector pass_outputs;
+ vector> luts;
+
+ unordered_map texture_semantic_map;
+ unordered_map texture_semantic_uniform_map;
+ unique_ptr shader_preset;
+
+ GLuint quad_program = 0;
+ GLuint quad_vbo = 0;
+ gl_core_buffer_locations quad_loc = {};
+ void draw_quad() const;
+};
+
+CommonResources::CommonResources()
+{
+ static float quad_data[] = {
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f,
+ };
+
+ glGenBuffers(1, &quad_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ quad_program = gl_core_cross_compile_program(opaque_vert, sizeof(opaque_vert),
+ opaque_frag, sizeof(opaque_frag), &quad_loc, true);
+}
+
+CommonResources::~CommonResources()
+{
+ if (quad_program != 0)
+ glDeleteProgram(quad_program);
+ if (quad_vbo != 0)
+ glDeleteBuffers(1, &quad_vbo);
+}
+
+void CommonResources::draw_quad() const
+{
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
+ reinterpret_cast(uintptr_t(0)));
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
+ reinterpret_cast(uintptr_t(2 * sizeof(float))));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+}
+
+class Framebuffer
+{
+public:
+ Framebuffer(GLenum format, unsigned max_levels);
+
+ ~Framebuffer();
+ Framebuffer(Framebuffer&&) = delete;
+ void operator=(Framebuffer&&) = delete;
+
+ void set_size(const Size2D &size, GLenum format = 0);
+
+ const Size2D &get_size() const { return size; }
+ GLenum get_format() const { return format; }
+ GLuint get_image() const { return image; }
+ GLuint get_framebuffer() const { return framebuffer; }
+
+ void clear();
+ void copy(const CommonResources &common, GLuint image);
+ void copy_partial(const CommonResources &common, GLuint image, float rx, float ry);
+ bool is_complete() const
+ {
+ return complete;
+ }
+
+ unsigned get_levels() const { return levels; }
+ void generate_mips();
+
+private:
+ GLuint image = 0;
+ Size2D size;
+ GLenum format;
+ unsigned max_levels;
+ unsigned levels = 0;
+
+ GLuint framebuffer = 0;
+
+ void init();
+ bool complete = false;
+};
+
+Framebuffer::Framebuffer(GLenum format_, unsigned max_levels_)
+ : size({1, 1}), format(format_), max_levels(max_levels_)
+{
+ glGenFramebuffers(1, &framebuffer);
+
+ // Need to bind to create.
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ if (format == 0)
+ format = GL_RGBA8;
+}
+
+void Framebuffer::set_size(const Size2D &size_, GLenum format_)
+{
+ size = size_;
+ if (format_ != 0)
+ format = format_;
+
+ init();
+}
+
+void Framebuffer::init()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ if (image != 0)
+ {
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ glDeleteTextures(1, &image);
+ }
+
+ glGenTextures(1, &image);
+ glBindTexture(GL_TEXTURE_2D, image);
+
+ if (size.width == 0)
+ size.width = 1;
+ if (size.height == 0)
+ size.height = 1;
+
+ levels = num_miplevels(size.width, size.height);
+ if (max_levels < levels)
+ levels = max_levels;
+ if (levels == 0)
+ levels = 1;
+
+ glTexStorage2D(GL_TEXTURE_2D, levels,
+ format,
+ size.width, size.height);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
+ auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ bool fallback = false;
+
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ RARCH_ERR("[GLCore]: Incomplete attachment.\n");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ RARCH_ERR("[GLCore]: Incomplete, missing attachment.\n");
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ RARCH_ERR("[GLCore]: Unsupported FBO, falling back to RGBA8.\n");
+ fallback = true;
+ break;
+ }
+
+ complete = false;
+ }
+ else
+ complete = true;
+
+ if (fallback)
+ {
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ glDeleteTextures(1, &image);
+ glGenTextures(1, &image);
+ glBindTexture(GL_TEXTURE_2D, image);
+
+ unsigned levels = num_miplevels(size.width, size.height);
+ if (max_levels < levels)
+ levels = max_levels;
+ glTexStorage2D(GL_TEXTURE_2D, levels,
+ GL_RGBA8,
+ size.width, size.height);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ complete = status == GL_FRAMEBUFFER_COMPLETE;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void Framebuffer::clear()
+{
+ if (complete)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+}
+
+void Framebuffer::generate_mips()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, image);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void Framebuffer::copy(const CommonResources &common, GLuint image)
+{
+ if (!complete)
+ return;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glViewport(0, 0, size.width, size.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glUseProgram(common.quad_program);
+ if (common.quad_loc.flat_ubo_vertex >= 0)
+ {
+ float mvp[16];
+ build_default_matrix(mvp);
+ glUniform4fv(common.quad_loc.flat_ubo_vertex, 4, mvp);
+ }
+ common.draw_quad();
+ glUseProgram(0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void Framebuffer::copy_partial(const CommonResources &common, GLuint image, float rx, float ry)
+{
+ if (!complete)
+ return;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glViewport(0, 0, size.width, size.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glUseProgram(common.quad_program);
+ if (common.quad_loc.flat_ubo_vertex >= 0)
+ {
+ float mvp[16];
+ build_default_matrix(mvp);
+ glUniform4fv(common.quad_loc.flat_ubo_vertex, 4, mvp);
+ }
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ // A bit crude, but heeeey.
+ GLuint vbo;
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ const float quad_data[] = {
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, rx, 0.0f,
+ 0.0f, 1.0f, 0.0f, ry,
+ 1.0f, 1.0f, rx, ry,
+ };
+
+ glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STREAM_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
+ reinterpret_cast(uintptr_t(0)));
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
+ reinterpret_cast(uintptr_t(2 * sizeof(float))));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(1, &vbo);
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glUseProgram(0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+Framebuffer::~Framebuffer()
+{
+ if (framebuffer != 0)
+ glDeleteFramebuffers(1, &framebuffer);
+ if (image != 0)
+ glDeleteTextures(1, &image);
+}
+
+class UBORing
+{
+public:
+ ~UBORing();
+ void init(size_t size, unsigned count);
+ void update_and_bind(unsigned vertex_binding, unsigned fragment_binding, const void *data, size_t size);
+
+private:
+ std::vector buffers;
+ unsigned buffer_index = 0;
+};
+
+void UBORing::init(size_t size, unsigned count)
+{
+ buffers.resize(count);
+ glGenBuffers(count, buffers.data());
+ for (auto &buf : buffers)
+ {
+ glBindBuffer(GL_UNIFORM_BUFFER, buf);
+ glBufferData(GL_UNIFORM_BUFFER, size, nullptr, GL_STREAM_DRAW);
+ }
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
+
+void UBORing::update_and_bind(unsigned vertex_binding, unsigned fragment_binding, const void *data, size_t size)
+{
+ if (vertex_binding == GL_INVALID_INDEX && fragment_binding == GL_INVALID_INDEX)
+ return;
+
+ glBindBuffer(GL_UNIFORM_BUFFER, buffers[buffer_index]);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ if (vertex_binding != GL_INVALID_INDEX)
+ glBindBufferBase(GL_UNIFORM_BUFFER, vertex_binding, buffers[buffer_index]);
+ if (fragment_binding != GL_INVALID_INDEX)
+ glBindBufferBase(GL_UNIFORM_BUFFER, fragment_binding, buffers[buffer_index]);
+
+ buffer_index++;
+ if (buffer_index >= buffers.size())
+ buffer_index = 0;
+}
+
+UBORing::~UBORing()
+{
+ glDeleteBuffers(buffers.size(), buffers.data());
+}
+
+class Pass
+{
+public:
+ explicit Pass(bool final_pass) :
+ final_pass(final_pass)
+ {}
+
+ ~Pass();
+
+ Pass(Pass&&) = delete;
+ void operator=(Pass&&) = delete;
+
+ const Framebuffer &get_framebuffer() const
+ {
+ return *framebuffer;
+ }
+
+ Framebuffer *get_feedback_framebuffer()
+ {
+ return framebuffer_feedback.get();
+ }
+
+ void set_pass_info(const gl_core_filter_chain_pass_info &info);
+
+ void set_shader(GLenum stage,
+ const uint32_t *spirv,
+ size_t spirv_words);
+
+ bool build();
+ bool init_feedback();
+
+ void build_commands(
+ const Texture &original,
+ const Texture &source,
+ const gl_core_viewport &vp,
+ const float *mvp);
+
+ void set_frame_count(uint64_t count)
+ {
+ frame_count = count;
+ }
+
+ void set_frame_count_period(unsigned period)
+ {
+ frame_count_period = period;
+ }
+
+ void set_name(const char *name)
+ {
+ pass_name = name;
+ }
+
+ const string &get_name() const
+ {
+ return pass_name;
+ }
+
+ gl_core_filter_chain_filter get_source_filter() const
+ {
+ return pass_info.source_filter;
+ }
+
+ gl_core_filter_chain_filter get_mip_filter() const
+ {
+ return pass_info.mip_filter;
+ }
+
+ gl_core_filter_chain_address get_address_mode() const
+ {
+ return pass_info.address;
+ }
+
+ void set_common_resources(CommonResources *common)
+ {
+ this->common = common;
+ }
+
+ const slang_reflection &get_reflection() const
+ {
+ return reflection;
+ }
+
+ void set_pass_number(unsigned pass)
+ {
+ pass_number = pass;
+ }
+
+ void add_parameter(unsigned parameter_index, const std::string &id);
+
+ void end_frame();
+ void allocate_buffers();
+
+private:
+ bool final_pass;
+
+ Size2D get_output_size(const Size2D &original_size,
+ const Size2D &max_source) const;
+
+ GLuint pipeline = 0;
+ CommonResources *common = nullptr;
+
+ Size2D current_framebuffer_size = {};
+ gl_core_viewport current_viewport;
+ gl_core_filter_chain_pass_info pass_info;
+
+ vector vertex_shader;
+ vector fragment_shader;
+ unique_ptr framebuffer;
+ unique_ptr framebuffer_feedback;
+
+ bool init_pipeline();
+
+ void set_texture(unsigned binding,
+ const Texture &texture);
+
+ void set_semantic_texture(slang_texture_semantic semantic,
+ const Texture &texture);
+ void set_semantic_texture_array(slang_texture_semantic semantic, unsigned index,
+ const Texture &texture);
+
+ slang_reflection reflection;
+
+ std::vector uniforms;
+
+ void build_semantics(uint8_t *buffer,
+ const float *mvp, const Texture &original, const Texture &source);
+ void build_semantic_vec4(uint8_t *data, slang_semantic semantic,
+ unsigned width, unsigned height);
+ void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value);
+ void build_semantic_parameter(uint8_t *data, unsigned index, float value);
+ void build_semantic_texture_vec4(uint8_t *data,
+ slang_texture_semantic semantic,
+ unsigned width, unsigned height);
+ void build_semantic_texture_array_vec4(uint8_t *data,
+ slang_texture_semantic semantic, unsigned index,
+ unsigned width, unsigned height);
+ void build_semantic_texture(uint8_t *buffer,
+ slang_texture_semantic semantic, const Texture &texture);
+ void build_semantic_texture_array(uint8_t *buffer,
+ slang_texture_semantic semantic, unsigned index, const Texture &texture);
+
+ uint64_t frame_count = 0;
+ unsigned frame_count_period = 0;
+ unsigned pass_number = 0;
+
+ size_t ubo_offset = 0;
+ string pass_name;
+
+ struct Parameter
+ {
+ string id;
+ unsigned index;
+ unsigned semantic_index;
+ };
+
+ vector parameters;
+ vector filtered_parameters;
+ vector push_constant_buffer;
+ gl_core_buffer_locations locations = {};
+ UBORing ubo_ring;
+
+ void reflect_parameter(const std::string &name, slang_semantic_meta &meta);
+ void reflect_parameter(const std::string &name, slang_texture_semantic_meta &meta);
+ void reflect_parameter_array(const std::string &name, std::vector &meta);
+};
+
+bool Pass::build()
+{
+ unordered_map semantic_map;
+ unsigned i;
+ unsigned j = 0;
+
+ framebuffer.reset();
+ framebuffer_feedback.reset();
+
+ if (!final_pass)
+ {
+ framebuffer = unique_ptr(
+ new Framebuffer(pass_info.rt_format, pass_info.max_levels));
+ }
+
+ for (auto ¶m : parameters)
+ {
+ if (!gl_core_shader_set_unique_map(semantic_map, param.id,
+ slang_semantic_map{ SLANG_SEMANTIC_FLOAT_PARAMETER, j }))
+ return false;
+ j++;
+ }
+
+ reflection = slang_reflection{};
+ reflection.pass_number = pass_number;
+ reflection.texture_semantic_map = &common->texture_semantic_map;
+ reflection.texture_semantic_uniform_map = &common->texture_semantic_uniform_map;
+ reflection.semantic_map = &semantic_map;
+
+ if (!slang_reflect_spirv(vertex_shader, fragment_shader, &reflection))
+ return false;
+
+ /* Filter out parameters which we will never use anyways. */
+ filtered_parameters.clear();
+
+ for (i = 0; i < reflection.semantic_float_parameters.size(); i++)
+ {
+ if (reflection.semantic_float_parameters[i].uniform ||
+ reflection.semantic_float_parameters[i].push_constant)
+ filtered_parameters.push_back(parameters[i]);
+ }
+
+ if (!init_pipeline())
+ return false;
+
+ return true;
+}
+
+void Pass::reflect_parameter(const std::string &name, slang_semantic_meta &meta)
+{
+ if (meta.uniform)
+ {
+ meta.location.ubo_vertex = glGetUniformLocation(pipeline, (std::string("RARCH_UBO_VERTEX_INSTANCE.") + name).c_str());
+ meta.location.ubo_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + name).c_str());
+ }
+
+ if (meta.push_constant)
+ {
+ meta.location.push_vertex = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_VERTEX_INSTANCE.") + name).c_str());
+ meta.location.push_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + name).c_str());
+ }
+}
+
+void Pass::reflect_parameter(const std::string &name, slang_texture_semantic_meta &meta)
+{
+ if (meta.uniform)
+ {
+ meta.location.ubo_vertex = glGetUniformLocation(pipeline, (std::string("RARCH_UBO_VERTEX_INSTANCE.") + name).c_str());
+ meta.location.ubo_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + name).c_str());
+ }
+
+ if (meta.push_constant)
+ {
+ meta.location.push_vertex = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_VERTEX_INSTANCE.") + name).c_str());
+ meta.location.push_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + name).c_str());
+ }
+}
+
+void Pass::reflect_parameter_array(const std::string &name, std::vector &meta)
+{
+ for (size_t i = 0; i < meta.size(); i++)
+ {
+ auto n = name + std::to_string(i);
+ auto &m = meta[i];
+
+ if (m.uniform)
+ {
+ m.location.ubo_vertex = glGetUniformLocation(pipeline,
+ (std::string("RARCH_UBO_VERTEX_INSTANCE.") + n).c_str());
+ m.location.ubo_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + n).c_str());
+ }
+
+ if (m.push_constant)
+ {
+ m.location.push_vertex = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_VERTEX_INSTANCE.") + n).c_str());
+ m.location.push_fragment = glGetUniformLocation(pipeline,
+ (std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + n).c_str());
+ }
+ }
+}
+
+bool Pass::init_pipeline()
+{
+ pipeline = gl_core_cross_compile_program(vertex_shader.data(), vertex_shader.size() * sizeof(uint32_t),
+ fragment_shader.data(), fragment_shader.size() * sizeof(uint32_t),
+ &locations, false);
+
+ if (!pipeline)
+ return false;
+
+ uniforms.resize(reflection.ubo_size);
+ if (reflection.ubo_size)
+ ubo_ring.init(reflection.ubo_size, 16);
+ push_constant_buffer.resize(reflection.push_constant_size);
+
+ reflect_parameter("MVP", reflection.semantics[SLANG_SEMANTIC_MVP]);
+ reflect_parameter("OutputSize", reflection.semantics[SLANG_SEMANTIC_OUTPUT]);
+ reflect_parameter("FinalViewportSize", reflection.semantics[SLANG_SEMANTIC_FINAL_VIEWPORT]);
+ reflect_parameter("FrameCount", reflection.semantics[SLANG_SEMANTIC_FRAME_COUNT]);
+
+ reflect_parameter("OriginalSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_ORIGINAL][0]);
+ reflect_parameter("SourceSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_SOURCE][0]);
+ reflect_parameter_array("OriginalHistorySize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY]);
+ reflect_parameter_array("PassOutputSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT]);
+ reflect_parameter_array("PassFeedbackSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK]);
+ reflect_parameter_array("UserSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_USER]);
+ for (auto &m : common->texture_semantic_uniform_map)
+ {
+ auto &array = reflection.semantic_textures[m.second.semantic];
+ if (m.second.index < array.size())
+ reflect_parameter(m.first, array[m.second.index]);
+ }
+
+ for (auto &m : filtered_parameters)
+ if (m.semantic_index < reflection.semantic_float_parameters.size())
+ reflect_parameter(m.id, reflection.semantic_float_parameters[m.semantic_index]);
+
+ return true;
+}
+
+void Pass::set_pass_info(const gl_core_filter_chain_pass_info &info)
+{
+ pass_info = info;
+}
+
+Size2D Pass::get_output_size(const Size2D &original, const Size2D &source) const
+{
+ float width, height;
+ switch (pass_info.scale_type_x)
+ {
+ case GL_CORE_FILTER_CHAIN_SCALE_ORIGINAL:
+ width = float(original.width) * pass_info.scale_x;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_SOURCE:
+ width = float(source.width) * pass_info.scale_x;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT:
+ width = current_viewport.width * pass_info.scale_x;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_ABSOLUTE:
+ width = pass_info.scale_x;
+ break;
+
+ default:
+ width = 0.0f;
+ }
+
+ switch (pass_info.scale_type_y)
+ {
+ case GL_CORE_FILTER_CHAIN_SCALE_ORIGINAL:
+ height = float(original.height) * pass_info.scale_y;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_SOURCE:
+ height = float(source.height) * pass_info.scale_y;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT:
+ height = current_viewport.height * pass_info.scale_y;
+ break;
+
+ case GL_CORE_FILTER_CHAIN_SCALE_ABSOLUTE:
+ height = pass_info.scale_y;
+ break;
+
+ default:
+ height = 0.0f;
+ }
+
+ return { unsigned(roundf(width)), unsigned(roundf(height)) };
+}
+
+void Pass::end_frame()
+{
+ if (framebuffer_feedback)
+ swap(framebuffer, framebuffer_feedback);
+}
+
+void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
+ unsigned width, unsigned height)
+{
+ auto &refl = reflection.semantics[semantic];
+
+ if (data && refl.uniform)
+ {
+ if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0)
+ {
+ float v4[4];
+ build_vec4(v4, width, height);
+ if (refl.location.ubo_vertex >= 0)
+ glUniform4fv(refl.location.ubo_vertex, 1, v4);
+ if (refl.location.ubo_fragment >= 0)
+ glUniform4fv(refl.location.ubo_fragment, 1, v4);
+ }
+ else
+ {
+ build_vec4(
+ reinterpret_cast(data + refl.ubo_offset),
+ width,
+ height);
+ }
+ }
+
+ if (refl.push_constant)
+ {
+ if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0)
+ {
+ float v4[4];
+ build_vec4(v4, width, height);
+ if (refl.location.push_vertex >= 0)
+ glUniform4fv(refl.location.push_vertex, 1, v4);
+ if (refl.location.push_fragment >= 0)
+ glUniform4fv(refl.location.push_fragment, 1, v4);
+ }
+ else
+ {
+ build_vec4(
+ reinterpret_cast(push_constant_buffer.data() + refl.push_constant_offset),
+ width,
+ height);
+ }
+ }
+}
+
+void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)
+{
+ auto &refl = reflection.semantic_float_parameters[index];
+
+ /* We will have filtered out stale parameters. */
+ if (data && refl.uniform)
+ {
+ if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0)
+ {
+ if (refl.location.ubo_vertex >= 0)
+ glUniform1f(refl.location.ubo_vertex, value);
+ if (refl.location.ubo_fragment >= 0)
+ glUniform1f(refl.location.ubo_fragment, value);
+ }
+ else
+ *reinterpret_cast(data + refl.ubo_offset) = value;
+ }
+
+ if (refl.push_constant)
+ {
+ if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0)
+ {
+ if (refl.location.push_vertex >= 0)
+ glUniform1f(refl.location.push_vertex, value);
+ if (refl.location.push_fragment >= 0)
+ glUniform1f(refl.location.push_fragment, value);
+ }
+ else
+ *reinterpret_cast(push_constant_buffer.data() + refl.push_constant_offset) = value;
+ }
+}
+
+void Pass::build_semantic_uint(uint8_t *data, slang_semantic semantic,
+ uint32_t value)
+{
+ auto &refl = reflection.semantics[semantic];
+
+ if (data && refl.uniform)
+ {
+ if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0)
+ {
+ if (refl.location.ubo_vertex >= 0)
+ glUniform1ui(refl.location.ubo_vertex, value);
+ if (refl.location.ubo_fragment >= 0)
+ glUniform1ui(refl.location.ubo_fragment, value);
+ }
+ else
+ *reinterpret_cast(data + reflection.semantics[semantic].ubo_offset) = value;
+ }
+
+ if (refl.push_constant)
+ {
+ if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0)
+ {
+ if (refl.location.push_vertex >= 0)
+ glUniform1ui(refl.location.push_vertex, value);
+ if (refl.location.push_fragment >= 0)
+ glUniform1ui(refl.location.push_fragment, value);
+ }
+ else
+ *reinterpret_cast(push_constant_buffer.data() + refl.push_constant_offset) = value;
+ }
+}
+
+void Pass::build_semantic_texture(uint8_t *buffer,
+ slang_texture_semantic semantic, const Texture &texture)
+{
+ build_semantic_texture_vec4(buffer, semantic,
+ texture.texture.width, texture.texture.height);
+ set_semantic_texture(semantic, texture);
+}
+
+void Pass::set_semantic_texture_array(
+ slang_texture_semantic semantic, unsigned index,
+ const Texture &texture)
+{
+ if (index < reflection.semantic_textures[semantic].size() &&
+ reflection.semantic_textures[semantic][index].texture)
+ set_texture(reflection.semantic_textures[semantic][index].binding, texture);
+}
+
+void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semantic semantic,
+ unsigned index, unsigned width, unsigned height)
+{
+ auto &refl = reflection.semantic_textures[semantic];
+ if (index >= refl.size())
+ return;
+
+ if (data && refl[index].uniform)
+ {
+ if (refl[index].location.ubo_vertex >= 0 || refl[index].location.ubo_fragment >= 0)
+ {
+ float v4[4];
+ build_vec4(v4, width, height);
+ if (refl[index].location.ubo_vertex >= 0)
+ glUniform4fv(refl[index].location.ubo_vertex, 1, v4);
+ if (refl[index].location.ubo_fragment >= 0)
+ glUniform4fv(refl[index].location.ubo_fragment, 1, v4);
+ }
+ else
+ {
+ build_vec4(
+ reinterpret_cast(data + refl[index].ubo_offset),
+ width,
+ height);
+ }
+ }
+
+ if (refl[index].push_constant)
+ {
+ if (refl[index].location.push_vertex >= 0 || refl[index].location.push_fragment >= 0)
+ {
+ float v4[4];
+ build_vec4(v4, width, height);
+ if (refl[index].location.push_vertex >= 0)
+ glUniform4fv(refl[index].location.push_vertex, 1, v4);
+ if (refl[index].location.push_fragment >= 0)
+ glUniform4fv(refl[index].location.push_fragment, 1, v4);
+ }
+ else
+ {
+ build_vec4(
+ reinterpret_cast(push_constant_buffer.data() + refl[index].push_constant_offset),
+ width,
+ height);
+ }
+ }
+}
+
+void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic,
+ unsigned width, unsigned height)
+{
+ build_semantic_texture_array_vec4(data, semantic, 0, width, height);
+}
+
+bool Pass::init_feedback()
+{
+ if (final_pass)
+ return false;
+
+ framebuffer_feedback = unique_ptr(
+ new Framebuffer(pass_info.rt_format, pass_info.max_levels));
+ return true;
+}
+
+Pass::~Pass()
+{
+ if (pipeline != 0)
+ glDeleteProgram(pipeline);
+}
+
+void Pass::set_shader(GLenum stage,
+ const uint32_t *spirv,
+ size_t spirv_words)
+{
+ if (stage == GL_VERTEX_SHADER)
+ {
+ vertex_shader.clear();
+ vertex_shader.insert(end(vertex_shader),
+ spirv, spirv + spirv_words);
+ }
+ else if (stage == GL_FRAGMENT_SHADER)
+ {
+ fragment_shader.clear();
+ fragment_shader.insert(end(fragment_shader),
+ spirv, spirv + spirv_words);
+ }
+}
+
+void Pass::add_parameter(unsigned index, const std::string &id)
+{
+ parameters.push_back({ id, index, unsigned(parameters.size()) });
+}
+
+void Pass::set_texture(unsigned binding, const Texture &texture)
+{
+ glActiveTexture(GL_TEXTURE0 + binding);
+ glBindTexture(GL_TEXTURE_2D, texture.texture.image);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_filter_to_mag_gl(texture.filter));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_filter_to_min_gl(texture.filter, texture.mip_filter));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, address_to_gl(texture.address));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, address_to_gl(texture.address));
+}
+
+void Pass::set_semantic_texture(slang_texture_semantic semantic, const Texture &texture)
+{
+ if (reflection.semantic_textures[semantic][0].texture)
+ set_texture(reflection.semantic_textures[semantic][0].binding, texture);
+}
+
+void Pass::build_semantic_texture_array(uint8_t *buffer,
+ slang_texture_semantic semantic, unsigned index, const Texture &texture)
+{
+ build_semantic_texture_array_vec4(buffer, semantic, index,
+ texture.texture.width, texture.texture.height);
+ set_semantic_texture_array(semantic, index, texture);
+}
+
+void Pass::build_semantics(uint8_t *buffer,
+ const float *mvp, const Texture &original, const Texture &source)
+{
+ /* MVP */
+ if (buffer && reflection.semantics[SLANG_SEMANTIC_MVP].uniform)
+ {
+ size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].ubo_offset;
+ if (mvp)
+ memcpy(buffer + offset, mvp, sizeof(float) * 16);
+ else
+ build_default_matrix(reinterpret_cast(buffer + offset));
+ }
+
+ if (reflection.semantics[SLANG_SEMANTIC_MVP].push_constant)
+ {
+ size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].push_constant_offset;
+ if (mvp)
+ memcpy(push_constant_buffer.data() + offset, mvp, sizeof(float) * 16);
+ else
+ build_default_matrix(reinterpret_cast(push_constant_buffer.data() + offset));
+ }
+
+ /* Output information */
+ build_semantic_vec4(buffer, SLANG_SEMANTIC_OUTPUT,
+ current_framebuffer_size.width, current_framebuffer_size.height);
+ build_semantic_vec4(buffer, SLANG_SEMANTIC_FINAL_VIEWPORT,
+ unsigned(current_viewport.width), unsigned(current_viewport.height));
+
+ build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_COUNT,
+ frame_count_period ? uint32_t(frame_count % frame_count_period) : uint32_t(frame_count));
+
+ /* Standard inputs */
+ build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original);
+ build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source);
+
+ /* ORIGINAL_HISTORY[0] is an alias of ORIGINAL. */
+ build_semantic_texture_array(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
+
+ /* Parameters. */
+ for (auto ¶m : filtered_parameters)
+ {
+ float value = common->shader_preset->parameters[param.index].current;
+ build_semantic_parameter(buffer, param.semantic_index, value);
+ }
+
+ /* Previous inputs. */
+ unsigned i = 0;
+ for (auto &texture : common->original_history)
+ {
+ build_semantic_texture_array(buffer,
+ SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, i + 1,
+ texture);
+ i++;
+ }
+
+ /* Previous passes. */
+ i = 0;
+ for (auto &texture : common->pass_outputs)
+ {
+ build_semantic_texture_array(buffer,
+ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i,
+ texture);
+ i++;
+ }
+
+ /* Feedback FBOs. */
+ i = 0;
+ for (auto &texture : common->framebuffer_feedback)
+ {
+ build_semantic_texture_array(buffer,
+ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i,
+ texture);
+ i++;
+ }
+
+ /* LUTs. */
+ i = 0;
+ for (auto &lut : common->luts)
+ {
+ build_semantic_texture_array(buffer,
+ SLANG_TEXTURE_SEMANTIC_USER, i,
+ lut->get_texture());
+ i++;
+ }
+}
+
+void Pass::build_commands(
+ const Texture &original,
+ const Texture &source,
+ const gl_core_viewport &vp,
+ const float *mvp)
+{
+ current_viewport = vp;
+ auto size = get_output_size(
+ { original.texture.width, original.texture.height },
+ { source.texture.width, source.texture.height });
+
+ if (framebuffer &&
+ (size.width != framebuffer->get_size().width ||
+ size.height != framebuffer->get_size().height))
+ {
+ framebuffer->set_size(size);
+ }
+ current_framebuffer_size = size;
+
+ glUseProgram(pipeline);
+
+ build_semantics(uniforms.data(), mvp, original, source);
+
+ if (locations.flat_ubo_vertex >= 0)
+ {
+ glUniform4fv(locations.flat_ubo_vertex,
+ GLsizei((reflection.ubo_size + 15) / 16),
+ reinterpret_cast(uniforms.data()));
+ }
+
+ if (locations.flat_ubo_fragment >= 0)
+ {
+ glUniform4fv(locations.flat_ubo_fragment,
+ GLsizei((reflection.ubo_size + 15) / 16),
+ reinterpret_cast(uniforms.data()));
+ }
+
+ if (locations.flat_push_vertex >= 0)
+ {
+ glUniform4fv(locations.flat_push_vertex,
+ GLsizei((reflection.push_constant_size + 15) / 16),
+ reinterpret_cast(push_constant_buffer.data()));
+ }
+
+ if (locations.flat_push_fragment >= 0)
+ {
+ glUniform4fv(locations.flat_push_fragment,
+ GLsizei((reflection.push_constant_size + 15) / 16),
+ reinterpret_cast(push_constant_buffer.data()));
+ }
+
+ ubo_ring.update_and_bind(locations.buffer_index_ubo_vertex, locations.buffer_index_ubo_fragment,
+ uniforms.data(), reflection.ubo_size);
+
+ /* The final pass is always executed inside
+ * another render pass since the frontend will
+ * want to overlay various things on top for
+ * the passes that end up on-screen. */
+ if (!final_pass && framebuffer->is_complete())
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->get_framebuffer());
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ if (final_pass)
+ {
+ glViewport(current_viewport.x, current_viewport.y,
+ current_viewport.width, current_viewport.height);
+ }
+ else
+ {
+ glViewport(0, 0, size.width, size.height);
+ }
+
+#ifndef HAVE_OPENGLES3
+ if (framebuffer && framebuffer->get_format() == GL_SRGB8_ALPHA8)
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ else
+ glDisable(GL_FRAMEBUFFER_SRGB);
+#endif
+
+ common->draw_quad();
+#ifndef HAVE_OPENGLES3
+ glDisable(GL_FRAMEBUFFER_SRGB);
+#endif
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ if (!final_pass)
+ {
+ if (framebuffer->get_levels() > 1)
+ framebuffer->generate_mips();
+ }
+}
+
+}
+
+struct gl_core_filter_chain
+{
+public:
+ gl_core_filter_chain(unsigned num_passes)
+ {
+ set_num_passes(num_passes);
+ }
+
+ inline void set_shader_preset(unique_ptr shader)
+ {
+ common.shader_preset = move(shader);
+ }
+
+ inline video_shader *get_shader_preset()
+ {
+ return common.shader_preset.get();
+ }
+
+ void set_pass_info(unsigned pass,
+ const gl_core_filter_chain_pass_info &info);
+ void set_shader(unsigned pass, GLenum stage,
+ const uint32_t *spirv, size_t spirv_words);
+
+ bool init();
+
+ void set_input_texture(const gl_core_filter_chain_texture &texture);
+ void build_offscreen_passes(const gl_core_viewport &vp);
+ void build_viewport_pass(const gl_core_viewport &vp, const float *mvp);
+ void end_frame();
+
+ void set_frame_count(uint64_t count);
+ void set_frame_count_period(unsigned pass, unsigned period);
+ void set_pass_name(unsigned pass, const char *name);
+
+ void add_static_texture(unique_ptr texture);
+ void add_parameter(unsigned pass, unsigned parameter_index, const std::string &id);
+ void set_num_passes(unsigned passes);
+
+private:
+ vector> passes;
+ vector pass_info;
+ vector>> deferred_calls;
+ std::unique_ptr copy_framebuffer;
+ gl_core::CommonResources common;
+
+ gl_core_filter_chain_texture input_texture = {};
+
+ bool init_history();
+ bool init_feedback();
+ bool init_alias();
+ vector> original_history;
+ void update_history();
+ bool require_clear = false;
+ void clear_history_and_feedback();
+ void update_feedback_info();
+ void update_history_info();
+};
+
+void gl_core_filter_chain::clear_history_and_feedback()
+{
+ for (auto &texture : original_history)
+ texture->clear();
+ for (auto &pass : passes)
+ {
+ auto *fb = pass->get_feedback_framebuffer();
+ if (fb)
+ fb->clear();
+ }
+}
+
+void gl_core_filter_chain::update_history_info()
+{
+ unsigned i = 0;
+ for (auto &texture : original_history)
+ {
+ auto &source = common.original_history[i];
+ source.texture.image = texture->get_image();
+ source.texture.width = texture->get_size().width;
+ source.texture.height = texture->get_size().height;
+ source.filter = passes.front()->get_source_filter();
+ source.mip_filter = passes.front()->get_mip_filter();
+ source.address = passes.front()->get_address_mode();
+ i++;
+ }
+}
+
+void gl_core_filter_chain::update_feedback_info()
+{
+ if (common.framebuffer_feedback.empty())
+ return;
+
+ for (unsigned i = 0; i < passes.size() - 1; i++)
+ {
+ auto fb = passes[i]->get_feedback_framebuffer();
+ if (!fb)
+ continue;
+
+ auto &source = common.framebuffer_feedback[i];
+ source.texture.image = fb->get_image();
+ source.texture.width = fb->get_size().width;
+ source.texture.height = fb->get_size().height;
+ source.filter = passes[i]->get_source_filter();
+ source.mip_filter = passes[i]->get_mip_filter();
+ source.address = passes[i]->get_address_mode();
+ }
+}
+
+void gl_core_filter_chain::build_offscreen_passes(const gl_core_viewport &vp)
+{
+ /* First frame, make sure our history and feedback textures are in a clean state. */
+ if (require_clear)
+ {
+ clear_history_and_feedback();
+ require_clear = false;
+ }
+
+ update_history_info();
+ update_feedback_info();
+
+ const gl_core::Texture original = {
+ input_texture,
+ passes.front()->get_source_filter(),
+ passes.front()->get_mip_filter(),
+ passes.front()->get_address_mode(),
+ };
+ gl_core::Texture source = original;
+
+ for (unsigned i = 0; i < passes.size() - 1; i++)
+ {
+ passes[i]->build_commands(original, source, vp, nullptr);
+
+ auto &fb = passes[i]->get_framebuffer();
+ source.texture.image = fb.get_image();
+ source.texture.width = fb.get_size().width;
+ source.texture.height = fb.get_size().height;
+ source.filter = passes[i + 1]->get_source_filter();
+ source.mip_filter = passes[i + 1]->get_mip_filter();
+ source.address = passes[i + 1]->get_address_mode();
+
+ common.pass_outputs[i] = source;
+ }
+}
+
+void gl_core_filter_chain::update_history()
+{
+ unique_ptr tmp;
+ unique_ptr &back = original_history.back();
+ swap(back, tmp);
+
+ if (input_texture.width != tmp->get_size().width ||
+ input_texture.height != tmp->get_size().height ||
+ (input_texture.format != 0 && input_texture.format != tmp->get_format()))
+ {
+ tmp->set_size({ input_texture.width, input_texture.height }, input_texture.format);
+ }
+
+ tmp->copy(common, input_texture.image);
+
+ /* Should ring buffer, but we don't have *that* many passes. */
+ move_backward(begin(original_history), end(original_history) - 1, end(original_history));
+ swap(original_history.front(), tmp);
+}
+
+void gl_core_filter_chain::end_frame()
+{
+ /* If we need to keep old frames, copy it after fragment is complete.
+ * TODO: We can improve pipelining by figuring out which
+ * pass is the last that reads from
+ * the history and dispatch the copy earlier. */
+ if (!original_history.empty())
+ {
+ update_history();
+ }
+}
+
+void gl_core_filter_chain::build_viewport_pass(
+ const gl_core_viewport &vp, const float *mvp)
+{
+ /* First frame, make sure our history and feedback textures are in a clean state. */
+ if (require_clear)
+ {
+ clear_history_and_feedback();
+ require_clear = false;
+ }
+
+ gl_core::Texture source;
+ const gl_core::Texture original = {
+ input_texture,
+ passes.front()->get_source_filter(),
+ passes.front()->get_mip_filter(),
+ passes.front()->get_address_mode(),
+ };
+
+ if (passes.size() == 1)
+ {
+ source = {
+ input_texture,
+ passes.back()->get_source_filter(),
+ passes.back()->get_mip_filter(),
+ passes.back()->get_address_mode(),
+ };
+ }
+ else
+ {
+ auto &fb = passes[passes.size() - 2]->get_framebuffer();
+ source.texture.image = fb.get_image();
+ source.texture.width = fb.get_size().width;
+ source.texture.height = fb.get_size().height;
+ source.filter = passes.back()->get_source_filter();
+ source.mip_filter = passes.back()->get_mip_filter();
+ source.address = passes.back()->get_address_mode();
+ }
+
+ passes.back()->build_commands(original, source, vp, mvp);
+
+ /* For feedback FBOs, swap current and previous. */
+ for (auto &pass : passes)
+ pass->end_frame();
+}
+
+bool gl_core_filter_chain::init_history()
+{
+ original_history.clear();
+ common.original_history.clear();
+
+ size_t required_images = 0;
+ for (auto &pass : passes)
+ {
+ required_images =
+ max(required_images,
+ pass->get_reflection().semantic_textures[SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY].size());
+ }
+
+ if (required_images < 2)
+ {
+ RARCH_LOG("[GLCore]: Not using frame history.\n");
+ return true;
+ }
+
+ /* We don't need to store array element #0,
+ * since it's aliased with the actual original. */
+ required_images--;
+ original_history.reserve(required_images);
+ common.original_history.resize(required_images);
+
+ for (unsigned i = 0; i < required_images; i++)
+ {
+ original_history.emplace_back(new gl_core::Framebuffer(0, 1));
+ }
+
+ RARCH_LOG("[GLCore]: Using history of %u frames.\n", required_images);
+
+ /* On first frame, we need to clear the textures to
+ * a known state, but we need
+ * a command buffer for that, so just defer to first frame.
+ */
+ require_clear = true;
+ return true;
+}
+
+bool gl_core_filter_chain::init_feedback()
+{
+ common.framebuffer_feedback.clear();
+
+ bool use_feedbacks = false;
+
+ /* Final pass cannot have feedback. */
+ for (unsigned i = 0; i < passes.size() - 1; i++)
+ {
+ bool use_feedback = false;
+ for (auto &pass : passes)
+ {
+ auto &r = pass->get_reflection();
+ auto &feedbacks = r.semantic_textures[SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK];
+ if (i < feedbacks.size() && feedbacks[i].texture)
+ {
+ use_feedback = true;
+ use_feedbacks = true;
+ break;
+ }
+ }
+
+ if (use_feedback && !passes[i]->init_feedback())
+ return false;
+
+ if (use_feedback)
+ RARCH_LOG("[GLCore]: Using framebuffer feedback for pass #%u.\n", i);
+ }
+
+ if (!use_feedbacks)
+ {
+ RARCH_LOG("[GLCore]: Not using framebuffer feedback.\n");
+ return true;
+ }
+
+ common.framebuffer_feedback.resize(passes.size() - 1);
+ require_clear = true;
+ return true;
+}
+
+bool gl_core_filter_chain::init_alias()
+{
+ common.texture_semantic_map.clear();
+ common.texture_semantic_uniform_map.clear();
+
+ for (auto &pass : passes)
+ {
+ auto &name = pass->get_name();
+ if (name.empty())
+ continue;
+
+ unsigned i = &pass - passes.data();
+
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_map, name,
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
+ return false;
+
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_uniform_map, name + "Size",
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
+ return false;
+
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_map, name + "Feedback",
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
+ return false;
+
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_uniform_map, name + "FeedbackSize",
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
+ return false;
+ }
+
+ for (auto &lut : common.luts)
+ {
+ unsigned i = &lut - common.luts.data();
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_map, lut->get_id(),
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i }))
+ return false;
+
+ if (!gl_core_shader_set_unique_map(common.texture_semantic_uniform_map, lut->get_id() + "Size",
+ slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i }))
+ return false;
+ }
+
+ return true;
+}
+
+void gl_core_filter_chain::set_pass_info(unsigned pass, const gl_core_filter_chain_pass_info &info)
+{
+ if (pass >= pass_info.size())
+ pass_info.resize(pass + 1);
+ pass_info[pass] = info;
+}
+
+void gl_core_filter_chain::set_num_passes(unsigned num_passes)
+{
+ pass_info.resize(num_passes);
+ passes.reserve(num_passes);
+ for (unsigned i = 0; i < num_passes; i++)
+ {
+ passes.emplace_back(new gl_core::Pass(i + 1 == num_passes));
+ passes.back()->set_common_resources(&common);
+ passes.back()->set_pass_number(i);
+ }
+}
+
+void gl_core_filter_chain::set_shader(unsigned pass, GLenum stage, const uint32_t *spirv, size_t spirv_words)
+{
+ passes[pass]->set_shader(stage, spirv, spirv_words);
+}
+
+void gl_core_filter_chain::add_parameter(unsigned pass, unsigned index, const std::string &id)
+{
+ passes[pass]->add_parameter(index, id);
+}
+
+bool gl_core_filter_chain::init()
+{
+ if (!init_alias())
+ return false;
+
+ for (unsigned i = 0; i < passes.size(); i++)
+ {
+ auto &pass = passes[i];
+ RARCH_LOG("[slang]: Building pass #%u (%s)\n", i,
+ pass->get_name().empty() ?
+ msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE) :
+ pass->get_name().c_str());
+
+ pass->set_pass_info(pass_info[i]);
+ if (!pass->build())
+ return false;
+ }
+
+ require_clear = false;
+ if (!init_history())
+ return false;
+ if (!init_feedback())
+ return false;
+ common.pass_outputs.resize(passes.size());
+ return true;
+}
+
+void gl_core_filter_chain::set_input_texture(
+ const gl_core_filter_chain_texture &texture)
+{
+ input_texture = texture;
+
+ // Need a copy to remove padding.
+ // GL HW render interface in libretro is kinda garbage now ...
+ if (input_texture.padded_width != input_texture.width ||
+ input_texture.padded_height != input_texture.height)
+ {
+ if (!copy_framebuffer)
+ copy_framebuffer.reset(new gl_core::Framebuffer(texture.format, 1));
+
+ if (input_texture.width != copy_framebuffer->get_size().width ||
+ input_texture.height != copy_framebuffer->get_size().height ||
+ (input_texture.format != 0 && input_texture.format != copy_framebuffer->get_format()))
+ {
+ copy_framebuffer->set_size({ input_texture.width, input_texture.height }, input_texture.format);
+ }
+
+ copy_framebuffer->copy_partial(common, input_texture.image,
+ float(input_texture.width) / input_texture.padded_width,
+ float(input_texture.height) / input_texture.padded_height);
+ input_texture.image = copy_framebuffer->get_image();
+ }
+}
+
+void gl_core_filter_chain::add_static_texture(unique_ptr texture)
+{
+ common.luts.push_back(move(texture));
+}
+
+void gl_core_filter_chain::set_frame_count(uint64_t count)
+{
+ for (auto &pass : passes)
+ pass->set_frame_count(count);
+}
+
+void gl_core_filter_chain::set_frame_count_period(unsigned pass, unsigned period)
+{
+ passes[pass]->set_frame_count_period(period);
+}
+
+void gl_core_filter_chain::set_pass_name(unsigned pass, const char *name)
+{
+ passes[pass]->set_name(name);
+}
+
+static unique_ptr gl_core_filter_chain_load_lut(
+ gl_core_filter_chain *chain,
+ const video_shader_lut *shader)
+{
+ texture_image image = {};
+ image.supports_rgba = true;
+
+ if (!image_texture_load(&image, shader->path))
+ return {};
+
+ unsigned levels = shader->mipmap ? gl_core::num_miplevels(image.width, image.height) : 1;
+ GLuint tex = 0;
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexStorage2D(GL_TEXTURE_2D, levels,
+ GL_RGBA8, image.width, image.height);
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ image.width, image.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, image.pixels);
+
+ if (levels > 1)
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ if (image.pixels)
+ image_texture_free(&image);
+
+ return unique_ptr(new gl_core::StaticTexture(shader->id,
+ tex, image.width, image.height,
+ shader->filter != RARCH_FILTER_NEAREST,
+ levels > 1,
+ gl_core::address_to_gl(gl_core::wrap_to_address(shader->wrap))));
+}
+
+static bool gl_core_filter_chain_load_luts(
+ gl_core_filter_chain *chain,
+ video_shader *shader)
+{
+ for (unsigned i = 0; i < shader->luts; i++)
+ {
+ auto image = gl_core_filter_chain_load_lut(chain, &shader->lut[i]);
+ if (!image)
+ {
+ RARCH_ERR("[GLCore]: Failed to load LUT \"%s\".\n", shader->lut[i].path);
+ return false;
+ }
+
+ chain->add_static_texture(move(image));
+ }
+
+ return true;
+}
+
+gl_core_filter_chain_t *gl_core_filter_chain_create_default(
+ gl_core_filter_chain_filter filter)
+{
+ struct gl_core_filter_chain_pass_info pass_info;
+
+ unique_ptr chain{ new gl_core_filter_chain(1) };
+ if (!chain)
+ return nullptr;
+
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ pass_info.scale_x = 1.0f;
+ pass_info.scale_y = 1.0f;
+ pass_info.rt_format = 0;
+ pass_info.source_filter = filter;
+ pass_info.mip_filter = GL_CORE_FILTER_CHAIN_NEAREST;
+ pass_info.address = GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
+ pass_info.max_levels = 0;
+
+ chain->set_pass_info(0, pass_info);
+
+ chain->set_shader(0, GL_VERTEX_SHADER,
+ gl_core::opaque_vert,
+ sizeof(gl_core::opaque_vert) / sizeof(uint32_t));
+ chain->set_shader(0, GL_FRAGMENT_SHADER,
+ gl_core::opaque_frag,
+ sizeof(gl_core::opaque_frag) / sizeof(uint32_t));
+
+ if (!chain->init())
+ return nullptr;
+
+ return chain.release();
+}
+
+gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
+ const char *path, gl_core_filter_chain_filter filter)
+{
+ unsigned i;
+ unique_ptr shader{ new video_shader() };
+ if (!shader)
+ return nullptr;
+
+ unique_ptr conf{ config_file_new(path) };
+ if (!conf)
+ return nullptr;
+
+ if (!video_shader_read_conf_cgp(conf.get(), shader.get()))
+ return nullptr;
+
+ video_shader_resolve_relative(shader.get(), path);
+
+ bool last_pass_is_fbo = shader->pass[shader->passes - 1].fbo.valid;
+
+ unique_ptr chain{ new gl_core_filter_chain(shader->passes + (last_pass_is_fbo ? 1 : 0)) };
+ if (!chain)
+ return nullptr;
+
+ if (shader->luts && !gl_core_filter_chain_load_luts(chain.get(), shader.get()))
+ return nullptr;
+
+ shader->num_parameters = 0;
+
+ for (i = 0; i < shader->passes; i++)
+ {
+ glslang_output output;
+ struct gl_core_filter_chain_pass_info pass_info;
+ const video_shader_pass *pass = &shader->pass[i];
+ const video_shader_pass *next_pass =
+ i + 1 < shader->passes ? &shader->pass[i + 1] : nullptr;
+
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_ORIGINAL;
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_ORIGINAL;
+ pass_info.scale_x = 0.0f;
+ pass_info.scale_y = 0.0f;
+ pass_info.rt_format = 0;
+ pass_info.source_filter = GL_CORE_FILTER_CHAIN_LINEAR;
+ pass_info.mip_filter = GL_CORE_FILTER_CHAIN_LINEAR;
+ pass_info.address = GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT;
+ pass_info.max_levels = 0;
+
+ if (!glslang_compile_shader(pass->source.path, &output))
+ {
+ RARCH_ERR("Failed to compile shader: \"%s\".\n",
+ pass->source.path);
+ return nullptr;
+ }
+
+ for (auto &meta_param : output.meta.parameters)
+ {
+ if (shader->num_parameters >= GFX_MAX_PARAMETERS)
+ {
+ RARCH_ERR("[GLCore]: Exceeded maximum number of parameters.\n");
+ return nullptr;
+ }
+
+ auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters,
+ [&](const video_shader_parameter ¶m)
+ {
+ return meta_param.id == param.id;
+ });
+
+ if (itr != shader->parameters + shader->num_parameters)
+ {
+ /* Allow duplicate #pragma parameter, but
+ * only if they are exactly the same. */
+ if (meta_param.desc != itr->desc ||
+ meta_param.initial != itr->initial ||
+ meta_param.minimum != itr->minimum ||
+ meta_param.maximum != itr->maximum ||
+ meta_param.step != itr->step)
+ {
+ RARCH_ERR("[GLCore]: Duplicate parameters found for \"%s\", but arguments do not match.\n",
+ itr->id);
+ return nullptr;
+ }
+ chain->add_parameter(i, itr - shader->parameters, meta_param.id);
+ }
+ else
+ {
+ auto ¶m = shader->parameters[shader->num_parameters];
+ strlcpy(param.id, meta_param.id.c_str(), sizeof(param.id));
+ strlcpy(param.desc, meta_param.desc.c_str(), sizeof(param.desc));
+ param.current = meta_param.initial;
+ param.initial = meta_param.initial;
+ param.minimum = meta_param.minimum;
+ param.maximum = meta_param.maximum;
+ param.step = meta_param.step;
+ chain->add_parameter(i, shader->num_parameters, meta_param.id);
+ shader->num_parameters++;
+ }
+ }
+
+ chain->set_shader(i,
+ GL_VERTEX_SHADER,
+ output.vertex.data(),
+ output.vertex.size());
+
+ chain->set_shader(i,
+ GL_FRAGMENT_SHADER,
+ output.fragment.data(),
+ output.fragment.size());
+
+ chain->set_frame_count_period(i, pass->frame_count_mod);
+
+ if (!output.meta.name.empty())
+ chain->set_pass_name(i, output.meta.name.c_str());
+
+ /* Preset overrides. */
+ if (*pass->alias)
+ chain->set_pass_name(i, pass->alias);
+
+ if (pass->filter == RARCH_FILTER_UNSPEC)
+ pass_info.source_filter = filter;
+ else
+ {
+ pass_info.source_filter =
+ pass->filter == RARCH_FILTER_LINEAR ? GL_CORE_FILTER_CHAIN_LINEAR :
+ GL_CORE_FILTER_CHAIN_NEAREST;
+ }
+ pass_info.address = gl_core::wrap_to_address(pass->wrap);
+ pass_info.max_levels = 1;
+
+ /* TODO: Expose max_levels in slangp.
+ * CGP format is a bit awkward in that it uses mipmap_input,
+ * so we much check if next pass needs the mipmapping.
+ */
+ if (next_pass && next_pass->mipmap)
+ pass_info.max_levels = ~0u;
+
+ pass_info.mip_filter = pass->filter != RARCH_FILTER_NEAREST && pass_info.max_levels > 1
+ ? GL_CORE_FILTER_CHAIN_LINEAR : GL_CORE_FILTER_CHAIN_NEAREST;
+
+ bool explicit_format = output.meta.rt_format != SLANG_FORMAT_UNKNOWN;
+
+ /* Set a reasonable default. */
+ if (output.meta.rt_format == SLANG_FORMAT_UNKNOWN)
+ output.meta.rt_format = SLANG_FORMAT_R8G8B8A8_UNORM;
+
+ if (!pass->fbo.valid)
+ {
+ pass_info.scale_type_x = i + 1 == shader->passes
+ ? GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT
+ : GL_CORE_FILTER_CHAIN_SCALE_SOURCE;
+ pass_info.scale_type_y = i + 1 == shader->passes
+ ? GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT
+ : GL_CORE_FILTER_CHAIN_SCALE_SOURCE;
+ pass_info.scale_x = 1.0f;
+ pass_info.scale_y = 1.0f;
+
+ if (i + 1 == shader->passes)
+ {
+ pass_info.rt_format = 0;
+
+ if (explicit_format)
+ RARCH_WARN("[slang]: Using explicit format for last pass in chain,"
+ " but it is not rendered to framebuffer, using swapchain format instead.\n");
+ }
+ else
+ {
+ pass_info.rt_format = gl_core::convert_glslang_format(output.meta.rt_format);
+ RARCH_LOG("[slang]: Using render target format %s for pass output #%u.\n",
+ glslang_format_to_string(output.meta.rt_format), i);
+ }
+ }
+ else
+ {
+ /* Preset overrides shader.
+ * Kinda ugly ... */
+ if (pass->fbo.srgb_fbo)
+ output.meta.rt_format = SLANG_FORMAT_R8G8B8A8_SRGB;
+ else if (pass->fbo.fp_fbo)
+ output.meta.rt_format = SLANG_FORMAT_R16G16B16A16_SFLOAT;
+
+ pass_info.rt_format = gl_core::convert_glslang_format(output.meta.rt_format);
+ RARCH_LOG("[slang]: Using render target format %s for pass output #%u.\n",
+ glslang_format_to_string(output.meta.rt_format), i);
+
+ switch (pass->fbo.type_x)
+ {
+ case RARCH_SCALE_INPUT:
+ pass_info.scale_x = pass->fbo.scale_x;
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_SOURCE;
+ break;
+
+ case RARCH_SCALE_ABSOLUTE:
+ pass_info.scale_x = float(pass->fbo.abs_x);
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_ABSOLUTE;
+ break;
+
+ case RARCH_SCALE_VIEWPORT:
+ pass_info.scale_x = pass->fbo.scale_x;
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ break;
+ }
+
+ switch (pass->fbo.type_y)
+ {
+ case RARCH_SCALE_INPUT:
+ pass_info.scale_y = pass->fbo.scale_y;
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_SOURCE;
+ break;
+
+ case RARCH_SCALE_ABSOLUTE:
+ pass_info.scale_y = float(pass->fbo.abs_y);
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_ABSOLUTE;
+ break;
+
+ case RARCH_SCALE_VIEWPORT:
+ pass_info.scale_y = pass->fbo.scale_y;
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ break;
+ }
+ }
+
+ chain->set_pass_info(i, pass_info);
+ }
+
+ if (last_pass_is_fbo)
+ {
+ struct gl_core_filter_chain_pass_info pass_info;
+
+ pass_info.scale_type_x = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ pass_info.scale_type_y = GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT;
+ pass_info.scale_x = 1.0f;
+ pass_info.scale_y = 1.0f;
+
+ pass_info.rt_format = 0;
+
+ pass_info.source_filter = filter;
+ pass_info.mip_filter = GL_CORE_FILTER_CHAIN_NEAREST;
+ pass_info.address = GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
+
+ pass_info.max_levels = 0;
+
+ chain->set_pass_info(shader->passes, pass_info);
+
+ chain->set_shader(shader->passes,
+ GL_VERTEX_SHADER,
+ gl_core::opaque_vert,
+ sizeof(gl_core::opaque_vert) / sizeof(uint32_t));
+
+ chain->set_shader(shader->passes,
+ GL_FRAGMENT_SHADER,
+ gl_core::opaque_frag,
+ sizeof(gl_core::opaque_frag) / sizeof(uint32_t));
+ }
+
+ if (!video_shader_resolve_current_parameters(conf.get(), shader.get()))
+ return nullptr;
+
+ chain->set_shader_preset(move(shader));
+
+ if (!chain->init())
+ return nullptr;
+
+ return chain.release();
+}
+
+struct video_shader *gl_core_filter_chain_get_preset(
+ gl_core_filter_chain_t *chain)
+{
+ return chain->get_shader_preset();
+}
+
+void gl_core_filter_chain_free(
+ gl_core_filter_chain_t *chain)
+{
+ delete chain;
+}
+
+void gl_core_filter_chain_set_shader(
+ gl_core_filter_chain_t *chain,
+ unsigned pass,
+ GLenum shader_stage,
+ const uint32_t *spirv,
+ size_t spirv_words)
+{
+ chain->set_shader(pass, shader_stage, spirv, spirv_words);
+}
+
+void gl_core_filter_chain_set_pass_info(
+ gl_core_filter_chain_t *chain,
+ unsigned pass,
+ const struct gl_core_filter_chain_pass_info *info)
+{
+ chain->set_pass_info(pass, *info);
+}
+
+bool gl_core_filter_chain_init(gl_core_filter_chain_t *chain)
+{
+ return chain->init();
+}
+
+void gl_core_filter_chain_set_input_texture(
+ gl_core_filter_chain_t *chain,
+ const struct gl_core_filter_chain_texture *texture)
+{
+ chain->set_input_texture(*texture);
+}
+
+void gl_core_filter_chain_set_frame_count(
+ gl_core_filter_chain_t *chain,
+ uint64_t count)
+{
+ chain->set_frame_count(count);
+}
+
+void gl_core_filter_chain_set_frame_count_period(
+ gl_core_filter_chain_t *chain,
+ unsigned pass,
+ unsigned period)
+{
+ chain->set_frame_count_period(pass, period);
+}
+
+void gl_core_filter_chain_set_pass_name(
+ gl_core_filter_chain_t *chain,
+ unsigned pass,
+ const char *name)
+{
+ chain->set_pass_name(pass, name);
+}
+
+void gl_core_filter_chain_build_offscreen_passes(
+ gl_core_filter_chain_t *chain,
+ const gl_core_viewport *vp)
+{
+ chain->build_offscreen_passes(*vp);
+}
+
+void gl_core_filter_chain_build_viewport_pass(
+ gl_core_filter_chain_t *chain,
+ const gl_core_viewport *vp, const float *mvp)
+{
+ chain->build_viewport_pass(*vp, mvp);
+}
+
+void gl_core_filter_chain_end_frame(gl_core_filter_chain_t *chain)
+{
+ chain->end_frame();
+}
diff --git a/gfx/drivers_shader/shader_gl_core.h b/gfx/drivers_shader/shader_gl_core.h
new file mode 100644
index 0000000000..7dbf586ab2
--- /dev/null
+++ b/gfx/drivers_shader/shader_gl_core.h
@@ -0,0 +1,157 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2019 - 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 .
+ */
+
+#ifndef SHADER_GL_CORE_H
+#define SHADER_GL_CORE_H
+
+#include
+#include
+
+#include
+#include
+#include
+
+RETRO_BEGIN_DECLS
+
+typedef struct gl_core_filter_chain gl_core_filter_chain_t;
+
+enum gl_core_filter_chain_filter
+{
+ GL_CORE_FILTER_CHAIN_LINEAR = 0,
+ GL_CORE_FILTER_CHAIN_NEAREST = 1,
+ GL_CORE_FILTER_CHAIN_COUNT
+};
+
+enum gl_core_filter_chain_address
+{
+ GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT = 0,
+ GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT = 1,
+ GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE = 2,
+ GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER = 3,
+ GL_CORE_FILTER_CHAIN_ADDRESS_MIRROR_CLAMP_TO_EDGE = 4,
+ GL_CORE_FILTER_CHAIN_ADDRESS_COUNT
+};
+
+struct gl_core_filter_chain_texture
+{
+ GLuint image;
+ unsigned width;
+ unsigned height;
+ unsigned padded_width;
+ unsigned padded_height;
+ GLenum format;
+};
+
+struct gl_core_viewport
+{
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+};
+
+enum gl_core_filter_chain_scale
+{
+ GL_CORE_FILTER_CHAIN_SCALE_ORIGINAL,
+ GL_CORE_FILTER_CHAIN_SCALE_SOURCE,
+ GL_CORE_FILTER_CHAIN_SCALE_VIEWPORT,
+ GL_CORE_FILTER_CHAIN_SCALE_ABSOLUTE
+};
+
+struct gl_core_filter_chain_pass_info
+{
+ /* For the last pass, make sure VIEWPORT scale
+ * with scale factors of 1 are used. */
+ enum gl_core_filter_chain_scale scale_type_x;
+ enum gl_core_filter_chain_scale scale_type_y;
+ float scale_x;
+ float scale_y;
+
+ /* Ignored for the last pass, swapchain info will be used instead. */
+ GLenum rt_format;
+
+ /* The filter to use for source in this pass. */
+ enum gl_core_filter_chain_filter source_filter;
+ enum gl_core_filter_chain_filter mip_filter;
+ enum gl_core_filter_chain_address address;
+
+ /* Maximum number of mip-levels to use. */
+ unsigned max_levels;
+};
+
+gl_core_filter_chain_t *gl_core_filter_chain_new(void);
+void gl_core_filter_chain_free(gl_core_filter_chain_t *chain);
+
+void gl_core_filter_chain_set_shader(gl_core_filter_chain_t *chain,
+ unsigned pass,
+ GLenum shader_type,
+ const uint32_t *spirv,
+ size_t spirv_words);
+
+void gl_core_filter_chain_set_pass_info(gl_core_filter_chain_t *chain,
+ unsigned pass,
+ const struct gl_core_filter_chain_pass_info *info);
+
+bool gl_core_filter_chain_init(gl_core_filter_chain_t *chain);
+
+void gl_core_filter_chain_set_input_texture(
+ gl_core_filter_chain_t *chain,
+ const struct gl_core_filter_chain_texture *texture);
+
+void gl_core_filter_chain_set_frame_count(gl_core_filter_chain_t *chain,
+ uint64_t count);
+
+void gl_core_filter_chain_set_frame_count_period(gl_core_filter_chain_t *chain,
+ unsigned pass,
+ unsigned period);
+
+void gl_core_filter_chain_set_pass_name(gl_core_filter_chain_t *chain,
+ unsigned pass,
+ const char *name);
+
+void gl_core_filter_chain_build_offscreen_passes(gl_core_filter_chain_t *chain,
+ const struct gl_core_viewport *vp);
+void gl_core_filter_chain_build_viewport_pass(gl_core_filter_chain_t *chain,
+ const struct gl_core_viewport *vp,
+ const float *mvp);
+
+gl_core_filter_chain_t *gl_core_filter_chain_create_default(
+ enum gl_core_filter_chain_filter filter);
+
+gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
+ const char *path, enum gl_core_filter_chain_filter filter);
+
+struct video_shader *gl_core_filter_chain_get_preset(
+ gl_core_filter_chain_t *chain);
+
+void gl_core_filter_chain_end_frame(gl_core_filter_chain_t *chain);
+
+struct gl_core_buffer_locations
+{
+ GLint flat_ubo_vertex;
+ GLint flat_ubo_fragment;
+ GLint flat_push_vertex;
+ GLint flat_push_fragment;
+ GLuint buffer_index_ubo_vertex;
+ GLuint buffer_index_ubo_fragment;
+};
+
+GLuint gl_core_cross_compile_program(const uint32_t *vertex, size_t vertex_size,
+ const uint32_t *fragment, size_t fragment_size,
+ struct gl_core_buffer_locations *loc, bool flatten);
+
+RETRO_END_DECLS
+
+#endif
diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp
index 9dff3c500b..5e36f7627e 100644
--- a/gfx/drivers_shader/shader_vulkan.cpp
+++ b/gfx/drivers_shader/shader_vulkan.cpp
@@ -831,7 +831,6 @@ bool vulkan_filter_chain::init_alias()
common.texture_semantic_map.clear();
common.texture_semantic_uniform_map.clear();
- unsigned i = 0;
for (auto &pass : passes)
{
auto &name = pass->get_name();
diff --git a/gfx/drivers_shader/slang_preprocess.cpp b/gfx/drivers_shader/slang_preprocess.cpp
index 45c5bcdf1d..546ff87f58 100644
--- a/gfx/drivers_shader/slang_preprocess.cpp
+++ b/gfx/drivers_shader/slang_preprocess.cpp
@@ -54,7 +54,7 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
param.maximum != itr->maximum ||
param.step != itr->step)
{
- RARCH_ERR("[Vulkan]: Duplicate parameters"
+ RARCH_ERR("[slang]: Duplicate parameters"
" found for \"%s\", but arguments do not match.\n",
itr->id);
mismatch_dup = true;
diff --git a/gfx/drivers_shader/slang_reflection.hpp b/gfx/drivers_shader/slang_reflection.hpp
index dc5817574c..4c94eb05a4 100644
--- a/gfx/drivers_shader/slang_reflection.hpp
+++ b/gfx/drivers_shader/slang_reflection.hpp
@@ -21,6 +21,14 @@
#include
#include
+struct slang_semantic_location
+{
+ int ubo_vertex = -1;
+ int push_vertex = -1;
+ int ubo_fragment = -1;
+ int push_fragment = -1;
+};
+
struct slang_texture_semantic_meta
{
size_t ubo_offset = 0;
@@ -31,6 +39,10 @@ struct slang_texture_semantic_meta
bool texture = false;
bool uniform = false;
bool push_constant = false;
+
+ // For APIs which need location information ala legacy GL.
+ // API user fills this struct in.
+ slang_semantic_location location;
};
struct slang_semantic_meta
@@ -40,6 +52,9 @@ struct slang_semantic_meta
unsigned num_components = 0;
bool uniform = false;
bool push_constant = false;
+
+ // For APIs which need location information ala legacy GL.
+ slang_semantic_location location;
};
struct slang_texture_semantic_map
diff --git a/gfx/font_driver.c b/gfx/font_driver.c
index d82acd4172..3f433e2a4e 100644
--- a/gfx/font_driver.c
+++ b/gfx/font_driver.c
@@ -214,6 +214,37 @@ static bool gl1_font_init_first(
return false;
}
#endif
+
+#ifdef HAVE_OPENGL_CORE
+static const font_renderer_t *gl_core_font_backends[] = {
+ &gl_core_raster_font,
+ NULL,
+};
+
+static bool gl_core_font_init_first(
+ const void **font_driver, void **font_handle,
+ void *video_data, const char *font_path,
+ float font_size, bool is_threaded)
+{
+ unsigned i;
+
+ for (i = 0; gl_core_font_backends[i]; i++)
+ {
+ void *data = gl_core_font_backends[i]->init(
+ video_data, font_path, font_size,
+ is_threaded);
+
+ if (!data)
+ continue;
+
+ *font_driver = gl_core_font_backends[i];
+ *font_handle = data;
+ return true;
+ }
+
+ return false;
+}
+#endif
#endif
#ifdef HAVE_CACA
@@ -666,6 +697,11 @@ static bool font_init_first(
return gl1_font_init_first(font_driver, font_handle,
video_data, font_path, font_size, is_threaded);
#endif
+#ifdef HAVE_OPENGL_CORE
+ case FONT_DRIVER_RENDER_OPENGL_CORE_API:
+ return gl_core_font_init_first(font_driver, font_handle,
+ video_data, font_path, font_size, is_threaded);
+#endif
#endif
#ifdef HAVE_VULKAN
case FONT_DRIVER_RENDER_VULKAN_API:
diff --git a/gfx/font_driver.h b/gfx/font_driver.h
index 1f64ce20f1..97cbc69b05 100644
--- a/gfx/font_driver.h
+++ b/gfx/font_driver.h
@@ -160,6 +160,7 @@ void font_driver_free_osd(void);
int font_driver_get_line_height(void *font_data, float scale);
extern font_renderer_t gl_raster_font;
+extern font_renderer_t gl_core_raster_font;
extern font_renderer_t gl1_raster_font;
extern font_renderer_t libdbg_font;
extern font_renderer_t d3d_xbox360_font;
diff --git a/gfx/video_defines.h b/gfx/video_defines.h
index b06287f5cc..288dde5656 100644
--- a/gfx/video_defines.h
+++ b/gfx/video_defines.h
@@ -83,6 +83,7 @@ enum font_driver_render_api
{
FONT_DRIVER_RENDER_DONT_CARE,
FONT_DRIVER_RENDER_OPENGL_API,
+ FONT_DRIVER_RENDER_OPENGL_CORE_API,
FONT_DRIVER_RENDER_OPENGL1_API,
FONT_DRIVER_RENDER_D3D8_API,
FONT_DRIVER_RENDER_D3D9_API,
diff --git a/gfx/video_driver.c b/gfx/video_driver.c
index 52c40c0a87..a31d8e1506 100644
--- a/gfx/video_driver.c
+++ b/gfx/video_driver.c
@@ -261,6 +261,9 @@ struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {
};
static const video_driver_t *video_drivers[] = {
+#if defined(HAVE_OPENGL_CORE)
+ &video_gl_core,
+#endif
#ifdef HAVE_OPENGL
&video_gl2,
#endif
@@ -992,7 +995,7 @@ static bool video_driver_init_internal(bool *video_is_threaded)
else
width = roundf(geom->base_width * settings->floats.video_scale);
height = roundf(geom->base_height * settings->floats.video_scale);
-}
+ }
}
if (width && height)
@@ -1924,7 +1927,24 @@ bool video_driver_find_driver(void)
if (hwr && hw_render_context_is_gl(hwr->context_type))
{
RARCH_LOG("[Video]: Using HW render, OpenGL driver forced.\n");
- current_video = &video_gl2;
+
+ /* If we have configured one of the HW render capable GL drivers, go with that. */
+ if (!string_is_equal(settings->arrays.video_driver, "gl") &&
+ !string_is_equal(settings->arrays.video_driver, "glcore"))
+ {
+#if defined(HAVE_OPENGL_CORE)
+ current_video = &video_gl_core;
+ RARCH_LOG("[Video]: Forcing \"glcore\" driver.\n");
+#else
+ current_video = &video_gl2;
+ RARCH_LOG("[Video]: Forcing \"gl\" driver.\n");
+#endif
+ }
+ else
+ {
+ RARCH_LOG("[Video]: Using configured \"%s\" driver for GL HW render.\n",
+ settings->arrays.video_driver);
+ }
}
#endif
diff --git a/gfx/video_driver.h b/gfx/video_driver.h
index 11a693ce25..e3453dc64a 100644
--- a/gfx/video_driver.h
+++ b/gfx/video_driver.h
@@ -1215,6 +1215,7 @@ void video_driver_set_gpu_api_version_string(const char *str);
const char* video_driver_get_gpu_api_version_string(void);
+extern video_driver_t video_gl_core;
extern video_driver_t video_gl2;
extern video_driver_t video_gl1;
extern video_driver_t video_vulkan;
diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c
index 0b9e45089b..9f1195e859 100644
--- a/gfx/video_shader_parse.c
+++ b/gfx/video_shader_parse.c
@@ -1266,6 +1266,8 @@ enum rarch_shader_type video_shader_get_type_from_ext(
case GFX_CTX_DIRECT3D12_API:
case GFX_CTX_GX2_API:
case GFX_CTX_VULKAN_API:
+ case GFX_CTX_OPENGL_API:
+ case GFX_CTX_OPENGL_ES_API:
case GFX_CTX_METAL_API:
return RARCH_SHADER_SLANG;
default:
@@ -1285,6 +1287,8 @@ enum rarch_shader_type video_shader_get_type_from_ext(
case GFX_CTX_DIRECT3D12_API:
case GFX_CTX_GX2_API:
case GFX_CTX_VULKAN_API:
+ case GFX_CTX_OPENGL_API:
+ case GFX_CTX_OPENGL_ES_API:
case GFX_CTX_METAL_API:
return RARCH_SHADER_SLANG;
default:
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 2246e8dc39..4c7deb0202 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -422,6 +422,9 @@ VIDEO DRIVER
#ifdef HAVE_OPENGL1
#include "../gfx/drivers/gl1.c"
#endif
+#ifdef HAVE_OPENGL_CORE
+#include "../gfx/drivers/gl_core.c"
+#endif
#include "../libretro-common/gfx/gl_capabilities.c"
#ifndef HAVE_PSGL
@@ -502,6 +505,9 @@ FONTS
#ifdef HAVE_OPENGL1
#include "../gfx/drivers_font/gl1_raster_font.c"
#endif
+#ifdef HAVE_OPENGL_CORE
+#include "../gfx/drivers_font/gl_core_raster_font.c"
+#endif
#endif
#if defined(_XBOX1)
@@ -1263,6 +1269,9 @@ MENU
#ifdef HAVE_OPENGL1
#include "../menu/drivers_display/menu_display_gl1.c"
#endif
+#ifdef HAVE_OPENGL_CORE
+#include "../menu/drivers_display/menu_display_gl_core.c"
+#endif
#endif
#ifdef HAVE_VULKAN
diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp
index 717231a9d8..6b90c1b80f 100644
--- a/griffin/griffin_cpp.cpp
+++ b/griffin/griffin_cpp.cpp
@@ -76,6 +76,10 @@ VIDEO DRIVER
#include "../gfx/drivers_shader/shader_vulkan.cpp"
#endif
+#if defined(HAVE_OPENGL) && defined(HAVE_OPENGL_CORE)
+#include "../gfx/drivers_shader/shader_gl_core.cpp"
+#endif
+
#if defined(HAVE_SPIRV_CROSS)
#if defined(ENABLE_HLSL)
#include "../deps/SPIRV-Cross/spirv_hlsl.cpp"
diff --git a/menu/drivers_display/menu_display_gl_core.c b/menu/drivers_display/menu_display_gl_core.c
new file mode 100644
index 0000000000..b5e9372718
--- /dev/null
+++ b/menu/drivers_display/menu_display_gl_core.c
@@ -0,0 +1,354 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2016-2017 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ *
+ * 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 .
+ */
+
+#include
+#include
+#include