From 367704aa829a515188d87860ffd230b1b2a136c8 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 15 Apr 2019 23:01:35 -0400 Subject: GPU MemoryManager: Implement ReadBlockUnsafe and WriteBlockUnsafe --- src/video_core/memory_manager.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/video_core/memory_manager.cpp') diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 0f4e820aa..3b9f6caf0 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -226,6 +226,22 @@ void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t } } +void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { + std::size_t remaining_size{size}; + std::size_t page_index{src_addr >> page_bits}; + std::size_t page_offset{src_addr & page_mask}; + + while (remaining_size > 0) { + const std::size_t copy_amount{ + std::min(static_cast(page_size) - page_offset, remaining_size)}; + std::memcpy(dest_buffer, src_ptr, copy_amount); + page_index++; + page_offset = 0; + dest_buffer = static_cast(dest_buffer) + copy_amount; + remaining_size -= copy_amount; + } +} + void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { std::size_t remaining_size{size}; std::size_t page_index{dest_addr >> page_bits}; @@ -253,6 +269,22 @@ void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std:: } } +void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { + std::size_t remaining_size{size}; + std::size_t page_index{dest_addr >> page_bits}; + std::size_t page_offset{dest_addr & page_mask}; + + while (remaining_size > 0) { + const std::size_t copy_amount{ + std::min(static_cast(page_size) - page_offset, remaining_size)}; + std::memcpy(dest_ptr, src_buffer, copy_amount); + page_index++; + page_offset = 0; + src_buffer = static_cast(src_buffer) + copy_amount; + remaining_size -= copy_amount; + } +} + void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size) { std::size_t remaining_size{size}; std::size_t page_index{src_addr >> page_bits}; -- cgit v1.2.3 From ef381e6924ee28162d3ce1cff0523ea7a88981d2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 15 Apr 2019 23:05:05 -0400 Subject: Use ReadBlockUnsafe on TIC and TSC reading Use ReadBlockUnsafe on TIC and TSC reading as memory is never flushed from host GPU there. --- src/video_core/memory_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/memory_manager.cpp') diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 3b9f6caf0..20d744c61 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -234,6 +234,7 @@ void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, std::s while (remaining_size > 0) { const std::size_t copy_amount{ std::min(static_cast(page_size) - page_offset, remaining_size)}; + const u8* src_ptr{page_table.pointers[page_index] + page_offset}; std::memcpy(dest_buffer, src_ptr, copy_amount); page_index++; page_offset = 0; @@ -277,6 +278,7 @@ void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, while (remaining_size > 0) { const std::size_t copy_amount{ std::min(static_cast(page_size) - page_offset, remaining_size)}; + u8* dest_ptr{page_table.pointers[page_index] + page_offset}; std::memcpy(dest_ptr, src_buffer, copy_amount); page_index++; page_offset = 0; -- cgit v1.2.3 From 06d1c5a9912dac4f20e6f0d31839ef44d8a260f2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 16 Apr 2019 10:11:35 -0400 Subject: Document unsafe versions and add BlockCopyUnsafe --- src/video_core/memory_manager.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/video_core/memory_manager.cpp') diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 20d744c61..18a8d2684 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -199,7 +199,7 @@ const u8* MemoryManager::GetPointer(GPUVAddr addr) const { return {}; } -void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { +void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, const std::size_t size) const { std::size_t remaining_size{size}; std::size_t page_index{src_addr >> page_bits}; std::size_t page_offset{src_addr & page_mask}; @@ -226,7 +226,8 @@ void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t } } -void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { +void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, + const std::size_t size) const { std::size_t remaining_size{size}; std::size_t page_index{src_addr >> page_bits}; std::size_t page_offset{src_addr & page_mask}; @@ -243,7 +244,7 @@ void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, std::s } } -void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { +void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, const std::size_t size) { std::size_t remaining_size{size}; std::size_t page_index{dest_addr >> page_bits}; std::size_t page_offset{dest_addr & page_mask}; @@ -270,7 +271,8 @@ void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std:: } } -void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { +void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, + const std::size_t size) { std::size_t remaining_size{size}; std::size_t page_index{dest_addr >> page_bits}; std::size_t page_offset{dest_addr & page_mask}; @@ -287,7 +289,7 @@ void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, } } -void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size) { +void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, const std::size_t size) { std::size_t remaining_size{size}; std::size_t page_index{src_addr >> page_bits}; std::size_t page_offset{src_addr & page_mask}; @@ -315,6 +317,12 @@ void MemoryManager::CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t } } +void MemoryManager::CopyBlockUnsafe(GPUVAddr dest_addr, GPUVAddr src_addr, const std::size_t size) { + std::vector tmp_buffer(size); + ReadBlockUnsafe(src_addr, tmp_buffer.data(), size); + WriteBlockUnsafe(dest_addr, tmp_buffer.data(), size); +} + void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, VAddr backing_addr) { LOG_DEBUG(HW_GPU, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * page_size, -- cgit v1.2.3 From d0082de82a094c98a5ef8907583415daef91604a Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 16 Apr 2019 15:45:24 -0400 Subject: Implement IsBlockContinous This detects when a GPU Memory Block is not continous within host cpu memory. --- src/video_core/memory_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/video_core/memory_manager.cpp') diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 18a8d2684..095a7e5a4 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -199,6 +199,14 @@ const u8* MemoryManager::GetPointer(GPUVAddr addr) const { return {}; } +bool MemoryManager::IsBlockContinous(const GPUVAddr start, const std::size_t size) { + const GPUVAddr end = start + size; + const auto host_ptr_start = reinterpret_cast(GetPointer(start)); + const auto host_ptr_end = reinterpret_cast(GetPointer(end)); + const std::size_t range = static_cast(host_ptr_end - host_ptr_start); + return range == size; +} + void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, const std::size_t size) const { std::size_t remaining_size{size}; std::size_t page_index{src_addr >> page_bits}; -- cgit v1.2.3 From db4b2bc798388fd22d3ea60eb82c5f894b2b3506 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 19 Apr 2019 20:35:54 -0400 Subject: make ReadBlockunsafe and WriteBlockunsafe, ignore invalid pages. --- src/video_core/memory_manager.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/video_core/memory_manager.cpp') diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 095a7e5a4..6c98c6701 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -243,8 +243,13 @@ void MemoryManager::ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, while (remaining_size > 0) { const std::size_t copy_amount{ std::min(static_cast(page_size) - page_offset, remaining_size)}; - const u8* src_ptr{page_table.pointers[page_index] + page_offset}; - std::memcpy(dest_buffer, src_ptr, copy_amount); + const u8* page_pointer = page_table.pointers[page_index]; + if (page_pointer) { + const u8* src_ptr{page_pointer + page_offset}; + std::memcpy(dest_buffer, src_ptr, copy_amount); + } else { + std::memset(dest_buffer, 0, copy_amount); + } page_index++; page_offset = 0; dest_buffer = static_cast(dest_buffer) + copy_amount; @@ -288,8 +293,11 @@ void MemoryManager::WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, while (remaining_size > 0) { const std::size_t copy_amount{ std::min(static_cast(page_size) - page_offset, remaining_size)}; - u8* dest_ptr{page_table.pointers[page_index] + page_offset}; - std::memcpy(dest_ptr, src_buffer, copy_amount); + u8* page_pointer = page_table.pointers[page_index]; + if (page_pointer) { + u8* dest_ptr{page_pointer + page_offset}; + std::memcpy(dest_ptr, src_buffer, copy_amount); + } page_index++; page_offset = 0; src_buffer = static_cast(src_buffer) + copy_amount; -- cgit v1.2.3