1 // Copyright 2010 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "VideoCommon/FramebufferManager.h"
6 
7 #include <memory>
8 
9 #include "Common/ChunkFile.h"
10 #include "Common/Logging/Log.h"
11 #include "Common/MsgHandler.h"
12 #include "Core/Config/GraphicsSettings.h"
13 #include "VideoCommon/AbstractFramebuffer.h"
14 #include "VideoCommon/AbstractPipeline.h"
15 #include "VideoCommon/AbstractShader.h"
16 #include "VideoCommon/AbstractStagingTexture.h"
17 #include "VideoCommon/AbstractTexture.h"
18 #include "VideoCommon/DriverDetails.h"
19 #include "VideoCommon/FramebufferShaderGen.h"
20 #include "VideoCommon/RenderBase.h"
21 #include "VideoCommon/VertexManagerBase.h"
22 #include "VideoCommon/VideoCommon.h"
23 #include "VideoCommon/VideoConfig.h"
24 
25 // Maximum number of pixels poked in one batch * 6
26 constexpr size_t MAX_POKE_VERTICES = 32768;
27 
28 std::unique_ptr<FramebufferManager> g_framebuffer_manager;
29 
30 FramebufferManager::FramebufferManager() = default;
31 
~FramebufferManager()32 FramebufferManager::~FramebufferManager()
33 {
34   DestroyClearPipelines();
35   DestroyPokePipelines();
36   DestroyConversionPipelines();
37   DestroyReadbackPipelines();
38   DestroyReadbackFramebuffer();
39   DestroyEFBFramebuffer();
40 }
41 
Initialize()42 bool FramebufferManager::Initialize()
43 {
44   if (!CreateEFBFramebuffer())
45   {
46     PanicAlert("Failed to create EFB framebuffer");
47     return false;
48   }
49 
50   m_efb_cache_tile_size = static_cast<u32>(std::max(g_ActiveConfig.iEFBAccessTileSize, 0));
51   if (!CreateReadbackFramebuffer())
52   {
53     PanicAlert("Failed to create EFB readback framebuffer");
54     return false;
55   }
56 
57   if (!CompileReadbackPipelines())
58   {
59     PanicAlert("Failed to compile EFB readback pipelines");
60     return false;
61   }
62 
63   if (!CompileConversionPipelines())
64   {
65     PanicAlert("Failed to compile EFB conversion pipelines");
66     return false;
67   }
68 
69   if (!CompileClearPipelines())
70   {
71     PanicAlert("Failed to compile EFB clear pipelines");
72     return false;
73   }
74 
75   if (!CompilePokePipelines())
76   {
77     PanicAlert("Failed to compile EFB poke pipelines");
78     return false;
79   }
80 
81   return true;
82 }
83 
RecreateEFBFramebuffer()84 void FramebufferManager::RecreateEFBFramebuffer()
85 {
86   FlushEFBPokes();
87   InvalidatePeekCache(true);
88 
89   DestroyReadbackFramebuffer();
90   DestroyEFBFramebuffer();
91   if (!CreateEFBFramebuffer() || !CreateReadbackFramebuffer())
92     PanicAlert("Failed to recreate EFB framebuffer");
93 }
94 
RecompileShaders()95 void FramebufferManager::RecompileShaders()
96 {
97   DestroyPokePipelines();
98   DestroyClearPipelines();
99   DestroyConversionPipelines();
100   DestroyReadbackPipelines();
101   if (!CompileReadbackPipelines() || !CompileConversionPipelines() || !CompileClearPipelines() ||
102       !CompilePokePipelines())
103   {
104     PanicAlert("Failed to recompile EFB pipelines");
105   }
106 }
107 
GetEFBColorFormat()108 AbstractTextureFormat FramebufferManager::GetEFBColorFormat()
109 {
110   // The EFB can be set to different pixel formats by the game through the
111   // BPMEM_ZCOMPARE register (which should probably have a different name).
112   // They are:
113   // - 24-bit RGB (8-bit components) with 24-bit Z
114   // - 24-bit RGBA (6-bit components) with 24-bit Z
115   // - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
116   // We only use one EFB format here: 32-bit ARGB with 32-bit Z.
117   // Multisampling depends on user settings.
118   // The distinction becomes important for certain operations, i.e. the
119   // alpha channel should be ignored if the EFB does not have one.
120   return AbstractTextureFormat::RGBA8;
121 }
122 
GetEFBDepthFormat()123 AbstractTextureFormat FramebufferManager::GetEFBDepthFormat()
124 {
125   // 32-bit depth clears are broken in the Adreno Vulkan driver, and have no effect.
126   // To work around this, we use a D24_S8 buffer instead, which results in a loss of accuracy.
127   // We still resolve this to a R32F texture, as there is no 24-bit format.
128   if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_D32F_CLEAR))
129     return AbstractTextureFormat::D24_S8;
130   else
131     return AbstractTextureFormat::D32F;
132 }
133 
GetEFBDepthCopyFormat()134 AbstractTextureFormat FramebufferManager::GetEFBDepthCopyFormat()
135 {
136   return AbstractTextureFormat::R32F;
137 }
138 
CalculateEFBLayers()139 static u32 CalculateEFBLayers()
140 {
141   return (g_ActiveConfig.stereo_mode != StereoMode::Off) ? 2 : 1;
142 }
143 
GetEFBColorTextureConfig()144 TextureConfig FramebufferManager::GetEFBColorTextureConfig()
145 {
146   return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1,
147                        CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBColorFormat(),
148                        AbstractTextureFlag_RenderTarget);
149 }
150 
GetEFBDepthTextureConfig()151 TextureConfig FramebufferManager::GetEFBDepthTextureConfig()
152 {
153   return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1,
154                        CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBDepthFormat(),
155                        AbstractTextureFlag_RenderTarget);
156 }
157 
GetEFBFramebufferState() const158 FramebufferState FramebufferManager::GetEFBFramebufferState() const
159 {
160   FramebufferState ret = {};
161   ret.color_texture_format = m_efb_color_texture->GetFormat();
162   ret.depth_texture_format = m_efb_depth_texture->GetFormat();
163   ret.per_sample_shading = IsEFBMultisampled() && g_ActiveConfig.bSSAA;
164   ret.samples = m_efb_color_texture->GetSamples();
165   return ret;
166 }
167 
CreateEFBFramebuffer()168 bool FramebufferManager::CreateEFBFramebuffer()
169 {
170   const TextureConfig efb_color_texture_config = GetEFBColorTextureConfig();
171   const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig();
172 
173   // We need a second texture to swap with for changing pixel formats
174   m_efb_color_texture = g_renderer->CreateTexture(efb_color_texture_config);
175   m_efb_depth_texture = g_renderer->CreateTexture(efb_depth_texture_config);
176   m_efb_convert_color_texture = g_renderer->CreateTexture(efb_color_texture_config);
177   if (!m_efb_color_texture || !m_efb_depth_texture || !m_efb_convert_color_texture)
178     return false;
179 
180   m_efb_framebuffer =
181       g_renderer->CreateFramebuffer(m_efb_color_texture.get(), m_efb_depth_texture.get());
182   m_efb_convert_framebuffer =
183       g_renderer->CreateFramebuffer(m_efb_convert_color_texture.get(), m_efb_depth_texture.get());
184   if (!m_efb_framebuffer || !m_efb_convert_framebuffer)
185     return false;
186 
187   // Create resolved textures if MSAA is on
188   if (g_ActiveConfig.MultisamplingEnabled())
189   {
190     m_efb_resolve_color_texture = g_renderer->CreateTexture(
191         TextureConfig(efb_color_texture_config.width, efb_color_texture_config.height, 1,
192                       efb_color_texture_config.layers, 1, efb_color_texture_config.format, 0));
193     if (!m_efb_resolve_color_texture)
194       return false;
195   }
196 
197   // We also need one to convert the D24S8 to R32F if that is being used (Adreno).
198   if (g_ActiveConfig.MultisamplingEnabled() || GetEFBDepthFormat() != AbstractTextureFormat::R32F)
199   {
200     m_efb_depth_resolve_texture = g_renderer->CreateTexture(
201         TextureConfig(efb_depth_texture_config.width, efb_depth_texture_config.height, 1,
202                       efb_depth_texture_config.layers, 1, GetEFBDepthCopyFormat(),
203                       AbstractTextureFlag_RenderTarget));
204     if (!m_efb_depth_resolve_texture)
205       return false;
206 
207     m_efb_depth_resolve_framebuffer =
208         g_renderer->CreateFramebuffer(m_efb_depth_resolve_texture.get(), nullptr);
209     if (!m_efb_depth_resolve_framebuffer)
210       return false;
211   }
212 
213   // Clear the renderable textures out.
214   g_renderer->SetAndClearFramebuffer(
215       m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
216       g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
217   return true;
218 }
219 
DestroyEFBFramebuffer()220 void FramebufferManager::DestroyEFBFramebuffer()
221 {
222   m_efb_framebuffer.reset();
223   m_efb_convert_framebuffer.reset();
224   m_efb_color_texture.reset();
225   m_efb_convert_color_texture.reset();
226   m_efb_depth_texture.reset();
227   m_efb_resolve_color_texture.reset();
228   m_efb_depth_resolve_framebuffer.reset();
229   m_efb_depth_resolve_texture.reset();
230 }
231 
BindEFBFramebuffer()232 void FramebufferManager::BindEFBFramebuffer()
233 {
234   g_renderer->SetFramebuffer(m_efb_framebuffer.get());
235 }
236 
ResolveEFBColorTexture(const MathUtil::Rectangle<int> & region)237 AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rectangle<int>& region)
238 {
239   // Return the normal EFB texture if multisampling is off.
240   if (!IsEFBMultisampled())
241     return m_efb_color_texture.get();
242 
243   // It's not valid to resolve an out-of-range rectangle.
244   MathUtil::Rectangle<int> clamped_region = region;
245   clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight());
246 
247   // Resolve to our already-created texture.
248   for (u32 layer = 0; layer < GetEFBLayers(); layer++)
249   {
250     m_efb_resolve_color_texture->ResolveFromTexture(m_efb_color_texture.get(), clamped_region,
251                                                     layer, 0);
252   }
253 
254   m_efb_resolve_color_texture->FinishedRendering();
255   return m_efb_resolve_color_texture.get();
256 }
257 
ResolveEFBDepthTexture(const MathUtil::Rectangle<int> & region,bool force_r32f)258 AbstractTexture* FramebufferManager::ResolveEFBDepthTexture(const MathUtil::Rectangle<int>& region,
259                                                             bool force_r32f)
260 {
261   if (!IsEFBMultisampled() &&
262       (!force_r32f || m_efb_depth_texture->GetFormat() == AbstractTextureFormat::D32F))
263   {
264     return m_efb_depth_texture.get();
265   }
266 
267   // It's not valid to resolve an out-of-range rectangle.
268   MathUtil::Rectangle<int> clamped_region = region;
269   clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight());
270 
271   m_efb_depth_texture->FinishedRendering();
272   g_renderer->BeginUtilityDrawing();
273   g_renderer->SetAndDiscardFramebuffer(m_efb_depth_resolve_framebuffer.get());
274   g_renderer->SetPipeline(IsEFBMultisampled() ? m_efb_depth_resolve_pipeline.get() :
275                                                 m_efb_depth_cache.copy_pipeline.get());
276   g_renderer->SetTexture(0, m_efb_depth_texture.get());
277   g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState());
278   g_renderer->SetViewportAndScissor(clamped_region);
279   g_renderer->Draw(0, 3);
280   m_efb_depth_resolve_texture->FinishedRendering();
281   g_renderer->EndUtilityDrawing();
282 
283   return m_efb_depth_resolve_texture.get();
284 }
285 
ReinterpretPixelData(EFBReinterpretType convtype)286 bool FramebufferManager::ReinterpretPixelData(EFBReinterpretType convtype)
287 {
288   if (!m_format_conversion_pipelines[static_cast<u32>(convtype)])
289     return false;
290 
291   // Draw to the secondary framebuffer.
292   // We don't discard here because discarding the framebuffer also throws away the depth
293   // buffer, which we want to preserve. If we find this to be hindering performance in the
294   // future (e.g. on mobile/tilers), it may be worth discarding only the color buffer.
295   m_efb_color_texture->FinishedRendering();
296   g_renderer->BeginUtilityDrawing();
297   g_renderer->SetFramebuffer(m_efb_convert_framebuffer.get());
298   g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect());
299   g_renderer->SetPipeline(m_format_conversion_pipelines[static_cast<u32>(convtype)].get());
300   g_renderer->SetTexture(0, m_efb_color_texture.get());
301   g_renderer->Draw(0, 3);
302 
303   // And swap the framebuffers around, so we do new drawing to the converted framebuffer.
304   std::swap(m_efb_color_texture, m_efb_convert_color_texture);
305   std::swap(m_efb_framebuffer, m_efb_convert_framebuffer);
306   g_renderer->EndUtilityDrawing();
307   InvalidatePeekCache(true);
308   return true;
309 }
310 
CompileConversionPipelines()311 bool FramebufferManager::CompileConversionPipelines()
312 {
313   for (u32 i = 0; i < NUM_EFB_REINTERPRET_TYPES; i++)
314   {
315     std::unique_ptr<AbstractShader> pixel_shader = g_renderer->CreateShaderFromSource(
316         ShaderStage::Pixel, FramebufferShaderGen::GenerateFormatConversionShader(
317                                 static_cast<EFBReinterpretType>(i), GetEFBSamples()));
318     if (!pixel_shader)
319       return false;
320 
321     AbstractPipelineConfig config = {};
322     config.vertex_shader = g_shader_cache->GetScreenQuadVertexShader();
323     config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetTexcoordGeometryShader() : nullptr;
324     config.pixel_shader = pixel_shader.get();
325     config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles);
326     config.depth_state = RenderState::GetNoDepthTestingDepthState();
327     config.blending_state = RenderState::GetNoBlendingBlendState();
328     config.framebuffer_state = GetEFBFramebufferState();
329     config.usage = AbstractPipelineUsage::Utility;
330     m_format_conversion_pipelines[i] = g_renderer->CreatePipeline(config);
331     if (!m_format_conversion_pipelines[i])
332       return false;
333   }
334 
335   return true;
336 }
337 
DestroyConversionPipelines()338 void FramebufferManager::DestroyConversionPipelines()
339 {
340   for (auto& pipeline : m_format_conversion_pipelines)
341     pipeline.reset();
342 }
343 
IsUsingTiledEFBCache() const344 bool FramebufferManager::IsUsingTiledEFBCache() const
345 {
346   return m_efb_cache_tile_size > 0;
347 }
348 
IsEFBCacheTilePresent(bool depth,u32 x,u32 y,u32 * tile_index) const349 bool FramebufferManager::IsEFBCacheTilePresent(bool depth, u32 x, u32 y, u32* tile_index) const
350 {
351   const EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache;
352   if (m_efb_cache_tile_size == 0)
353   {
354     *tile_index = 0;
355     return data.valid;
356   }
357   else
358   {
359     *tile_index =
360         ((y / m_efb_cache_tile_size) * m_efb_cache_tiles_wide) + (x / m_efb_cache_tile_size);
361     return data.valid && data.tiles[*tile_index];
362   }
363 }
364 
GetEFBCacheTileRect(u32 tile_index) const365 MathUtil::Rectangle<int> FramebufferManager::GetEFBCacheTileRect(u32 tile_index) const
366 {
367   if (m_efb_cache_tile_size == 0)
368     return MathUtil::Rectangle<int>(0, 0, EFB_WIDTH, EFB_HEIGHT);
369 
370   const u32 tile_y = tile_index / m_efb_cache_tiles_wide;
371   const u32 tile_x = tile_index % m_efb_cache_tiles_wide;
372   const u32 start_y = tile_y * m_efb_cache_tile_size;
373   const u32 start_x = tile_x * m_efb_cache_tile_size;
374   return MathUtil::Rectangle<int>(
375       start_x, start_y, std::min(start_x + m_efb_cache_tile_size, static_cast<u32>(EFB_WIDTH)),
376       std::min(start_y + m_efb_cache_tile_size, static_cast<u32>(EFB_HEIGHT)));
377 }
378 
PeekEFBColor(u32 x,u32 y)379 u32 FramebufferManager::PeekEFBColor(u32 x, u32 y)
380 {
381   // The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
382   if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
383     y = EFB_HEIGHT - 1 - y;
384 
385   u32 tile_index;
386   if (!IsEFBCacheTilePresent(false, x, y, &tile_index))
387     PopulateEFBCache(false, tile_index);
388 
389   u32 value;
390   m_efb_color_cache.readback_texture->ReadTexel(x, y, &value);
391   return value;
392 }
393 
PeekEFBDepth(u32 x,u32 y)394 float FramebufferManager::PeekEFBDepth(u32 x, u32 y)
395 {
396   // The y coordinate here assumes upper-left origin, but the readback texture is lower-left in GL.
397   if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
398     y = EFB_HEIGHT - 1 - y;
399 
400   u32 tile_index;
401   if (!IsEFBCacheTilePresent(true, x, y, &tile_index))
402     PopulateEFBCache(true, tile_index);
403 
404   float value;
405   m_efb_depth_cache.readback_texture->ReadTexel(x, y, &value);
406   return value;
407 }
408 
SetEFBCacheTileSize(u32 size)409 void FramebufferManager::SetEFBCacheTileSize(u32 size)
410 {
411   if (m_efb_cache_tile_size == size)
412     return;
413 
414   InvalidatePeekCache(true);
415   m_efb_cache_tile_size = size;
416   DestroyReadbackFramebuffer();
417   if (!CreateReadbackFramebuffer())
418     PanicAlert("Failed to create EFB readback framebuffers");
419 }
420 
InvalidatePeekCache(bool forced)421 void FramebufferManager::InvalidatePeekCache(bool forced)
422 {
423   if (forced || m_efb_color_cache.out_of_date)
424   {
425     if (m_efb_color_cache.valid)
426       std::fill(m_efb_color_cache.tiles.begin(), m_efb_color_cache.tiles.end(), false);
427 
428     m_efb_color_cache.valid = false;
429     m_efb_color_cache.out_of_date = false;
430   }
431   if (forced || m_efb_depth_cache.out_of_date)
432   {
433     if (m_efb_depth_cache.valid)
434       std::fill(m_efb_depth_cache.tiles.begin(), m_efb_depth_cache.tiles.end(), false);
435 
436     m_efb_depth_cache.valid = false;
437     m_efb_depth_cache.out_of_date = false;
438   }
439 }
440 
FlagPeekCacheAsOutOfDate()441 void FramebufferManager::FlagPeekCacheAsOutOfDate()
442 {
443   if (m_efb_color_cache.valid)
444     m_efb_color_cache.out_of_date = true;
445   if (m_efb_depth_cache.valid)
446     m_efb_depth_cache.out_of_date = true;
447 
448   if (!g_ActiveConfig.bEFBAccessDeferInvalidation)
449     InvalidatePeekCache();
450 }
451 
CompileReadbackPipelines()452 bool FramebufferManager::CompileReadbackPipelines()
453 {
454   AbstractPipelineConfig config = {};
455   config.vertex_shader = g_shader_cache->GetTextureCopyVertexShader();
456   config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetTexcoordGeometryShader() : nullptr;
457   config.pixel_shader = g_shader_cache->GetTextureCopyPixelShader();
458   config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles);
459   config.depth_state = RenderState::GetNoDepthTestingDepthState();
460   config.blending_state = RenderState::GetNoBlendingBlendState();
461   config.framebuffer_state = RenderState::GetColorFramebufferState(GetEFBColorFormat());
462   config.usage = AbstractPipelineUsage::Utility;
463   m_efb_color_cache.copy_pipeline = g_renderer->CreatePipeline(config);
464   if (!m_efb_color_cache.copy_pipeline)
465     return false;
466 
467   // same for depth, except different format
468   config.framebuffer_state.color_texture_format = GetEFBDepthCopyFormat();
469   m_efb_depth_cache.copy_pipeline = g_renderer->CreatePipeline(config);
470   if (!m_efb_depth_cache.copy_pipeline)
471     return false;
472 
473   if (IsEFBMultisampled())
474   {
475     auto depth_resolve_shader = g_renderer->CreateShaderFromSource(
476         ShaderStage::Pixel, FramebufferShaderGen::GenerateResolveDepthPixelShader(GetEFBSamples()));
477     if (!depth_resolve_shader)
478       return false;
479 
480     config.pixel_shader = depth_resolve_shader.get();
481     m_efb_depth_resolve_pipeline = g_renderer->CreatePipeline(config);
482     if (!m_efb_depth_resolve_pipeline)
483       return false;
484   }
485 
486   // EFB restore pipeline
487   auto restore_shader = g_renderer->CreateShaderFromSource(
488       ShaderStage::Pixel, FramebufferShaderGen::GenerateEFBRestorePixelShader());
489   if (!restore_shader)
490     return false;
491 
492   config.depth_state = RenderState::GetAlwaysWriteDepthState();
493   config.framebuffer_state = GetEFBFramebufferState();
494   config.framebuffer_state.per_sample_shading = false;
495   config.vertex_shader = g_shader_cache->GetScreenQuadVertexShader();
496   config.pixel_shader = restore_shader.get();
497   m_efb_restore_pipeline = g_renderer->CreatePipeline(config);
498   if (!m_efb_restore_pipeline)
499     return false;
500 
501   return true;
502 }
503 
DestroyReadbackPipelines()504 void FramebufferManager::DestroyReadbackPipelines()
505 {
506   m_efb_depth_resolve_pipeline.reset();
507   m_efb_depth_cache.copy_pipeline.reset();
508   m_efb_color_cache.copy_pipeline.reset();
509 }
510 
CreateReadbackFramebuffer()511 bool FramebufferManager::CreateReadbackFramebuffer()
512 {
513   if (g_renderer->GetEFBScale() != 1)
514   {
515     const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH,
516                                      IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
517                                      1, 1, GetEFBColorFormat(), AbstractTextureFlag_RenderTarget);
518     m_efb_color_cache.texture = g_renderer->CreateTexture(color_config);
519     if (!m_efb_color_cache.texture)
520       return false;
521 
522     m_efb_color_cache.framebuffer =
523         g_renderer->CreateFramebuffer(m_efb_color_cache.texture.get(), nullptr);
524     if (!m_efb_color_cache.framebuffer)
525       return false;
526   }
527 
528   // Since we can't partially copy from a depth buffer directly to the staging texture in D3D, we
529   // use an intermediate buffer to avoid copying the whole texture.
530   if (!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
531       (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) ||
532       !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
533                                                          GetEFBDepthCopyFormat()) ||
534       g_renderer->GetEFBScale() != 1)
535   {
536     const TextureConfig depth_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH,
537                                      IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
538                                      1, 1, GetEFBDepthCopyFormat(),
539                                      AbstractTextureFlag_RenderTarget);
540     m_efb_depth_cache.texture = g_renderer->CreateTexture(depth_config);
541     if (!m_efb_depth_cache.texture)
542       return false;
543 
544     m_efb_depth_cache.framebuffer =
545         g_renderer->CreateFramebuffer(m_efb_depth_cache.texture.get(), nullptr);
546     if (!m_efb_depth_cache.framebuffer)
547       return false;
548   }
549 
550   // Staging texture use the full EFB dimensions, as this is the buffer for the whole cache.
551   m_efb_color_cache.readback_texture = g_renderer->CreateStagingTexture(
552       StagingTextureType::Mutable,
553       TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBColorFormat(), 0));
554   m_efb_depth_cache.readback_texture = g_renderer->CreateStagingTexture(
555       StagingTextureType::Mutable,
556       TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBDepthCopyFormat(), 0));
557   if (!m_efb_color_cache.readback_texture || !m_efb_depth_cache.readback_texture)
558     return false;
559 
560   if (IsUsingTiledEFBCache())
561   {
562     const u32 tiles_wide = ((EFB_WIDTH + (m_efb_cache_tile_size - 1)) / m_efb_cache_tile_size);
563     const u32 tiles_high = ((EFB_HEIGHT + (m_efb_cache_tile_size - 1)) / m_efb_cache_tile_size);
564     const u32 total_tiles = tiles_wide * tiles_high;
565     m_efb_color_cache.tiles.resize(total_tiles);
566     std::fill(m_efb_color_cache.tiles.begin(), m_efb_color_cache.tiles.end(), false);
567     m_efb_depth_cache.tiles.resize(total_tiles);
568     std::fill(m_efb_depth_cache.tiles.begin(), m_efb_depth_cache.tiles.end(), false);
569     m_efb_cache_tiles_wide = tiles_wide;
570   }
571 
572   return true;
573 }
574 
DestroyReadbackFramebuffer()575 void FramebufferManager::DestroyReadbackFramebuffer()
576 {
577   auto DestroyCache = [](EFBCacheData& data) {
578     data.readback_texture.reset();
579     data.framebuffer.reset();
580     data.texture.reset();
581     data.valid = false;
582   };
583   DestroyCache(m_efb_color_cache);
584   DestroyCache(m_efb_depth_cache);
585 }
586 
PopulateEFBCache(bool depth,u32 tile_index)587 void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index)
588 {
589   g_vertex_manager->OnCPUEFBAccess();
590 
591   // Force the path through the intermediate texture, as we can't do an image copy from a depth
592   // buffer directly to a staging texture (must be the whole resource).
593   const bool force_intermediate_copy =
594       depth &&
595       (!g_ActiveConfig.backend_info.bSupportsDepthReadback ||
596        (!g_ActiveConfig.backend_info.bSupportsPartialDepthCopies && IsUsingTiledEFBCache()) ||
597        !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
598                                                           GetEFBDepthCopyFormat()));
599 
600   // Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
601   EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache;
602   const MathUtil::Rectangle<int> rect = GetEFBCacheTileRect(tile_index);
603   const MathUtil::Rectangle<int> native_rect = g_renderer->ConvertEFBRectangle(rect);
604   AbstractTexture* src_texture =
605       depth ? ResolveEFBDepthTexture(native_rect) : ResolveEFBColorTexture(native_rect);
606   if (g_renderer->GetEFBScale() != 1 || force_intermediate_copy)
607   {
608     // Downsample from internal resolution to 1x.
609     // TODO: This won't produce correct results at IRs above 2x. More samples are required.
610     // This is the same issue as with EFB copies.
611     src_texture->FinishedRendering();
612     g_renderer->BeginUtilityDrawing();
613 
614     const float rcp_src_width = 1.0f / m_efb_framebuffer->GetWidth();
615     const float rcp_src_height = 1.0f / m_efb_framebuffer->GetHeight();
616     const std::array<float, 4> uniforms = {
617         {native_rect.left * rcp_src_width, native_rect.top * rcp_src_height,
618          native_rect.GetWidth() * rcp_src_width, native_rect.GetHeight() * rcp_src_height}};
619     g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
620 
621     // Viewport will not be TILE_SIZExTILE_SIZE for the last row of tiles, assuming a tile size of
622     // 64, because 528 is not evenly divisible by 64.
623     g_renderer->SetAndDiscardFramebuffer(data.framebuffer.get());
624     g_renderer->SetViewportAndScissor(
625         MathUtil::Rectangle<int>(0, 0, rect.GetWidth(), rect.GetHeight()));
626     g_renderer->SetPipeline(data.copy_pipeline.get());
627     g_renderer->SetTexture(0, src_texture);
628     g_renderer->SetSamplerState(0, depth ? RenderState::GetPointSamplerState() :
629                                            RenderState::GetLinearSamplerState());
630     g_renderer->Draw(0, 3);
631 
632     // Copy from EFB or copy texture to staging texture.
633     // No need to call FinishedRendering() here because CopyFromTexture() transitions.
634     data.readback_texture->CopyFromTexture(
635         data.texture.get(), MathUtil::Rectangle<int>(0, 0, rect.GetWidth(), rect.GetHeight()), 0, 0,
636         rect);
637 
638     g_renderer->EndUtilityDrawing();
639   }
640   else
641   {
642     data.readback_texture->CopyFromTexture(src_texture, rect, 0, 0, rect);
643   }
644 
645   // Wait until the copy is complete.
646   data.readback_texture->Flush();
647   data.valid = true;
648   data.out_of_date = false;
649   if (IsUsingTiledEFBCache())
650     data.tiles[tile_index] = true;
651 }
652 
ClearEFB(const MathUtil::Rectangle<int> & rc,bool clear_color,bool clear_alpha,bool clear_z,u32 color,u32 z)653 void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool clear_color,
654                                   bool clear_alpha, bool clear_z, u32 color, u32 z)
655 {
656   FlushEFBPokes();
657   FlagPeekCacheAsOutOfDate();
658   g_renderer->BeginUtilityDrawing();
659 
660   // Set up uniforms.
661   struct Uniforms
662   {
663     float clear_color[4];
664     float clear_depth;
665     float padding1, padding2, padding3;
666   };
667   static_assert(std::is_standard_layout<Uniforms>::value);
668   Uniforms uniforms = {{static_cast<float>((color >> 16) & 0xFF) / 255.0f,
669                         static_cast<float>((color >> 8) & 0xFF) / 255.0f,
670                         static_cast<float>((color >> 0) & 0xFF) / 255.0f,
671                         static_cast<float>((color >> 24) & 0xFF) / 255.0f},
672                        static_cast<float>(z & 0xFFFFFF) / 16777216.0f};
673   if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
674     uniforms.clear_depth = 1.0f - uniforms.clear_depth;
675   g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
676 
677   const auto target_rc = g_renderer->ConvertFramebufferRectangle(
678       g_renderer->ConvertEFBRectangle(rc), m_efb_framebuffer.get());
679   g_renderer->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get());
680   g_renderer->SetViewportAndScissor(target_rc);
681   g_renderer->Draw(0, 3);
682   g_renderer->EndUtilityDrawing();
683 }
684 
CompileClearPipelines()685 bool FramebufferManager::CompileClearPipelines()
686 {
687   auto vertex_shader = g_renderer->CreateShaderFromSource(
688       ShaderStage::Vertex, FramebufferShaderGen::GenerateClearVertexShader());
689   if (!vertex_shader)
690     return false;
691 
692   AbstractPipelineConfig config;
693   config.vertex_format = nullptr;
694   config.vertex_shader = vertex_shader.get();
695   config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetColorGeometryShader() : nullptr;
696   config.pixel_shader = g_shader_cache->GetColorPixelShader();
697   config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles);
698   config.depth_state = RenderState::GetAlwaysWriteDepthState();
699   config.blending_state = RenderState::GetNoBlendingBlendState();
700   config.framebuffer_state = GetEFBFramebufferState();
701   config.usage = AbstractPipelineUsage::Utility;
702 
703   for (u32 color_enable = 0; color_enable < 2; color_enable++)
704   {
705     config.blending_state.colorupdate = color_enable != 0;
706     for (u32 alpha_enable = 0; alpha_enable < 2; alpha_enable++)
707     {
708       config.blending_state.alphaupdate = alpha_enable != 0;
709       for (u32 depth_enable = 0; depth_enable < 2; depth_enable++)
710       {
711         config.depth_state.testenable = depth_enable != 0;
712         config.depth_state.updateenable = depth_enable != 0;
713 
714         m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable] =
715             g_renderer->CreatePipeline(config);
716         if (!m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable])
717           return false;
718       }
719     }
720   }
721 
722   return true;
723 }
724 
DestroyClearPipelines()725 void FramebufferManager::DestroyClearPipelines()
726 {
727   for (u32 color_enable = 0; color_enable < 2; color_enable++)
728   {
729     for (u32 alpha_enable = 0; alpha_enable < 2; alpha_enable++)
730     {
731       for (u32 depth_enable = 0; depth_enable < 2; depth_enable++)
732       {
733         m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable].reset();
734       }
735     }
736   }
737 }
738 
PokeEFBColor(u32 x,u32 y,u32 color)739 void FramebufferManager::PokeEFBColor(u32 x, u32 y, u32 color)
740 {
741   // Flush if we exceeded the number of vertices per batch.
742   if ((m_color_poke_vertices.size() + 6) > MAX_POKE_VERTICES)
743     FlushEFBPokes();
744 
745   CreatePokeVertices(&m_color_poke_vertices, x, y, 0.0f, color);
746 
747   // See comment above for reasoning for lower-left coordinates.
748   if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
749     y = EFB_HEIGHT - 1 - y;
750 
751   // Update the peek cache if it's valid, since we know the color of the pixel now.
752   u32 tile_index;
753   if (IsEFBCacheTilePresent(false, x, y, &tile_index))
754     m_efb_color_cache.readback_texture->WriteTexel(x, y, &color);
755 }
756 
PokeEFBDepth(u32 x,u32 y,float depth)757 void FramebufferManager::PokeEFBDepth(u32 x, u32 y, float depth)
758 {
759   // Flush if we exceeded the number of vertices per batch.
760   if ((m_depth_poke_vertices.size() + 6) > MAX_POKE_VERTICES)
761     FlushEFBPokes();
762 
763   CreatePokeVertices(&m_depth_poke_vertices, x, y, depth, 0);
764 
765   // See comment above for reasoning for lower-left coordinates.
766   if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
767     y = EFB_HEIGHT - 1 - y;
768 
769   // Update the peek cache if it's valid, since we know the color of the pixel now.
770   u32 tile_index;
771   if (IsEFBCacheTilePresent(true, x, y, &tile_index))
772     m_efb_depth_cache.readback_texture->WriteTexel(x, y, &depth);
773 }
774 
CreatePokeVertices(std::vector<EFBPokeVertex> * destination_list,u32 x,u32 y,float z,u32 color)775 void FramebufferManager::CreatePokeVertices(std::vector<EFBPokeVertex>* destination_list, u32 x,
776                                             u32 y, float z, u32 color)
777 {
778   const float cs_pixel_width = 1.0f / EFB_WIDTH * 2.0f;
779   const float cs_pixel_height = 1.0f / EFB_HEIGHT * 2.0f;
780   if (g_ActiveConfig.backend_info.bSupportsLargePoints)
781   {
782     // GPU will expand the point to a quad.
783     const float cs_x = (static_cast<float>(x) + 0.5f) * cs_pixel_width - 1.0f;
784     const float cs_y = 1.0f - (static_cast<float>(y) + 0.5f) * cs_pixel_height;
785     const float point_size = static_cast<float>(g_renderer->GetEFBScale());
786     destination_list->push_back({{cs_x, cs_y, z, point_size}, color});
787     return;
788   }
789 
790   // Generate quad from the single point (clip-space coordinates).
791   const float x1 = static_cast<float>(x) * cs_pixel_width - 1.0f;
792   const float y1 = 1.0f - static_cast<float>(y) * cs_pixel_height;
793   const float x2 = x1 + cs_pixel_width;
794   const float y2 = y1 - cs_pixel_height;
795   destination_list->push_back({{x1, y1, z, 1.0f}, color});
796   destination_list->push_back({{x2, y1, z, 1.0f}, color});
797   destination_list->push_back({{x1, y2, z, 1.0f}, color});
798   destination_list->push_back({{x1, y2, z, 1.0f}, color});
799   destination_list->push_back({{x2, y1, z, 1.0f}, color});
800   destination_list->push_back({{x2, y2, z, 1.0f}, color});
801 }
802 
FlushEFBPokes()803 void FramebufferManager::FlushEFBPokes()
804 {
805   if (!m_color_poke_vertices.empty())
806   {
807     DrawPokeVertices(m_color_poke_vertices.data(), static_cast<u32>(m_color_poke_vertices.size()),
808                      m_color_poke_pipeline.get());
809     m_color_poke_vertices.clear();
810   }
811 
812   if (!m_depth_poke_vertices.empty())
813   {
814     DrawPokeVertices(m_depth_poke_vertices.data(), static_cast<u32>(m_depth_poke_vertices.size()),
815                      m_depth_poke_pipeline.get());
816     m_depth_poke_vertices.clear();
817   }
818 }
819 
DrawPokeVertices(const EFBPokeVertex * vertices,u32 vertex_count,const AbstractPipeline * pipeline)820 void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, u32 vertex_count,
821                                           const AbstractPipeline* pipeline)
822 {
823   // Copy to vertex buffer.
824   g_renderer->BeginUtilityDrawing();
825   u32 base_vertex, base_index;
826   g_vertex_manager->UploadUtilityVertices(vertices, sizeof(EFBPokeVertex),
827                                           static_cast<u32>(vertex_count), nullptr, 0, &base_vertex,
828                                           &base_index);
829 
830   // Now we can draw.
831   g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect());
832   g_renderer->SetPipeline(pipeline);
833   g_renderer->Draw(base_vertex, vertex_count);
834   g_renderer->EndUtilityDrawing();
835 }
836 
CompilePokePipelines()837 bool FramebufferManager::CompilePokePipelines()
838 {
839   PortableVertexDeclaration vtx_decl = {};
840   vtx_decl.position.enable = true;
841   vtx_decl.position.type = VAR_FLOAT;
842   vtx_decl.position.components = 4;
843   vtx_decl.position.integer = false;
844   vtx_decl.position.offset = offsetof(EFBPokeVertex, position);
845   vtx_decl.colors[0].enable = true;
846   vtx_decl.colors[0].type = VAR_UNSIGNED_BYTE;
847   vtx_decl.colors[0].components = 4;
848   vtx_decl.colors[0].integer = false;
849   vtx_decl.colors[0].offset = offsetof(EFBPokeVertex, color);
850   vtx_decl.stride = sizeof(EFBPokeVertex);
851 
852   m_poke_vertex_format = g_renderer->CreateNativeVertexFormat(vtx_decl);
853   if (!m_poke_vertex_format)
854     return false;
855 
856   auto poke_vertex_shader = g_renderer->CreateShaderFromSource(
857       ShaderStage::Vertex, FramebufferShaderGen::GenerateEFBPokeVertexShader());
858   if (!poke_vertex_shader)
859     return false;
860 
861   AbstractPipelineConfig config = {};
862   config.vertex_format = m_poke_vertex_format.get();
863   config.vertex_shader = poke_vertex_shader.get();
864   config.geometry_shader = IsEFBStereo() ? g_shader_cache->GetColorGeometryShader() : nullptr;
865   config.pixel_shader = g_shader_cache->GetColorPixelShader();
866   config.rasterization_state = RenderState::GetNoCullRasterizationState(
867       g_ActiveConfig.backend_info.bSupportsLargePoints ? PrimitiveType::Points :
868                                                          PrimitiveType::Triangles);
869   config.depth_state = RenderState::GetNoDepthTestingDepthState();
870   config.blending_state = RenderState::GetNoBlendingBlendState();
871   config.framebuffer_state = GetEFBFramebufferState();
872   config.usage = AbstractPipelineUsage::Utility;
873   m_color_poke_pipeline = g_renderer->CreatePipeline(config);
874   if (!m_color_poke_pipeline)
875     return false;
876 
877   // Turn off color writes, depth writes on for depth pokes.
878   config.depth_state = RenderState::GetAlwaysWriteDepthState();
879   config.blending_state = RenderState::GetNoColorWriteBlendState();
880   m_depth_poke_pipeline = g_renderer->CreatePipeline(config);
881   if (!m_depth_poke_pipeline)
882     return false;
883 
884   return true;
885 }
886 
DestroyPokePipelines()887 void FramebufferManager::DestroyPokePipelines()
888 {
889   m_depth_poke_pipeline.reset();
890   m_color_poke_pipeline.reset();
891   m_poke_vertex_format.reset();
892 }
893 
DoState(PointerWrap & p)894 void FramebufferManager::DoState(PointerWrap& p)
895 {
896   FlushEFBPokes();
897 
898   bool save_efb_state = Config::Get(Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE);
899   p.Do(save_efb_state);
900   if (!save_efb_state)
901     return;
902 
903   if (p.GetMode() == PointerWrap::MODE_WRITE || p.GetMode() == PointerWrap::MODE_MEASURE)
904     DoSaveState(p);
905   else
906     DoLoadState(p);
907 }
908 
DoSaveState(PointerWrap & p)909 void FramebufferManager::DoSaveState(PointerWrap& p)
910 {
911   // For multisampling, we need to resolve first before we can save.
912   // This won't be bit-exact when loading, which could cause interesting rendering side-effects for
913   // a frame. But whatever, MSAA doesn't exactly behave that well anyway.
914   AbstractTexture* color_texture = ResolveEFBColorTexture(m_efb_color_texture->GetRect());
915   AbstractTexture* depth_texture = ResolveEFBDepthTexture(m_efb_depth_texture->GetRect(), true);
916 
917   // We don't want to save these as rendertarget textures, just the data itself when deserializing.
918   const TextureConfig color_texture_config(color_texture->GetWidth(), color_texture->GetHeight(),
919                                            color_texture->GetLevels(), color_texture->GetLayers(),
920                                            1, GetEFBColorFormat(), 0);
921   g_texture_cache->SerializeTexture(color_texture, color_texture_config, p);
922 
923   const TextureConfig depth_texture_config(depth_texture->GetWidth(), depth_texture->GetHeight(),
924                                            depth_texture->GetLevels(), depth_texture->GetLayers(),
925                                            1, GetEFBDepthCopyFormat(), 0);
926   g_texture_cache->SerializeTexture(depth_texture, depth_texture_config, p);
927 }
928 
DoLoadState(PointerWrap & p)929 void FramebufferManager::DoLoadState(PointerWrap& p)
930 {
931   // Invalidate any peek cache tiles.
932   InvalidatePeekCache(true);
933 
934   // Deserialize the color and depth textures. This could fail.
935   auto color_tex = g_texture_cache->DeserializeTexture(p);
936   auto depth_tex = g_texture_cache->DeserializeTexture(p);
937 
938   // If the stereo mode is different in the save state, throw it away.
939   if (!color_tex || !depth_tex ||
940       color_tex->texture->GetLayers() != m_efb_color_texture->GetLayers())
941   {
942     WARN_LOG(VIDEO, "Failed to deserialize EFB contents. Clearing instead.");
943     g_renderer->SetAndClearFramebuffer(
944         m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
945         g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f);
946     return;
947   }
948 
949   // Size differences are okay here, since the linear filtering will downscale/upscale it.
950   // Depth buffer is always point sampled, since we don't want to interpolate depth values.
951   const bool rescale = color_tex->texture->GetWidth() != m_efb_color_texture->GetWidth() ||
952                        color_tex->texture->GetHeight() != m_efb_color_texture->GetHeight();
953 
954   // Draw the deserialized textures over the EFB.
955   g_renderer->BeginUtilityDrawing();
956   g_renderer->SetAndDiscardFramebuffer(m_efb_framebuffer.get());
957   g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect());
958   g_renderer->SetPipeline(m_efb_restore_pipeline.get());
959   g_renderer->SetTexture(0, color_tex->texture.get());
960   g_renderer->SetTexture(1, depth_tex->texture.get());
961   g_renderer->SetSamplerState(0, rescale ? RenderState::GetLinearSamplerState() :
962                                            RenderState::GetPointSamplerState());
963   g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState());
964   g_renderer->Draw(0, 3);
965   g_renderer->EndUtilityDrawing();
966 }
967