summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/jni/native.cpp3
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/host_memory.cpp28
-rw-r--r--src/core/file_sys/patch_manager.cpp4
-rw-r--r--src/core/file_sys/romfs.cpp19
-rw-r--r--src/core/file_sys/romfs_factory.cpp2
-rw-r--r--src/core/hle/service/nfc/common/device.cpp10
-rw-r--r--src/core/loader/nca.cpp6
-rw-r--r--src/shader_recompiler/backend/glsl/glsl_emit_context.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp84
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h7
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp66
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.h22
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h8
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h4
-rw-r--r--src/video_core/texture_cache/texture_cache.h2
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/main.cpp5
24 files changed, 159 insertions, 159 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index ed5ce6f8a..3d795b57f 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -123,9 +123,6 @@ int EmulationSession::InstallFileToNand(std::string filename, std::string file_e
ErrorFilenameExtension = 4,
};
- m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
- m_system.GetFileSystemController().CreateFactories(*m_vfs);
-
[[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp;
if (file_extension == "nsp") {
nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 2c6fc7657..b58a7073f 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -188,7 +188,7 @@ if (UNIX AND NOT APPLE)
linux/gamemode.h
)
- target_link_libraries(common PRIVATE gamemode)
+ target_link_libraries(common PRIVATE gamemode::headers)
endif()
if(ARCHITECTURE_x86_64)
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 3a9ea6eb4..4bfc64f2d 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -25,6 +25,10 @@
#include <unistd.h>
#include "common/scope_exit.h"
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
#endif // ^^^ Linux ^^^
#include <mutex>
@@ -404,6 +408,16 @@ static void* ChooseVirtualBase(size_t virtual_size) {
#else
static void* ChooseVirtualBase(size_t virtual_size) {
+#if defined(__FreeBSD__)
+ void* virtual_base =
+ mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
+
+ if (virtual_base != MAP_FAILED) {
+ return virtual_base;
+ }
+#endif
+
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
}
@@ -459,24 +473,12 @@ public:
}
// Virtual memory initialization
-#if defined(__FreeBSD__)
- virtual_base =
- static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0));
- if (virtual_base == MAP_FAILED) {
- virtual_base = static_cast<u8*>(
- mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
- if (virtual_base == MAP_FAILED) {
- LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
- throw std::bad_alloc{};
- }
- }
-#else
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
if (virtual_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};
}
+#if defined(__linux__)
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
#endif
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 0bca05587..cc7af2ea3 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -429,10 +429,6 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs
LOG_DEBUG(Loader, "{}", log_string);
}
- if (base_romfs == nullptr) {
- return base_romfs;
- }
-
auto romfs = base_romfs;
// Game Updates
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 1eb1f439a..6de2103a0 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -3,6 +3,7 @@
#include <memory>
+#include "common/assert.h"
#include "common/common_types.h"
#include "common/string_util.h"
#include "common/swap.h"
@@ -101,24 +102,30 @@ void ProcessDirectory(const VirtualFile& file, std::size_t dir_offset, std::size
} // Anonymous namespace
VirtualDir ExtractRomFS(VirtualFile file) {
+ auto root_container = std::make_shared<VectorVfsDirectory>();
+ if (!file) {
+ return root_container;
+ }
+
RomFSHeader header{};
- if (file->ReadObject(&header) != sizeof(RomFSHeader))
- return nullptr;
+ if (file->ReadObject(&header) != sizeof(RomFSHeader)) {
+ return root_container;
+ }
- if (header.header_size != sizeof(RomFSHeader))
- return nullptr;
+ if (header.header_size != sizeof(RomFSHeader)) {
+ return root_container;
+ }
const u64 file_offset = header.file_meta.offset;
const u64 dir_offset = header.directory_meta.offset;
- auto root_container = std::make_shared<VectorVfsDirectory>();
-
ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container);
if (auto root = root_container->GetSubdirectory(""); root) {
return std::make_shared<CachedVfsDirectory>(std::move(root));
}
+ ASSERT(false);
return nullptr;
}
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp
index 1bc07dae5..35e149905 100644
--- a/src/core/file_sys/romfs_factory.cpp
+++ b/src/core/file_sys/romfs_factory.cpp
@@ -22,7 +22,7 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader, ContentProvider& provi
: content_provider{provider}, filesystem_controller{controller} {
// Load the RomFS from the app
if (app_loader.ReadRomFS(file) != Loader::ResultStatus::Success) {
- LOG_ERROR(Service_FS, "Unable to read RomFS!");
+ LOG_WARNING(Service_FS, "Unable to read base RomFS");
}
updatable = app_loader.IsRomFSUpdatable();
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 47516f883..f97e5b44c 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -438,16 +438,16 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
is_corrupted = true;
}
- if (!is_corrupted) {
+ device_state = DeviceState::TagMounted;
+ mount_target = mount_target_;
+
+ if (!is_corrupted && mount_target != NFP::MountTarget::Rom) {
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
WriteBackupData(encrypted_tag_data.uuid, data);
}
- device_state = DeviceState::TagMounted;
- mount_target = mount_target_;
-
- if (is_corrupted) {
+ if (is_corrupted && mount_target != NFP::MountTarget::Rom) {
bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess();
return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData;
}
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index 4feb6968a..814407535 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -74,10 +74,8 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::S
return load_result;
}
- if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) {
- system.GetFileSystemController().RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(
- *this, system.GetContentProvider(), system.GetFileSystemController()));
- }
+ system.GetFileSystemController().RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(
+ *this, system.GetContentProvider(), system.GetFileSystemController()));
is_loaded = true;
return load_result;
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
index fd9a99449..b2ceeefc4 100644
--- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/div_ceil.h"
#include "shader_recompiler/backend/bindings.h"
#include "shader_recompiler/backend/glsl/glsl_emit_context.h"
#include "shader_recompiler/frontend/ir/program.h"
@@ -431,9 +432,11 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) {
}
for (const auto& desc : info.constant_buffer_descriptors) {
const auto cbuf_type{profile.has_gl_cbuf_ftou_bug ? "uvec4" : "vec4"};
+ const u32 cbuf_used_size{Common::DivCeil(info.constant_buffer_used_sizes[desc.index], 16U)};
+ const u32 cbuf_binding_size{info.uses_global_memory ? 0x1000U : cbuf_used_size};
header += fmt::format("layout(std140,binding={}) uniform {}_cbuf_{}{{{} {}_cbuf{}[{}];}};",
bindings.uniform_buffer, stage_name, desc.index, cbuf_type,
- stage_name, desc.index, 4 * 1024);
+ stage_name, desc.index, cbuf_binding_size);
bindings.uniform_buffer += desc.count;
}
}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index dfd696de6..e6c70fb34 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -53,13 +53,11 @@ Buffer::Buffer(BufferCacheRuntime& runtime, VideoCore::RasterizerInterface& rast
VAddr cpu_addr_, u64 size_bytes_)
: VideoCommon::BufferBase<VideoCore::RasterizerInterface>(rasterizer_, cpu_addr_, size_bytes_) {
buffer.Create();
- const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr());
- glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data());
- glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW);
-
- if (runtime.has_unified_vertex_buffers) {
- glGetNamedBufferParameterui64vNV(buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &address);
+ if (runtime.device.HasDebuggingToolAttached()) {
+ const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr());
+ glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data());
}
+ glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW);
}
void Buffer::ImmediateUpload(size_t offset, std::span<const u8> data) noexcept {
@@ -111,7 +109,6 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
: device{device_}, staging_buffer_pool{staging_buffer_pool_},
has_fast_buffer_sub_data{device.HasFastBufferSubData()},
use_assembly_shaders{device.UseAssemblyShaders()},
- has_unified_vertex_buffers{device.HasVertexBufferUnifiedMemory()},
stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} {
GLint gl_max_attributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &gl_max_attributes);
@@ -123,16 +120,18 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
GL_STREAM_DRAW);
}
}
- for (auto& stage_uniforms : copy_uniforms) {
- for (OGLBuffer& buffer : stage_uniforms) {
+ if (use_assembly_shaders) {
+ for (auto& stage_uniforms : copy_uniforms) {
+ for (OGLBuffer& buffer : stage_uniforms) {
+ buffer.Create();
+ glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
+ }
+ }
+ for (OGLBuffer& buffer : copy_compute_uniforms) {
buffer.Create();
glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
}
}
- for (OGLBuffer& buffer : copy_compute_uniforms) {
- buffer.Create();
- glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
- }
device_access_memory = [this]() -> u64 {
if (device.CanReportMemoryUsage()) {
@@ -146,8 +145,12 @@ StagingBufferMap BufferCacheRuntime::UploadStagingBuffer(size_t size) {
return staging_buffer_pool.RequestUploadBuffer(size);
}
-StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size) {
- return staging_buffer_pool.RequestDownloadBuffer(size);
+StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
+ return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
+}
+
+void BufferCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
+ staging_buffer_pool.FreeDeferredStagingBuffer(buffer);
}
u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
@@ -207,14 +210,8 @@ void BufferCacheRuntime::ClearBuffer(Buffer& dest_buffer, u32 offset, size_t siz
}
void BufferCacheRuntime::BindIndexBuffer(Buffer& buffer, u32 offset, u32 size) {
- if (has_unified_vertex_buffers) {
- buffer.MakeResident(GL_READ_ONLY);
- glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, buffer.HostGpuAddr() + offset,
- static_cast<GLsizeiptr>(Common::AlignUp(size, 4)));
- } else {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.Handle());
- index_buffer_offset = offset;
- }
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.Handle());
+ index_buffer_offset = offset;
}
void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset, u32 size,
@@ -222,24 +219,23 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset,
if (index >= max_attributes) {
return;
}
- if (has_unified_vertex_buffers) {
- buffer.MakeResident(GL_READ_ONLY);
- glBindVertexBuffer(index, 0, 0, static_cast<GLsizei>(stride));
- glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, index,
- buffer.HostGpuAddr() + offset, static_cast<GLsizeiptr>(size));
- } else {
- glBindVertexBuffer(index, buffer.Handle(), static_cast<GLintptr>(offset),
- static_cast<GLsizei>(stride));
- }
+ glBindVertexBuffer(index, buffer.Handle(), static_cast<GLintptr>(offset),
+ static_cast<GLsizei>(stride));
}
void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
- for (u32 index = 0; index < bindings.buffers.size(); ++index) {
- BindVertexBuffer(bindings.min_index + index, *bindings.buffers[index],
- static_cast<u32>(bindings.offsets[index]),
- static_cast<u32>(bindings.sizes[index]),
- static_cast<u32>(bindings.strides[index]));
- }
+ // TODO: Should HostBindings provide the correct runtime types to avoid these transforms?
+ std::array<GLuint, 32> buffer_handles;
+ std::array<GLsizei, 32> buffer_strides;
+ std::ranges::transform(bindings.buffers, buffer_handles.begin(),
+ [](const Buffer* const buffer) { return buffer->Handle(); });
+ std::ranges::transform(bindings.strides, buffer_strides.begin(),
+ [](u64 stride) { return static_cast<GLsizei>(stride); });
+ const u32 count =
+ std::min(static_cast<u32>(bindings.buffers.size()), max_attributes - bindings.min_index);
+ glBindVertexBuffers(bindings.min_index, static_cast<GLsizei>(count), buffer_handles.data(),
+ reinterpret_cast<const GLintptr*>(bindings.offsets.data()),
+ buffer_strides.data());
}
void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buffer& buffer,
@@ -331,11 +327,13 @@ void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, Buffer& buffer,
}
void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
- for (u32 index = 0; index < bindings.buffers.size(); ++index) {
- glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index, bindings.buffers[index]->Handle(),
- static_cast<GLintptr>(bindings.offsets[index]),
- static_cast<GLsizeiptr>(bindings.sizes[index]));
- }
+ std::array<GLuint, 4> buffer_handles;
+ std::ranges::transform(bindings.buffers, buffer_handles.begin(),
+ [](const Buffer* const buffer) { return buffer->Handle(); });
+ glBindBuffersRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
+ static_cast<GLsizei>(bindings.buffers.size()), buffer_handles.data(),
+ reinterpret_cast<const GLintptr*>(bindings.offsets.data()),
+ reinterpret_cast<const GLsizeiptr*>(bindings.strides.data()));
}
void BufferCacheRuntime::BindTextureBuffer(Buffer& buffer, u32 offset, u32 size,
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index 000f29a82..71cd45d35 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -66,7 +66,9 @@ public:
[[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size);
- [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size);
+ [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false);
+
+ void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
bool CanReorderUpload(const Buffer&, std::span<const VideoCommon::BufferCopy>) {
return false;
@@ -207,7 +209,6 @@ private:
bool has_fast_buffer_sub_data = false;
bool use_assembly_shaders = false;
- bool has_unified_vertex_buffers = false;
bool use_storage_buffers = false;
@@ -246,7 +247,7 @@ struct BufferCacheParams {
static constexpr bool NEEDS_BIND_STORAGE_INDEX = true;
static constexpr bool USE_MEMORY_MAPS = true;
static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true;
- static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false;
+ static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
// TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false;
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 993438a27..a6c93068f 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -200,7 +200,6 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
has_broken_texture_view_formats = is_amd || (!is_linux && is_intel);
has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2;
has_derivative_control = GLAD_GL_ARB_derivative_control;
- has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory;
has_debugging_tool_attached = IsDebugToolAttached(extensions);
has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float");
has_geometry_shader_passthrough = GLAD_GL_NV_geometry_shader_passthrough;
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index a5a6bbbba..96034ea4a 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -72,10 +72,6 @@ public:
return has_texture_shadow_lod;
}
- bool HasVertexBufferUnifiedMemory() const {
- return has_vertex_buffer_unified_memory;
- }
-
bool HasASTC() const {
return has_astc;
}
@@ -215,7 +211,6 @@ private:
bool has_vertex_viewport_layer{};
bool has_image_load_formatted{};
bool has_texture_shadow_lod{};
- bool has_vertex_buffer_unified_memory{};
bool has_astc{};
bool has_variable_aoffi{};
bool has_component_indexing_bug{};
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
index bbb06e51f..cadad6507 100644
--- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
@@ -28,63 +28,69 @@ StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
StagingBuffers::~StagingBuffers() = default;
-StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence) {
+StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence,
+ bool deferred) {
MICROPROFILE_SCOPE(OpenGL_BufferRequest);
const size_t index = RequestBuffer(requested_size);
- OGLSync* const sync = insert_fence ? &syncs[index] : nullptr;
- sync_indices[index] = insert_fence ? ++current_sync_index : 0;
+ OGLSync* const sync = insert_fence ? &allocs[index].sync : nullptr;
+ allocs[index].sync_index = insert_fence ? ++current_sync_index : 0;
+ allocs[index].deferred = deferred;
return StagingBufferMap{
- .mapped_span = std::span(maps[index], requested_size),
+ .mapped_span = std::span(allocs[index].map, requested_size),
.sync = sync,
- .buffer = buffers[index].handle,
+ .buffer = allocs[index].buffer.handle,
+ .index = index,
};
}
+void StagingBuffers::FreeDeferredStagingBuffer(size_t index) {
+ ASSERT(allocs[index].deferred);
+ allocs[index].deferred = false;
+}
+
size_t StagingBuffers::RequestBuffer(size_t requested_size) {
if (const std::optional<size_t> index = FindBuffer(requested_size); index) {
return *index;
}
-
- OGLBuffer& buffer = buffers.emplace_back();
- buffer.Create();
+ StagingBufferAlloc alloc;
+ alloc.buffer.Create();
const auto next_pow2_size = Common::NextPow2(requested_size);
- glNamedBufferStorage(buffer.handle, next_pow2_size, nullptr,
+ glNamedBufferStorage(alloc.buffer.handle, next_pow2_size, nullptr,
storage_flags | GL_MAP_PERSISTENT_BIT);
- maps.push_back(static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, next_pow2_size,
- map_flags | GL_MAP_PERSISTENT_BIT)));
- syncs.emplace_back();
- sync_indices.emplace_back();
- sizes.push_back(next_pow2_size);
-
- ASSERT(syncs.size() == buffers.size() && buffers.size() == maps.size() &&
- maps.size() == sizes.size());
-
- return buffers.size() - 1;
+ alloc.map = static_cast<u8*>(glMapNamedBufferRange(alloc.buffer.handle, 0, next_pow2_size,
+ map_flags | GL_MAP_PERSISTENT_BIT));
+ alloc.size = next_pow2_size;
+ allocs.emplace_back(std::move(alloc));
+ return allocs.size() - 1;
}
std::optional<size_t> StagingBuffers::FindBuffer(size_t requested_size) {
size_t known_unsignaled_index = current_sync_index + 1;
size_t smallest_buffer = std::numeric_limits<size_t>::max();
std::optional<size_t> found;
- const size_t num_buffers = sizes.size();
+ const size_t num_buffers = allocs.size();
for (size_t index = 0; index < num_buffers; ++index) {
- const size_t buffer_size = sizes[index];
+ StagingBufferAlloc& alloc = allocs[index];
+ const size_t buffer_size = alloc.size;
if (buffer_size < requested_size || buffer_size >= smallest_buffer) {
continue;
}
- if (syncs[index].handle != 0) {
- if (sync_indices[index] >= known_unsignaled_index) {
+ if (alloc.deferred) {
+ continue;
+ }
+ if (alloc.sync.handle != 0) {
+ if (alloc.sync_index >= known_unsignaled_index) {
// This fence is later than a fence that is known to not be signaled
continue;
}
- if (!syncs[index].IsSignaled()) {
+ if (!alloc.sync.IsSignaled()) {
// Since this fence hasn't been signaled, it's safe to assume all later
// fences haven't been signaled either
- known_unsignaled_index = std::min(known_unsignaled_index, sync_indices[index]);
+ known_unsignaled_index = std::min(known_unsignaled_index, alloc.sync_index);
continue;
}
- syncs[index].Release();
+ alloc.sync.Release();
}
smallest_buffer = buffer_size;
found = index;
@@ -143,8 +149,12 @@ StagingBufferMap StagingBufferPool::RequestUploadBuffer(size_t size) {
return upload_buffers.RequestMap(size, true);
}
-StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size) {
- return download_buffers.RequestMap(size, false);
+StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size, bool deferred) {
+ return download_buffers.RequestMap(size, false, deferred);
+}
+
+void StagingBufferPool::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
+ download_buffers.FreeDeferredStagingBuffer(buffer.index);
}
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
index 60f72d3a0..07a56b4d2 100644
--- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
@@ -26,23 +26,30 @@ struct StagingBufferMap {
size_t offset = 0;
OGLSync* sync;
GLuint buffer;
+ size_t index;
};
struct StagingBuffers {
explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
~StagingBuffers();
- StagingBufferMap RequestMap(size_t requested_size, bool insert_fence);
+ StagingBufferMap RequestMap(size_t requested_size, bool insert_fence, bool deferred = false);
+
+ void FreeDeferredStagingBuffer(size_t index);
size_t RequestBuffer(size_t requested_size);
std::optional<size_t> FindBuffer(size_t requested_size);
- std::vector<OGLSync> syncs;
- std::vector<OGLBuffer> buffers;
- std::vector<u8*> maps;
- std::vector<size_t> sizes;
- std::vector<size_t> sync_indices;
+ struct StagingBufferAlloc {
+ OGLSync sync;
+ OGLBuffer buffer;
+ u8* map;
+ size_t size;
+ size_t sync_index;
+ bool deferred;
+ };
+ std::vector<StagingBufferAlloc> allocs;
GLenum storage_flags;
GLenum map_flags;
size_t current_sync_index = 0;
@@ -85,7 +92,8 @@ public:
~StagingBufferPool() = default;
StagingBufferMap RequestUploadBuffer(size_t size);
- StagingBufferMap RequestDownloadBuffer(size_t size);
+ StagingBufferMap RequestDownloadBuffer(size_t size, bool deferred = false);
+ void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
private:
StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT};
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 512eef575..66a5ca03e 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -557,8 +557,12 @@ StagingBufferMap TextureCacheRuntime::UploadStagingBuffer(size_t size) {
return staging_buffer_pool.RequestUploadBuffer(size);
}
-StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) {
- return staging_buffer_pool.RequestDownloadBuffer(size);
+StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
+ return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
+}
+
+void TextureCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
+ staging_buffer_pool.FreeDeferredStagingBuffer(buffer);
}
u64 TextureCacheRuntime::GetDeviceMemoryUsage() const {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index e71b87e99..34870c81f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -74,7 +74,9 @@ public:
StagingBufferMap UploadStagingBuffer(size_t size);
- StagingBufferMap DownloadStagingBuffer(size_t size);
+ StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false);
+
+ void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
u64 GetDeviceLocalMemory() const {
return device_access_memory;
@@ -359,7 +361,7 @@ struct TextureCacheParams {
static constexpr bool FRAMEBUFFER_BLITS = true;
static constexpr bool HAS_EMULATED_COPIES = true;
static constexpr bool HAS_DEVICE_MEMORY_INFO = true;
- static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false;
+ static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
using Runtime = OpenGL::TextureCacheRuntime;
using Image = OpenGL::Image;
@@ -367,7 +369,7 @@ struct TextureCacheParams {
using ImageView = OpenGL::ImageView;
using Sampler = OpenGL::Sampler;
using Framebuffer = OpenGL::Framebuffer;
- using AsyncBuffer = u32;
+ using AsyncBuffer = OpenGL::StagingBufferMap;
using BufferType = GLuint;
};
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 6b8d4e554..6bfed08a1 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -168,15 +168,6 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
if (!GLAD_GL_ARB_seamless_cubemap_per_texture && !GLAD_GL_AMD_seamless_cubemap_per_texture) {
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
- // Enable unified vertex attributes and query vertex buffer address when the driver supports it
- if (device.HasVertexBufferUnifiedMemory()) {
- glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV);
- glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV);
-
- glMakeNamedBufferResidentNV(vertex_buffer.handle, GL_READ_ONLY);
- glGetNamedBufferParameterui64vNV(vertex_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV,
- &vertex_buffer_address);
- }
}
RendererOpenGL::~RendererOpenGL() = default;
@@ -680,13 +671,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
offsetof(ScreenRectVertex, tex_coord));
glVertexAttribBinding(PositionLocation, 0);
glVertexAttribBinding(TexCoordLocation, 0);
- if (device.HasVertexBufferUnifiedMemory()) {
- glBindVertexBuffer(0, 0, 0, sizeof(ScreenRectVertex));
- glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, vertex_buffer_address,
- sizeof(vertices));
- } else {
- glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
- }
+ glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::NearestNeighbor) {
glBindSampler(0, present_sampler.handle);
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 66483a900..5e461fbd0 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -1211,7 +1211,7 @@ void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
return;
}
- aa_renderpass = CreateRenderPassImpl(GetFormat(framebuffer));
+ aa_renderpass = CreateRenderPassImpl(VK_FORMAT_R16G16B16A16_SFLOAT);
aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
const std::array<VkPipelineShaderStageCreateInfo, 2> fxaa_shader_stages{{
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 5dbec2e62..38b1619df 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1439,7 +1439,7 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
UploadMemory(map.buffer, map.offset, copies);
}
-void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
+void Image::DownloadMemory(VkBuffer buffer, size_t offset,
std::span<const VideoCommon::BufferImageCopy> copies) {
std::array buffer_handles{
buffer,
@@ -1450,7 +1450,7 @@ void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
DownloadMemory(buffer_handles, buffer_offsets, copies);
}
-void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceSize> offsets_span,
+void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> offsets_span,
std::span<const VideoCommon::BufferImageCopy> copies) {
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
if (is_rescaled) {
@@ -1530,7 +1530,7 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
map.buffer,
};
std::array offsets{
- map.offset,
+ static_cast<size_t>(map.offset),
};
DownloadMemory(buffers, offsets, copies);
}
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index edf5d7635..0dbde65d6 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -147,10 +147,10 @@ public:
void UploadMemory(const StagingBufferRef& map,
std::span<const VideoCommon::BufferImageCopy> copies);
- void DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
+ void DownloadMemory(VkBuffer buffer, size_t offset,
std::span<const VideoCommon::BufferImageCopy> copies);
- void DownloadMemory(std::span<VkBuffer> buffers, std::span<VkDeviceSize> offsets,
+ void DownloadMemory(std::span<VkBuffer> buffers, std::span<size_t> offsets,
std::span<const VideoCommon::BufferImageCopy> copies);
void DownloadMemory(const StagingBufferRef& map,
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index d575c57ca..dade38b18 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -995,7 +995,7 @@ void TextureCache<P>::DownloadImageIntoBuffer(typename TextureCache<P>::Image* i
buffer,
download_map.buffer,
};
- std::array<u64, 2> buffer_offsets{
+ std::array<size_t, 2> buffer_offsets{
buffer_offset,
download_map.offset,
};
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index f3ad2214b..90278052a 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -386,7 +386,7 @@ if (NOT WIN32)
target_include_directories(yuzu PRIVATE ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS})
endif()
if (UNIX AND NOT APPLE)
- target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::DBus gamemode)
+ target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::DBus)
endif()
target_compile_definitions(yuzu PRIVATE
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 10c788290..b056c3717 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2713,11 +2713,6 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
}
const auto base_romfs = base_nca->GetRomFS();
- if (!base_romfs) {
- failed();
- return;
- }
-
const auto dump_dir =
target == DumpRomFSTarget::Normal
? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)