diff options
Diffstat (limited to '')
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) |