From 07a69b7c7b2f469cb946c4caec42981e7a4400ad Mon Sep 17 00:00:00 2001 From: emufan4568 Date: Sun, 21 Aug 2022 01:52:49 +0300 Subject: [PATCH] renderer_opengl: Remove amd hacks and legacy paths * AMDs new driver fixed many issues in the OpenGL driver. No reason to keep these hacks. In addition the upgrade to 4.3 guarantees the existance of required extensions, so no need to check for them --- .../gl_format_reinterpreter.cpp | 140 +----------------- .../renderer_opengl/gl_rasterizer.cpp | 50 ++----- .../renderer_opengl/gl_rasterizer.h | 4 - .../renderer_opengl/gl_shader_gen.cpp | 30 ---- .../renderer_opengl/gl_shader_manager.cpp | 20 +-- .../renderer_opengl/gl_shader_manager.h | 2 +- .../renderer_opengl/gl_stream_buffer.cpp | 12 +- .../renderer_opengl/gl_stream_buffer.h | 3 +- 8 files changed, 20 insertions(+), 241 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp b/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp index d642e0400..11db7ce6d 100644 --- a/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp +++ b/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp @@ -2,11 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/assert.h" #include "common/scope_exit.h" #include "video_core/renderer_opengl/gl_format_reinterpreter.h" #include "video_core/renderer_opengl/gl_state.h" -#include "video_core/renderer_opengl/gl_vars.h" namespace OpenGL { @@ -98,129 +96,6 @@ private: OGLVertexArray vao; }; -class PixelBufferD24S8toABGR final : public FormatReinterpreterBase { -public: - PixelBufferD24S8toABGR() { - attributeless_vao.Create(); - d24s8_abgr_buffer.Create(); - d24s8_abgr_buffer_size = 0; - - constexpr std::string_view vs_source = R"( -const vec2 vertices[4] = vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), - vec2(-1.0, 1.0), vec2(1.0, 1.0)); -void main() { - gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0); -} -)"; - - std::string fs_source = GLES ? fragment_shader_precision_OES : ""; - fs_source += R"( -uniform samplerBuffer tbo; -uniform vec2 tbo_size; -uniform vec4 viewport; - -out vec4 color; - -void main() { - vec2 tbo_coord = (gl_FragCoord.xy - viewport.xy) * tbo_size / viewport.zw; - int tbo_offset = int(tbo_coord.y) * int(tbo_size.x) + int(tbo_coord.x); - color = texelFetch(tbo, tbo_offset).rabg; -} -)"; - d24s8_abgr_shader.Create(vs_source.data(), fs_source.c_str()); - - OpenGLState state = OpenGLState::GetCurState(); - GLuint old_program = state.draw.shader_program; - state.draw.shader_program = d24s8_abgr_shader.handle; - state.Apply(); - - GLint tbo_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "tbo"); - ASSERT(tbo_u_id != -1); - glUniform1i(tbo_u_id, 0); - - state.draw.shader_program = old_program; - state.Apply(); - - d24s8_abgr_tbo_size_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "tbo_size"); - ASSERT(d24s8_abgr_tbo_size_u_id != -1); - d24s8_abgr_viewport_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "viewport"); - ASSERT(d24s8_abgr_viewport_u_id != -1); - } - - ~PixelBufferD24S8toABGR() {} - - PixelFormat GetSourceFormat() const override { - return PixelFormat::D24S8; - } - - void Reinterpret(const OGLTexture& src_tex, Common::Rectangle src_rect, - const OGLTexture& dst_tex, Common::Rectangle dst_rect) override { - OpenGLState prev_state = OpenGLState::GetCurState(); - SCOPE_EXIT({ prev_state.Apply(); }); - - OpenGLState state; - state.draw.read_framebuffer = read_fbo.handle; - state.draw.draw_framebuffer = draw_fbo.handle; - state.Apply(); - - glBindBuffer(GL_PIXEL_PACK_BUFFER, d24s8_abgr_buffer.handle); - - GLsizeiptr target_pbo_size = - static_cast(src_rect.GetWidth()) * src_rect.GetHeight() * 4; - if (target_pbo_size > d24s8_abgr_buffer_size) { - d24s8_abgr_buffer_size = target_pbo_size * 2; - glBufferData(GL_PIXEL_PACK_BUFFER, d24s8_abgr_buffer_size, nullptr, GL_STREAM_COPY); - } - - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - src_tex.handle, 0); - - glReadPixels(static_cast(src_rect.left), static_cast(src_rect.bottom), - static_cast(src_rect.GetWidth()), - static_cast(src_rect.GetHeight()), GL_DEPTH_STENCIL, - GL_UNSIGNED_INT_24_8, 0); - - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - - // PBO now contains src_tex in RABG format - state.draw.shader_program = d24s8_abgr_shader.handle; - state.draw.vertex_array = attributeless_vao.handle; - state.viewport.x = static_cast(dst_rect.left); - state.viewport.y = static_cast(dst_rect.bottom); - state.viewport.width = static_cast(dst_rect.GetWidth()); - state.viewport.height = static_cast(dst_rect.GetHeight()); - state.Apply(); - - OGLTexture tbo; - tbo.Create(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_BUFFER, tbo.handle); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, d24s8_abgr_buffer.handle); - - glUniform2f(d24s8_abgr_tbo_size_u_id, static_cast(src_rect.GetWidth()), - static_cast(src_rect.GetHeight())); - glUniform4f(d24s8_abgr_viewport_u_id, static_cast(state.viewport.x), - static_cast(state.viewport.y), - static_cast(state.viewport.width), - static_cast(state.viewport.height)); - - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - dst_tex.handle, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - 0, 0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindTexture(GL_TEXTURE_BUFFER, 0); - } - -private: - OGLVertexArray attributeless_vao; - OGLBuffer d24s8_abgr_buffer; - GLsizeiptr d24s8_abgr_buffer_size; - OGLProgram d24s8_abgr_shader; - GLint d24s8_abgr_tbo_size_u_id; - GLint d24s8_abgr_viewport_u_id; -}; class ShaderD24S8toRGBA8 final : public FormatReinterpreterBase { public: @@ -371,24 +246,13 @@ FormatReinterpreterOpenGL::FormatReinterpreterOpenGL() { const std::string_view vendor{reinterpret_cast(glGetString(GL_VENDOR))}; const std::string_view version{reinterpret_cast(glGetString(GL_VERSION))}; - // Fallback to PBO path on obsolete intel drivers - // intel`s GL_VERSION string - `3.3.0 - Build 25.20.100.6373` - const bool intel_broken_drivers = - vendor.find("Intel") != vendor.npos && (std::atoi(version.substr(14, 2).data()) < 30); - auto Register = [this](PixelFormat dest, std::unique_ptr&& obj) { const u32 dst_index = static_cast(dest); return reinterpreters[dst_index].push_back(std::move(obj)); }; - if ((!intel_broken_drivers && GLAD_GL_ARB_stencil_texturing && - GLAD_GL_ARB_texture_storage && GLAD_GL_ARB_copy_image) || GLES) { - Register(PixelFormat::RGBA8, std::make_unique()); - LOG_INFO(Render_OpenGL, "Using shader for D24S8 to RGBA8 reinterpretation"); - } else { - Register(PixelFormat::RGBA8, std::make_unique()); - LOG_INFO(Render_OpenGL, "Using PBO for D24S8 to RGBA8 reinterpretation"); - } + Register(PixelFormat::RGBA8, std::make_unique()); + LOG_INFO(Render_OpenGL, "Using shader for D24S8 to RGBA8 reinterpretation"); Register(PixelFormat::RGB5A1, std::make_unique()); } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a4eb373cc..b8e67b4bc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -13,7 +13,6 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/microprofile.h" -#include "common/scope_exit.h" #include "common/vector_math.h" #include "core/hw/gpu.h" #include "video_core/pica_state.h" @@ -36,34 +35,13 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); -static bool IsVendorAmd() { - const std::string_view gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; - return gpu_vendor == "ATI Technologies Inc." || gpu_vendor == "Advanced Micro Devices, Inc."; -} -static bool IsVendorIntel() { - std::string gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; - return gpu_vendor == "Intel Inc."; -} - RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window) - : is_amd(IsVendorAmd()), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), + : vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE), uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE, false), index_buffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE, false), texture_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE, false), texture_lf_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE, false) { - allow_shadow = GLES || (GLAD_GL_ARB_shader_image_load_store && GLAD_GL_ARB_shader_image_size && - GLAD_GL_ARB_framebuffer_no_attachments); - if (!allow_shadow) { - LOG_WARNING(Render_OpenGL, - "Shadow might not be able to render because of unsupported OpenGL extensions."); - } - - if (!GLAD_GL_ARB_copy_image && !GLES) { - LOG_WARNING(Render_OpenGL, - "ARB_copy_image not supported. Some games might produce artifacts."); - } - // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0 state.clip_distance[0] = true; @@ -178,7 +156,7 @@ RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window) } #else shader_program_manager = std::make_unique( - emu_window, GLAD_GL_ARB_separate_shader_objects, is_amd); + emu_window, GLAD_GL_ARB_separate_shader_objects); #endif glEnable(GL_BLEND); @@ -574,9 +552,10 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { state.Apply(); if (shadow_rendering) { - if (!allow_shadow || color_surface == nullptr) { + if (color_surface == nullptr) { return true; } + glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, color_surface->width * color_surface->res_scale); glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, @@ -663,9 +642,6 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { using TextureType = Pica::TexturingRegs::TextureConfig::TextureType; switch (texture.config.type.Value()) { case TextureType::Shadow2D: { - if (!allow_shadow) - continue; - Surface surface = res_cache.GetTextureSurface(texture); if (surface != nullptr) { CheckBarrier(state.image_shadow_texture_px = surface->texture.handle); @@ -675,8 +651,6 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { continue; } case TextureType::ShadowCube: { - if (!allow_shadow) - continue; Pica::Texture::TextureInfo info = Pica::Texture::TextureInfo::FromPicaRegister( texture.config, texture.format); Surface surface; @@ -875,15 +849,13 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { state.texture_units[texture_index].texture_2d = 0; } state.texture_cube_unit.texture_cube = 0; - if (allow_shadow) { - state.image_shadow_texture_px = 0; - state.image_shadow_texture_nx = 0; - state.image_shadow_texture_py = 0; - state.image_shadow_texture_ny = 0; - state.image_shadow_texture_pz = 0; - state.image_shadow_texture_nz = 0; - state.image_shadow_buffer = 0; - } + state.image_shadow_texture_px = 0; + state.image_shadow_texture_nx = 0; + state.image_shadow_texture_py = 0; + state.image_shadow_texture_ny = 0; + state.image_shadow_texture_pz = 0; + state.image_shadow_texture_nz = 0; + state.image_shadow_buffer = 0; state.Apply(); if (shadow_rendering) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index c5a9913b2..a6557d4e7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -263,8 +263,6 @@ private: /// Setup geometry shader for AccelerateDrawBatch bool SetupGeometryShader(); - bool is_amd; - OpenGLState state; GLuint default_texture; @@ -323,8 +321,6 @@ private: std::array proctex_alpha_map_data{}; std::array proctex_lut_data{}; std::array proctex_diff_lut_data{}; - - bool allow_shadow; }; } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 6c53984d1..ba15e93d4 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -1233,18 +1233,6 @@ ShaderDecompiler::ProgramResult GenerateFragmentShader(const PicaFSConfig& confi const auto& state = config.state; std::string out; - if (GLES) { - out += R"( -#define ALLOW_SHADOW (defined(CITRA_GLES)) -)"; - } else { - out += R"( -#extension GL_ARB_shader_image_load_store : enable -#extension GL_ARB_shader_image_size : enable -#define ALLOW_SHADOW (defined(GL_ARB_shader_image_load_store) && defined(GL_ARB_shader_image_size)) -)"; - } - if (separable_shader && !GLES) { out += "#extension GL_ARB_separate_shader_objects : enable\n"; } @@ -1270,7 +1258,6 @@ uniform samplerBuffer texture_buffer_lut_lf; uniform samplerBuffer texture_buffer_lut_rg; uniform samplerBuffer texture_buffer_lut_rgba; -#if ALLOW_SHADOW layout(r32ui) uniform readonly uimage2D shadow_texture_px; layout(r32ui) uniform readonly uimage2D shadow_texture_nx; layout(r32ui) uniform readonly uimage2D shadow_texture_py; @@ -1278,7 +1265,6 @@ layout(r32ui) uniform readonly uimage2D shadow_texture_ny; layout(r32ui) uniform readonly uimage2D shadow_texture_pz; layout(r32ui) uniform readonly uimage2D shadow_texture_nz; layout(r32ui) uniform uimage2D shadow_buffer; -#endif )"; out += UniformBlockDef; @@ -1332,8 +1318,6 @@ float getLod(vec2 coord) { return log2(max(d.x, d.y)); } -#if ALLOW_SHADOW - uvec2 DecodeShadow(uint pixel) { return uvec2(pixel >> 8, pixel & 0xFFu); } @@ -1459,18 +1443,6 @@ vec4 shadowTextureCube(vec2 uv, float w) { CompareShadow(pixels.w, z)); return vec4(mix2(s, f)); } - -#else - -vec4 shadowTexture(vec2 uv, float w) { - return vec4(1.0); -} - -vec4 shadowTextureCube(vec2 uv, float w) { - return vec4(1.0); -} - -#endif )"; if (config.state.proctex.enable) @@ -1559,7 +1531,6 @@ vec4 secondary_fragment_color = vec4(0.0); if (state.shadow_rendering) { out += R"( -#if ALLOW_SHADOW uint d = uint(clamp(depth, 0.0, 1.0) * float(0xFFFFFF)); uint s = uint(last_tex_env_out.g * float(0xFF)); ivec2 image_coord = ivec2(gl_FragCoord.xy); @@ -1582,7 +1553,6 @@ do { new = EncodeShadow(ref); } while ((old = imageAtomicCompSwap(shadow_buffer, image_coord, old, new)) != old2); -#endif // ALLOW_SHADOW )"; } else { out += "gl_FragDepth = depth;\n"; diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index f019bc80e..d928e7b34 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -7,7 +7,6 @@ #include #include #include -#include "core/core.h" #include "core/frontend/scope_acquire_context.h" #include "video_core/renderer_opengl/gl_shader_disk_cache.h" #include "video_core/renderer_opengl/gl_shader_manager.h" @@ -325,8 +324,8 @@ using FragmentShaders = ShaderCache(separable, is_amd)), emu_window{emu_window_} {} +ShaderProgramManager::ShaderProgramManager(Frontend::EmuWindow& emu_window_, bool separable) + : impl(std::make_unique(separable)), emu_window{emu_window_} {} ShaderProgramManager::~ShaderProgramManager() = default; @@ -439,15 +436,6 @@ void ShaderProgramManager::UseFragmentShader(const Pica::Regs& regs) { void ShaderProgramManager::ApplyTo(OpenGLState& state) { if (impl->separable) { - if (impl->is_amd) { - // Without this reseting, AMD sometimes freezes when one stage is changed but not - // for the others. On the other hand, including this reset seems to introduce memory - // leak in Intel Graphics. - glUseProgramStages( - impl->pipeline.handle, - GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, 0); - } - glUseProgramStages(impl->pipeline.handle, GL_VERTEX_SHADER_BIT, impl->current.vs); glUseProgramStages(impl->pipeline.handle, GL_GEOMETRY_SHADER_BIT, impl->current.gs); glUseProgramStages(impl->pipeline.handle, GL_FRAGMENT_SHADER_BIT, impl->current.fs); diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 39c1392f2..e914cc7c8 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -99,7 +99,7 @@ static_assert(sizeof(VSUniformData) < 16384, /// A class that manage different shader stages and configures them with given config data. class ShaderProgramManager { public: - ShaderProgramManager(Frontend::EmuWindow& emu_window_, bool separable, bool is_amd); + ShaderProgramManager(Frontend::EmuWindow& emu_window_, bool separable); ~ShaderProgramManager(); void LoadDiskCache(const std::atomic_bool& stop_loading, diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp index 4b9da6285..e100cc486 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp +++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp @@ -7,7 +7,6 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/microprofile.h" -#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning", @@ -15,21 +14,12 @@ MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning", namespace OpenGL { -OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool array_buffer_for_amd, - bool prefer_coherent) +OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent) : gl_target(target), buffer_size(size) { gl_buffer.Create(); glBindBuffer(gl_target, gl_buffer.handle); GLsizeiptr allocate_size = size; - if (array_buffer_for_amd) { - // On AMD GPU there is a strange crash in indexed drawing. The crash happens when the buffer - // read position is near the end and is an out-of-bound access to the vertex buffer. This is - // probably a bug in the driver and is related to the usage of vec3 attributes in the - // vertex array. Doubling the allocation size for the vertex buffer seems to avoid the - // crash. - allocate_size *= 2; - } if (GLAD_GL_ARB_buffer_storage) { persistent = true; diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_stream_buffer.h index 6b6044832..ae7961bd7 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.h +++ b/src/video_core/renderer_opengl/gl_stream_buffer.h @@ -13,8 +13,7 @@ namespace OpenGL { class OGLStreamBuffer : private NonCopyable { public: - explicit OGLStreamBuffer(GLenum target, GLsizeiptr size, bool array_buffer_for_amd, - bool prefer_coherent = false); + explicit OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent = false); ~OGLStreamBuffer(); GLuint GetHandle() const;