mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 09:09:18 +01:00
Latte: Enable colorbuffer optimization if gfx packs are aware
The optimization for colorbuffer resolution introduced in PR #706 is now enabled. This optimization changes the resolution of certain framebuffer textures, which may conflict with the texture resolution rules set by some graphic packs. As a result, if a graphic pack that specifies texture resolution rules is in use, the optimization will automatically be turned off to prevent any issues. To circumvent this, graphic packs can now include the setting "colorbufferOptimizationAware = true" in their rules.txt. This setting indicates that the pack has been updated to handle the resolution changes introduced by the optimization. Cemu will allow the optimization to remain enabled if resolution packs have this flag set.
This commit is contained in:
parent
4d148b3696
commit
4b7d2f88ae
@ -280,6 +280,10 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||
m_enabled = m_default_enabled;
|
||||
}
|
||||
|
||||
auto option_allowRendertargetSizeOptimization = rules.FindOption("colorbufferOptimizationAware");
|
||||
if (option_allowRendertargetSizeOptimization)
|
||||
m_allowRendertargetSizeOptimization = boost::iequals(*option_allowRendertargetSizeOptimization, "true") || boost::iequals(*option_allowRendertargetSizeOptimization, "1");
|
||||
|
||||
auto option_vendorFilter = rules.FindOption("vendorFilter");
|
||||
if (option_vendorFilter)
|
||||
{
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
const std::string& GetVirtualPath() const { return m_virtualPath; } // returns the path in the gfx tree hierarchy
|
||||
const std::string& GetDescription() const { return m_description; }
|
||||
bool IsDefaultEnabled() const { return m_default_enabled; }
|
||||
bool AllowRendertargetSizeOptimization() const { return m_allowRendertargetSizeOptimization; }
|
||||
|
||||
void SetEnabled(bool state) { m_enabled = state; }
|
||||
|
||||
@ -217,6 +218,8 @@ private:
|
||||
|
||||
bool m_default_enabled = false;
|
||||
|
||||
bool m_allowRendertargetSizeOptimization = false; // gfx pack supports framebuffers with non-padded sizes, which is an optional optimization introduced with Cemu 2.0-74
|
||||
|
||||
// filter
|
||||
std::optional<RendererAPI> m_renderer_api;
|
||||
std::optional<GfxVendor> m_gfx_vendor;
|
||||
|
@ -25,6 +25,8 @@ struct LatteGPUState_t
|
||||
// context control
|
||||
uint32 contextControl0;
|
||||
uint32 contextControl1;
|
||||
// optional features
|
||||
bool allowFramebufferSizeOptimization{false}; // allow using scissor box as size hint to determine non-padded rendertarget size
|
||||
// draw context
|
||||
struct
|
||||
{
|
||||
|
@ -267,14 +267,15 @@ LatteTextureView* LatteMRT::GetColorAttachmentTexture(uint32 index, bool createN
|
||||
|
||||
// colorbuffer width/height has to be padded to 8/32 alignment but the actual resolution might be smaller
|
||||
// use the scissor box as a clue to figure out the original resolution if possible
|
||||
#if 0
|
||||
uint32 scissorBoxWidth = LatteGPUState.contextNew.PA_SC_GENERIC_SCISSOR_BR.get_BR_X();
|
||||
uint32 scissorBoxHeight = LatteGPUState.contextNew.PA_SC_GENERIC_SCISSOR_BR.get_BR_Y();
|
||||
if (((scissorBoxWidth + 7) & ~7) == colorBufferWidth)
|
||||
colorBufferWidth = scissorBoxWidth;
|
||||
if (((colorBufferHeight + 31) & ~31) == colorBufferHeight)
|
||||
colorBufferHeight = scissorBoxHeight;
|
||||
#endif
|
||||
if(LatteGPUState.allowFramebufferSizeOptimization)
|
||||
{
|
||||
uint32 scissorBoxWidth = LatteGPUState.contextNew.PA_SC_GENERIC_SCISSOR_BR.get_BR_X();
|
||||
uint32 scissorBoxHeight = LatteGPUState.contextNew.PA_SC_GENERIC_SCISSOR_BR.get_BR_Y();
|
||||
if (((scissorBoxWidth + 7) & ~7) == colorBufferWidth)
|
||||
colorBufferWidth = scissorBoxWidth;
|
||||
if (((colorBufferHeight + 31) & ~31) == colorBufferHeight)
|
||||
colorBufferHeight = scissorBoxHeight;
|
||||
}
|
||||
|
||||
// log resolution changes if the above heuristic takes effect
|
||||
// this is useful to find resolutions which need to be updated in gfx pack texture rules
|
||||
@ -303,7 +304,7 @@ LatteTextureView* LatteMRT::GetColorAttachmentTexture(uint32 index, bool createN
|
||||
if (colorBufferView == nullptr)
|
||||
{
|
||||
// create color buffer view
|
||||
colorBufferView = LatteTexture_CreateMapping(colorBufferPhysMem, 0, colorBufferWidth, colorBufferHeight, (viewFirstSlice + viewNumSlices), colorBufferPitch, colorBufferTileMode, colorBufferSwizzle>>8, viewFirstMip, 1, viewFirstSlice, viewNumSlices, (Latte::E_GX2SURFFMT)colorBufferFormat, (viewFirstSlice + viewNumSlices)>1? Latte::E_DIM::DIM_2D_ARRAY: Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, false);
|
||||
colorBufferView = LatteTexture_CreateMapping(colorBufferPhysMem, 0, colorBufferWidth, colorBufferHeight, (viewFirstSlice + viewNumSlices), colorBufferPitch, colorBufferTileMode, colorBufferSwizzle>>8, viewFirstMip, 1, viewFirstSlice, viewNumSlices, (Latte::E_GX2SURFFMT)colorBufferFormat, (viewFirstSlice + viewNumSlices)>1? Latte::E_DIM::DIM_2D_ARRAY: Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, false, true);
|
||||
LatteGPUState.repeatTextureInitialization = true;
|
||||
checkForTextureChanges = false;
|
||||
}
|
||||
@ -582,7 +583,7 @@ bool LatteMRT::UpdateCurrentFBO()
|
||||
if (!depthBufferView)
|
||||
{
|
||||
// create new depth buffer view and if it doesn't exist then also create the texture
|
||||
depthBufferView = LatteTexture_CreateMapping(depthBufferPhysMem, 0, depthBufferWidth, depthBufferHeight, depthBufferViewFirstSlice+1, depthBufferPitch, depthBufferTileMode, depthBufferSwizzle, 0, 1, depthBufferViewFirstSlice, 1, depthBufferFormat, depthBufferViewFirstSlice > 0 ? Latte::E_DIM::DIM_2D_ARRAY : Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, true);
|
||||
depthBufferView = LatteTexture_CreateMapping(depthBufferPhysMem, 0, depthBufferWidth, depthBufferHeight, depthBufferViewFirstSlice+1, depthBufferPitch, depthBufferTileMode, depthBufferSwizzle, 0, 1, depthBufferViewFirstSlice, 1, depthBufferFormat, depthBufferViewFirstSlice > 0 ? Latte::E_DIM::DIM_2D_ARRAY : Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, true, true);
|
||||
LatteGPUState.repeatTextureInitialization = true;
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteDraw.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteShader.h"
|
||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||
@ -9,6 +8,8 @@
|
||||
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
struct TexMemOccupancyEntry
|
||||
{
|
||||
uint32 addrStart;
|
||||
@ -963,7 +964,7 @@ void LatteTexture_RecreateTextureWithDifferentMipSliceCount(LatteTexture* textur
|
||||
}
|
||||
|
||||
// create new texture representation
|
||||
// if allowCreateNewDataTexture is true, a new texture will be created if necessary. If it is false, only existing textures may be used, except if a data-compatible version of the requested texture already exists and it's not view compatible
|
||||
// if allowCreateNewDataTexture is true, a new texture will be created if necessary. If it is false, only existing textures may be used, except if a data-compatible version of the requested texture already exists and it's not view compatible (todo - we should differentiate between Latte compatible views and renderer compatible)
|
||||
// the returned view will map to the provided mip and slice range within the created texture, this is to match the behavior of lookupSliceEx
|
||||
LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, sint32 width, sint32 height, sint32 depth, sint32 pitch, Latte::E_HWTILEMODE tileMode, uint32 swizzle, sint32 firstMip, sint32 numMip, sint32 firstSlice, sint32 numSlice, Latte::E_GX2SURFFMT format, Latte::E_DIM dimBase, Latte::E_DIM dimView, bool isDepth, bool allowCreateNewDataTexture)
|
||||
{
|
||||
@ -980,7 +981,7 @@ LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, si
|
||||
// todo, depth and numSlice are redundant
|
||||
|
||||
sint32 sliceCount = firstSlice + numSlice;
|
||||
std::vector<LatteTexture*> list_overlappingTextures;
|
||||
boost::container::small_vector<LatteTexture*, 16> list_overlappingTextures;
|
||||
for (sint32 sliceIndex = 0; sliceIndex < sliceCount; sliceIndex++)
|
||||
{
|
||||
sint32 mipIndex = 0;
|
||||
|
@ -175,6 +175,23 @@ int Latte_ThreadEntry()
|
||||
|
||||
// before doing anything with game specific shaders, we need to wait for graphic packs to finish loading
|
||||
GraphicPack2::WaitUntilReady();
|
||||
// if legacy packs are enabled we cannot use the colorbuffer resolution optimization
|
||||
LatteGPUState.allowFramebufferSizeOptimization = true;
|
||||
for(auto& pack : GraphicPack2::GetActiveGraphicPacks())
|
||||
{
|
||||
if(pack->AllowRendertargetSizeOptimization())
|
||||
continue;
|
||||
for(auto& rule : pack->GetTextureRules())
|
||||
{
|
||||
if(rule.filter_settings.width >= 0 || rule.filter_settings.height >= 0 || rule.filter_settings.depth >= 0 ||
|
||||
rule.overwrite_settings.width >= 0 || rule.overwrite_settings.height >= 0 || rule.overwrite_settings.depth >= 0)
|
||||
{
|
||||
LatteGPUState.allowFramebufferSizeOptimization = false;
|
||||
cemuLog_log(LogType::Force, "Graphic pack {} prevents rendertarget size optimization.", pack->GetName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// load disk shader cache
|
||||
LatteShaderCache_Load();
|
||||
// init registers
|
||||
|
Loading…
Reference in New Issue
Block a user