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_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_unloadAll();

View File

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

View File

@ -221,35 +221,9 @@ void LatteMRT::BindDepthBufferOnly(LatteTextureView* view)
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* textureView;
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);
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);
LatteMRT::SetDepthAndStencilAttachment(textureView, textureView->baseTexture->hasStencil);
return textureView;
}
@ -605,7 +579,7 @@ bool LatteMRT::UpdateCurrentFBO()
if (depthBufferPhysMem != MPTR_NULL)
{
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
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);
}
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 colorBufferMipIndex = 0; // todo
@ -803,13 +780,11 @@ void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorB
bool targetFound = false;
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)
break;
if (Latte::GetFormatBits((Latte::E_GX2SURFFMT)colorBufferFormat) != Latte::GetFormatBits(colorView->baseTexture->format))
{
if (Latte::GetFormatBits(colorBufferFormat) != Latte::GetFormatBits(colorView->baseTexture->format))
continue;
}
if (colorView->baseTexture->pitch == colorBufferPitch && colorView->baseTexture->height == colorBufferHeight)
targetFound = true;
@ -821,7 +796,7 @@ void LatteRenderTarget_itHLEClearColorDepthStencil(uint32 clearMask, MPTR colorB
{
// create new texture with matching format
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);
}
}

View File

@ -1199,6 +1199,15 @@ std::vector<LatteTexture*>& LatteTexture::GetAllTextures()
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,
Latte::E_HWTILEMODE tileMode, bool isDepth)
{
@ -1217,6 +1226,7 @@ LatteTexture::LatteTexture(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddre
this->mipLevels = mipLevels;
this->tileMode = tileMode;
this->isDepth = isDepth;
this->hasStencil = LatteTexture_GX2FormatHasStencil(isDepth, format);
this->physMipAddress = physMipAddress;
this->lastUpdateEventCounter = 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);
virtual ~LatteTexture();
virtual void AllocateOnHost() = 0;
LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
{
for (auto& itr : views)

View File

@ -316,7 +316,7 @@ void LatteTexture_Delete(LatteTexture* texture)
delete[] texture->sliceMipInfo;
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)
{
g_renderer->texture_reserveTextureOnGPU(tex);
tex->AllocateOnHost();
tex->isDataDefined = true;
// if decoder is not set then clear texture
// 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"
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,
Latte::E_HWTILEMODE tileMode, bool 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);
this->glInternalFormat = glFormatInfo.glInternalFormat;
this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat;
this->hasStencil = glFormatInfo.hasStencil; // todo - should get this from the GX2 format?
// set debug name
bool useGLDebugNames = false;
#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)
{
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;
}
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();
return;
}
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;
}
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;
}
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;
}
// unsupported depth format
cemuLog_log(LogType::Force, "OpenGL: Unsupported texture depth format 0x{:04x}", (uint32)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();
return;
}
@ -496,3 +481,49 @@ void LatteTextureGL::GetOpenGLFormatInfo(bool isDepth, Latte::E_GX2SURFFMT forma
formatInfoOut->glIsCompressed = glIsCompressed;
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();
void AllocateOnHost() override;
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType);
protected:
@ -23,7 +25,6 @@ public:
sint32 glSuppliedFormat;
sint32 glSuppliedFormatType;
bool glIsCompressed;
bool hasStencil{};
bool isUsingAlternativeFormat{};
void setFormat(sint32 glInternalFormat, sint32 glSuppliedFormat, sint32 glSuppliedFormatType)
@ -34,15 +35,6 @@ public:
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)
{
setFormat(glInternalFormat, glSuppliedFormat, glSuppliedFormatType);

View File

@ -1002,57 +1002,6 @@ TextureDecoder* OpenGLRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT
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
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);
// texture functions
void texture_destroy(LatteTexture* hostTexture) override;
void* texture_acquireTextureUploadBuffer(uint32 size) 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;
void texture_reserveTextureOnGPU(LatteTexture* hostTexture) 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_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;
// texture functions
virtual void texture_destroy(LatteTexture* hostTexture) = 0;
virtual void* texture_acquireTextureUploadBuffer(uint32 size) = 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 void texture_reserveTextureOnGPU(LatteTexture* hostTexture) = 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_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())
delete m_usedByPipelines[0];
auto vkr = VulkanRenderer::GetInstance();
vkr->releaseDestructibleObject(m_vkrObjFramebuffer);
vkr->ReleaseDestructibleObject(m_vkrObjFramebuffer);
m_vkrObjFramebuffer = nullptr;
vkr->releaseDestructibleObject(m_vkrObjRenderPass);
vkr->ReleaseDestructibleObject(m_vkrObjRenderPass);
m_vkrObjRenderPass = nullptr;
}

View File

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

View File

