diff --git a/Utilities/VirtualMemory.cpp b/Utilities/VirtualMemory.cpp index 23fed38db4..5cfe5fc72a 100644 --- a/Utilities/VirtualMemory.cpp +++ b/Utilities/VirtualMemory.cpp @@ -136,7 +136,6 @@ namespace utils shm::shm(u32 size) : m_size(::align(size, 0x10000)) - , m_ptr(nullptr) { #ifdef _WIN32 m_handle = ::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, m_size, NULL); @@ -159,17 +158,13 @@ namespace utils verify(HERE), ::shm_unlink("/rpcs3-mem1") >= 0; verify(HERE), ::ftruncate(m_file, m_size) >= 0; #endif - - m_ptr = verify(HERE, this->map(nullptr)); } shm::~shm() { #ifdef _WIN32 - ::UnmapViewOfFile(m_ptr); ::CloseHandle(m_handle); #else - ::munmap(m_ptr, m_size); ::close(m_file); #endif } diff --git a/Utilities/VirtualMemory.h b/Utilities/VirtualMemory.h index 4618baf012..f3c06470bc 100644 --- a/Utilities/VirtualMemory.h +++ b/Utilities/VirtualMemory.h @@ -46,7 +46,6 @@ namespace utils int m_file; #endif u32 m_size; - u8* m_ptr; public: explicit shm(u32 size); @@ -69,17 +68,6 @@ namespace utils // Unmap shared memory, undoing map_critical void unmap_critical(void* ptr); - // Access memory with simple range check - u8* get(u32 offset, u32 size) const - { - if (offset >= m_size || m_size - offset < size) - { - return nullptr; - } - - return m_ptr + offset; - } - u32 size() const { return m_size; diff --git a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp index 01bf476c1c..149ac29ea9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp @@ -33,7 +33,7 @@ error_code sys_dbg_read_process_memory(s32 pid, u32 address, u32 size, vm::ptr(address, size).get(), size); + std::memcpy(data.get_ptr(), vm::get_super_ptr(address), size); return CELL_OK; } @@ -64,7 +64,7 @@ error_code sys_dbg_write_process_memory(s32 pid, u32 address, u32 size, vm::cptr return CELL_EFAULT; } - std::memcpy(vm::get_super_ptr(address, size).get(), data.get_ptr(), size); + std::memcpy(vm::get_super_ptr(address), data.get_ptr(), size); return CELL_OK; } diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index a58c74eede..6c5cff0bf6 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -31,10 +31,13 @@ namespace vm } // Emulated virtual memory - u8* const g_base_addr = memory_reserve_4GiB(0); + u8* const g_base_addr = memory_reserve_4GiB(0x2'0000'0000); + + // Unprotected virtual memory mirror + u8* const g_sudo_addr = memory_reserve_4GiB((std::uintptr_t)g_base_addr); // Auxiliary virtual memory for executable areas - u8* const g_exec_addr = memory_reserve_4GiB((std::uintptr_t)g_base_addr); + u8* const g_exec_addr = memory_reserve_4GiB((std::uintptr_t)g_sudo_addr); // Stats for debugging u8* const g_stat_addr = memory_reserve_4GiB((std::uintptr_t)g_exec_addr); @@ -305,7 +308,7 @@ namespace vm utils::memory_protect(g_base_addr + addr, size, utils::protection::rw); std::memset(g_base_addr + addr, 0, size); } - else if (shm->map_critical(g_base_addr + addr) != g_base_addr + addr) + else if (shm->map_critical(g_base_addr + addr) != g_base_addr + addr || shm->map_critical(g_sudo_addr + addr) != g_sudo_addr + addr) { fmt::throw_exception("Memory mapping failed - blame Windows (addr=0x%x, size=0x%x, flags=0x%x)", addr, size, flags); } @@ -437,6 +440,7 @@ namespace vm else { shm->unmap_critical(g_base_addr + addr); + shm->unmap_critical(g_sudo_addr + addr); } if (is_exec) @@ -575,6 +579,7 @@ namespace vm // Special path for 4k-aligned pages m_common = std::make_shared(size); verify(HERE), m_common->map_critical(vm::base(addr), utils::protection::no) == vm::base(addr); + verify(HERE), m_common->map_critical(vm::get_super_ptr(addr), utils::protection::no) == vm::get_super_ptr(addr); } } @@ -596,6 +601,7 @@ namespace vm if (m_common) { m_common->unmap_critical(vm::base(addr)); + m_common->unmap_critical(vm::get_super_ptr(addr)); } } } diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index e66cf9540f..d27ee13bc0 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -12,6 +12,7 @@ class notifier; namespace vm { extern u8* const g_base_addr; + extern u8* const g_sudo_addr; extern u8* const g_exec_addr; extern u8* const g_stat_addr; extern u8* const g_reservations; @@ -303,32 +304,10 @@ namespace vm } // Access memory bypassing memory protection - template - inline std::shared_ptr> get_super_ptr(u32 addr, u32 count = 1) + template + inline to_be_t* get_super_ptr(u32 addr) { - const auto area = vm::get(vm::any, addr); - - if (!area || addr + u64{count} * sizeof(T) > UINT32_MAX) - { - return nullptr; - } - - const auto shm = area->get(addr, sizeof(T) * count); - - if (!shm.second || shm.first > addr) - { - return nullptr; - } - - const auto ptr = reinterpret_cast*>(shm.second->get(addr - shm.first, sizeof(T) * count)); - - if (!ptr) - { - return nullptr; - } - - // Create a shared pointer using the aliasing constructor - return {shm.second, ptr}; + return reinterpret_cast*>(g_sudo_addr + addr); } inline const be_t& read16(u32 addr) diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 7e911d1517..5b132509c6 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -2583,16 +2583,13 @@ namespace rsx void tag_framebuffer(u32 texaddr) { - auto super_ptr = rsx::get_super_ptr(texaddr, 4); - volatile u32 *ptr = super_ptr.get(); + auto ptr = vm::get_super_ptr>(texaddr); *ptr = texaddr; - super_ptr.flush(0, 4); } bool test_framebuffer(u32 texaddr) { - auto super_ptr = rsx::get_super_ptr(texaddr, 4); - volatile const u32 *ptr = super_ptr.get(); + auto ptr = vm::get_super_ptr>(texaddr); return *ptr == texaddr; } }; diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 21b2762d5c..dbdbc25e80 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -495,7 +495,7 @@ namespace gl const u32 valid_length = valid_range.second; AUDIT( valid_length > 0 ); - void *dst = get_ptr_by_offset(valid_range.first, true); + void *dst = get_ptr(get_section_base() + valid_offset); glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); void *src = glMapBufferRange(GL_PIXEL_PACK_BUFFER, valid_offset, valid_length, GL_MAP_READ_BIT); @@ -588,7 +588,6 @@ namespace gl } } - flush_ptr_by_offset(valid_offset, valid_length); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 3c6ce825d3..c371b2853a 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2744,22 +2744,6 @@ namespace rsx return; on_invalidate_memory_range(m_invalidated_memory_range); - - // Clean the main memory super_ptr cache if invalidated - for (auto It = main_super_memory_block.begin(); It != main_super_memory_block.end();) - { - const auto block_range = address_range::start_length(It->first, It->second.size()); - - if (m_invalidated_memory_range.overlaps(block_range)) - { - It = main_super_memory_block.erase(It); - } - else - { - It++; - } - } - m_invalidated_memory_range.invalidate(); } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 09f1eaeca2..a3a69a087b 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -430,10 +430,6 @@ namespace rsx GcmTileInfo tiles[limits::tiles_count]; GcmZcullInfo zculls[limits::zculls_count]; - // Super memory map (mapped block with r/w permissions) - std::pair> local_super_memory_block; - std::unordered_map main_super_memory_block; - bool capture_current_frame = false; void capture_frame(const std::string &name); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index ffa90fdc20..d2d42a90a8 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -309,7 +309,7 @@ namespace vk AUDIT( valid_length > 0 ); void* pixels_src = dma_buffer->map(valid_offset, valid_length); - void* pixels_dst = get_ptr_by_offset(valid_offset, true); + void* pixels_dst = get_ptr(get_section_base() + valid_offset); if (real_pitch >= rsx_pitch || valid_length <= rsx_pitch) { @@ -334,7 +334,6 @@ namespace vk } } - flush_ptr_by_offset(valid_offset, valid_length); dma_buffer->unmap(); reset_write_statistics(); diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index f254b81477..4c2b6e0227 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -48,7 +48,6 @@ namespace rsx address_range locked_range; address_range cpu_range = {}; address_range confirmed_range; - weak_ptr super_ptr; utils::protection protection = utils::protection::rw; @@ -98,8 +97,6 @@ namespace rsx protection = utils::protection::rw; locked = false; - super_ptr = {}; - init_lockable_range(cpu_range); } @@ -137,8 +134,6 @@ namespace rsx if (protection == utils::protection::no) { - super_ptr = rsx::get_super_ptr(cpu_range); - verify(HERE), super_ptr; tag_memory(); } else @@ -148,8 +143,6 @@ namespace rsx //Unprotect range also invalidates secured range confirmed_range.invalidate(); } - - super_ptr = {}; } } @@ -177,7 +170,7 @@ namespace rsx confirmed_range = address_range::start_length(cpu_range.start + new_confirm.first, new_confirm.second); ASSERT(!locked || locked_range.inside(confirmed_range.to_page_range())); } - + verify(HERE), confirmed_range.inside(cpu_range); init_lockable_range(confirmed_range); } @@ -200,7 +193,6 @@ namespace rsx protection = utils::protection::rw; confirmed_range.invalidate(); - super_ptr = {}; locked = false; } @@ -324,44 +316,11 @@ namespace rsx * Super Pointer */ template - inline T* get_ptr_by_offset(u32 offset = 0, bool no_sync = false) + inline T* get_ptr(u32 address) { - verify(HERE), super_ptr && cpu_range.length() >= (offset + sizeof(T)); - return super_ptr.get(offset, no_sync); + return reinterpret_cast(vm::g_sudo_addr + address); } - // specialization due to sizeof(void) being illegal - inline void* get_ptr_by_offset(u32 offset, bool no_sync) - { - verify(HERE), super_ptr && cpu_range.length() >= (offset + 1); - return super_ptr.get(offset, no_sync); - } - - template - inline T* get_ptr(u32 address, bool no_sync = false) - { - verify(HERE), cpu_range.start <= address; // super_ptr & sizeof(T) tests are done by get_ptr_by_offset - return get_ptr_by_offset(address - cpu_range.start, no_sync); - } - - inline void flush_ptr_by_offset(u32 offset = 0, u32 len = 0) const - { - verify(HERE), super_ptr && cpu_range.length() >= (offset + len); - super_ptr.flush(offset, len); - } - - inline void flush_ptr(u32 address, u32 len = 0) const - { - verify(HERE), cpu_range.start <= address; // super_ptr & length tests are done by flush_ptr_by_offset - return flush_ptr_by_offset(address - cpu_range.start, len); - } - - inline void flush_ptr(const address_range &range) const - { - return flush_ptr(range.start, range.length()); - } - - /** * Memory tagging */ @@ -372,18 +331,15 @@ namespace rsx if (guard_policy == protect_policy_full_range) return; - AUDIT(locked && super_ptr); + AUDIT(locked); const address_range& range = get_confirmed_range(); - volatile u32* first = get_ptr(range.start, true); - volatile u32* last = get_ptr(range.end - 3, true); + volatile u32* first = get_ptr(range.start); + volatile u32* last = get_ptr(range.end - 3); *first = range.start; *last = range.end; - - flush_ptr(range.start, 4); - flush_ptr(range.end - 3, 4); } public: @@ -392,7 +348,7 @@ namespace rsx if (guard_policy == protect_policy_full_range) return true; - AUDIT(locked && super_ptr); + AUDIT(locked); const auto& range = get_confirmed_range(); volatile const u32* first = get_ptr(range.start); @@ -404,7 +360,7 @@ namespace rsx if (guard_policy == protect_policy_full_range) return true; - AUDIT(locked && super_ptr); + AUDIT(locked); const auto& range = get_confirmed_range(); volatile const u32* last = get_ptr(range.end-3); @@ -510,7 +466,7 @@ namespace rsx ref_cnt--; }); } - + virtual void set_limit(u32 index, u32 limit) { ref_cnt++; diff --git a/rpcs3/Emu/RSX/rsx_utils.cpp b/rpcs3/Emu/RSX/rsx_utils.cpp index fd813357d5..79381d2027 100644 --- a/rpcs3/Emu/RSX/rsx_utils.cpp +++ b/rpcs3/Emu/RSX/rsx_utils.cpp @@ -76,94 +76,6 @@ namespace rsx } } - weak_ptr get_super_ptr(const address_range &range) - { - return get_super_ptr(range.start, range.length()); - } - - weak_ptr get_super_ptr(u32 addr, u32 len) - { - verify(HERE), g_current_renderer; - - if (!g_current_renderer->local_super_memory_block.first) - { - auto block = vm::get(vm::any, 0xC0000000); - if (block) - { - g_current_renderer->local_super_memory_block.first = block->used(); - g_current_renderer->local_super_memory_block.second = vm::get_super_ptr(0xC0000000, g_current_renderer->local_super_memory_block.first - 1); - - if (!g_current_renderer->local_super_memory_block.second) - { - //Disjoint allocation? - LOG_ERROR(RSX, "Could not initialize contiguous RSX super-memory"); - } - } - else - { - fmt::throw_exception("RSX memory not mapped!"); - } - } - - if (g_current_renderer->local_super_memory_block.second) - { - if (addr >= 0xC0000000 && (addr + len) <= (0xC0000000 + g_current_renderer->local_super_memory_block.first)) - { - //RSX local - return { g_current_renderer->local_super_memory_block.second.get() + (addr - 0xC0000000) }; - } - } - - const auto cached = g_current_renderer->main_super_memory_block.find(addr); - if (cached != g_current_renderer->main_super_memory_block.end()) - { - const auto& _ptr = cached->second; - if (_ptr.size() >= len) - { - return _ptr; - } - } - - if (auto result = vm::get_super_ptr(addr, len - 1)) - { - weak_ptr _ptr = { result, len }; - auto &ret = g_current_renderer->main_super_memory_block[addr] = std::move(_ptr); - return _ptr; - } - - //Probably allocated as split blocks. Try to grab separate chunks - std::vector blocks; - const u32 limit = addr + len; - u32 next = addr; - u32 remaining = len; - - while (true) - { - auto region = vm::get(vm::any, next)->get(next, 1); - if (!region.second) - { - break; - } - - const u32 block_offset = next - region.first; - const u32 block_length = std::min(remaining, region.second->size() - block_offset); - std::shared_ptr _ptr = { region.second, region.second->get(block_offset, block_length) }; - blocks.push_back({_ptr, block_length}); - - remaining -= block_length; - next = region.first + region.second->size(); - if (next >= limit) - { - weak_ptr _ptr = { blocks }; - auto &ret = g_current_renderer->main_super_memory_block[addr] = std::move(_ptr); - return ret; - } - } - - LOG_ERROR(RSX, "Could not get super_ptr for memory block 0x%x+0x%x", addr, len); - return {}; - } - /* Fast image scaling routines * Only uses fast nearest scaling and integral scaling factors * T - Dst type diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index c21a976a64..8c5522ce6e 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -39,184 +39,6 @@ namespace rsx void reset_refs() { deref_count = 0; } }; - //Weak pointer without lock semantics - //Backed by a real shared_ptr for non-rsx memory - //Backed by a global shared pool for rsx memory - class weak_ptr - { - public: - using memory_block_t = std::pair, u32>; - - private: - void* _ptr = nullptr; - std::vector _blocks; - std::vector io_cache; - bool contiguous = true; - bool synchronized = true; - - public: - weak_ptr(void* raw, bool is_rsx_mem = true) - { - _ptr = raw; - - if (!is_rsx_mem) - { - _blocks.push_back({}); - _blocks.back().first.reset((u8*)raw); - } - } - - weak_ptr(std::shared_ptr& block, u32 size) - { - _blocks.push_back({ block, size }); - _ptr = block.get(); - } - - weak_ptr(std::vector& blocks) - { - verify(HERE), blocks.size() > 0; - - _blocks = std::move(blocks); - _ptr = nullptr; - - if (blocks.size() == 1) - { - _ptr = _blocks[0].first.get(); - contiguous = true; - } - else - { - u32 block_length = 0; - for (const auto &block : _blocks) - { - block_length += block.second; - } - - io_cache.resize(block_length); - contiguous = false; - synchronized = false; - } - } - - weak_ptr() - { - _ptr = nullptr; - } - - template - T* get(u32 offset = 0, bool no_sync = false) - { - if (contiguous) - { - return (T*)((u8*)_ptr + offset); - } - else - { - if (!synchronized && !no_sync) - sync(); - - return (T*)(io_cache.data() + offset); - } - } - - void sync() - { - if (synchronized) - return; - - u8* dst = (u8*)io_cache.data(); - for (const auto &block : _blocks) - { - memcpy(dst, block.first.get(), block.second); - dst += block.second; - } - - synchronized = true; - } - - void flush(u32 offset = 0, u32 len = 0) const - { - if (contiguous) - return; - - u8* src = (u8*)io_cache.data(); - - if (!offset && (!len || len == io_cache.size())) - { - for (const auto &block : _blocks) - { - memcpy(block.first.get(), src, block.second); - src += block.second; - } - } - else - { - auto remaining_bytes = len? len : io_cache.size() - offset; - const auto write_end = remaining_bytes + offset; - - u32 write_offset; - u32 write_length; - u32 base_offset = 0; - - for (const auto &block : _blocks) - { - const u32 block_end = base_offset + block.second; - - if (offset >= base_offset && offset < block_end) - { - // Head - write_offset = (offset - base_offset); - write_length = std::min(block.second - write_offset, (u32)remaining_bytes); - } - else if (base_offset > offset && block_end <= write_end) - { - // Completely spanned - write_offset = 0; - write_length = block.second; - } - else if (base_offset > offset && write_end < block_end) - { - // Tail - write_offset = 0; - write_length = (u32)remaining_bytes; - } - else - { - // No overlap; skip - write_length = 0; - } - - if (write_length) - { - memcpy(block.first.get() + write_offset, src + (base_offset + write_offset), write_length); - - verify(HERE), write_length <= remaining_bytes; - remaining_bytes -= write_length; - if (!remaining_bytes) - break; - } - - base_offset += block.second; - } - } - } - - u32 size() const - { - return contiguous ? _blocks[0].second : (u32)io_cache.size(); - } - - operator bool() const - { - return (_ptr != nullptr || _blocks.size() > 1); - } - }; - - // Acquire memory mirror with r/w permissions - weak_ptr get_super_ptr(const address_range &range); - weak_ptr get_super_ptr(u32 addr, u32 size); - - /** * Holds information about a framebuffer */