Latte+Vulkan: Code cleanup

Besides a general cleanup:
- Remove deprecated resource destruction queues
- Move functionality from renderer into Latte base classes to deduplicate code
This commit is contained in:
Exzap 2024-03-14 01:04:05 +01:00
parent bc04662525
commit 193767e6cc
23 changed files with 115 additions and 269 deletions

View File

@ -98,7 +98,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
void LatteRenderTarget_GetCurrentVirtualViewportSize(sint32* viewportWidth, sint32* viewportHeight); void LatteRenderTarget_GetCurrentVirtualViewportSize(sint32* viewportWidth, sint32* viewportHeight);
void LatteRenderTarget_itHLESwapScanBuffer(); void LatteRenderTarget_itHLESwapScanBuffer();
void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorBufferMPTR, MPTR colorBufferFormat, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferPitch, uint32 colorBufferViewFirstSlice, uint32 colorBufferViewNumSlice, MPTR depthBufferMPTR, MPTR depthBufferFormat, Latte::E_HWTILEMODE depthBufferTileMode, sint32 depthBufferWidth, sint32 depthBufferHeight, sint32 depthBufferPitch, sint32 depthBufferViewFirstSlice, sint32 depthBufferViewNumSlice, float r, float g, float b, float a, float clearDepth, uint32 clearStencil); void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorBufferMPTR, Latte::E_GX2SURFFMT colorBufferFormat, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferPitch, uint32 colorBufferViewFirstSlice, uint32 colorBufferViewNumSlice, MPTR depthBufferMPTR, Latte::E_GX2SURFFMT depthBufferFormat, Latte::E_HWTILEMODE depthBufferTileMode, sint32 depthBufferWidth, sint32 depthBufferHeight, sint32 depthBufferPitch, sint32 depthBufferViewFirstSlice, sint32 depthBufferViewNumSlice, float r, float g, float b, float a, float clearDepth, uint32 clearStencil);
void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferSliceIndex, uint32 colorBufferFormat, uint32 colorBufferPitch, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferSwizzle, uint32 renderTarget); void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferSliceIndex, uint32 colorBufferFormat, uint32 colorBufferPitch, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferSwizzle, uint32 renderTarget);
void LatteRenderTarget_unloadAll(); void LatteRenderTarget_unloadAll();

View File

@ -864,8 +864,8 @@ LatteCMDPtr LatteCP_itHLEClearColorDepthStencil(LatteCMDPtr cmd, uint32 nWords)
cemu_assert_debug(nWords == 23); cemu_assert_debug(nWords == 23);
uint32 clearMask = LatteReadCMD(); // color (1), depth (2), stencil (4) uint32 clearMask = LatteReadCMD(); // color (1), depth (2), stencil (4)
// color buffer // color buffer
MPTR colorBufferMPTR = LatteReadCMD(); // MPTR for color buffer (physical address) MPTR colorBufferMPTR = LatteReadCMD(); // physical address for color buffer
MPTR colorBufferFormat = LatteReadCMD(); // format for color buffer Latte::E_GX2SURFFMT colorBufferFormat = (Latte::E_GX2SURFFMT)LatteReadCMD();
Latte::E_HWTILEMODE colorBufferTilemode = (Latte::E_HWTILEMODE)LatteReadCMD(); Latte::E_HWTILEMODE colorBufferTilemode = (Latte::E_HWTILEMODE)LatteReadCMD();
uint32 colorBufferWidth = LatteReadCMD(); uint32 colorBufferWidth = LatteReadCMD();
uint32 colorBufferHeight = LatteReadCMD(); uint32 colorBufferHeight = LatteReadCMD();
@ -873,8 +873,8 @@ LatteCMDPtr LatteCP_itHLEClearColorDepthStencil(LatteCMDPtr cmd, uint32 nWords)
uint32 colorBufferViewFirstSlice = LatteReadCMD(); uint32 colorBufferViewFirstSlice = LatteReadCMD();
uint32 colorBufferViewNumSlice = LatteReadCMD(); uint32 colorBufferViewNumSlice = LatteReadCMD();
// depth buffer // depth buffer
MPTR depthBufferMPTR = LatteReadCMD(); // MPTR for depth buffer (physical address) MPTR depthBufferMPTR = LatteReadCMD(); // physical address for depth buffer
MPTR depthBufferFormat = LatteReadCMD(); // format for depth buffer Latte::E_GX2SURFFMT depthBufferFormat = (Latte::E_GX2SURFFMT)LatteReadCMD();
Latte::E_HWTILEMODE depthBufferTileMode = (Latte::E_HWTILEMODE)LatteReadCMD(); Latte::E_HWTILEMODE depthBufferTileMode = (Latte::E_HWTILEMODE)LatteReadCMD();
uint32 depthBufferWidth = LatteReadCMD(); uint32 depthBufferWidth = LatteReadCMD();
uint32 depthBufferHeight = LatteReadCMD(); uint32 depthBufferHeight = LatteReadCMD();

View File

