diff --git a/android/app/build.gradle b/android/app/build.gradle index c19e12add..022d4179e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -28,7 +28,6 @@ android { externalNativeBuild { cmake { arguments "-DCMAKE_BUILD_TYPE=RelWithDebInfo" - abiFilters "x86" } } } diff --git a/android/app/src/cpp/CMakeLists.txt b/android/app/src/cpp/CMakeLists.txt index bd48713f1..62e34222c 100644 --- a/android/app/src/cpp/CMakeLists.txt +++ b/android/app/src/cpp/CMakeLists.txt @@ -3,8 +3,8 @@ set(SRCS android_audio_stream.h android_host_interface.cpp android_host_interface.h - android_gles2_host_display.cpp - android_gles2_host_display.h + android_gles_host_display.cpp + android_gles_host_display.h main.cpp ) diff --git a/android/app/src/cpp/android_gles2_host_display.cpp b/android/app/src/cpp/android_gles_host_display.cpp similarity index 75% rename from android/app/src/cpp/android_gles2_host_display.cpp rename to android/app/src/cpp/android_gles_host_display.cpp index 5504f4195..3f657dd80 100644 --- a/android/app/src/cpp/android_gles2_host_display.cpp +++ b/android/app/src/cpp/android_gles_host_display.cpp @@ -1,17 +1,17 @@ -#include "android_gles2_host_display.h" +#include "android_gles_host_display.h" #include "YBaseLib/Log.h" #include #include #include #include #include -Log_SetChannel(AndroidGLES2HostDisplay); +Log_SetChannel(AndroidGLESHostDisplay); -class AndroidGLES2HostDisplayTexture : public HostDisplayTexture +class AndroidGLESHostDisplayTexture : public HostDisplayTexture { public: - AndroidGLES2HostDisplayTexture(GLuint id, u32 width, u32 height) : m_id(id), m_width(width), m_height(height) {} - ~AndroidGLES2HostDisplayTexture() override { glDeleteTextures(1, &m_id); } + AndroidGLESHostDisplayTexture(GLuint id, u32 width, u32 height) : m_id(id), m_width(width), m_height(height) {} + ~AndroidGLESHostDisplayTexture() override { glDeleteTextures(1, &m_id); } void* GetHandle() const override { return reinterpret_cast(static_cast(m_id)); } u32 GetWidth() const override { return m_width; } @@ -19,7 +19,7 @@ public: GLuint GetGLID() const { return m_id; } - static std::unique_ptr Create(u32 width, u32 height, const void* initial_data, + static std::unique_ptr Create(u32 width, u32 height, const void* initial_data, u32 initial_data_stride) { GLuint id; @@ -38,7 +38,7 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, id); - return std::make_unique(id, width, height); + return std::make_unique(id, width, height); } private: @@ -47,12 +47,12 @@ private: u32 m_height; }; -AndroidGLES2HostDisplay::AndroidGLES2HostDisplay(ANativeWindow* window) +AndroidGLESHostDisplay::AndroidGLESHostDisplay(ANativeWindow* window) : m_window(window), m_window_width(ANativeWindow_getWidth(window)), m_window_height(ANativeWindow_getHeight(window)) { } -AndroidGLES2HostDisplay::~AndroidGLES2HostDisplay() +AndroidGLESHostDisplay::~AndroidGLESHostDisplay() { if (m_egl_context != EGL_NO_CONTEXT) { @@ -66,27 +66,27 @@ AndroidGLES2HostDisplay::~AndroidGLES2HostDisplay() eglDestroySurface(m_egl_display, m_egl_surface); } -HostDisplay::RenderAPI AndroidGLES2HostDisplay::GetRenderAPI() const +HostDisplay::RenderAPI AndroidGLESHostDisplay::GetRenderAPI() const { return HostDisplay::RenderAPI::OpenGLES; } -void* AndroidGLES2HostDisplay::GetRenderDevice() const +void* AndroidGLESHostDisplay::GetRenderDevice() const { return nullptr; } -void* AndroidGLES2HostDisplay::GetRenderContext() const +void* AndroidGLESHostDisplay::GetRenderContext() const { return m_egl_context; } -void* AndroidGLES2HostDisplay::GetRenderWindow() const +void* AndroidGLESHostDisplay::GetRenderWindow() const { return m_window; } -void AndroidGLES2HostDisplay::ChangeRenderWindow(void* new_window) +void AndroidGLESHostDisplay::ChangeRenderWindow(void* new_window) { eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -101,16 +101,16 @@ void AndroidGLES2HostDisplay::ChangeRenderWindow(void* new_window) Panic("Failed to make context current after window change"); } -std::unique_ptr AndroidGLES2HostDisplay::CreateTexture(u32 width, u32 height, const void* data, +std::unique_ptr AndroidGLESHostDisplay::CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic) { - return AndroidGLES2HostDisplayTexture::Create(width, height, data, data_stride); + return AndroidGLESHostDisplayTexture::Create(width, height, data, data_stride); } -void AndroidGLES2HostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, +void AndroidGLESHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride) { - AndroidGLES2HostDisplayTexture* tex = static_cast(texture); + AndroidGLESHostDisplayTexture* tex = static_cast(texture); Assert(data_stride == (width * sizeof(u32))); GLint old_texture_binding = 0; @@ -122,7 +122,7 @@ void AndroidGLES2HostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, glBindTexture(GL_TEXTURE_2D, old_texture_binding); } -void AndroidGLES2HostDisplay::SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, +void AndroidGLESHostDisplay::SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, u32 texture_height, float aspect_ratio) { m_display_texture_id = static_cast(reinterpret_cast(texture)); @@ -136,39 +136,41 @@ void AndroidGLES2HostDisplay::SetDisplayTexture(void* texture, s32 offset_x, s32 m_display_texture_changed = true; } -void AndroidGLES2HostDisplay::SetDisplayLinearFiltering(bool enabled) +void AndroidGLESHostDisplay::SetDisplayLinearFiltering(bool enabled) { m_display_linear_filtering = enabled; } -void AndroidGLES2HostDisplay::SetDisplayTopMargin(int height) +void AndroidGLESHostDisplay::SetDisplayTopMargin(int height) { m_display_top_margin = height; } -void AndroidGLES2HostDisplay::SetVSync(bool enabled) +void AndroidGLESHostDisplay::SetVSync(bool enabled) { eglSwapInterval(m_egl_display, enabled ? 1 : 0); } -std::tuple AndroidGLES2HostDisplay::GetWindowSize() const +std::tuple AndroidGLESHostDisplay::GetWindowSize() const { return std::make_tuple(static_cast(m_window_width), static_cast(m_window_height)); } -void AndroidGLES2HostDisplay::WindowResized() +void AndroidGLESHostDisplay::WindowResized() { m_window_width = ANativeWindow_getWidth(m_window); m_window_height = ANativeWindow_getHeight(m_window); + ImGui::GetIO().DisplaySize.x = static_cast(m_window_width); + ImGui::GetIO().DisplaySize.y = static_cast(m_window_height); Log_InfoPrintf("WindowResized %dx%d", m_window_width, m_window_height); } -const char* AndroidGLES2HostDisplay::GetGLSLVersionString() const +const char* AndroidGLESHostDisplay::GetGLSLVersionString() const { return "#version 100"; } -std::string AndroidGLES2HostDisplay::GetGLSLVersionHeader() const +std::string AndroidGLESHostDisplay::GetGLSLVersionHeader() const { return R"( #version 100 @@ -178,7 +180,7 @@ precision highp int; )"; } -bool AndroidGLES2HostDisplay::CreateGLContext() +bool AndroidGLESHostDisplay::CreateGLContext() { m_egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!m_egl_display) @@ -209,8 +211,15 @@ bool AndroidGLES2HostDisplay::CreateGLContext() eglBindAPI(EGL_OPENGL_ES_API); - static constexpr std::array egl_context_attribs = {{EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}}; - m_egl_context = eglCreateContext(m_egl_display, m_egl_config, EGL_NO_CONTEXT, egl_context_attribs.data()); + // Try GLES 3, then fall back to GLES 2. + for (int major_version : {3, 2}) { + std::array egl_context_attribs = {{EGL_CONTEXT_CLIENT_VERSION, major_version, EGL_NONE}}; + m_egl_context = eglCreateContext(m_egl_display, m_egl_config, EGL_NO_CONTEXT, + egl_context_attribs.data()); + if (m_egl_context) + break; + } + if (!m_egl_context) { Log_ErrorPrint("eglCreateContext() failed"); @@ -233,10 +242,12 @@ bool AndroidGLES2HostDisplay::CreateGLContext() return false; } + Log_InfoPrintf("GLES Version: %s", glGetString(GL_VERSION)); + Log_InfoPrintf("GLES Renderer: %s", glGetString(GL_RENDERER)); return true; } -bool AndroidGLES2HostDisplay::CreateSurface() +bool AndroidGLESHostDisplay::CreateSurface() { EGLint native_visual; eglGetConfigAttrib(m_egl_display, m_egl_config, EGL_NATIVE_VISUAL_ID, &native_visual); @@ -255,13 +266,13 @@ bool AndroidGLES2HostDisplay::CreateSurface() return true; } -void AndroidGLES2HostDisplay::DestroySurface() +void AndroidGLESHostDisplay::DestroySurface() { eglDestroySurface(m_egl_display, m_egl_surface); m_egl_surface = EGL_NO_SURFACE; } -bool AndroidGLES2HostDisplay::CreateImGuiContext() +bool AndroidGLESHostDisplay::CreateImGuiContext() { if (!ImGui_ImplOpenGL3_Init(GetGLSLVersionString())) return false; @@ -272,7 +283,7 @@ bool AndroidGLES2HostDisplay::CreateImGuiContext() return true; } -bool AndroidGLES2HostDisplay::CreateGLResources() +bool AndroidGLESHostDisplay::CreateGLResources() { static constexpr char fullscreen_quad_vertex_shader[] = R"( attribute vec2 a_pos; @@ -321,9 +332,9 @@ void main() return true; } -std::unique_ptr AndroidGLES2HostDisplay::Create(ANativeWindow* window) +std::unique_ptr AndroidGLESHostDisplay::Create(ANativeWindow* window) { - std::unique_ptr display = std::make_unique(window); + std::unique_ptr display = std::make_unique(window); if (!display->CreateGLContext() || !display->CreateImGuiContext() || !display->CreateGLResources()) return nullptr; @@ -331,7 +342,7 @@ std::unique_ptr AndroidGLES2HostDisplay::Create(ANativeWindow* wind return display; } -void AndroidGLES2HostDisplay::Render() +void AndroidGLESHostDisplay::Render() { glDisable(GL_SCISSOR_TEST); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -349,7 +360,7 @@ void AndroidGLES2HostDisplay::Render() GL::Program::ResetLastProgram(); } -void AndroidGLES2HostDisplay::RenderDisplay() +void AndroidGLESHostDisplay::RenderDisplay() { if (!m_display_texture_id) return; @@ -378,6 +389,7 @@ void AndroidGLES2HostDisplay::RenderDisplay() {{1.0f, 1.0f, tex_right, tex_top}}, // top-right }}; + glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), &vertices[0][0]); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), &vertices[0][2]); diff --git a/android/app/src/cpp/android_gles2_host_display.h b/android/app/src/cpp/android_gles_host_display.h similarity index 94% rename from android/app/src/cpp/android_gles2_host_display.h rename to android/app/src/cpp/android_gles_host_display.h index 9b093c14f..b5b6c06ba 100644 --- a/android/app/src/cpp/android_gles2_host_display.h +++ b/android/app/src/cpp/android_gles_host_display.h @@ -8,11 +8,11 @@ #include #include -class AndroidGLES2HostDisplay final : public HostDisplay +class AndroidGLESHostDisplay final : public HostDisplay { public: - AndroidGLES2HostDisplay(ANativeWindow* window); - ~AndroidGLES2HostDisplay(); + AndroidGLESHostDisplay(ANativeWindow* window); + ~AndroidGLESHostDisplay(); static std::unique_ptr Create(ANativeWindow* window); diff --git a/android/app/src/cpp/android_host_interface.cpp b/android/app/src/cpp/android_host_interface.cpp index a53c3b1c6..9b9fa79cf 100644 --- a/android/app/src/cpp/android_host_interface.cpp +++ b/android/app/src/cpp/android_host_interface.cpp @@ -3,11 +3,12 @@ #include "YBaseLib/Log.h" #include "YBaseLib/String.h" #include "android_audio_stream.h" -#include "android_gles2_host_display.h" +#include "android_gles_host_display.h" #include "core/gpu.h" #include "core/host_display.h" #include "core/system.h" #include +#include #include Log_SetChannel(AndroidHostInterface); @@ -52,10 +53,12 @@ AndroidHostInterface::AndroidHostInterface(jobject java_object) : m_java_object( m_settings.SetDefaults(); m_settings.bios_path = "/sdcard/PSX/BIOS/scph1001.bin"; m_settings.memory_card_a_path = "/sdcard/PSX/memory_card_a.mcd"; - m_settings.gpu_renderer = GPURenderer::Software; - m_settings.video_sync_enabled = true; + m_settings.cpu_execution_mode = CPUExecutionMode::CachedInterpreter; + //m_settings.gpu_renderer = GPURenderer::Software; + m_settings.speed_limiter_enabled = false; + m_settings.video_sync_enabled = false; m_settings.audio_sync_enabled = false; - // m_settings.debugging.show_vram = true; + //m_settings.debugging.show_vram = true; } AndroidHostInterface::~AndroidHostInterface() @@ -136,7 +139,7 @@ void AndroidHostInterface::EmulationThreadEntryPoint(ANativeWindow* initial_surf CreateImGuiContext(); // Create display. - m_display = AndroidGLES2HostDisplay::Create(initial_surface); + m_display = AndroidGLESHostDisplay::Create(initial_surface); if (!m_display) { Log_ErrorPrint("Failed to create display on emulation thread."); @@ -219,6 +222,8 @@ void AndroidHostInterface::EmulationThreadEntryPoint(ANativeWindow* initial_surf if (m_speed_limiter_enabled) Throttle(); } + + UpdatePerformanceCounters(); } } @@ -243,61 +248,69 @@ void AndroidHostInterface::DestroyImGuiContext() void AndroidHostInterface::DrawImGui() { + DrawFPSWindow(); DrawOSDMessages(); ImGui::Render(); } -void AndroidHostInterface::AddOSDMessage(const char* message, float duration) +void AndroidHostInterface::DrawFPSWindow() { - OSDMessage msg; - msg.text = message; - msg.duration = duration; + const bool show_fps = true; + const bool show_vps = true; + const bool show_speed = true; - std::unique_lock lock(m_osd_messages_lock); - m_osd_messages.push_back(std::move(msg)); -} + ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x - 175.0f, 0.0f), ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(175.0f, 16.0f)); -void AndroidHostInterface::DrawOSDMessages() -{ - constexpr ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | - ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing; - - std::unique_lock lock(m_osd_messages_lock); - const float scale = ImGui::GetIO().DisplayFramebufferScale.x; - - auto iter = m_osd_messages.begin(); - float position_x = 10.0f * scale; - float position_y = (10.0f + (m_settings.display_fullscreen ? 0.0f : 20.0f)) * scale; - u32 index = 0; - while (iter != m_osd_messages.end()) + if (!ImGui::Begin("FPSWindow", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoBringToFrontOnFocus)) { - const OSDMessage& msg = *iter; - const double time = msg.time.GetTimeSeconds(); - const float time_remaining = static_cast(msg.duration - time); - if (time_remaining <= 0.0f) - { - iter = m_osd_messages.erase(iter); - continue; - } + ImGui::End(); + return; + } - const float opacity = std::min(time_remaining, 1.0f); - ImGui::SetNextWindowPos(ImVec2(position_x, position_y)); - ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity); + bool first = true; + if (show_fps) + { + ImGui::Text("%.2f", m_fps); + first = false; + } + if (show_vps) + { + if (first) { + first = false; + } + else { + ImGui::SameLine(); + ImGui::Text("/"); + ImGui::SameLine(); + } - if (ImGui::Begin(SmallString::FromFormat("osd_%u", index++), nullptr, window_flags)) - { - ImGui::TextUnformatted(msg.text.c_str()); - position_y += ImGui::GetWindowSize().y + (4.0f * scale); + ImGui::Text("%.2f", m_vps); + } + if (show_speed) + { + if (first) { + first = false; + } + else { + ImGui::SameLine(); + ImGui::Text("/"); + ImGui::SameLine(); } - ImGui::End(); - ImGui::PopStyleVar(); - ++iter; + const u32 rounded_speed = static_cast(std::round(m_speed)); + if (m_speed < 90.0f) + ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "%u%%", rounded_speed); + else if (m_speed < 110.0f) + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%u%%", rounded_speed); + else + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), "%u%%", rounded_speed); } + + ImGui::End(); } void AndroidHostInterface::SurfaceChanged(ANativeWindow* window, int format, int width, int height) diff --git a/android/app/src/cpp/android_host_interface.h b/android/app/src/cpp/android_host_interface.h index 0e922d991..58e567259 100644 --- a/android/app/src/cpp/android_host_interface.h +++ b/android/app/src/cpp/android_host_interface.h @@ -3,10 +3,8 @@ #include "YBaseLib/Timer.h" #include "core/host_interface.h" #include -#include #include #include -#include #include struct ANativeWindow; @@ -19,7 +17,6 @@ public: void ReportError(const char* message) override; void ReportMessage(const char* message) override; - void AddOSDMessage(const char* message, float duration = 2.0f) override; bool IsEmulationThreadRunning() const { return m_emulation_thread.joinable(); } bool StartEmulationThread(ANativeWindow* initial_surface, std::string initial_filename, @@ -30,25 +27,16 @@ public: void SurfaceChanged(ANativeWindow* window, int format, int width, int height); private: - struct OSDMessage - { - std::string text; - Timer time; - float duration; - }; - void EmulationThreadEntryPoint(ANativeWindow* initial_surface, std::string initial_filename, std::string initial_state_filename); void CreateImGuiContext(); void DestroyImGuiContext(); void DrawImGui(); - void DrawOSDMessages(); - jobject m_java_object = {}; + void DrawFPSWindow(); - std::deque m_osd_messages; - std::mutex m_osd_messages_lock; + jobject m_java_object = {}; std::mutex m_callback_mutex; std::deque> m_callback_queue; diff --git a/src/core/cpu_recompiler_code_generator.h b/src/core/cpu_recompiler_code_generator.h index d71905d3e..40ab4130c 100644 --- a/src/core/cpu_recompiler_code_generator.h +++ b/src/core/cpu_recompiler_code_generator.h @@ -15,7 +15,7 @@ #if defined(Y_CPU_X64) #if defined(Y_PLATFORM_WINDOWS) #define ABI_WIN64 1 -#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_OSX) +#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_OSX) || defined(Y_PLATFORM_ANDROID) #define ABI_SYSV 1 #else #error Unknown ABI. diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index 82c055e40..a45939268 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -22,38 +22,43 @@ static void DefineMacro(std::stringstream& ss, const char* name, bool enabled) ss << "#define " << name << " " << BoolToUInt32(enabled) << "\n"; } -void GPU_HW_ShaderGen::SetGLSLVersionString() -{ - const char* glsl_version = reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION)); +void GPU_HW_ShaderGen::SetGLSLVersionString() { + const char *glsl_version = reinterpret_cast(glGetString( + GL_SHADING_LANGUAGE_VERSION)); Assert(glsl_version != nullptr); - int major_version = 0, minor_version = 0; - if (std::sscanf(glsl_version, "%d.%d", &major_version, &minor_version) != 2) - { - Log_ErrorPrintf("Invalid GLSL version string: '%s'", glsl_version); - m_glsl_version_string = m_glsl_es ? "300" : "130"; - return; - } + // Skip any strings in front of the version code. + const char *glsl_version_start = glsl_version; + while (*glsl_version_start != '\0' && (*glsl_version_start < '0' || *glsl_version_start > '9')) + glsl_version_start++; - // Cap at GLSL 3.3, we're not using anything newer for now. - if (!m_glsl_es && major_version >= 4) + int major_version = 0, minor_version = 0; + if (std::sscanf(glsl_version_start, "%d.%d", &major_version, &minor_version) == 2) { - major_version = 3; - minor_version = 30; + // Cap at GLSL 3.3, we're not using anything newer for now. + if (!m_glsl_es && major_version >= 4) { + major_version = 3; + minor_version = 30; + } else if (m_glsl_es && (major_version > 3 || minor_version > 20)) { + major_version = 3; + minor_version = 20; + } } - else if (m_glsl_es && (major_version > 3 || minor_version > 20)) + else { - major_version = 3; - minor_version = 20; + Log_ErrorPrintf("Invalid GLSL version string: '%s' ('%s')", glsl_version, glsl_version_start); + if (m_glsl_es) { + major_version = 3; + minor_version = 0; + } + m_glsl_version_string = m_glsl_es ? "300" : "130"; } - m_glsl_version_string = "#version "; - m_glsl_version_string += std::to_string(major_version); - m_glsl_version_string += std::to_string(minor_version); - if (!m_glsl_es && major_version >= 3 && minor_version >= 3) - m_glsl_version_string += " core"; - else if (m_glsl_es) - m_glsl_version_string += " es"; + + char buf[128]; + std::snprintf(buf, sizeof(buf), "#version %d%02d %s", major_version, minor_version, + (!m_glsl_es && major_version >= 3 && minor_version >= 3) ? "core" : (m_glsl_es ? "es" : "")); + m_glsl_version_string = buf; } void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss) @@ -61,14 +66,12 @@ void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss) if (m_render_api == HostDisplay::RenderAPI::OpenGL || m_render_api == HostDisplay::RenderAPI::OpenGLES) ss << m_glsl_version_string << "\n\n"; - if (m_render_api == HostDisplay::RenderAPI::OpenGL) - { - ss << "#define API_OPENGL 1\n"; - } - else if (m_render_api == HostDisplay::RenderAPI::OpenGLES) - { - ss << "#define API_OPENGL_ES 1\n"; + DefineMacro(ss, "API_OPENGL", m_render_api == HostDisplay::RenderAPI::OpenGL); + DefineMacro(ss, "API_OPENGL_ES", m_render_api == HostDisplay::RenderAPI::OpenGLES); + DefineMacro(ss, "API_D3D11", m_render_api == HostDisplay::RenderAPI::D3D11); + if (m_render_api == HostDisplay::RenderAPI::OpenGLES) + { ss << "precision highp float;\n"; ss << "precision highp int;\n"; ss << "precision highp sampler2D;\n"; @@ -78,10 +81,6 @@ void GPU_HW_ShaderGen::WriteHeader(std::stringstream& ss) ss << "\n"; } - else if (m_render_api == HostDisplay::RenderAPI::D3D11) - { - ss << "#define API_D3D11 1\n"; - } if (m_glsl) {