summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-24 00:19:36 -0400
committerGravatar bunnei2018-04-24 22:31:45 -0400
commit4415e00181f71b35eea779157976773d9bccf638 (patch)
tree604e0f8de1fe238ac74eee4fd3d5eabdb59e7bc1 /src
parentmemory_manager: Add implement CpuToGpuAddress. (diff)
downloadyuzu-4415e00181f71b35eea779157976773d9bccf638.tar.gz
yuzu-4415e00181f71b35eea779157976773d9bccf638.tar.xz
yuzu-4415e00181f71b35eea779157976773d9bccf638.zip
gl_rasterizer_cache: Update to be based on GPU addresses, not CPU addresses.
Diffstat (limited to 'src')
-rw-r--r--src/core/memory.cpp64
-rw-r--r--src/core/memory.h3
-rw-r--r--src/video_core/memory_manager.h1
-rw-r--r--src/video_core/rasterizer_interface.h7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h27
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp3
-rw-r--r--src/video_core/textures/decoders.cpp1
10 files changed, 122 insertions, 67 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 291bf066f..ff0420c56 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -325,15 +325,29 @@ u8* GetPhysicalPointer(PAddr address) {
325 return target_pointer; 325 return target_pointer;
326} 326}
327 327
328void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { 328void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
329 if (start == 0) { 329 if (gpu_addr == 0) {
330 return; 330 return;
331 } 331 }
332 332
333 u64 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; 333 // Iterate over a contiguous CPU address space, which corresponds to the specified GPU address
334 VAddr vaddr = start; 334 // space, marking the region as un/cached. The region is marked un/cached at a granularity of
335 // CPU pages, hence why we iterate on a CPU page basis (note: GPU page size is different). This
336 // assumes the specified GPU address region is contiguous as well.
337
338 u64 num_pages = ((gpu_addr + size - 1) >> PAGE_BITS) - (gpu_addr >> PAGE_BITS) + 1;
339 for (unsigned i = 0; i < num_pages; ++i, gpu_addr += PAGE_SIZE) {
340 boost::optional<VAddr> maybe_vaddr =
341 Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr);
342 // The GPU <-> CPU virtual memory mapping is not 1:1
343 if (!maybe_vaddr) {
344 LOG_ERROR(HW_Memory,
345 "Trying to flush a cached region to an invalid physical address %08X",
346 gpu_addr);
347 continue;
348 }
349 VAddr vaddr = *maybe_vaddr;
335 350
336 for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) {
337 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 351 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
338 352
339 if (cached) { 353 if (cached) {
@@ -347,6 +361,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) {
347 page_type = PageType::RasterizerCachedMemory; 361 page_type = PageType::RasterizerCachedMemory;
348 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; 362 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr;
349 break; 363 break;
364 case PageType::RasterizerCachedMemory:
365 // There can be more than one GPU region mapped per CPU region, so it's common that
366 // this area is already marked as cached.
367 break;
350 default: 368 default:
351 UNREACHABLE(); 369 UNREACHABLE();
352 } 370 }
@@ -357,6 +375,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) {
357 // It is not necessary for a process to have this region mapped into its address 375 // It is not necessary for a process to have this region mapped into its address
358 // space, for example, a system module need not have a VRAM mapping. 376 // space, for example, a system module need not have a VRAM mapping.
359 break; 377 break;
378 case PageType::Memory:
379 // There can be more than one GPU region mapped per CPU region, so it's common that
380 // this area is already unmarked as cached.
381 break;
360 case PageType::RasterizerCachedMemory: { 382 case PageType::RasterizerCachedMemory: {
361 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); 383 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK);
362 if (pointer == nullptr) { 384 if (pointer == nullptr) {
@@ -394,19 +416,29 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
394 416
395 VAddr overlap_start = std::max(start, region_start); 417 VAddr overlap_start = std::max(start, region_start);
396 VAddr overlap_end = std::min(end, region_end); 418 VAddr overlap_end = std::min(end, region_end);
419
420 std::vector<Tegra::GPUVAddr> gpu_addresses =
421 Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start);
422
423 if (gpu_addresses.empty()) {
424 return;
425 }
426
397 u64 overlap_size = overlap_end - overlap_start; 427 u64 overlap_size = overlap_end - overlap_start;
398 428
399 auto* rasterizer = VideoCore::g_renderer->Rasterizer(); 429 for (const auto& gpu_address : gpu_addresses) {
400 switch (mode) { 430 auto* rasterizer = VideoCore::g_renderer->Rasterizer();
401 case FlushMode::Flush: 431 switch (mode) {
402 rasterizer->FlushRegion(overlap_start, overlap_size); 432 case FlushMode::Flush:
403 break; 433 rasterizer->FlushRegion(gpu_address, overlap_size);
404 case FlushMode::Invalidate: 434 break;
405 rasterizer->InvalidateRegion(overlap_start, overlap_size); 435 case FlushMode::Invalidate:
406 break; 436 rasterizer->InvalidateRegion(gpu_address, overlap_size);
407 case FlushMode::FlushAndInvalidate: 437 break;
408 rasterizer->FlushAndInvalidateRegion(overlap_start, overlap_size); 438 case FlushMode::FlushAndInvalidate:
409 break; 439 rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size);
440 break;
441 }
410 } 442 }
411 }; 443 };
412 444
diff --git a/src/core/memory.h b/src/core/memory.h
index e9b8ca873..3f56a2c6a 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -14,6 +14,7 @@
14#include <boost/optional.hpp> 14#include <boost/optional.hpp>
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "core/memory_hook.h" 16#include "core/memory_hook.h"
17#include "video_core/memory_manager.h"
17 18
18namespace Kernel { 19namespace Kernel {
19class Process; 20class Process;
@@ -258,7 +259,7 @@ enum class FlushMode {
258/** 259/**
259 * Mark each page touching the region as cached. 260 * Mark each page touching the region as cached.
260 */ 261 */
261void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached); 262void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached);
262 263
263/** 264/**
264 * Flushes and invalidates any externally cached rasterizer resources touching the given virtual 265 * Flushes and invalidates any externally cached rasterizer resources touching the given virtual
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 7d745101f..08140c83a 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -11,7 +11,6 @@
11#include <boost/optional.hpp> 11#include <boost/optional.hpp>
12 12
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "core/memory.h"
15 14
16namespace Tegra { 15namespace Tegra {
17 16
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 36629dd11..f0e48a802 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -6,6 +6,7 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "video_core/gpu.h" 8#include "video_core/gpu.h"
9#include "video_core/memory_manager.h"
9 10
10struct ScreenInfo; 11struct ScreenInfo;
11 12
@@ -25,14 +26,14 @@ public:
25 virtual void FlushAll() = 0; 26 virtual void FlushAll() = 0;
26 27
27 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory 28 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
28 virtual void FlushRegion(VAddr addr, u64 size) = 0; 29 virtual void FlushRegion(Tegra::GPUVAddr addr, u64 size) = 0;
29 30
30 /// Notify rasterizer that any caches of the specified region should be invalidated 31 /// Notify rasterizer that any caches of the specified region should be invalidated
31 virtual void InvalidateRegion(VAddr addr, u64 size) = 0; 32 virtual void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0;
32 33
33 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory 34 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
34 /// and invalidated 35 /// and invalidated
35 virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; 36 virtual void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0;
36 37
37 /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 38 /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
38 virtual bool AccelerateDisplayTransfer(const void* config) { 39 virtual bool AccelerateDisplayTransfer(const void* config) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 71612790b..bc9368877 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -150,9 +150,8 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
150 u64 size = end - start + 1; 150 u64 size = end - start + 1;
151 151
152 // Copy vertex array data 152 // Copy vertex array data
153 const VAddr data_addr{*memory_manager->GpuToCpuAddress(start)}; 153 res_cache.FlushRegion(start, size, nullptr);
154 res_cache.FlushRegion(data_addr, size, nullptr); 154 Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size);
155 Memory::ReadBlock(data_addr, array_ptr, size);
156 155
157 // Bind the vertex array to the buffer at the current offset. 156 // Bind the vertex array to the buffer at the current offset.
158 glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); 157 glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride);
@@ -519,17 +518,17 @@ void RasterizerOpenGL::FlushAll() {
519 res_cache.FlushAll(); 518 res_cache.FlushAll();
520} 519}
521 520
522void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { 521void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) {
523 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 522 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
524 res_cache.FlushRegion(addr, size); 523 res_cache.FlushRegion(addr, size);
525} 524}
526 525
527void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { 526void RasterizerOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size) {
528 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 527 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
529 res_cache.InvalidateRegion(addr, size, nullptr); 528 res_cache.InvalidateRegion(addr, size, nullptr);
530} 529}
531 530
532void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { 531void RasterizerOpenGL::FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) {
533 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 532 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
534 res_cache.FlushRegion(addr, size); 533 res_cache.FlushRegion(addr, size);
535 res_cache.InvalidateRegion(addr, size, nullptr); 534 res_cache.InvalidateRegion(addr, size, nullptr);
@@ -560,7 +559,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu
560 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 559 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
561 560
562 SurfaceParams src_params; 561 SurfaceParams src_params;
563 src_params.addr = framebuffer_addr; 562 src_params.cpu_addr = framebuffer_addr;
564 src_params.width = std::min(framebuffer.width, pixel_stride); 563 src_params.width = std::min(framebuffer.width, pixel_stride);
565 src_params.height = framebuffer.height; 564 src_params.height = framebuffer.height;
566 src_params.stride = pixel_stride; 565 src_params.stride = pixel_stride;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 544714b95..9709e595e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -11,6 +11,7 @@
11#include <glad/glad.h> 11#include <glad/glad.h>
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "video_core/engines/maxwell_3d.h" 13#include "video_core/engines/maxwell_3d.h"
14#include "video_core/memory_manager.h"
14#include "video_core/rasterizer_interface.h" 15#include "video_core/rasterizer_interface.h"
15#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 16#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
16#include "video_core/renderer_opengl/gl_resource_manager.h" 17#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -29,9 +30,9 @@ public:
29 void DrawArrays() override; 30 void DrawArrays() override;
30 void NotifyMaxwellRegisterChanged(u32 method) override; 31 void NotifyMaxwellRegisterChanged(u32 method) override;
31 void FlushAll() override; 32 void FlushAll() override;
32 void FlushRegion(VAddr addr, u64 size) override; 33 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;
33 void InvalidateRegion(VAddr addr, u64 size) override; 34 void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) override;
34 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 35 void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) override;
35 bool AccelerateDisplayTransfer(const void* config) override; 36 bool AccelerateDisplayTransfer(const void* config) override;
36 bool AccelerateTextureCopy(const void* config) override; 37 bool AccelerateTextureCopy(const void* config) override;
37 bool AccelerateFill(const void* config) override; 38 bool AccelerateFill(const void* config) override;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index ced648c12..d139d51e9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -83,26 +83,30 @@ static u16 GetResolutionScaleFactor() {
83} 83}
84 84
85template <bool morton_to_gl, PixelFormat format> 85template <bool morton_to_gl, PixelFormat format>
86void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr base, VAddr start, 86void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base,
87 VAddr end) { 87 Tegra::GPUVAddr start, Tegra::GPUVAddr end) {
88 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; 88 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8;
89 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); 89 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
90 const auto& gpu = Core::System::GetInstance().GPU();
90 91
91 if (morton_to_gl) { 92 if (morton_to_gl) {
92 auto data = Tegra::Texture::UnswizzleTexture( 93 auto data = Tegra::Texture::UnswizzleTexture(
93 base, SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, 94 *gpu.memory_manager->GpuToCpuAddress(base),
94 block_height); 95 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
95 std::memcpy(gl_buffer, data.data(), data.size()); 96 std::memcpy(gl_buffer, data.data(), data.size());
96 } else { 97 } else {
97 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check 98 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check
98 // the configuration for this and perform more generic un/swizzle 99 // the configuration for this and perform more generic un/swizzle
99 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); 100 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
100 VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, 101 VideoCore::MortonCopyPixels128(
101 Memory::GetPointer(base), gl_buffer, morton_to_gl); 102 stride, height, bytes_per_pixel, gl_bytes_per_pixel,
103 Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(base)), gl_buffer,
104 morton_to_gl);
102 } 105 }
103} 106}
104 107
105static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), 108static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr,
109 Tegra::GPUVAddr),
106 SurfaceParams::MaxPixelFormat> 110 SurfaceParams::MaxPixelFormat>
107 morton_to_gl_fns = { 111 morton_to_gl_fns = {
108 MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, 112 MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
@@ -110,7 +114,8 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
110 MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, 114 MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>,
111}; 115};
112 116
113static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), 117static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr,
118 Tegra::GPUVAddr),
114 SurfaceParams::MaxPixelFormat> 119 SurfaceParams::MaxPixelFormat>
115 gl_to_morton_fns = { 120 gl_to_morton_fns = {
116 MortonCopy<false, PixelFormat::ABGR8>, 121 MortonCopy<false, PixelFormat::ABGR8>,
@@ -219,9 +224,9 @@ SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const {
219 SurfaceParams params = *this; 224 SurfaceParams params = *this;
220 const u32 tiled_size = is_tiled ? 8 : 1; 225 const u32 tiled_size = is_tiled ? 8 : 1;
221 const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size); 226 const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size);
222 VAddr aligned_start = 227 Tegra::GPUVAddr aligned_start =
223 addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); 228 addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes);
224 VAddr aligned_end = 229 Tegra::GPUVAddr aligned_end =
225 addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); 230 addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes);
226 231
227 if (aligned_end - aligned_start > stride_tiled_bytes) { 232 if (aligned_end - aligned_start > stride_tiled_bytes) {
@@ -342,6 +347,13 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const {
342 return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval(); 347 return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval();
343} 348}
344 349
350VAddr SurfaceParams::GetCpuAddr() const {
351 // When this function is used, only cpu_addr or (GPU) addr should be set, not both
352 ASSERT(!(cpu_addr && addr));
353 const auto& gpu = Core::System::GetInstance().GPU();
354 return cpu_addr.get_value_or(*gpu.memory_manager->GpuToCpuAddress(addr));
355}
356
345bool CachedSurface::CanFill(const SurfaceParams& dest_surface, 357bool CachedSurface::CanFill(const SurfaceParams& dest_surface,
346 SurfaceInterval fill_interval) const { 358 SurfaceInterval fill_interval) const {
347 if (type == SurfaceType::Fill && IsRegionValid(fill_interval) && 359 if (type == SurfaceType::Fill && IsRegionValid(fill_interval) &&
@@ -456,10 +468,10 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac
456} 468}
457 469
458MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); 470MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192));
459void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { 471void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end) {
460 ASSERT(type != SurfaceType::Fill); 472 ASSERT(type != SurfaceType::Fill);
461 473
462 u8* const texture_src_data = Memory::GetPointer(addr); 474 u8* const texture_src_data = Memory::GetPointer(GetCpuAddr());
463 if (texture_src_data == nullptr) 475 if (texture_src_data == nullptr)
464 return; 476 return;
465 477
@@ -485,8 +497,8 @@ void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) {
485} 497}
486 498
487MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); 499MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64));
488void CachedSurface::FlushGLBuffer(VAddr flush_start, VAddr flush_end) { 500void CachedSurface::FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end) {
489 u8* const dst_buffer = Memory::GetPointer(addr); 501 u8* const dst_buffer = Memory::GetPointer(GetCpuAddr());
490 if (dst_buffer == nullptr) 502 if (dst_buffer == nullptr)
491 return; 503 return;
492 504
@@ -1028,7 +1040,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
1028 auto& gpu = Core::System::GetInstance().GPU(); 1040 auto& gpu = Core::System::GetInstance().GPU();
1029 1041
1030 SurfaceParams params; 1042 SurfaceParams params;
1031 params.addr = *gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); 1043 params.addr = config.tic.Address();
1032 params.width = config.tic.Width(); 1044 params.width = config.tic.Width();
1033 params.height = config.tic.Height(); 1045 params.height = config.tic.Height();
1034 params.is_tiled = config.tic.IsTiled(); 1046 params.is_tiled = config.tic.IsTiled();
@@ -1045,7 +1057,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
1045 params.block_height = config.tic.BlockHeight(); 1057 params.block_height = config.tic.BlockHeight();
1046 } else { 1058 } else {
1047 // Use the texture-provided stride value if the texture isn't tiled. 1059 // Use the texture-provided stride value if the texture isn't tiled.
1048 params.stride = params.PixelsInBytes(config.tic.Pitch()); 1060 params.stride = static_cast<u32>(params.PixelsInBytes(config.tic.Pitch()));
1049 } 1061 }
1050 1062
1051 params.UpdateParams(); 1063 params.UpdateParams();
@@ -1073,7 +1085,6 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
1073SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( 1085SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
1074 bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { 1086 bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) {
1075 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 1087 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
1076 const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
1077 const auto& config = regs.rt[0]; 1088 const auto& config = regs.rt[0];
1078 1089
1079 // TODO(bunnei): This is hard corded to use just the first render buffer 1090 // TODO(bunnei): This is hard corded to use just the first render buffer
@@ -1106,7 +1117,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
1106 color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; 1117 color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
1107 SurfaceParams depth_params = color_params; 1118 SurfaceParams depth_params = color_params;
1108 1119
1109 color_params.addr = *memory_manager->GpuToCpuAddress(config.Address()); 1120 color_params.addr = config.Address();
1110 color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); 1121 color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format);
1111 color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); 1122 color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format);
1112 color_params.UpdateParams(); 1123 color_params.UpdateParams();
@@ -1222,7 +1233,8 @@ void RasterizerCacheOpenGL::DuplicateSurface(const Surface& src_surface,
1222 } 1233 }
1223} 1234}
1224 1235
1225void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr, u64 size) { 1236void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr,
1237 u64 size) {
1226 if (size == 0) 1238 if (size == 0)
1227 return; 1239 return;
1228 1240
@@ -1261,7 +1273,7 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr,
1261 } 1273 }
1262} 1274}
1263 1275
1264void RasterizerCacheOpenGL::FlushRegion(VAddr addr, u64 size, Surface flush_surface) { 1276void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface) {
1265 if (size == 0) 1277 if (size == 0)
1266 return; 1278 return;
1267 1279
@@ -1297,7 +1309,8 @@ void RasterizerCacheOpenGL::FlushAll() {
1297 FlushRegion(0, Kernel::VMManager::MAX_ADDRESS); 1309 FlushRegion(0, Kernel::VMManager::MAX_ADDRESS);
1298} 1310}
1299 1311
1300void RasterizerCacheOpenGL::InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner) { 1312void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size,
1313 const Surface& region_owner) {
1301 if (size == 0) 1314 if (size == 0)
1302 return; 1315 return;
1303 1316
@@ -1390,7 +1403,7 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
1390 surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); 1403 surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
1391} 1404}
1392 1405
1393void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { 1406void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {
1394 const u64 num_pages = 1407 const u64 num_pages =
1395 ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1; 1408 ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1;
1396 const u64 page_start = addr >> Memory::PAGE_BITS; 1409 const u64 page_start = addr >> Memory::PAGE_BITS;
@@ -1406,8 +1419,10 @@ void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int del
1406 const auto interval = pair.first & pages_interval; 1419 const auto interval = pair.first & pages_interval;
1407 const int count = pair.second; 1420 const int count = pair.second;
1408 1421
1409 const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; 1422 const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval)
1410 const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; 1423 << Memory::PAGE_BITS;
1424 const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval)
1425 << Memory::PAGE_BITS;
1411 const u64 interval_size = interval_end_addr - interval_start_addr; 1426 const u64 interval_size = interval_end_addr - interval_start_addr;
1412 1427
1413 if (delta > 0 && count == delta) 1428 if (delta > 0 && count == delta)
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index bf0fabb29..5f77f4e61 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -17,12 +17,14 @@
17#ifdef __GNUC__ 17#ifdef __GNUC__
18#pragma GCC diagnostic pop 18#pragma GCC diagnostic pop
19#endif 19#endif
20#include <boost/optional.hpp>
20#include <glad/glad.h> 21#include <glad/glad.h>
21#include "common/assert.h" 22#include "common/assert.h"
22#include "common/common_funcs.h" 23#include "common/common_funcs.h"
23#include "common/common_types.h" 24#include "common/common_types.h"
24#include "common/math_util.h" 25#include "common/math_util.h"
25#include "video_core/gpu.h" 26#include "video_core/gpu.h"
27#include "video_core/memory_manager.h"
26#include "video_core/renderer_opengl/gl_resource_manager.h" 28#include "video_core/renderer_opengl/gl_resource_manager.h"
27#include "video_core/textures/texture.h" 29#include "video_core/textures/texture.h"
28 30
@@ -30,9 +32,9 @@ struct CachedSurface;
30using Surface = std::shared_ptr<CachedSurface>; 32using Surface = std::shared_ptr<CachedSurface>;
31using SurfaceSet = std::set<Surface>; 33using SurfaceSet = std::set<Surface>;
32 34
33using SurfaceRegions = boost::icl::interval_set<VAddr>; 35using SurfaceRegions = boost::icl::interval_set<Tegra::GPUVAddr>;
34using SurfaceMap = boost::icl::interval_map<VAddr, Surface>; 36using SurfaceMap = boost::icl::interval_map<Tegra::GPUVAddr, Surface>;
35using SurfaceCache = boost::icl::interval_map<VAddr, SurfaceSet>; 37using SurfaceCache = boost::icl::interval_map<Tegra::GPUVAddr, SurfaceSet>;
36 38
37using SurfaceInterval = SurfaceCache::interval_type; 39using SurfaceInterval = SurfaceCache::interval_type;
38static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() && 40static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
@@ -277,6 +279,8 @@ struct SurfaceParams {
277 return pixels * GetFormatBpp(pixel_format) / CHAR_BIT; 279 return pixels * GetFormatBpp(pixel_format) / CHAR_BIT;
278 } 280 }
279 281
282 VAddr GetCpuAddr() const;
283
280 bool ExactMatch(const SurfaceParams& other_surface) const; 284 bool ExactMatch(const SurfaceParams& other_surface) const;
281 bool CanSubRect(const SurfaceParams& sub_surface) const; 285 bool CanSubRect(const SurfaceParams& sub_surface) const;
282 bool CanExpand(const SurfaceParams& expanded_surface) const; 286 bool CanExpand(const SurfaceParams& expanded_surface) const;
@@ -285,8 +289,9 @@ struct SurfaceParams {
285 MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const; 289 MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
286 MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const; 290 MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
287 291
288 VAddr addr = 0; 292 Tegra::GPUVAddr addr = 0;
289 VAddr end = 0; 293 Tegra::GPUVAddr end = 0;
294 boost::optional<VAddr> cpu_addr;
290 u64 size = 0; 295 u64 size = 0;
291 296
292 u32 width = 0; 297 u32 width = 0;
@@ -332,8 +337,8 @@ struct CachedSurface : SurfaceParams {
332 size_t gl_buffer_size = 0; 337 size_t gl_buffer_size = 0;
333 338
334 // Read/Write data in Switch memory to/from gl_buffer 339 // Read/Write data in Switch memory to/from gl_buffer
335 void LoadGLBuffer(VAddr load_start, VAddr load_end); 340 void LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end);
336 void FlushGLBuffer(VAddr flush_start, VAddr flush_end); 341 void FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end);
337 342
338 // Upload/Download data in gl_buffer in/to this surface's texture 343 // Upload/Download data in gl_buffer in/to this surface's texture
339 void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, 344 void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle,
@@ -381,10 +386,10 @@ public:
381 SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params); 386 SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params);
382 387
383 /// Write any cached resources overlapping the region back to memory (if dirty) 388 /// Write any cached resources overlapping the region back to memory (if dirty)
384 void FlushRegion(VAddr addr, u64 size, Surface flush_surface = nullptr); 389 void FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface = nullptr);
385 390
386 /// Mark region as being invalidated by region_owner (nullptr if Switch memory) 391 /// Mark region as being invalidated by region_owner (nullptr if Switch memory)
387 void InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner); 392 void InvalidateRegion(Tegra::GPUVAddr addr, u64 size, const Surface& region_owner);
388 393
389 /// Flush all cached resources tracked by this cache manager 394 /// Flush all cached resources tracked by this cache manager
390 void FlushAll(); 395 void FlushAll();
@@ -393,7 +398,7 @@ private:
393 void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); 398 void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);
394 399
395 /// Update surface's texture for given region when necessary 400 /// Update surface's texture for given region when necessary
396 void ValidateSurface(const Surface& surface, VAddr addr, u64 size); 401 void ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, u64 size);
397 402
398 /// Create a new surface 403 /// Create a new surface
399 Surface CreateSurface(const SurfaceParams& params); 404 Surface CreateSurface(const SurfaceParams& params);
@@ -405,7 +410,7 @@ private:
405 void UnregisterSurface(const Surface& surface); 410 void UnregisterSurface(const Surface& surface);
406 411
407 /// Increase/decrease the number of surface in pages touching the specified region 412 /// Increase/decrease the number of surface in pages touching the specified region
408 void UpdatePagesCachedCount(VAddr addr, u64 size, int delta); 413 void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta);
409 414
410 SurfaceCache surface_cache; 415 SurfaceCache surface_cache;
411 PageMap cached_pages; 416 PageMap cached_pages;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index baff2c7af..a266e21cf 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -152,7 +152,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
152 screen_info.display_texture = screen_info.texture.resource.handle; 152 screen_info.display_texture = screen_info.texture.resource.handle;
153 screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); 153 screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
154 154
155 Rasterizer()->FlushRegion(framebuffer_addr, size_in_bytes); 155 Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes,
156 Memory::FlushMode::Flush);
156 157
157 VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4, 158 VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4,
158 Memory::GetPointer(framebuffer_addr), 159 Memory::GetPointer(framebuffer_addr),
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index e0509f0ce..9c3ae875c 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -4,6 +4,7 @@
4 4
5#include <cstring> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/memory.h"
7#include "video_core/textures/decoders.h" 8#include "video_core/textures/decoders.h"
8#include "video_core/textures/texture.h" 9#include "video_core/textures/texture.h"
9 10