@ -221,35 +221,9 @@ void LatteMRT::BindDepthBufferOnly(LatteTextureView* view)
ApplyCurrentState(); ApplyCurrentState();
} }
/***************************************************/
LatteTextureView* LatteMRT_FindColorBufferForClearing(MPTR colorBufferPtr, sint32 colorBufferWidth, sint32 colorBufferHeight, sint32 colorBufferPitch, uint32 format, sint32 sliceIndex, sint32* searchIndex)
{
LatteTextureView* view = LatteTC_LookupTextureByData(colorBufferPtr, colorBufferWidth, colorBufferHeight, colorBufferPitch, 0, 1, sliceIndex, 1, searchIndex);
if (view == nullptr)
return nullptr;
return view;
}
LatteTextureView* LatteMRT_CreateColorBuffer(MPTR colorBufferPhysMem, uint32 width, uint32 height, uint32 pitch, Latte::E_GX2SURFFMT format, Latte::E_HWTILEMODE tileMode, uint32 swizzle, uint32 viewSlice)
{
cemu_assert_debug(colorBufferPhysMem != MPTR_NULL);
LatteTextureView* textureView;
if(viewSlice != 0)
textureView = LatteTexture_CreateMapping(colorBufferPhysMem, MPTR_NULL, width, height, viewSlice+1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D_ARRAY, Latte::E_DIM::DIM_2D, false);
else
textureView = LatteTexture_CreateMapping(colorBufferPhysMem, MPTR_NULL, width, height, 1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, false);
return textureView;
}
LatteTextureView* LatteMRT_CreateDepthBuffer(MPTR depthBufferPhysMem, uint32 width, uint32 height, uint32 pitch, Latte::E_HWTILEMODE tileMode, Latte::E_GX2SURFFMT format, uint32 swizzle, sint32 viewSlice) LatteTextureView* LatteMRT_CreateDepthBuffer(MPTR depthBufferPhysMem, uint32 width, uint32 height, uint32 pitch, Latte::E_HWTILEMODE tileMode, Latte::E_GX2SURFFMT format, uint32 swizzle, sint32 viewSlice)
{ {
LatteTextureView* textureView; LatteTextureView* textureView = LatteTexture_CreateMapping(depthBufferPhysMem, MPTR_NULL, width, height, viewSlice+1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, viewSlice > 0 ? Latte::E_DIM::DIM_2D_ARRAY : Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, true);
if(viewSlice == 0)
textureView = LatteTexture_CreateMapping(depthBufferPhysMem, MPTR_NULL, width, height, 1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, true);
else
textureView = LatteTexture_CreateMapping(depthBufferPhysMem, MPTR_NULL, width, height, viewSlice+1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D_ARRAY, Latte::E_DIM::DIM_2D, true);
LatteMRT::SetDepthAndStencilAttachment(textureView, textureView->baseTexture->hasStencil); LatteMRT::SetDepthAndStencilAttachment(textureView, textureView->baseTexture->hasStencil);
return textureView; return textureView;
} }
@ -605,7 +579,7 @@ bool LatteMRT::UpdateCurrentFBO()
if (depthBufferPhysMem != MPTR_NULL) if (depthBufferPhysMem != MPTR_NULL)
{ {
LatteTextureView* depthBufferView = LatteTextureViewLookupCache::lookupSliceEx(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, depthBufferViewFirstSlice, depthBufferFormat, true); LatteTextureView* depthBufferView = LatteTextureViewLookupCache::lookupSliceEx(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, depthBufferViewFirstSlice, depthBufferFormat, true);
if (depthBufferView == nullptr) if (!depthBufferView)
{ {
// create new depth buffer view and if it doesn't exist then also create the texture // 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);
@ -768,7 +742,10 @@ void LatteRenderTarget_applyTextureDepthClear(LatteTexture* texture, uint32 slic
LatteTexture_MarkDynamicTextureAsChanged(texture->baseView, sliceIndex, mipIndex, eventCounter); LatteTexture_MarkDynamicTextureAsChanged(texture->baseView, sliceIndex, mipIndex, eventCounter);
} }
void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorBufferMPTR, MPTR colorBufferFormat, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferPitch, uint32 colorBufferViewFirstSlice, uint32 colorBufferViewNumSlice, MPTR depthBufferMPTR, MPTR depthBufferFormat, Latte::E_HWTILEMODE depthBufferTileMode, sint32 depthBufferWidth, sint32 depthBufferHeight, sint32 depthBufferPitch, sint32 depthBufferViewFirstSlice, sint32 depthBufferViewNumSlice, float r, float g, float b, float a, float clearDepth, uint32 clearStencil) void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask,
MPTR colorBufferMPTR, Latte::E_GX2SURFFMT colorBufferFormat, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferPitch, uint32 colorBufferViewFirstSlice, uint32 colorBufferViewNumSlice,
MPTR depthBufferMPTR, Latte::E_GX2SURFFMT depthBufferFormat, Latte::E_HWTILEMODE depthBufferTileMode, sint32 depthBufferWidth, sint32 depthBufferHeight, sint32 depthBufferPitch, sint32 depthBufferViewFirstSlice, sint32 depthBufferViewNumSlice,
float r, float g, float b, float a, float clearDepth, uint32 clearStencil)
{ {
uint32 depthBufferMipIndex = 0; // todo uint32 depthBufferMipIndex = 0; // todo
uint32 colorBufferMipIndex = 0; // todo uint32 colorBufferMipIndex = 0; // todo
@ -803,13 +780,11 @@ void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorB
bool targetFound = false; bool targetFound = false;
while (true) while (true)
{ {
LatteTextureView* colorView = LatteMRT_FindColorBufferForClearing(colorBufferMPTR, colorBufferWidth, colorBufferHeight, colorBufferPitch, colorBufferFormat, colorBufferViewFirstSlice, &searchIndex); LatteTextureView* colorView = LatteTC_LookupTextureByData(colorBufferMPTR, colorBufferWidth, colorBufferHeight, colorBufferPitch, 0, 1, colorBufferViewFirstSlice, 1, &searchIndex);
if (!colorView) if (!colorView)
break; break;
if (Latte::GetFormatBits((Latte::E_GX2SURFFMT)colorBufferFormat) != Latte::GetFormatBits(colorView->baseTexture->format)) if (Latte::GetFormatBits(colorBufferFormat) != Latte::GetFormatBits(colorView->baseTexture->format))
{
continue; continue;
}
if (colorView->baseTexture->pitch == colorBufferPitch && colorView->baseTexture->height == colorBufferHeight) if (colorView->baseTexture->pitch == colorBufferPitch && colorView->baseTexture->height == colorBufferHeight)
targetFound = true; targetFound = true;
@ -821,7 +796,7 @@ void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorB
{ {
// create new texture with matching format // create new texture with matching format
cemu_assert_debug(colorBufferViewNumSlice <= 1); cemu_assert_debug(colorBufferViewNumSlice <= 1);
LatteTextureView* newColorView = LatteMRT_CreateColorBuffer(colorBufferMPTR, colorBufferWidth, colorBufferHeight, colorBufferPitch, (Latte::E_GX2SURFFMT)colorBufferFormat, colorBufferTilemode, colorBufferSwizzle, colorBufferViewFirstSlice); LatteTextureView* newColorView = LatteTexture_CreateMapping(colorBufferMPTR, MPTR_NULL, colorBufferWidth, colorBufferHeight, colorBufferViewFirstSlice+1, colorBufferPitch, colorBufferTilemode, colorBufferSwizzle, 0, 1, colorBufferViewFirstSlice, 1, colorBufferFormat, colorBufferViewFirstSlice > 0 ? Latte::E_DIM::DIM_2D_ARRAY : Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, false);
LatteRenderTarget_applyTextureColorClear(newColorView->baseTexture, colorBufferViewFirstSlice, colorBufferMipIndex, r, g, b, a, eventCounter); LatteRenderTarget_applyTextureColorClear(newColorView->baseTexture, colorBufferViewFirstSlice, colorBufferMipIndex, r, g, b, a, eventCounter);
} }
} }

View File

@ -1199,6 +1199,15 @@ std::vector<LatteTexture*>& LatteTexture::GetAllTextures()
return sAllTextures; return sAllTextures;
} }
bool LatteTexture_GX2FormatHasStencil(bool isDepth, Latte::E_GX2SURFFMT format)
{
if (!isDepth)
return false;
return format == Latte::E_GX2SURFFMT::D24_S8_UNORM ||
format == Latte::E_GX2SURFFMT::D24_S8_FLOAT ||
format == Latte::E_GX2SURFFMT::D32_S8_FLOAT;
}
LatteTexture::LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, LatteTexture::LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
Latte::E_HWTILEMODE tileMode, bool isDepth) Latte::E_HWTILEMODE tileMode, bool isDepth)
{ {
@ -1217,6 +1226,7 @@ LatteTexture::LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddre
this->mipLevels = mipLevels; this->mipLevels = mipLevels;
this->tileMode = tileMode; this->tileMode = tileMode;
this->isDepth = isDepth; this->isDepth = isDepth;
this->hasStencil = LatteTexture_GX2FormatHasStencil(isDepth, format);
this->physMipAddress = physMipAddress; this->physMipAddress = physMipAddress;
this->lastUpdateEventCounter = LatteTexture_getNextUpdateEventCounter(); this->lastUpdateEventCounter = LatteTexture_getNextUpdateEventCounter();
this->lastWriteEventCounter = LatteTexture_getNextUpdateEventCounter(); this->lastWriteEventCounter = LatteTexture_getNextUpdateEventCounter();

View File

@ -27,6 +27,8 @@ public:
LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth); LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth);
virtual ~LatteTexture(); virtual ~LatteTexture();
virtual void AllocateOnHost() = 0;
LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
{ {
for (auto& itr : views) for (auto& itr : views)

View File

@ -316,7 +316,7 @@ void LatteTexture_Delete(LatteTexture* texture)
delete[] texture->sliceMipInfo; delete[] texture->sliceMipInfo;
texture->sliceMipInfo = nullptr; texture->sliceMipInfo = nullptr;
} }
g_renderer->texture_destroy(texture); delete texture;
} }
/* /*

View File

@ -621,7 +621,7 @@ void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, uint32 sliceIn
if (tex->isDataDefined == false) if (tex->isDataDefined == false)
{ {
g_renderer->texture_reserveTextureOnGPU(tex); tex->AllocateOnHost();
tex->isDataDefined = true; tex->isDataDefined = true;
// if decoder is not set then clear texture // if decoder is not set then clear texture
// on Vulkan this is used to make sure the texture is no longer in UNDEFINED layout // on Vulkan this is used to make sure the texture is no longer in UNDEFINED layout

View File

@ -5,20 +5,6 @@
#include "config/LaunchSettings.h" #include "config/LaunchSettings.h"
GLuint texIdPool[64];
sint32 texIdPoolIndex = 64;
static GLuint _genTextureHandleGL()
{
if (texIdPoolIndex == 64)
{
glGenTextures(64, texIdPool);
texIdPoolIndex = 0;
}
texIdPoolIndex++;
return texIdPool[texIdPoolIndex - 1];
}
LatteTextureGL::LatteTextureGL(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, LatteTextureGL::LatteTextureGL(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
Latte::E_HWTILEMODE tileMode, bool isDepth) Latte::E_HWTILEMODE tileMode, bool isDepth)
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth) : LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth)
@ -29,7 +15,6 @@ LatteTextureGL::LatteTextureGL(Latte::E_DIM dim, MPTR physAddress, MPTR physMipA
GetOpenGLFormatInfo(isDepth, overwriteInfo.hasFormatOverwrite ? (Latte::E_GX2SURFFMT)overwriteInfo.format : format, dim, &glFormatInfo); GetOpenGLFormatInfo(isDepth, overwriteInfo.hasFormatOverwrite ? (Latte::E_GX2SURFFMT)overwriteInfo.format : format, dim, &glFormatInfo);
this->glInternalFormat = glFormatInfo.glInternalFormat; this->glInternalFormat = glFormatInfo.glInternalFormat;
this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat; this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat;
this->hasStencil = glFormatInfo.hasStencil; // todo - should get this from the GX2 format?
// set debug name // set debug name
bool useGLDebugNames = false; bool useGLDebugNames = false;
#ifdef CEMU_DEBUG_ASSERT #ifdef CEMU_DEBUG_ASSERT
@ -88,34 +73,34 @@ void LatteTextureGL::GetOpenGLFormatInfo(bool isDepth, Latte::E_GX2SURFFMT forma
{ {
if (format == Latte::E_GX2SURFFMT::D24_S8_UNORM) if (format == Latte::E_GX2SURFFMT::D24_S8_UNORM)
{ {
formatInfoOut->setDepthFormat(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, true); formatInfoOut->setFormat(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
return; return;
} }
else if (format == Latte::E_GX2SURFFMT::D24_S8_FLOAT) else if (format == Latte::E_GX2SURFFMT::D24_S8_FLOAT)
{ {
formatInfoOut->setDepthFormat(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, true); formatInfoOut->setFormat(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
formatInfoOut->markAsAlternativeFormat(); formatInfoOut->markAsAlternativeFormat();
return; return;
} }
else if (format == Latte::E_GX2SURFFMT::D32_S8_FLOAT) else if (format == Latte::E_GX2SURFFMT::D32_S8_FLOAT)
{ {
formatInfoOut->setDepthFormat(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, true); formatInfoOut->setFormat(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
return; return;
} }
else if (format == Latte::E_GX2SURFFMT::D32_FLOAT) else if (format == Latte::E_GX2SURFFMT::D32_FLOAT)
{ {
formatInfoOut->setDepthFormat(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false); formatInfoOut->setFormat(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
return; return;
} }
else if (format == Latte::E_GX2SURFFMT::D16_UNORM) else if (format == Latte::E_GX2SURFFMT::D16_UNORM)
{ {
formatInfoOut->setDepthFormat(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false); formatInfoOut->setFormat(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
return; return;
} }
// unsupported depth format // unsupported depth format
cemuLog_log(LogType::Force, "OpenGL: Unsupported texture depth format 0x{:04x}", (uint32)format); cemuLog_log(LogType::Force, "OpenGL: Unsupported texture depth format 0x{:04x}", (uint32)format);
// use placeholder format // use placeholder format
formatInfoOut->setDepthFormat(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false); formatInfoOut->setFormat(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
formatInfoOut->markAsAlternativeFormat(); formatInfoOut->markAsAlternativeFormat();
return; return;
} }
@ -496,3 +481,49 @@ void LatteTextureGL::GetOpenGLFormatInfo(bool isDepth, Latte::E_GX2SURFFMT forma
formatInfoOut->glIsCompressed = glIsCompressed; formatInfoOut->glIsCompressed = glIsCompressed;
formatInfoOut->isUsingAlternativeFormat = isUsingAlternativeFormat; formatInfoOut->isUsingAlternativeFormat = isUsingAlternativeFormat;
} }
void LatteTextureGL::AllocateOnHost()
{
auto hostTexture = this;
cemu_assert_debug(hostTexture->isDataDefined == false);
sint32 effectiveBaseWidth = hostTexture->width;
sint32 effectiveBaseHeight = hostTexture->height;
sint32 effectiveBaseDepth = hostTexture->depth;
if (hostTexture->overwriteInfo.hasResolutionOverwrite)
{
effectiveBaseWidth = hostTexture->overwriteInfo.width;
effectiveBaseHeight = hostTexture->overwriteInfo.height;
effectiveBaseDepth = hostTexture->overwriteInfo.depth;
}
// calculate mip count
sint32 mipLevels = std::min(hostTexture->mipLevels, hostTexture->maxPossibleMipLevels);
mipLevels = std::max(mipLevels, 1);
// create immutable storage
if (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
{
cemu_assert_debug(effectiveBaseDepth == 1);
glTextureStorage2DWrapper(GL_TEXTURE_2D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight);
}
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
{
cemu_assert_debug(effectiveBaseHeight == 1);
cemu_assert_debug(effectiveBaseDepth == 1);
glTextureStorage1DWrapper(GL_TEXTURE_1D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth);
}
else if (hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY || hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA)
{
glTextureStorage3DWrapper(GL_TEXTURE_2D_ARRAY, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
}
else if (hostTexture->dim == Latte::E_DIM::DIM_3D)
{
glTextureStorage3DWrapper(GL_TEXTURE_3D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
}
else if (hostTexture->dim == Latte::E_DIM::DIM_CUBEMAP)
{
glTextureStorage3DWrapper(GL_TEXTURE_CUBE_MAP_ARRAY, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, effectiveBaseDepth);
}
else
{
cemu_assert_unimplemented();
}
}

View File

@ -11,6 +11,8 @@ public:
~LatteTextureGL(); ~LatteTextureGL();
void AllocateOnHost() override;
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType); static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType);
protected: protected:
@ -23,7 +25,6 @@ public:
sint32 glSuppliedFormat; sint32 glSuppliedFormat;
sint32 glSuppliedFormatType; sint32 glSuppliedFormatType;
bool glIsCompressed; bool glIsCompressed;
bool hasStencil{};
bool isUsingAlternativeFormat{}; bool isUsingAlternativeFormat{};
void setFormat(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType) void setFormat(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType)
@ -34,15 +35,6 @@ public:
this->glIsCompressed = false; this->glIsCompressed = false;
} }
void setDepthFormat(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType, bool hasStencil)
{
this->glInternalFormat = glInternalFormat;
this->glSuppliedFormat = glSuppliedFormat;
this->glSuppliedFormatType = glSuppliedFormatType;
this->glIsCompressed = false;
this->hasStencil = hasStencil;
}
void setCompressed(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType) void setCompressed(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType)
{ {
setFormat(glInternalFormat, glSuppliedFormat, glSuppliedFormatType); setFormat(glInternalFormat, glSuppliedFormat, glSuppliedFormatType);

View File

@ -1002,57 +1002,6 @@ TextureDecoder* OpenGLRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT
return texDecoder; return texDecoder;
} }
void OpenGLRenderer::texture_destroy(LatteTexture* hostTexture)
{
delete hostTexture;
}
void OpenGLRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTextureGeneric)
{
auto hostTexture = (LatteTextureGL*)hostTextureGeneric;
cemu_assert_debug(hostTexture->isDataDefined == false);
sint32 effectiveBaseWidth = hostTexture->width;
sint32 effectiveBaseHeight = hostTexture->height;
sint32 effectiveBaseDepth = hostTexture->depth;
if (hostTexture->overwriteInfo.hasResolutionOverwrite)
{
effectiveBaseWidth = hostTexture->overwriteInfo.width;
effectiveBaseHeight = hostTexture->overwriteInfo.height;
effectiveBaseDepth = hostTexture->overwriteInfo.depth;
}
// calculate mip count
sint32 mipLevels = std::min(hostTexture->mipLevels, hostTexture->maxPossibleMipLevels);
mipLevels = std::max(mipLevels, 1);
// create immutable storage
if (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
{
cemu_assert_debug(effectiveBaseDepth == 1);
glTextureStorage2DWrapper(GL_TEXTURE_2D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight);
}
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
{
cemu_assert_debug(effectiveBaseHeight == 1);
cemu_assert_debug(effectiveBaseDepth == 1);
glTextureStorage1DWrapper(GL_TEXTURE_1D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth);
}
else if (hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY || hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA)
{
glTextureStorage3DWrapper(GL_TEXTURE_2D_ARRAY, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
}
else if (hostTexture->dim == Latte::E_DIM::DIM_3D)
{
glTextureStorage3DWrapper(GL_TEXTURE_3D, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
}
else if (hostTexture->dim == Latte::E_DIM::DIM_CUBEMAP)
{
glTextureStorage3DWrapper(GL_TEXTURE_CUBE_MAP_ARRAY, hostTexture->glId_texture, mipLevels, hostTexture->glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, effectiveBaseDepth);
}
else
{
cemu_assert_unimplemented();
}
}
// use standard API to upload texture data // use standard API to upload texture data
void OpenGLRenderer_texture_loadSlice_normal(LatteTexture* hostTextureGeneric, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 imageSize) void OpenGLRenderer_texture_loadSlice_normal(LatteTexture* hostTextureGeneric, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 imageSize)
{ {

View File

@ -66,14 +66,11 @@ public:
void renderstate_updateTextureSettingsGL(LatteDecompilerShader* shaderContext, LatteTextureView* _hostTextureView, uint32 hostTextureUnit, const Latte::LATTE_SQ_TEX_RESOURCE_WORD4_N texUnitWord4, uint32 texUnitIndex, bool isDepthSampler); void renderstate_updateTextureSettingsGL(LatteDecompilerShader* shaderContext, LatteTextureView* _hostTextureView, uint32 hostTextureUnit, const Latte::LATTE_SQ_TEX_RESOURCE_WORD4_N texUnitWord4, uint32 texUnitIndex, bool isDepthSampler);
// texture functions // texture functions
void texture_destroy(LatteTexture* hostTexture) override;
void* texture_acquireTextureUploadBuffer(uint32 size) override; void* texture_acquireTextureUploadBuffer(uint32 size) override;
void texture_releaseTextureUploadBuffer(uint8* mem) override; void texture_releaseTextureUploadBuffer(uint8* mem) override;
TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) override; TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) override;
void texture_reserveTextureOnGPU(LatteTexture* hostTexture) override;
void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) override; void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) override;
void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) override; void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) override;
void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override; void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override;

View File

@ -97,14 +97,11 @@ public:
virtual void rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) = 0; virtual void rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) = 0;
// texture functions // texture functions
virtual void texture_destroy(LatteTexture* hostTexture) = 0;
virtual void* texture_acquireTextureUploadBuffer(uint32 size) = 0; virtual void* texture_acquireTextureUploadBuffer(uint32 size) = 0;
virtual void texture_releaseTextureUploadBuffer(uint8* mem) = 0; virtual void texture_releaseTextureUploadBuffer(uint8* mem) = 0;
virtual TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) = 0; virtual TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) = 0;
virtual void texture_reserveTextureOnGPU(LatteTexture* hostTexture) = 0;
virtual void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) = 0; virtual void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) = 0;
virtual void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) = 0; virtual void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) = 0;
virtual void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) = 0; virtual void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) = 0;

View File

@ -44,9 +44,9 @@ CachedFBOVk::~CachedFBOVk()
while (!m_usedByPipelines.empty()) while (!m_usedByPipelines.empty())
delete m_usedByPipelines[0]; delete m_usedByPipelines[0];
auto vkr = VulkanRenderer::GetInstance(); auto vkr = VulkanRenderer::GetInstance();
vkr->releaseDestructibleObject(m_vkrObjFramebuffer); vkr->ReleaseDestructibleObject(m_vkrObjFramebuffer);
m_vkrObjFramebuffer = nullptr; m_vkrObjFramebuffer = nullptr;
vkr->releaseDestructibleObject(m_vkrObjRenderPass); vkr->ReleaseDestructibleObject(m_vkrObjRenderPass);
m_vkrObjRenderPass = nullptr; m_vkrObjRenderPass = nullptr;
} }

View File

@ -79,14 +79,14 @@ LatteTextureViewVk::~LatteTextureViewVk()
delete list_descriptorSets[0]; delete list_descriptorSets[0];
if (m_smallCacheView0) if (m_smallCacheView0)
VulkanRenderer::GetInstance()->releaseDestructibleObject(m_smallCacheView0); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_smallCacheView0);
if (m_smallCacheView1) if (m_smallCacheView1)
VulkanRenderer::GetInstance()->releaseDestructibleObject(m_smallCacheView1); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_smallCacheView1);
if (m_fallbackCache) if (m_fallbackCache)
{ {
for (auto& itr : *m_fallbackCache) for (auto& itr : *m_fallbackCache)
VulkanRenderer::GetInstance()->releaseDestructibleObject(itr.second); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(itr.second);
delete m_fallbackCache; delete m_fallbackCache;
m_fallbackCache = nullptr; m_fallbackCache = nullptr;
} }

View File

@ -46,7 +46,7 @@ LatteTextureVk::LatteTextureVk(class VulkanRenderer* vkRenderer, Latte::E_DIM di
VulkanRenderer::FormatInfoVK texFormatInfo; VulkanRenderer::FormatInfoVK texFormatInfo;
vkRenderer->GetTextureFormatInfoVK(format, isDepth, dim, effectiveBaseWidth, effectiveBaseHeight, &texFormatInfo); vkRenderer->GetTextureFormatInfoVK(format, isDepth, dim, effectiveBaseWidth, effectiveBaseHeight, &texFormatInfo);
hasStencil = (texFormatInfo.vkImageAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; cemu_assert_debug(hasStencil == ((texFormatInfo.vkImageAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0));
imageInfo.format = texFormatInfo.vkImageFormat; imageInfo.format = texFormatInfo.vkImageFormat;
vkObjTex->m_imageAspect = texFormatInfo.vkImageAspect; vkObjTex->m_imageAspect = texFormatInfo.vkImageAspect;
@ -117,7 +117,7 @@ LatteTextureVk::~LatteTextureVk()
m_vkr->surfaceCopy_notifyTextureRelease(this); m_vkr->surfaceCopy_notifyTextureRelease(this);
VulkanRenderer::GetInstance()->releaseDestructibleObject(vkObjTex); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(vkObjTex);
vkObjTex = nullptr; vkObjTex = nullptr;
} }
@ -130,12 +130,8 @@ LatteTextureView* LatteTextureVk::CreateView(Latte::E_DIM dim, Latte::E_GX2SURFF
return new LatteTextureViewVk(m_vkr->GetLogicalDevice(), this, dim, format, firstMip, mipCount, firstSlice, sliceCount); return new LatteTextureViewVk(m_vkr->GetLogicalDevice(), this, dim, format, firstMip, mipCount, firstSlice, sliceCount);
} }
void LatteTextureVk::setAllocation(struct VkImageMemAllocation* memAllocation) void LatteTextureVk::AllocateOnHost()
{ {
vkObjTex->m_allocation = memAllocation; auto allocationInfo = VulkanRenderer::GetInstance()->GetMemoryManager()->imageMemoryAllocate(GetImageObj()->m_image);
} vkObjTex->m_allocation = allocationInfo;
struct VkImageMemAllocation* LatteTextureVk::getAllocation() const
{
return vkObjTex->m_allocation;
} }

View File

@ -14,14 +14,13 @@ public:
~LatteTextureVk(); ~LatteTextureVk();
void AllocateOnHost() override;
VKRObjectTexture* GetImageObj() const { return vkObjTex; }; VKRObjectTexture* GetImageObj() const { return vkObjTex; };
VkFormat GetFormat() const { return vkObjTex->m_format; } VkFormat GetFormat() const { return vkObjTex->m_format; }
VkImageAspectFlags GetImageAspect() const { return vkObjTex->m_imageAspect; } VkImageAspectFlags GetImageAspect() const { return vkObjTex->m_imageAspect; }
void setAllocation(struct VkImageMemAllocation* memAllocation);
struct VkImageMemAllocation* getAllocation() const;
VkImageLayout GetImageLayout(VkImageSubresource& subresource) VkImageLayout GetImageLayout(VkImageSubresource& subresource)
{ {
cemu_assert_debug(subresource.mipLevel < m_layoutsMips); cemu_assert_debug(subresource.mipLevel < m_layoutsMips);

View File

@ -207,7 +207,8 @@ RendererShaderVk::RendererShaderVk(ShaderType type, uint64 baseHash, uint64 auxH
RendererShaderVk::~RendererShaderVk() RendererShaderVk::~RendererShaderVk()
{ {
VulkanRenderer::GetInstance()->destroyShader(this); while (!list_pipelineInfo.empty())
delete list_pipelineInfo[0];
} }
void RendererShaderVk::Init() void RendererShaderVk::Init()

View File

@ -84,7 +84,7 @@ PipelineInfo::~PipelineInfo()
// queue pipeline for destruction // queue pipeline for destruction
if (m_vkrObjPipeline) if (m_vkrObjPipeline)
{ {
VulkanRenderer::GetInstance()->releaseDestructibleObject(m_vkrObjPipeline); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_vkrObjPipeline);
m_vkrObjPipeline = nullptr; m_vkrObjPipeline = nullptr;
} }

View File

@ -300,7 +300,7 @@ void VulkanPipelineStableCache::LoadPipelineFromCache(std::span<uint8> fileData)
delete pipelineInfo; delete pipelineInfo;
delete lcr; delete lcr;
delete cachedPipeline; delete cachedPipeline;
VulkanRenderer::GetInstance()->releaseDestructibleObject(renderPass); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(renderPass);
s_spinlockSharedInternal.unlock(); s_spinlockSharedInternal.unlock();
} }

View File

@ -1803,44 +1803,6 @@ void VulkanRenderer::PreparePresentationFrame(bool mainWindow)
AcquireNextSwapchainImage(mainWindow); AcquireNextSwapchainImage(mainWindow);
} }
void VulkanRenderer::ProcessDestructionQueues(size_t commandBufferIndex)
{
auto& current_descriptor_cache = m_destructionQueues.m_cmd_descriptor_set_objects[commandBufferIndex];
if (!current_descriptor_cache.empty())
{
assert_dbg();
//for (const auto& descriptor : current_descriptor_cache)
//{
// vkFreeDescriptorSets(m_logicalDevice, m_descriptorPool, 1, &descriptor);
// performanceMonitor.vk.numDescriptorSets.decrement();
//}
current_descriptor_cache.clear();
}
// destroy buffers
for (auto& itr : m_destructionQueues.m_buffers[commandBufferIndex])
vkDestroyBuffer(m_logicalDevice, itr, nullptr);
m_destructionQueues.m_buffers[commandBufferIndex].clear();
// destroy device memory objects
for (auto& itr : m_destructionQueues.m_memory[commandBufferIndex])
vkFreeMemory(m_logicalDevice, itr, nullptr);
m_destructionQueues.m_memory[commandBufferIndex].clear();
// destroy image views
for (auto& itr : m_destructionQueues.m_cmd_image_views[commandBufferIndex])
vkDestroyImageView(m_logicalDevice, itr, nullptr);
m_destructionQueues.m_cmd_image_views[commandBufferIndex].clear();
// destroy host textures
for (auto itr : m_destructionQueues.m_host_textures[commandBufferIndex])
delete itr;
m_destructionQueues.m_host_textures[commandBufferIndex].clear();
ProcessDestructionQueue2();
}
void VulkanRenderer::InitFirstCommandBuffer() void VulkanRenderer::InitFirstCommandBuffer()
{ {
cemu_assert_debug(m_state.currentCommandBuffer == nullptr); cemu_assert_debug(m_state.currentCommandBuffer == nullptr);
@ -1869,7 +1831,7 @@ void VulkanRenderer::ProcessFinishedCommandBuffers()
VkResult fenceStatus = vkGetFenceStatus(m_logicalDevice, m_cmd_buffer_fences[m_commandBufferSyncIndex]); VkResult fenceStatus = vkGetFenceStatus(m_logicalDevice, m_cmd_buffer_fences[m_commandBufferSyncIndex]);
if (fenceStatus == VK_SUCCESS) if (fenceStatus == VK_SUCCESS)
{ {
ProcessDestructionQueues(m_commandBufferSyncIndex); ProcessDestructionQueue();
m_commandBufferSyncIndex = (m_commandBufferSyncIndex + 1) % m_commandBuffers.size(); m_commandBufferSyncIndex = (m_commandBufferSyncIndex + 1) % m_commandBuffers.size();
memoryManager->cleanupBuffers(m_countCommandBufferFinished); memoryManager->cleanupBuffers(m_countCommandBufferFinished);
m_countCommandBufferFinished++; m_countCommandBufferFinished++;
@ -3035,48 +2997,7 @@ TextureDecoder* VulkanRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT
return texFormatInfo.decoder; return texFormatInfo.decoder;
} }
void VulkanRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTexture) void VulkanRenderer::ReleaseDestructibleObject(VKRDestructibleObject* destructibleObject)
{
LatteTextureVk* vkTexture = (LatteTextureVk*)hostTexture;
auto allocationInfo = memoryManager->imageMemoryAllocate(vkTexture->GetImageObj()->m_image);
vkTexture->setAllocation(allocationInfo);
}
void VulkanRenderer::texture_destroy(LatteTexture* hostTexture)
{
LatteTextureVk* texVk = (LatteTextureVk*)hostTexture;
delete texVk;
}
void VulkanRenderer::destroyViewDepr(VkImageView imageView)
{
cemu_assert_debug(false);
m_destructionQueues.m_cmd_image_views[m_commandBufferIndex].emplace_back(imageView);
}
void VulkanRenderer::destroyBuffer(VkBuffer buffer)
{
m_destructionQueues.m_buffers[m_commandBufferIndex].emplace_back(buffer);
}
void VulkanRenderer::destroyDeviceMemory(VkDeviceMemory mem)
{
m_destructionQueues.m_memory[m_commandBufferIndex].emplace_back(mem);
}
void VulkanRenderer::destroyPipelineInfo(PipelineInfo* pipelineInfo)
{
cemu_assert_debug(false);
}
void VulkanRenderer::destroyShader(RendererShaderVk* shader)
{
while (!shader->list_pipelineInfo.empty())
delete shader->list_pipelineInfo[0];
}
void VulkanRenderer::releaseDestructibleObject(VKRDestructibleObject* destructibleObject)
{ {
// destroy immediately if possible // destroy immediately if possible
if (destructibleObject->canDestroy()) if (destructibleObject->canDestroy())
@ -3090,7 +3011,7 @@ void VulkanRenderer::releaseDestructibleObject(VKRDestructibleObject* destructib
m_spinlockDestructionQueue.unlock(); m_spinlockDestructionQueue.unlock();
} }
void VulkanRenderer::ProcessDestructionQueue2() void VulkanRenderer::ProcessDestructionQueue()
{ {
m_spinlockDestructionQueue.lock(); m_spinlockDestructionQueue.lock();
for (auto it = m_destructionQueue.begin(); it != m_destructionQueue.end();) for (auto it = m_destructionQueue.begin(); it != m_destructionQueue.end();)
@ -3139,7 +3060,7 @@ VkDescriptorSetInfo::~VkDescriptorSetInfo()
performanceMonitor.vk.numDescriptorDynUniformBuffers.decrement(statsNumDynUniformBuffers); performanceMonitor.vk.numDescriptorDynUniformBuffers.decrement(statsNumDynUniformBuffers);
performanceMonitor.vk.numDescriptorStorageBuffers.decrement(statsNumStorageBuffers); performanceMonitor.vk.numDescriptorStorageBuffers.decrement(statsNumStorageBuffers);
VulkanRenderer::GetInstance()->releaseDestructibleObject(m_vkObjDescriptorSet); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_vkObjDescriptorSet);
m_vkObjDescriptorSet = nullptr; m_vkObjDescriptorSet = nullptr;
} }

View File

@ -231,7 +231,6 @@ public:
void DrawEmptyFrame(bool mainWindow) override; void DrawEmptyFrame(bool mainWindow) override;
void PreparePresentationFrame(bool mainWindow); void PreparePresentationFrame(bool mainWindow);
void ProcessDestructionQueues(size_t commandBufferIndex);
void InitFirstCommandBuffer(); void InitFirstCommandBuffer();
void ProcessFinishedCommandBuffers(); void ProcessFinishedCommandBuffers();
void WaitForNextFinishedCommandBuffer(); void WaitForNextFinishedCommandBuffer();
@ -244,15 +243,9 @@ public:
bool HasCommandBufferFinished(uint64 commandBufferId) const; bool HasCommandBufferFinished(uint64 commandBufferId) const;
void WaitCommandBufferFinished(uint64 commandBufferId); void WaitCommandBufferFinished(uint64 commandBufferId);
// clean up (deprecated) // resource destruction queue
void destroyViewDepr(VkImageView imageView); void ReleaseDestructibleObject(VKRDestructibleObject* destructibleObject);
void destroyBuffer(VkBuffer buffer); void ProcessDestructionQueue();
void destroyDeviceMemory(VkDeviceMemory mem);
void destroyPipelineInfo(PipelineInfo* pipelineInfo);
void destroyShader(RendererShaderVk* shader);
// clean up (new)
void releaseDestructibleObject(VKRDestructibleObject* destructibleObject);
void ProcessDestructionQueue2();
FSpinlock m_spinlockDestructionQueue; FSpinlock m_spinlockDestructionQueue;
std::vector<VKRDestructibleObject*> m_destructionQueue; std::vector<VKRDestructibleObject*> m_destructionQueue;
@ -290,9 +283,6 @@ public:
TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) override; TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) override;
void texture_reserveTextureOnGPU(LatteTexture* hostTexture) override;
void texture_destroy(LatteTexture* hostTexture) override;
void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) override; void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) override;
void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override; void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override;
void texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) override; void texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) override;
@ -634,15 +624,6 @@ private:
// command buffer, garbage collection, synchronization // command buffer, garbage collection, synchronization
static constexpr uint32 kCommandBufferPoolSize = 128; static constexpr uint32 kCommandBufferPoolSize = 128;
struct
{
std::array<std::vector<VkDescriptorSet>, kCommandBufferPoolSize> m_cmd_descriptor_set_objects;
std::array<std::vector<VkImageView>, kCommandBufferPoolSize> m_cmd_image_views;
std::array<std::vector<LatteTextureVk*>, kCommandBufferPoolSize> m_host_textures;
std::array<std::vector<VkBuffer>, kCommandBufferPoolSize> m_buffers;
std::array<std::vector<VkDeviceMemory>, kCommandBufferPoolSize> m_memory;
}m_destructionQueues;
size_t m_commandBufferIndex = 0; // current buffer being filled size_t m_commandBufferIndex = 0; // current buffer being filled
size_t m_commandBufferSyncIndex = 0; // latest buffer that finished execution (updated on submit) size_t m_commandBufferSyncIndex = 0; // latest buffer that finished execution (updated on submit)
std::array<VkFence, kCommandBufferPoolSize> m_cmd_buffer_fences; std::array<VkFence, kCommandBufferPoolSize> m_cmd_buffer_fences;

View File

@ -813,9 +813,9 @@ void VulkanRenderer::surfaceCopy_notifyTextureRelease(LatteTextureVk* hostTextur
{ {
if (p) if (p)
{ {
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjDescriptorSet); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjDescriptorSet);
p->vkObjDescriptorSet = nullptr; p->vkObjDescriptorSet = nullptr;
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjImageView); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjImageView);
p->vkObjImageView = nullptr; p->vkObjImageView = nullptr;
} }
} }
@ -829,9 +829,9 @@ void VulkanRenderer::surfaceCopy_notifyTextureRelease(LatteTextureVk* hostTextur
{ {
if (p) if (p)
{ {
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjFramebuffer); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjFramebuffer);
p->vkObjFramebuffer = nullptr; p->vkObjFramebuffer = nullptr;
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjImageView); VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjImageView);
p->vkObjImageView = nullptr; p->vkObjImageView = nullptr;
} }
} }

View File

@ -245,18 +245,13 @@ static void check_vk_result(VkResult err)
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage) static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
{ {
VulkanRenderer* vkRenderer = VulkanRenderer::GetInstance();
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
vkDeviceWaitIdle(v->Device); // make sure previously created buffer is not in use anymore
VkResult err; VkResult err;
if (buffer != VK_NULL_HANDLE) if (buffer != VK_NULL_HANDLE)
{ vkDestroyBuffer(v->Device, buffer, v->Allocator);
vkRenderer->destroyBuffer(buffer);
}
if (buffer_memory != VK_NULL_HANDLE) if (buffer_memory != VK_NULL_HANDLE)
{ vkFreeMemory(v->Device, buffer_memory, v->Allocator);
vkRenderer->destroyDeviceMemory(buffer_memory);
}
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment; VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {}; VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;