Skip to content

Commit

Permalink
Latte: Simplify and fix texture copy
Browse files Browse the repository at this point in the history
  • Loading branch information
Exzap committed Dec 10, 2023
1 parent f6bb666 commit 9398c0c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 25 deletions.
26 changes: 3 additions & 23 deletions src/Cafe/HW/Latte/Core/LatteSurfaceCopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ void LatteSurfaceCopy_copySurfaceNew(MPTR srcPhysAddr, MPTR srcMipAddr, uint32 s
// mark source and destination texture as still in use
LatteTC_MarkTextureStillInUse(destinationTexture);
LatteTC_MarkTextureStillInUse(sourceTexture);
// determine GL slice indices
sint32 realSrcSlice = srcSlice;
sint32 realDstSlice = dstSlice;
if (LatteTexture_doesEffectiveRescaleRatioMatch(sourceTexture, sourceView->firstMip, destinationTexture, destinationView->firstMip))
{
// adjust copy size
Expand All @@ -62,29 +60,11 @@ void LatteSurfaceCopy_copySurfaceNew(MPTR srcPhysAddr, MPTR srcMipAddr, uint32 s
LatteTexture_scaleToEffectiveSize(sourceTexture, &effectiveCopyWidth, &effectiveCopyHeight, 0);
// copy slice
if (sourceView->baseTexture->isDepth != destinationView->baseTexture->isDepth)
{
g_renderer->surfaceCopy_copySurfaceWithFormatConversion(sourceTexture, sourceView->firstMip, sourceView->firstSlice, destinationTexture, destinationView->firstMip, destinationView->firstSlice, copyWidth, copyHeight);
uint64 eventCounter = LatteTexture_getNextUpdateEventCounter();
LatteTexture_MarkDynamicTextureAsChanged(destinationTexture->baseView, destinationView->firstSlice, destinationView->firstMip, eventCounter);
}
else
{
// calculate mip levels relative to texture base
sint32 texDstMipLevel;
if (destinationTexture->physAddress == dstPhysAddr)
{
texDstMipLevel = dstLevel;
}
else
{
// todo - handle mip addresses properly
texDstMipLevel = dstLevel - destinationView->firstMip;
}

g_renderer->texture_copyImageSubData(sourceTexture, sourceView->firstMip, 0, 0, realSrcSlice, destinationTexture, texDstMipLevel, 0, 0, realDstSlice, effectiveCopyWidth, effectiveCopyHeight, 1);
uint64 eventCounter = LatteTexture_getNextUpdateEventCounter();
LatteTexture_MarkDynamicTextureAsChanged(destinationTexture->baseView, destinationView->firstSlice, texDstMipLevel, eventCounter);
}
g_renderer->texture_copyImageSubData(sourceTexture, sourceView->firstMip, 0, 0, realSrcSlice, destinationTexture, destinationView->firstMip, 0, 0, destinationView->firstSlice, effectiveCopyWidth, effectiveCopyHeight, 1);
const uint64 eventCounter = LatteTexture_getNextUpdateEventCounter();
LatteTexture_MarkDynamicTextureAsChanged(destinationTexture->baseView, destinationView->firstSlice, destinationView->firstMip, eventCounter);
}
else
{
Expand Down
18 changes: 16 additions & 2 deletions src/Cafe/HW/Latte/Core/LatteTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,11 @@ bool IsDimensionCompatibleForView(Latte::E_DIM baseDim, Latte::E_DIM viewDim)
// not compatible
incompatibleDim = true;
}
else if (baseDim == Latte::E_DIM::DIM_3D && viewDim == Latte::E_DIM::DIM_3D)
{
// incompatible by default, but may be compatible if the view matches the depth of the base texture and starts at mip/slice 0
incompatibleDim = true;
}
else if ((baseDim == Latte::E_DIM::DIM_2D && viewDim == Latte::E_DIM::DIM_CUBEMAP) ||
(baseDim == Latte::E_DIM::DIM_CUBEMAP && viewDim == Latte::E_DIM::DIM_2D))
{
Expand Down Expand Up @@ -872,7 +877,9 @@ VIEWCOMPATIBILITY LatteTexture_CanTextureBeRepresentedAsView(LatteTexture* baseT
return VIEW_NOT_COMPATIBLE; // depth and non-depth formats are never compatible (on OpenGL)
if (!LatteTexture_IsTexelSizeCompatibleFormat(baseTexture->format, format) || baseTexture->width != width || baseTexture->height != height)
return VIEW_NOT_COMPATIBLE;
if (!IsDimensionCompatibleForView(baseTexture->dim, dimView))
// 3D views are only compatible on Vulkan if they match the base texture in regards to mip and slice count
bool isCompatible3DView = dimView == Latte::E_DIM::DIM_3D && baseTexture->dim == dimView && firstSlice == 0 && firstMip == 0 && baseTexture->mipLevels == numMip && baseTexture->depth == numSlice;
if (!isCompatible3DView && !IsDimensionCompatibleForView(baseTexture->dim, dimView))
return VIEW_NOT_COMPATIBLE;
if (baseTexture->isDepth && baseTexture->format != format)
{
Expand Down Expand Up @@ -999,6 +1006,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
// 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)
{
if (format == Latte::E_GX2SURFFMT::INVALID_FORMAT)
Expand Down Expand Up @@ -1105,11 +1113,17 @@ LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, si
if (allowCreateNewDataTexture == false)
return nullptr;
LatteTextureView* view = LatteTexture_CreateTexture(0, dimBase, physAddr, physMipAddr, format, width, height, depth, pitch, firstMip + numMip, swizzle, tileMode, isDepth);
LatteTexture* newTexture = view->baseTexture;
LatteTexture_GatherTextureRelations(view->baseTexture);
LatteTexture_UpdateTextureFromDynamicChanges(view->baseTexture);
// delete any individual smaller slices/mips that have become redundant
LatteTexture_DeleteAbsorbedSubtextures(view->baseTexture);
return view;
// create view
sint32 relativeMipIndex;
sint32 relativeSliceIndex;
VIEWCOMPATIBILITY viewCompatibility = LatteTexture_CanTextureBeRepresentedAsView(newTexture, physAddr, width, height, pitch, dimView, format, isDepth, firstMip, numMip, firstSlice, numSlice, relativeMipIndex, relativeSliceIndex);
cemu_assert(viewCompatibility == VIEW_COMPATIBLE);
return view->baseTexture->GetOrCreateView(dimView, format, relativeMipIndex + firstMip, numMip, relativeSliceIndex + firstSlice, numSlice);
}

LatteTextureView* LatteTC_LookupTextureByData(MPTR physAddr, sint32 width, sint32 height, sint32 pitch, sint32 firstMip, sint32 numMip, sint32 firstSlice, sint32 numSlice, sint32* searchIndex)
Expand Down

0 comments on commit 9398c0c

Please sign in to comment.