diff options
Diffstat (limited to '')
23 files changed, 137 insertions, 68 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index d4dd10bb6..f1f7b384b 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -135,6 +135,20 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_) buffer.Create(); glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY); } + + device_access_memory = [this]() -> u64 { + if (device.CanReportMemoryUsage()) { + return device.GetCurrentDedicatedVideoMemory() + 512_MiB; + } + return 2_GiB; // Return minimum requirements + }(); +} + +u64 BufferCacheRuntime::GetDeviceMemoryUsage() const { + if (device.CanReportMemoryUsage()) { + return device_access_memory - device.GetCurrentDedicatedVideoMemory(); + } + return 2_GiB; } void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 060d36427..a8699f28c 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -7,9 +7,7 @@ #include <array> #include <span> -#include "common/alignment.h" #include "common/common_types.h" -#include "common/dynamic_library.h" #include "video_core/buffer_cache/buffer_cache.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_device.h" @@ -91,6 +89,8 @@ public: void BindImageBuffer(Buffer& buffer, u32 offset, u32 size, VideoCore::Surface::PixelFormat format); + u64 GetDeviceMemoryUsage() const; + void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { const GLuint handle = fast_uniforms[stage][binding_index].handle; const GLsizeiptr gl_size = static_cast<GLsizeiptr>(size); @@ -153,6 +153,14 @@ public: use_storage_buffers = use_storage_buffers_; } + u64 GetDeviceLocalMemory() const { + return device_access_memory; + } + + bool CanReportMemoryUsage() const { + return device.CanReportMemoryUsage(); + } + private: static constexpr std::array PABO_LUT{ GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, @@ -186,6 +194,8 @@ private: std::array<OGLBuffer, VideoCommon::NUM_COMPUTE_UNIFORM_BUFFERS> copy_compute_uniforms; u32 index_buffer_offset = 0; + + u64 device_access_memory; }; struct BufferCacheParams { diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h index 50c676365..b0d183b46 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.h +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h @@ -6,7 +6,6 @@ #include <array> #include <type_traits> -#include <utility> #include "common/common_types.h" #include "shader_recompiler/shader_info.h" diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index e62912a22..597301eeb 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -6,8 +6,6 @@ #include <array> #include <cstddef> #include <cstdlib> -#include <cstring> -#include <limits> #include <optional> #include <span> #include <stdexcept> @@ -15,13 +13,15 @@ #include <glad/glad.h> +#include "common/literals.h" #include "common/logging/log.h" -#include "common/scope_exit.h" #include "common/settings.h" #include "shader_recompiler/stage.h" #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_resource_manager.h" +using namespace Common::Literals; + namespace OpenGL { namespace { constexpr std::array LIMIT_UBOS = { @@ -168,6 +168,7 @@ Device::Device() { has_sparse_texture_2 = GLAD_GL_ARB_sparse_texture2; warp_size_potentially_larger_than_guest = !is_nvidia && !is_intel; need_fastmath_off = is_nvidia; + can_report_memory = GLAD_GL_NVX_gpu_memory_info; // At the moment of writing this, only Nvidia's driver optimizes BufferSubData on exclusive // uniform buffers as "push constants" @@ -279,4 +280,10 @@ void main() { })"); } +u64 Device::GetCurrentDedicatedVideoMemory() const { + GLint cur_avail_mem_kb = 0; + glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &cur_avail_mem_kb); + return static_cast<u64>(cur_avail_mem_kb) * 1_KiB; +} + } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 95c2e8d38..9bb0b9148 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h @@ -20,6 +20,8 @@ public: [[nodiscard]] std::string GetVendorName() const; + u64 GetCurrentDedicatedVideoMemory() const; + u32 GetMaxUniformBuffers(Shader::Stage stage) const noexcept { return max_uniform_buffers[static_cast<size_t>(stage)]; } @@ -168,6 +170,10 @@ public: return vendor_name == "ATI Technologies Inc."; } + bool CanReportMemoryUsage() const { + return can_report_memory; + } + private: static bool TestVariableAoffi(); static bool TestPreciseBug(); @@ -210,6 +216,7 @@ private: bool need_fastmath_off{}; bool has_cbuf_ftou_bug{}; bool has_bool_ref_bug{}; + bool can_report_memory{}; std::string vendor_name; }; diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 9e6732abd..fd40966d5 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -253,7 +253,7 @@ GraphicsPipeline::GraphicsPipeline( } } if (in_parallel) { - std::lock_guard lock{built_mutex}; + std::scoped_lock lock{built_mutex}; built_fence.Create(); // Flush this context to ensure compilation commands and fence are in the GPU pipe. glFlush(); diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h index 311d49f3f..4f8049717 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h @@ -14,7 +14,6 @@ #include "common/common_types.h" #include "shader_recompiler/shader_info.h" #include "video_core/engines/maxwell_3d.h" -#include "video_core/memory_manager.h" #include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_texture_cache.h" diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp index acebbf5f4..9e6c50055 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.cpp +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp @@ -3,15 +3,12 @@ // Refer to the license.txt file included. #include <algorithm> -#include <cstring> #include <memory> -#include <unordered_map> #include <utility> #include <vector> #include <glad/glad.h> -#include "common/assert.h" #include "core/core.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 142412a8e..8ef79753f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -6,9 +6,7 @@ #include <array> #include <bitset> #include <memory> -#include <string> #include <string_view> -#include <tuple> #include <utility> #include <glad/glad.h> @@ -17,8 +15,9 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/microprofile.h" +#include "common/scope_exit.h" #include "common/settings.h" -#include "core/memory.h" + #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" @@ -212,6 +211,7 @@ void RasterizerOpenGL::Clear() { void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { MICROPROFILE_SCOPE(OpenGL_Drawing); + SCOPE_EXIT({ gpu.TickWork(); }); query_cache.UpdateCounters(); GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; @@ -267,8 +267,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { ++num_queued_commands; has_written_global_memory |= pipeline->WritesGlobalMemory(); - - gpu.TickWork(); } void RasterizerOpenGL::DispatchCompute() { @@ -522,6 +520,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, // ASSERT_MSG(image_view->size.width == config.width, "Framebuffer width is different"); // ASSERT_MSG(image_view->size.height == config.height, "Framebuffer height is different"); + screen_info.texture.width = image_view->size.width; + screen_info.texture.height = image_view->size.height; screen_info.display_texture = image_view->Handle(Shader::TextureType::Color2D); screen_info.display_srgb = VideoCore::Surface::IsPixelFormatSRGB(image_view->format); return true; @@ -559,12 +559,19 @@ void RasterizerOpenGL::SyncViewport() { const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports; const bool dirty_clip_control = flags[Dirty::ClipControl]; - if (dirty_clip_control || flags[Dirty::FrontFace]) { + if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) { flags[Dirty::FrontFace] = false; GLenum mode = MaxwellToGL::FrontFace(regs.front_face); + bool flip_faces = false; if (regs.screen_y_control.triangle_rast_flip != 0 && regs.viewport_transform[0].scale_y < 0.0f) { + flip_faces = !flip_faces; + } + if (regs.viewport_transform[0].scale_z < 0.0f) { + flip_faces = !flip_faces; + } + if (flip_faces) { switch (mode) { case GL_CW: mode = GL_CCW; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 98f6fd342..c79461d59 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -5,20 +5,14 @@ #pragma once #include <array> -#include <atomic> #include <cstddef> -#include <memory> #include <optional> -#include <tuple> -#include <utility> #include <boost/container/static_vector.hpp> #include <glad/glad.h> #include "common/common_types.h" -#include "video_core/engines/const_buffer_info.h" -#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_dma.h" #include "video_core/rasterizer_accelerated.h" #include "video_core/rasterizer_interface.h" @@ -26,12 +20,8 @@ #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_fence_manager.h" #include "video_core/renderer_opengl/gl_query_cache.h" -#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_shader_cache.h" -#include "video_core/renderer_opengl/gl_shader_manager.h" -#include "video_core/renderer_opengl/gl_state_tracker.h" #include "video_core/renderer_opengl/gl_texture_cache.h" -#include "video_core/textures/texture.h" namespace Core::Memory { class Memory; diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp index 5e7101d28..f6839a657 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <string_view> -#include <utility> #include <glad/glad.h> -#include "common/common_types.h" #include "common/microprofile.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_shader_util.h" diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index f71e01a34..05c5e702c 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -14,10 +14,8 @@ #include "common/fs/fs.h" #include "common/fs/path_util.h" #include "common/logging/log.h" -#include "common/scope_exit.h" #include "common/settings.h" #include "common/thread_worker.h" -#include "core/core.h" #include "shader_recompiler/backend/glasm/emit_glasm.h" #include "shader_recompiler/backend/glsl/emit_glsl.h" #include "shader_recompiler/backend/spirv/emit_spirv.h" @@ -29,7 +27,6 @@ #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" #include "video_core/renderer_opengl/gl_rasterizer.h" -#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_shader_cache.h" #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_state_tracker.h" @@ -261,7 +258,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { ctx->pools.ReleaseContents(); auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; - std::lock_guard lock{state.mutex}; + std::scoped_lock lock{state.mutex}; if (pipeline) { compute_cache.emplace(key, std::move(pipeline)); } @@ -283,7 +280,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, } ctx->pools.ReleaseContents(); auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; - std::lock_guard lock{state.mutex}; + std::scoped_lock lock{state.mutex}; if (pipeline) { graphics_cache.emplace(key, std::move(pipeline)); } diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index a34110b37..06d4b38bb 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -4,18 +4,13 @@ #pragma once -#include <array> #include <filesystem> #include <stop_token> #include <unordered_map> -#include <glad/glad.h> - #include "common/common_types.h" #include "common/thread_worker.h" -#include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/host_translate_info.h" -#include "shader_recompiler/object_pool.h" #include "shader_recompiler/profile.h" #include "video_core/renderer_opengl/gl_compute_pipeline.h" #include "video_core/renderer_opengl/gl_graphics_pipeline.h" diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index d432072ad..129966e72 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -6,7 +6,6 @@ #include <vector> #include <glad/glad.h> -#include "common/assert.h" #include "common/logging/log.h" #include "common/settings.h" #include "video_core/renderer_opengl/gl_shader_util.h" diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h index 4e1a2a8e1..a64ef37dc 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.h +++ b/src/video_core/renderer_opengl/gl_shader_util.h @@ -5,14 +5,10 @@ #pragma once #include <span> -#include <string> #include <string_view> -#include <vector> #include <glad/glad.h> -#include "common/assert.h" -#include "common/logging/log.h" #include "video_core/renderer_opengl/gl_resource_manager.h" namespace OpenGL { diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 5864c7c07..550ed6d36 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -9,7 +9,6 @@ #include <glad/glad.h> #include "common/common_types.h" -#include "core/core.h" #include "video_core/dirty_flags.h" #include "video_core/engines/maxwell_3d.h" diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_stream_buffer.h index 2e67922a6..f0cb29dca 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.h +++ b/src/video_core/renderer_opengl/gl_stream_buffer.h @@ -5,7 +5,6 @@ #pragma once #include <array> -#include <memory> #include <span> #include <utility> diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 3c1f79a27..d12076358 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -409,8 +409,8 @@ ImageBufferMap::~ImageBufferMap() { TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager, StateTracker& state_tracker_) - : device{device_}, state_tracker{state_tracker_}, - util_shaders(program_manager), resolution{Settings::values.resolution_info} { + : device{device_}, state_tracker{state_tracker_}, util_shaders(program_manager), + format_conversion_pass{util_shaders}, resolution{Settings::values.resolution_info} { static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D}; for (size_t i = 0; i < TARGETS.size(); ++i) { const GLenum target = TARGETS[i]; @@ -484,6 +484,13 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& rescale_read_fbos[i].Create(); } } + + device_access_memory = [this]() -> u64 { + if (device.CanReportMemoryUsage()) { + return device.GetCurrentDedicatedVideoMemory() + 512_MiB; + } + return 2_GiB; // Return minimum requirements + }(); } TextureCacheRuntime::~TextureCacheRuntime() = default; @@ -500,13 +507,11 @@ ImageBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) { return download_buffers.RequestMap(size, false); } -u64 TextureCacheRuntime::GetDeviceLocalMemory() const { - if (GLAD_GL_NVX_gpu_memory_info) { - GLint cur_avail_mem_kb = 0; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb); - return static_cast<u64>(cur_avail_mem_kb) * 1_KiB; +u64 TextureCacheRuntime::GetDeviceMemoryUsage() const { + if (device.CanReportMemoryUsage()) { + return device_access_memory - device.GetCurrentDedicatedVideoMemory(); } - return 2_GiB; // Return minimum requirements + return 2_GiB; } void TextureCacheRuntime::CopyImage(Image& dst_image, Image& src_image, @@ -686,6 +691,7 @@ Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, } if (IsConverted(runtime->device, info.format, info.type)) { flags |= ImageFlagBits::Converted; + flags |= ImageFlagBits::CostlyLoad; gl_internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8; gl_format = GL_RGBA; gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -1319,6 +1325,9 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM Framebuffer::~Framebuffer() = default; +FormatConversionPass::FormatConversionPass(UtilShaders& util_shaders_) + : util_shaders{util_shaders_} {} + void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image, std::span<const VideoCommon::ImageCopy> copies) { const GLenum dst_target = ImageTarget(dst_image.info); @@ -1351,6 +1360,12 @@ void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image, dst_origin.z, region.width, region.height, region.depth, dst_image.GlFormat(), dst_image.GlType(), nullptr); } + + // Swap component order of S8D24 to ABGR8 reinterprets + if (src_image.info.format == PixelFormat::D24_UNORM_S8_UINT && + dst_image.info.format == PixelFormat::A8B8G8R8_UNORM) { + util_shaders.ConvertS8D24(dst_image, copies); + } } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 7f425631f..672fa8dde 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -10,6 +10,7 @@ #include <glad/glad.h> #include "shader_recompiler/shader_info.h" +#include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/util_shaders.h" #include "video_core/texture_cache/image_view_base.h" @@ -21,7 +22,6 @@ struct ResolutionScalingInfo; namespace OpenGL { -class Device; class ProgramManager; class StateTracker; @@ -55,13 +55,14 @@ struct FormatProperties { class FormatConversionPass { public: - FormatConversionPass() = default; + explicit FormatConversionPass(UtilShaders& util_shaders); ~FormatConversionPass() = default; void ConvertImage(Image& dst_image, Image& src_image, std::span<const VideoCommon::ImageCopy> copies); private: + UtilShaders& util_shaders; OGLBuffer intermediate_pbo; size_t pbo_size{}; }; @@ -83,7 +84,15 @@ public: ImageBufferMap DownloadStagingBuffer(size_t size); - u64 GetDeviceLocalMemory() const; + u64 GetDeviceLocalMemory() const { + return device_access_memory; + } + + u64 GetDeviceMemoryUsage() const; + + bool CanReportMemoryUsage() const { + return device.CanReportMemoryUsage(); + } bool ShouldReinterpret([[maybe_unused]] Image& dst, [[maybe_unused]] Image& src) { return true; @@ -172,6 +181,7 @@ private: std::array<OGLFramebuffer, 4> rescale_draw_fbos; std::array<OGLFramebuffer, 4> rescale_read_fbos; const Settings::ResolutionScalingInfo& resolution; + u64 device_access_memory; }; class Image : public VideoCommon::ImageBase { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index f81c1b233..3a3c213bb 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -5,7 +5,6 @@ #include <algorithm> #include <cstddef> #include <cstdlib> -#include <cstring> #include <memory> #include <glad/glad.h> @@ -15,11 +14,9 @@ #include "common/microprofile.h" #include "common/settings.h" #include "common/telemetry.h" -#include "core/core.h" #include "core/core_timing.h" #include "core/frontend/emu_window.h" #include "core/memory.h" -#include "core/perf_stats.h" #include "core/telemetry_session.h" #include "video_core/host_shaders/fxaa_frag.h" #include "video_core/host_shaders/fxaa_vert.h" @@ -211,6 +208,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf // Framebuffer orientation handling framebuffer_transform_flags = framebuffer.transform_flags; framebuffer_crop_rect = framebuffer.crop_rect; + framebuffer_width = framebuffer.width; + framebuffer_height = framebuffer.height; const VAddr framebuffer_addr{framebuffer.address + framebuffer.offset}; screen_info.was_accelerated = @@ -326,12 +325,12 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, GLint internal_format; switch (framebuffer.pixel_format) { - case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM: + case Service::android::PixelFormat::Rgba8888: internal_format = GL_RGBA8; texture.gl_format = GL_RGBA; texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; - case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM: + case Service::android::PixelFormat::Rgb565: internal_format = GL_RGB565; texture.gl_format = GL_RGB; texture.gl_type = GL_UNSIGNED_SHORT_5_6_5; @@ -467,8 +466,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { const auto& texcoords = screen_info.display_texcoords; auto left = texcoords.left; auto right = texcoords.right; - if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) { - if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { + if (framebuffer_transform_flags != Service::android::BufferTransformFlags::Unset) { + if (framebuffer_transform_flags == Service::android::BufferTransformFlags::FlipV) { // Flip the framebuffer vertically left = texcoords.right; right = texcoords.left; @@ -483,9 +482,12 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { ASSERT_MSG(framebuffer_crop_rect.top == 0, "Unimplemented"); ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented"); + f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width); + f32 scale_v = + static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height); + // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering // (e.g. handheld mode) on a 1920x1080 framebuffer. - f32 scale_u = 1.f, scale_v = 1.f; if (framebuffer_crop_rect.GetWidth() > 0) { scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) / static_cast<f32>(screen_info.texture.width); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index cda333cad..ae9558a33 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -8,10 +8,12 @@ #include <glad/glad.h> #include "common/common_types.h" #include "common/math_util.h" + #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_resource_manager.h" +#include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_state_tracker.h" namespace Core { @@ -44,7 +46,7 @@ struct TextureInfo { GLsizei height; GLenum gl_format; GLenum gl_type; - Tegra::FramebufferConfig::PixelFormat pixel_format; + Service::android::PixelFormat pixel_format; }; /// Structure used for storing information about the display target for the Switch screen @@ -133,8 +135,10 @@ private: std::vector<u8> gl_framebuffer_data; /// Used for transforming the framebuffer orientation - Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags{}; + Service::android::BufferTransformFlags framebuffer_transform_flags{}; Common::Rectangle<int> framebuffer_crop_rect; + u32 framebuffer_width; + u32 framebuffer_height; }; } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp index 897c380b3..04c482a09 100644 --- a/src/video_core/renderer_opengl/util_shaders.cpp +++ b/src/video_core/renderer_opengl/util_shaders.cpp @@ -13,6 +13,7 @@ #include "video_core/host_shaders/astc_decoder_comp.h" #include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h" #include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h" +#include "video_core/host_shaders/opengl_convert_s8d24_comp.h" #include "video_core/host_shaders/opengl_copy_bc4_comp.h" #include "video_core/host_shaders/pitch_unswizzle_comp.h" #include "video_core/renderer_opengl/gl_shader_manager.h" @@ -50,7 +51,8 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_) block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)), block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)), pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)), - copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) { + copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)), + convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)) { const auto swizzle_table = Tegra::Texture::MakeSwizzleTable(); swizzle_table_buffer.Create(); glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0); @@ -248,6 +250,26 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im program_manager.RestoreGuestCompute(); } +void UtilShaders::ConvertS8D24(Image& dst_image, std::span<const ImageCopy> copies) { + static constexpr GLuint BINDING_DESTINATION = 0; + static constexpr GLuint LOC_SIZE = 0; + + program_manager.BindComputeProgram(convert_s8d24_program.handle); + for (const ImageCopy& copy : copies) { + ASSERT(copy.src_subresource.base_layer == 0); + ASSERT(copy.src_subresource.num_layers == 1); + ASSERT(copy.dst_subresource.base_layer == 0); + ASSERT(copy.dst_subresource.num_layers == 1); + + glUniform3ui(LOC_SIZE, copy.extent.width, copy.extent.height, copy.extent.depth); + glBindImageTexture(BINDING_DESTINATION, dst_image.StorageHandle(), + copy.dst_subresource.base_level, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8UI); + glDispatchCompute(Common::DivCeil(copy.extent.width, 16u), + Common::DivCeil(copy.extent.height, 8u), copy.extent.depth); + } + program_manager.RestoreGuestCompute(); +} + GLenum StoreFormat(u32 bytes_per_block) { switch (bytes_per_block) { case 1: diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h index 5de95ea7a..5c132e67f 100644 --- a/src/video_core/renderer_opengl/util_shaders.h +++ b/src/video_core/renderer_opengl/util_shaders.h @@ -39,6 +39,8 @@ public: void CopyBC4(Image& dst_image, Image& src_image, std::span<const VideoCommon::ImageCopy> copies); + void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies); + private: ProgramManager& program_manager; @@ -49,6 +51,7 @@ private: OGLProgram block_linear_unswizzle_3d_program; OGLProgram pitch_unswizzle_program; OGLProgram copy_bc4_program; + OGLProgram convert_s8d24_program; }; GLenum StoreFormat(u32 bytes_per_block); |