@ -46,7 +46,7 @@ LatteTextureVk::LatteTextureVk(class VulkanRenderer* vkRenderer, Latte::E_DIM di
VulkanRenderer::FormatInfoVK 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;
vkObjTex->m_imageAspect = texFormatInfo.vkImageAspect;
@ -117,7 +117,7 @@ LatteTextureVk::~LatteTextureVk()
m_vkr->surfaceCopy_notifyTextureRelease(this);
VulkanRenderer::GetInstance()->releaseDestructibleObject(vkObjTex);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(vkObjTex);
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);
}
void LatteTextureVk::setAllocation(struct VkImageMemAllocation* memAllocation)
void LatteTextureVk::AllocateOnHost()
{
vkObjTex->m_allocation = memAllocation;
}
struct VkImageMemAllocation* LatteTextureVk::getAllocation() const
{
return vkObjTex->m_allocation;
auto allocationInfo = VulkanRenderer::GetInstance()->GetMemoryManager()->imageMemoryAllocate(GetImageObj()->m_image);
vkObjTex->m_allocation = allocationInfo;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1803,44 +1803,6 @@ void VulkanRenderer::PreparePresentationFrame(bool 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()
{
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]);
if (fenceStatus == VK_SUCCESS)
{
ProcessDestructionQueues(m_commandBufferSyncIndex);
ProcessDestructionQueue();
m_commandBufferSyncIndex = (m_commandBufferSyncIndex + 1) % m_commandBuffers.size();
memoryManager->cleanupBuffers(m_countCommandBufferFinished);
m_countCommandBufferFinished++;
@ -3035,48 +2997,7 @@ TextureDecoder* VulkanRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT
return texFormatInfo.decoder;
}
void VulkanRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTexture)
{
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)
void VulkanRenderer::ReleaseDestructibleObject(VKRDestructibleObject* destructibleObject)
{
// destroy immediately if possible
if (destructibleObject->canDestroy())
@ -3090,7 +3011,7 @@ void VulkanRenderer::releaseDestructibleObject(VKRDestructibleObject* destructib
m_spinlockDestructionQueue.unlock();
}
void VulkanRenderer::ProcessDestructionQueue2()
void VulkanRenderer::ProcessDestructionQueue()
{
m_spinlockDestructionQueue.lock();
for (auto it = m_destructionQueue.begin(); it != m_destructionQueue.end();)
@ -3139,7 +3060,7 @@ VkDescriptorSetInfo::~VkDescriptorSetInfo()
performanceMonitor.vk.numDescriptorDynUniformBuffers.decrement(statsNumDynUniformBuffers);
performanceMonitor.vk.numDescriptorStorageBuffers.decrement(statsNumStorageBuffers);
VulkanRenderer::GetInstance()->releaseDestructibleObject(m_vkObjDescriptorSet);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_vkObjDescriptorSet);
m_vkObjDescriptorSet = nullptr;
}

View File

@ -231,7 +231,6 @@ public:
void DrawEmptyFrame(bool mainWindow) override;
void PreparePresentationFrame(bool mainWindow);
void ProcessDestructionQueues(size_t commandBufferIndex);
void InitFirstCommandBuffer();
void ProcessFinishedCommandBuffers();
void WaitForNextFinishedCommandBuffer();
@ -244,15 +243,9 @@ public:
bool HasCommandBufferFinished(uint64 commandBufferId) const;
void WaitCommandBufferFinished(uint64 commandBufferId);
// clean up (deprecated)
void destroyViewDepr(VkImageView imageView);
void destroyBuffer(VkBuffer buffer);
void destroyDeviceMemory(VkDeviceMemory mem);
void destroyPipelineInfo(PipelineInfo* pipelineInfo);
void destroyShader(RendererShaderVk* shader);
// clean up (new)
void releaseDestructibleObject(VKRDestructibleObject* destructibleObject);
void ProcessDestructionQueue2();
// resource destruction queue
void ReleaseDestructibleObject(VKRDestructibleObject* destructibleObject);
void ProcessDestructionQueue();
FSpinlock m_spinlockDestructionQueue;
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;
void texture_reserveTextureOnGPU(LatteTexture* hostTexture) override;
void texture_destroy(LatteTexture* hostTexture) 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_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
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_commandBufferSyncIndex = 0; // latest buffer that finished execution (updated on submit)
std::array<VkFence, kCommandBufferPoolSize> m_cmd_buffer_fences;

View File

@ -813,9 +813,9 @@ void VulkanRenderer::surfaceCopy_notifyTextureRelease(LatteTextureVk* hostTextur
{
if (p)
{
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjDescriptorSet);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjDescriptorSet);
p->vkObjDescriptorSet = nullptr;
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjImageView);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjImageView);
p->vkObjImageView = nullptr;
}
}
@ -829,9 +829,9 @@ void VulkanRenderer::surfaceCopy_notifyTextureRelease(LatteTextureVk* hostTextur
{
if (p)
{
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjFramebuffer);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjFramebuffer);
p->vkObjFramebuffer = nullptr;
VulkanRenderer::GetInstance()->releaseDestructibleObject(p->vkObjImageView);
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(p->vkObjImageView);
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)
{
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;
if (buffer != VK_NULL_HANDLE)
{
vkRenderer->destroyBuffer(buffer);
}
vkDestroyBuffer(v->Device, buffer, v->Allocator);
if (buffer_memory != VK_NULL_HANDLE)
{
vkRenderer->destroyDeviceMemory(buffer_memory);
}
vkFreeMemory(v->Device, buffer_memory, v->Allocator);
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment;
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;