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;