summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-04-16 16:11:35 +0200
committerFernando Sahmkow <fsahmkow27@gmail.com>2019-04-16 16:11:35 +0200
commit06d1c5a9912dac4f20e6f0d31839ef44d8a260f2 (patch)
tree60b313ec3cc9854320a9abeaeead37db14091009
parentUse ReadBlockUnsafe for Shader Cache (diff)
downloadyuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar.gz
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar.bz2
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar.lz
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar.xz
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.tar.zst
yuzu-06d1c5a9912dac4f20e6f0d31839ef44d8a260f2.zip
-rw-r--r--src/video_core/memory_manager.cpp18
-rw-r--r--src/video_core/memory_manager.h30
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp13
3 files changed, 45 insertions, 16 deletions
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<u8> 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,
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 29f3860c1..084d834c8 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -65,11 +65,31 @@ public:
u8* GetPointer(GPUVAddr addr);
const u8* GetPointer(GPUVAddr addr) const;
- void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const;
- void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size);
- void ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const;
- void WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, std::size_t size);
- void CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size);
+
+ /*
+ * ReadBlock and WriteBlock are full read and write operations over virtual
+ * GPU Memory. It's important to use these when GPU memory may not be continous
+ * in the Host Memory counterpart. Note: This functions cause Host GPU Memory
+ * Flushes and Invalidations, respectively to each operation.
+ */
+ void ReadBlock(GPUVAddr src_addr, void* dest_buffer, const std::size_t size) const;
+ void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, const std::size_t size);
+ void CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, const std::size_t size);
+
+ /*
+ * ReadBlockUnsafe and WriteBlockUnsafe are special versions of ReadBlock and
+ * WriteBlock respectively. In this versions, no flushing or invalidation is actually
+ * done and their performance is similar to a memcpy. This functions can be used
+ * on either of this 2 scenarios instead of their safe counterpart:
+ * - Memory which is sure to never be represented in the Host GPU.
+ * - Memory Managed by a Cache Manager. Example: Texture Flushing should use
+ * WriteBlockUnsafe instead of WriteBlock since it shouldn't invalidate the texture
+ * being flushed.
+ */
+ void ReadBlockUnsafe(GPUVAddr src_addr, void* dest_buffer, const std::size_t size) const;
+ void WriteBlockUnsafe(GPUVAddr dest_addr, const void* src_buffer, const std::size_t size);
+ void CopyBlockUnsafe(GPUVAddr dest_addr, GPUVAddr src_addr, const std::size_t size);
+
private:
using VMAMap = std::map<GPUVAddr, VirtualMemoryArea>;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 90598e291..43f2906a8 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -38,14 +38,15 @@ GPUVAddr GetShaderAddress(Maxwell::ShaderProgram program) {
}
/// Gets the shader program code from memory for the specified address
-ProgramCode GetShaderCode(const GPUVAddr gpu_addr, const u8* host_ptr) {
- auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()};
+ProgramCode GetShaderCode(Tegra::MemoryManager& memory_manager, const GPUVAddr gpu_addr,
+ const u8* host_ptr) {
ProgramCode program_code(VideoCommon::Shader::MAX_PROGRAM_LENGTH);
ASSERT_OR_EXECUTE(host_ptr != nullptr, {
std::fill(program_code.begin(), program_code.end(), 0);
return program_code;
});
- memory_manager.ReadBlockUnsafe(gpu_addr, program_code.data(), program_code.size() * sizeof(u64));
+ memory_manager.ReadBlockUnsafe(gpu_addr, program_code.data(),
+ program_code.size() * sizeof(u64));
return program_code;
}
@@ -498,12 +499,12 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
if (!shader) {
// No shader found - create a new one
- ProgramCode program_code{GetShaderCode(program_addr, host_ptr)};
+ ProgramCode program_code{GetShaderCode(memory_manager, program_addr, host_ptr)};
ProgramCode program_code_b;
if (program == Maxwell::ShaderProgram::VertexA) {
const GPUVAddr program_addr_b{GetShaderAddress(Maxwell::ShaderProgram::VertexB)};
- program_code_b =
- GetShaderCode(program_addr_b, memory_manager.GetPointer(program_addr_b));
+ program_code_b = GetShaderCode(memory_manager, program_addr_b,
+ memory_manager.GetPointer(program_addr_b));
}
const u64 unique_identifier = GetUniqueIdentifier(program, program_code, program_code_b);
const VAddr cpu_addr{*memory_manager.GpuToCpuAddress(program_addr)};