diff options
| author | 2018-03-24 00:47:33 -0400 | |
|---|---|---|
| committer | 2018-03-26 21:16:51 -0400 | |
| commit | 170ac3f9ee3c2f3fe0b22f11e4933373e7742fd6 (patch) | |
| tree | a08914110bebc8b7ad2f912f2ef06cc225c2da42 /src | |
| parent | maxwell: Add RenderTargetFormat enum. (diff) | |
| download | yuzu-170ac3f9ee3c2f3fe0b22f11e4933373e7742fd6.tar.gz yuzu-170ac3f9ee3c2f3fe0b22f11e4933373e7742fd6.tar.xz yuzu-170ac3f9ee3c2f3fe0b22f11e4933373e7742fd6.zip | |
gl_rasterizer_cache: Implement GetFramebufferSurfaces.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 97 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 11 |
2 files changed, 104 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 78fa7c051..81b4a64a7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -21,10 +21,13 @@ | |||
| 21 | #include "common/microprofile.h" | 21 | #include "common/microprofile.h" |
| 22 | #include "common/scope_exit.h" | 22 | #include "common/scope_exit.h" |
| 23 | #include "common/vector_math.h" | 23 | #include "common/vector_math.h" |
| 24 | #include "core/core.h" | ||
| 24 | #include "core/frontend/emu_window.h" | 25 | #include "core/frontend/emu_window.h" |
| 26 | #include "core/hle/kernel/process.h" | ||
| 25 | #include "core/hle/kernel/vm_manager.h" | 27 | #include "core/hle/kernel/vm_manager.h" |
| 26 | #include "core/memory.h" | 28 | #include "core/memory.h" |
| 27 | #include "core/settings.h" | 29 | #include "core/settings.h" |
| 30 | #include "video_core/engines/maxwell_3d.h" | ||
| 28 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 31 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 29 | #include "video_core/renderer_opengl/gl_state.h" | 32 | #include "video_core/renderer_opengl/gl_state.h" |
| 30 | #include "video_core/utils.h" | 33 | #include "video_core/utils.h" |
| @@ -1098,9 +1101,97 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const void* config) { | |||
| 1098 | } | 1101 | } |
| 1099 | 1102 | ||
| 1100 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | 1103 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( |
| 1101 | bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport_rect) { | 1104 | bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { |
| 1102 | UNIMPLEMENTED(); | 1105 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; |
| 1103 | return {}; | 1106 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; |
| 1107 | const auto& config = regs.rt[0]; | ||
| 1108 | |||
| 1109 | // TODO(bunnei): This is hard corded to use just the first render buffer | ||
| 1110 | LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); | ||
| 1111 | |||
| 1112 | // update resolution_scale_factor and reset cache if changed | ||
| 1113 | // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We | ||
| 1114 | // need to fix this before making the renderer multi-threaded. | ||
| 1115 | static u16 resolution_scale_factor = GetResolutionScaleFactor(); | ||
| 1116 | if (resolution_scale_factor != GetResolutionScaleFactor()) { | ||
| 1117 | resolution_scale_factor = GetResolutionScaleFactor(); | ||
| 1118 | FlushAll(); | ||
| 1119 | while (!surface_cache.empty()) | ||
| 1120 | UnregisterSurface(*surface_cache.begin()->second.begin()); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | MathUtil::Rectangle<u32> viewport_clamped{ | ||
| 1124 | static_cast<u32>(MathUtil::Clamp(viewport.left, 0, static_cast<s32>(config.width))), | ||
| 1125 | static_cast<u32>(MathUtil::Clamp(viewport.top, 0, static_cast<s32>(config.height))), | ||
| 1126 | static_cast<u32>(MathUtil::Clamp(viewport.right, 0, static_cast<s32>(config.width))), | ||
| 1127 | static_cast<u32>(MathUtil::Clamp(viewport.bottom, 0, static_cast<s32>(config.height)))}; | ||
| 1128 | |||
| 1129 | // get color and depth surfaces | ||
| 1130 | SurfaceParams color_params; | ||
| 1131 | color_params.is_tiled = true; | ||
| 1132 | color_params.res_scale = resolution_scale_factor; | ||
| 1133 | color_params.width = config.width; | ||
| 1134 | color_params.height = config.height; | ||
| 1135 | SurfaceParams depth_params = color_params; | ||
| 1136 | |||
| 1137 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); | ||
| 1138 | color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); | ||
| 1139 | color_params.UpdateParams(); | ||
| 1140 | |||
| 1141 | ASSERT(!using_depth_fb, "depth buffer is unimplemented"); | ||
| 1142 | // depth_params.addr = config.GetDepthBufferPhysicalAddress(); | ||
| 1143 | // depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(config.depth_format); | ||
| 1144 | // depth_params.UpdateParams(); | ||
| 1145 | |||
| 1146 | auto color_vp_interval = color_params.GetSubRectInterval(viewport_clamped); | ||
| 1147 | auto depth_vp_interval = depth_params.GetSubRectInterval(viewport_clamped); | ||
| 1148 | |||
| 1149 | // Make sure that framebuffers don't overlap if both color and depth are being used | ||
| 1150 | if (using_color_fb && using_depth_fb && | ||
| 1151 | boost::icl::length(color_vp_interval & depth_vp_interval)) { | ||
| 1152 | LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " | ||
| 1153 | "overlapping framebuffers not supported!"); | ||
| 1154 | using_depth_fb = false; | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | MathUtil::Rectangle<u32> color_rect{}; | ||
| 1158 | Surface color_surface = nullptr; | ||
| 1159 | if (using_color_fb) | ||
| 1160 | std::tie(color_surface, color_rect) = | ||
| 1161 | GetSurfaceSubRect(color_params, ScaleMatch::Exact, false); | ||
| 1162 | |||
| 1163 | MathUtil::Rectangle<u32> depth_rect{}; | ||
| 1164 | Surface depth_surface = nullptr; | ||
| 1165 | if (using_depth_fb) | ||
| 1166 | std::tie(depth_surface, depth_rect) = | ||
| 1167 | GetSurfaceSubRect(depth_params, ScaleMatch::Exact, false); | ||
| 1168 | |||
| 1169 | MathUtil::Rectangle<u32> fb_rect{}; | ||
| 1170 | if (color_surface != nullptr && depth_surface != nullptr) { | ||
| 1171 | fb_rect = color_rect; | ||
| 1172 | // Color and Depth surfaces must have the same dimensions and offsets | ||
| 1173 | if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top || | ||
| 1174 | color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) { | ||
| 1175 | color_surface = GetSurface(color_params, ScaleMatch::Exact, false); | ||
| 1176 | depth_surface = GetSurface(depth_params, ScaleMatch::Exact, false); | ||
| 1177 | fb_rect = color_surface->GetScaledRect(); | ||
| 1178 | } | ||
| 1179 | } else if (color_surface != nullptr) { | ||
| 1180 | fb_rect = color_rect; | ||
| 1181 | } else if (depth_surface != nullptr) { | ||
| 1182 | fb_rect = depth_rect; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | if (color_surface != nullptr) { | ||
| 1186 | ValidateSurface(color_surface, boost::icl::first(color_vp_interval), | ||
| 1187 | boost::icl::length(color_vp_interval)); | ||
| 1188 | } | ||
| 1189 | if (depth_surface != nullptr) { | ||
| 1190 | ValidateSurface(depth_surface, boost::icl::first(depth_vp_interval), | ||
| 1191 | boost::icl::length(depth_vp_interval)); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | return std::make_tuple(color_surface, depth_surface, fb_rect); | ||
| 1104 | } | 1195 | } |
| 1105 | 1196 | ||
| 1106 | Surface RasterizerCacheOpenGL::GetFillSurface(const void* config) { | 1197 | Surface RasterizerCacheOpenGL::GetFillSurface(const void* config) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 14f3cdc38..0e1c481d7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -116,6 +116,15 @@ struct SurfaceParams { | |||
| 116 | return GetFormatBpp(pixel_format); | 116 | return GetFormatBpp(pixel_format); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { | ||
| 120 | switch (format) { | ||
| 121 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | ||
| 122 | return PixelFormat::RGBA8; | ||
| 123 | default: | ||
| 124 | UNREACHABLE(); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 119 | static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { | 128 | static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { |
| 120 | switch (format) { | 129 | switch (format) { |
| 121 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | 130 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: |
| @@ -308,7 +317,7 @@ public: | |||
| 308 | 317 | ||
| 309 | /// Get the color and depth surfaces based on the framebuffer configuration | 318 | /// Get the color and depth surfaces based on the framebuffer configuration |
| 310 | SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, | 319 | SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, |
| 311 | const MathUtil::Rectangle<s32>& viewport_rect); | 320 | const MathUtil::Rectangle<s32>& viewport); |
| 312 | 321 | ||
| 313 | /// Get a surface that matches the fill config | 322 | /// Get a surface that matches the fill config |
| 314 | Surface GetFillSurface(const void* config); | 323 | Surface GetFillSurface(const void* config); |