mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-07 23:41:18 +12:00
Add all the files
This commit is contained in:
parent
e3db07a16a
commit
d60742f52b
1445 changed files with 430238 additions and 0 deletions
244
src/Cafe/HW/Latte/Core/LatteTextureView.cpp
Normal file
244
src/Cafe/HW/Latte/Core/LatteTextureView.cpp
Normal file
|
@ -0,0 +1,244 @@
|
|||
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteTextureView.h"
|
||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
|
||||
LatteTextureView::LatteTextureView(LatteTexture* texture, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount, Latte::E_DIM dim, Latte::E_GX2SURFFMT format, bool registerView)
|
||||
{
|
||||
this->baseTexture = texture;
|
||||
this->firstMip = firstMip;
|
||||
this->numMip = mipCount;
|
||||
this->firstSlice = firstSlice;
|
||||
this->numSlice = sliceCount;
|
||||
this->dim = dim;
|
||||
this->format = format;
|
||||
if (registerView)
|
||||
{
|
||||
texture->views.emplace_back(this);
|
||||
LatteTextureViewLookupCache::Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
LatteTextureView::~LatteTextureView()
|
||||
{
|
||||
// unregister view
|
||||
LatteTextureViewLookupCache::RemoveAll(this);
|
||||
// remove from texture
|
||||
vectorRemoveByValue(baseTexture->views, this);
|
||||
if (baseTexture->baseView == this)
|
||||
baseTexture->baseView = nullptr;
|
||||
// delete all associated FBOs
|
||||
while (!list_associatedFbo.empty())
|
||||
LatteMRT::DeleteCachedFBO(list_associatedFbo[0]);
|
||||
}
|
||||
|
||||
void LatteTextureView::CreateLookupForSubTexture(uint32 mipStart, uint32 sliceStart)
|
||||
{
|
||||
cemu_assert_debug(mipStart != 0 || sliceStart != 0); // This function should never be called with both parameters zero. Every view creates a base lookup on construction
|
||||
LatteTextureViewLookupCache::Add(this, mipStart, sliceStart);
|
||||
}
|
||||
|
||||
/* View lookup cache */
|
||||
|
||||
struct LatteTexViewLookupDesc
|
||||
{
|
||||
LatteTexViewLookupDesc(LatteTextureView* view) : view(view)
|
||||
{
|
||||
this->physAddr = view->baseTexture->physAddress;
|
||||
this->physMipAddr = view->baseTexture->physMipAddress;
|
||||
this->width = view->baseTexture->width;
|
||||
this->height = view->baseTexture->height;
|
||||
this->pitch = view->baseTexture->pitch;
|
||||
this->firstMip = view->firstMip;
|
||||
this->numMip = view->numMip;
|
||||
this->firstSlice = view->firstSlice;
|
||||
this->numSlice = view->numSlice;
|
||||
this->format = view->format;
|
||||
this->dim = view->dim;
|
||||
this->isDepth = view->baseTexture->isDepth;
|
||||
}
|
||||
|
||||
void SetParametersForSubTexture(sint32 baseMip, sint32 baseSlice)
|
||||
{
|
||||
cemu_assert_debug(baseMip >= 0);
|
||||
cemu_assert_debug(baseSlice >= 0);
|
||||
LatteTextureSliceMipInfo* sliceMipInfo = view->baseTexture->GetSliceMipArrayEntry(baseSlice, baseMip);
|
||||
physAddr = sliceMipInfo->addrStart;
|
||||
pitch = sliceMipInfo->pitch;
|
||||
cemu_assert_debug(format == view->baseTexture->format); // if the format is different then width/height calculation might differ. This only affects the case where an integer format is mapped onto a compressed format or vice versa.
|
||||
width = view->baseTexture->GetMipWidth(baseMip);
|
||||
height = view->baseTexture->GetMipHeight(baseMip);
|
||||
// adjust firstMip and firstSlice to be relative to base of subtexture
|
||||
cemu_assert(firstMip >= baseMip);
|
||||
cemu_assert(firstSlice >= baseSlice);
|
||||
firstMip -= baseMip;
|
||||
firstSlice -= baseSlice;
|
||||
}
|
||||
|
||||
// key data for looking up views
|
||||
MPTR physAddr;
|
||||
MPTR physMipAddr;
|
||||
sint32 width;
|
||||
sint32 height;
|
||||
sint32 pitch;
|
||||
sint32 firstMip;
|
||||
sint32 numMip;
|
||||
sint32 firstSlice;
|
||||
sint32 numSlice;
|
||||
Latte::E_GX2SURFFMT format;
|
||||
Latte::E_DIM dim;
|
||||
bool isDepth;
|
||||
// associated view
|
||||
LatteTextureView* view;
|
||||
};
|
||||
|
||||
struct LatteTexViewBucket
|
||||
{
|
||||
std::vector<LatteTexViewLookupDesc> list;
|
||||
};
|
||||
|
||||
#define TEXTURE_VIEW_BUCKETS (1061)
|
||||
|
||||
inline uint32 _getViewBucketKey(MPTR physAddress, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
return (physAddress + width * 7 + height * 11 + pitch * 13) % TEXTURE_VIEW_BUCKETS;
|
||||
}
|
||||
|
||||
inline uint32 _getViewBucketKeyNoRes(MPTR physAddress, uint32 pitch)
|
||||
{
|
||||
return (physAddress + pitch * 13) % TEXTURE_VIEW_BUCKETS;
|
||||
}
|
||||
|
||||
LatteTexViewBucket texViewBucket[TEXTURE_VIEW_BUCKETS] = { };
|
||||
LatteTexViewBucket texViewBucket_nores[TEXTURE_VIEW_BUCKETS] = { };
|
||||
|
||||
void LatteTextureViewLookupCache::Add(LatteTextureView* view, uint32 baseMip, uint32 baseSlice)
|
||||
{
|
||||
LatteTexViewLookupDesc desc(view);
|
||||
if (baseMip != 0 || baseSlice != 0)
|
||||
desc.SetParametersForSubTexture(baseMip, baseSlice);
|
||||
// generic bucket
|
||||
uint32 key = _getViewBucketKey(desc.physAddr, desc.width, desc.height, desc.pitch);
|
||||
texViewBucket[key].list.emplace_back(desc);
|
||||
vectorAppendUnique(view->viewLookUpCacheKeys, key);
|
||||
// resolution-independent bucket
|
||||
key = _getViewBucketKeyNoRes(desc.physAddr, desc.pitch);
|
||||
texViewBucket_nores[key].list.push_back(desc);
|
||||
vectorAppendUnique(view->viewLookUpCacheKeysNoRes, key);
|
||||
}
|
||||
|
||||
void LatteTextureViewLookupCache::RemoveAll(LatteTextureView* view)
|
||||
{
|
||||
for (auto& key : view->viewLookUpCacheKeys)
|
||||
{
|
||||
auto& bucket = texViewBucket[key].list;
|
||||
bucket.erase(std::remove_if(bucket.begin(), bucket.end(), [view](const LatteTexViewLookupDesc& v) {
|
||||
return v.view == view; }), bucket.end());
|
||||
}
|
||||
for (auto& key : view->viewLookUpCacheKeysNoRes)
|
||||
{
|
||||
auto& bucket = texViewBucket_nores[key].list;
|
||||
bucket.erase(std::remove_if(bucket.begin(), bucket.end(), [view](const LatteTexViewLookupDesc& v) {
|
||||
return v.view == view; }), bucket.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LatteTextureView* LatteTextureViewLookupCache::lookup(MPTR physAddr, sint32 width, sint32 height, sint32 depth, sint32 pitch, sint32 firstMip, sint32 numMip, sint32 firstSlice, sint32 numSlice, Latte::E_GX2SURFFMT format, Latte::E_DIM dim)
|
||||
{
|
||||
// todo - add tileMode param to this and the other lookup functions?
|
||||
uint32 key = _getViewBucketKey(physAddr, width, height, pitch);
|
||||
key %= TEXTURE_VIEW_BUCKETS;
|
||||
for (auto& it : texViewBucket[key].list)
|
||||
{
|
||||
if (it.format == format && it.dim == dim &&
|
||||
it.width == width && it.height == height && it.pitch == pitch && it.physAddr == physAddr
|
||||
&& it.firstMip == firstMip && it.numMip == numMip
|
||||
&& it.firstSlice == firstSlice && it.numSlice == numSlice
|
||||
)
|
||||
{
|
||||
return it.view;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LatteTextureView* LatteTextureViewLookupCache::lookup(MPTR physAddr, sint32 width, sint32 height, sint32 depth, sint32 pitch, sint32 firstMip, sint32 numMip, sint32 firstSlice, sint32 numSlice, Latte::E_GX2SURFFMT format, Latte::E_DIM dim, bool isDepth)
|
||||
{
|
||||
cemu_assert_debug(firstSlice == 0);
|
||||
uint32 key = _getViewBucketKey(physAddr, width, height, pitch);
|
||||
key %= TEXTURE_VIEW_BUCKETS;
|
||||
for (auto& it : texViewBucket[key].list)
|
||||
{
|
||||
if (it.format == format && it.dim == dim && it.width == width && it.height == height && it.pitch == pitch && it.physAddr == physAddr
|
||||
&& it.firstMip == firstMip && it.numMip == numMip
|
||||
&& it.firstSlice == firstSlice && it.numSlice == numSlice &&
|
||||
it.isDepth == isDepth
|
||||
)
|
||||
{
|
||||
return it.view;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// look up view with unspecified mipCount and sliceCount
|
||||
LatteTextureView* LatteTextureViewLookupCache::lookupSlice(MPTR physAddr, sint32 width, sint32 height, sint32 pitch, sint32 firstMip, sint32 firstSlice, Latte::E_GX2SURFFMT format)
|
||||
{
|
||||
uint32 key = _getViewBucketKey(physAddr, width, height, pitch);
|
||||
key %= TEXTURE_VIEW_BUCKETS;
|
||||
for (auto& it : texViewBucket[key].list)
|
||||
{
|
||||
if (it.width == width && it.height == height && it.pitch == pitch && it.physAddr == physAddr && it.format == format)
|
||||
{
|
||||
if (firstSlice == it.firstSlice && firstMip == it.firstMip)
|
||||
return it.view;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// look up view with unspecified mipCount/sliceCount and only minimum width and height given
|
||||
LatteTextureView* LatteTextureViewLookupCache::lookupSliceMinSize(MPTR physAddr, sint32 minWidth, sint32 minHeight, sint32 pitch, sint32 firstMip, sint32 firstSlice, Latte::E_GX2SURFFMT format)
|
||||
{
|
||||
uint32 key = _getViewBucketKeyNoRes(physAddr, pitch);
|
||||
key %= TEXTURE_VIEW_BUCKETS;
|
||||
for (auto& it : texViewBucket_nores[key].list)
|
||||
{
|
||||
if (it.width >= minWidth && it.height >= minHeight && it.pitch == pitch && it.physAddr == physAddr && it.format == format)
|
||||
{
|
||||
if (firstSlice == it.firstSlice && firstMip == it.firstMip)
|
||||
return it.view;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// similar to lookupSlice but also compares isDepth
|
||||
LatteTextureView* LatteTextureViewLookupCache::lookupSliceEx(MPTR physAddr, sint32 width, sint32 height, sint32 pitch, sint32 firstMip, sint32 firstSlice, Latte::E_GX2SURFFMT format, bool isDepth)
|
||||
{
|
||||
cemu_assert_debug(firstMip == 0);
|
||||
uint32 key = _getViewBucketKey(physAddr, width, height, pitch);
|
||||
key %= TEXTURE_VIEW_BUCKETS;
|
||||
for (auto& it : texViewBucket[key].list)
|
||||
{
|
||||
if (it.width == width && it.height == height && it.pitch == pitch && it.physAddr == physAddr && it.format == format && it.isDepth == isDepth)
|
||||
{
|
||||
if (firstSlice == it.firstSlice && firstMip == it.firstMip)
|
||||
return it.view;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unordered_set<LatteTextureView*> LatteTextureViewLookupCache::GetAllViews()
|
||||
{
|
||||
std::unordered_set<LatteTextureView*> viewSet;
|
||||
for (uint32 i = 0; i < TEXTURE_VIEW_BUCKETS; i++)
|
||||
{
|
||||
for (auto& it : texViewBucket[i].list)
|
||||
viewSet.emplace(it.view);
|
||||
}
|
||||
return viewSet;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue