summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h14
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.h1
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_device.h7
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h1
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp19
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.h4
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h1
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.h1
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h16
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp18
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h8
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp24
-rw-r--r--src/video_core/renderer_opengl/util_shaders.h3
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);