diff options
| author | 2018-06-24 17:42:29 -0400 | |
|---|---|---|
| committer | 2018-06-27 00:08:03 -0400 | |
| commit | 3f9f047375dd9aae7eadcb957747fa8db01544bf (patch) | |
| tree | 4a5ce82d2726e5f723a3a7a0e72d973f6d6d0573 /src | |
| parent | gl_rasterizer_cache: Cache size_in_bytes as a const per surface. (diff) | |
| download | yuzu-3f9f047375dd9aae7eadcb957747fa8db01544bf.tar.gz yuzu-3f9f047375dd9aae7eadcb957747fa8db01544bf.tar.xz yuzu-3f9f047375dd9aae7eadcb957747fa8db01544bf.zip | |
gl_rasterizer: Implement AccelerateDisplay to forward textures to framebuffers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 2 |
6 files changed, 62 insertions, 8 deletions
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index f0e48a802..145e58334 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -51,9 +51,8 @@ public: | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | /// Attempt to use a faster method to display the framebuffer to screen | 53 | /// Attempt to use a faster method to display the framebuffer to screen |
| 54 | virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer, | 54 | virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |
| 55 | VAddr framebuffer_addr, u32 pixel_stride, | 55 | u32 pixel_stride, ScreenInfo& screen_info) { |
| 56 | ScreenInfo& screen_info) { | ||
| 57 | return false; | 56 | return false; |
| 58 | } | 57 | } |
| 59 | 58 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bc463fc30..f9b0ce434 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -468,11 +468,30 @@ bool RasterizerOpenGL::AccelerateFill(const void* config) { | |||
| 468 | return true; | 468 | return true; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer, | 471 | bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, |
| 472 | VAddr framebuffer_addr, u32 pixel_stride, | 472 | VAddr framebuffer_addr, u32 pixel_stride, |
| 473 | ScreenInfo& screen_info) { | 473 | ScreenInfo& screen_info) { |
| 474 | // TODO(bunnei): ImplementMe | 474 | if (!framebuffer_addr) { |
| 475 | return false; | 475 | return {}; |
| 476 | } | ||
| 477 | |||
| 478 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||
| 479 | |||
| 480 | const auto& surface{res_cache.TryFindFramebufferSurface(framebuffer_addr)}; | ||
| 481 | if (!surface) { | ||
| 482 | return {}; | ||
| 483 | } | ||
| 484 | |||
| 485 | // Verify that the cached surface is the same size and format as the requested framebuffer | ||
| 486 | const auto& params{surface->GetSurfaceParams()}; | ||
| 487 | const auto& pixel_format{SurfaceParams::PixelFormatFromGPUPixelFormat(config.pixel_format)}; | ||
| 488 | ASSERT_MSG(params.width == config.width, "Framebuffer width is different"); | ||
| 489 | ASSERT_MSG(params.height == config.height, "Framebuffer height is different"); | ||
| 490 | ASSERT_MSG(params.pixel_format == pixel_format, "Framebuffer pixel_format is different"); | ||
| 491 | |||
| 492 | screen_info.display_texture = surface->Texture().handle; | ||
| 493 | |||
| 494 | return true; | ||
| 476 | } | 495 | } |
| 477 | 496 | ||
| 478 | void RasterizerOpenGL::SamplerInfo::Create() { | 497 | void RasterizerOpenGL::SamplerInfo::Create() { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 882490f47..919931d64 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -436,3 +436,29 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) { | |||
| 436 | 436 | ||
| 437 | return surface; | 437 | return surface; |
| 438 | } | 438 | } |
| 439 | |||
| 440 | Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr cpu_addr) const { | ||
| 441 | // Tries to find the GPU address of a framebuffer based on the CPU address. This is because | ||
| 442 | // final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU | ||
| 443 | // addresses. We iterate through all cached framebuffers, and compare their starting CPU address | ||
| 444 | // to the one provided. This is obviously not great, and won't work if the framebuffer overlaps | ||
| 445 | // surfaces. | ||
| 446 | |||
| 447 | std::vector<Surface> surfaces; | ||
| 448 | for (const auto& surface : surface_cache) { | ||
| 449 | const auto& params = surface.second->GetSurfaceParams(); | ||
| 450 | const VAddr surface_cpu_addr = params.GetCpuAddr(); | ||
| 451 | if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + params.size_in_bytes)) { | ||
| 452 | ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported"); | ||
| 453 | surfaces.push_back(surface.second); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | if (surfaces.empty()) { | ||
| 458 | return {}; | ||
| 459 | } | ||
| 460 | |||
| 461 | ASSERT_MSG(surfaces.size() == 1, ">1 surface is unsupported"); | ||
| 462 | |||
| 463 | return surfaces[0]; | ||
| 464 | } | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 9f1209b0f..53ff2722d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -220,6 +220,16 @@ struct SurfaceParams { | |||
| 220 | } | 220 | } |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { | ||
| 224 | switch (format) { | ||
| 225 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | ||
| 226 | return PixelFormat::ABGR8; | ||
| 227 | default: | ||
| 228 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 229 | UNREACHABLE(); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 223 | static SurfaceType GetFormatType(PixelFormat pixel_format) { | 233 | static SurfaceType GetFormatType(PixelFormat pixel_format) { |
| 224 | if (static_cast<size_t>(pixel_format) < MaxPixelFormat) { | 234 | if (static_cast<size_t>(pixel_format) < MaxPixelFormat) { |
| 225 | return SurfaceType::ColorTexture; | 235 | return SurfaceType::ColorTexture; |
| @@ -302,6 +312,7 @@ public: | |||
| 302 | const MathUtil::Rectangle<s32>& viewport); | 312 | const MathUtil::Rectangle<s32>& viewport); |
| 303 | void LoadSurface(const Surface& surface); | 313 | void LoadSurface(const Surface& surface); |
| 304 | void FlushSurface(const Surface& surface); | 314 | void FlushSurface(const Surface& surface); |
| 315 | Surface TryFindFramebufferSurface(VAddr cpu_addr) const; | ||
| 305 | 316 | ||
| 306 | private: | 317 | private: |
| 307 | Surface GetSurface(const SurfaceParams& params); | 318 | Surface GetSurface(const SurfaceParams& params); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index f33766bfd..e3bb2cbb8 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -150,7 +150,6 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 150 | screen_info)) { | 150 | screen_info)) { |
| 151 | // Reset the screen info's display texture to its own permanent texture | 151 | // Reset the screen info's display texture to its own permanent texture |
| 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); | ||
| 154 | 153 | ||
| 155 | Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, | 154 | Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, |
| 156 | Memory::FlushMode::Flush); | 155 | Memory::FlushMode::Flush); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 2cc6d9a00..21f0d298c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -27,7 +27,7 @@ struct TextureInfo { | |||
| 27 | /// Structure used for storing information about the display target for the Switch screen | 27 | /// Structure used for storing information about the display target for the Switch screen |
| 28 | struct ScreenInfo { | 28 | struct ScreenInfo { |
| 29 | GLuint display_texture; | 29 | GLuint display_texture; |
| 30 | MathUtil::Rectangle<float> display_texcoords; | 30 | const MathUtil::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f}; |
| 31 | TextureInfo texture; | 31 | TextureInfo texture; |
| 32 | }; | 32 | }; |
| 33 | 33 | ||