summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-03-24 00:47:33 -0400
committerGravatar bunnei2018-03-26 21:16:51 -0400
commit170ac3f9ee3c2f3fe0b22f11e4933373e7742fd6 (patch)
treea08914110bebc8b7ad2f912f2ef06cc225c2da42 /src
parentmaxwell: Add RenderTargetFormat enum. (diff)
downloadyuzu-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.cpp97
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h11
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
1100SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( 1103SurfaceSurfaceRect_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
1106Surface RasterizerCacheOpenGL::GetFillSurface(const void* config) { 1197Surface 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);