mirror of https://github.com/AxioDL/metaforce.git
Async resource build fixes
This commit is contained in:
parent
bc6ba1141d
commit
9fcce94a7a
|
@ -436,6 +436,46 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
|
|||
}
|
||||
lk.unlock();
|
||||
|
||||
auto asyncSearch = m_asyncLoadList.find(tag);
|
||||
if (asyncSearch != m_asyncLoadList.end())
|
||||
{
|
||||
/* Async spinloop */
|
||||
AsyncTask& task = asyncSearch->second;
|
||||
task.EnsurePath(task.x0_tag, search->second);
|
||||
|
||||
/* Pump load pipeline (cooking if needed) */
|
||||
while (!task.AsyncPump()) {std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
||||
|
||||
if (task.m_complete)
|
||||
{
|
||||
/* Load complete, build resource */
|
||||
std::unique_ptr<IObj> newObj;
|
||||
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
||||
{
|
||||
newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer),
|
||||
task.x14_resSize, false, task.x18_cvXfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
||||
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
|
||||
}
|
||||
|
||||
*task.xc_targetPtr = newObj.get();
|
||||
Log.report(logvisor::Warning, "spin-built %.4s %08X",
|
||||
task.x0_tag.type.toString().c_str(),
|
||||
u32(task.x0_tag.id));
|
||||
m_asyncLoadList.erase(asyncSearch);
|
||||
return newObj;
|
||||
}
|
||||
Log.report(logvisor::Error, "unable to spin-build %.4s %08X",
|
||||
task.x0_tag.type.toString().c_str(),
|
||||
u32(task.x0_tag.id));
|
||||
m_asyncLoadList.erase(asyncSearch);
|
||||
return {};
|
||||
}
|
||||
|
||||
/* Fall-back to sync build */
|
||||
return BuildSync(tag, search->second, paramXfer);
|
||||
}
|
||||
|
||||
|
@ -545,8 +585,22 @@ void ProjectResourceFactoryBase::AsyncIdle()
|
|||
if (task.m_complete)
|
||||
{
|
||||
/* Load complete, build resource */
|
||||
std::unique_ptr<IObj> newObj;
|
||||
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
||||
{
|
||||
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
|
||||
task.x14_resSize, false, task.x18_cvXfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
||||
*task.xc_targetPtr = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer).release();
|
||||
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
|
||||
}
|
||||
|
||||
*task.xc_targetPtr = newObj.release();
|
||||
Log.report(logvisor::Info, "async-built %.4s %08X",
|
||||
task.x0_tag.type.toString().c_str(),
|
||||
u32(task.x0_tag.id));
|
||||
}
|
||||
it = m_asyncLoadList.erase(it);
|
||||
continue;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace urde
|
|||
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc)
|
||||
: ProjectResourceFactoryBase(clientProc)
|
||||
{
|
||||
m_factoryMgr.AddFactory(FOURCC('TXTR'), FFactoryFunc(FTextureFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('TXTR'), FMemFactoryFunc(FTextureFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('PART'), FFactoryFunc(FParticleFactory));
|
||||
m_factoryMgr.AddFactory(FOURCC('FRME'), FFactoryFunc(RGuiFrameFactoryInGame));
|
||||
m_factoryMgr.AddFactory(FOURCC('FONT'), FFactoryFunc(FRasterFontFactory));
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace urde
|
|||
void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
|
||||
{
|
||||
m_modelTest = objStore.GetObj("CMDL_GameCube");
|
||||
m_modelTest.Lock();
|
||||
|
||||
//m_partGenDesc = objStore.GetObj({hecl::FOURCC('PART'), 0x972A5CD2});
|
||||
m_partGenDesc = objStore.GetObj("BusterSparks");
|
||||
|
@ -58,9 +59,16 @@ void ViewManager::ParticleView::resized(const boo::SWindowRect& root, const boo:
|
|||
|
||||
void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
||||
{
|
||||
if (m_vm.m_modelTest)
|
||||
if (m_vm.m_modelTest.IsLoaded())
|
||||
{
|
||||
CModelFlags flags;
|
||||
|
||||
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||
CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
||||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||
CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||
|
||||
m_vm.m_modelTest->Draw(flags);
|
||||
}
|
||||
if (m_vm.m_partGen)
|
||||
|
@ -70,11 +78,11 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
|||
if (m_vm.m_partGen->IsSystemDeletable())
|
||||
m_vm.m_partGen->Reset();
|
||||
|
||||
urde::CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||
urde::CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
||||
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||
CGraphics::SetViewPointMatrix(zeus::CTransform::Identity() + zeus::CVector3f(0.f, -10.f, 0.f));
|
||||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||
urde::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||
CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||
//gfxQ->clearTarget(false, true);
|
||||
m_vm.m_partGen->Render();
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ class ViewManager : public specter::IViewManager
|
|||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
std::unique_ptr<ParticleView> m_particleView;
|
||||
urde::TLockedToken<CModel> m_modelTest;
|
||||
urde::TLockedToken<CGenDescription> m_partGenDesc;
|
||||
urde::TCachedToken<CModel> m_modelTest;
|
||||
urde::TCachedToken<CGenDescription> m_partGenDesc;
|
||||
std::unique_ptr<CElementGen> m_partGen;
|
||||
std::unique_ptr<CLineRenderer> m_lineRenderer;
|
||||
std::unique_ptr<CMoviePlayer> m_moviePlayer;
|
||||
|
|
|
@ -19,16 +19,10 @@ CToken CSimplePool::GetObj(const SObjectTag& tag, const CVParamTransfer& paramXf
|
|||
|
||||
if (iter != x4_resources.end())
|
||||
return CToken(iter->second);
|
||||
// TODO: There is some logic missing here, need to figure out what it's doing
|
||||
CObjectReference* ret = new CObjectReference(*this, x30_factory.Build(tag, paramXfer), tag, paramXfer);
|
||||
if (ret->GetObject())
|
||||
{
|
||||
|
||||
CObjectReference* ret = new CObjectReference(*this, std::unique_ptr<IObj>(), tag, paramXfer);
|
||||
x4_resources.push_back(std::make_pair<SObjectTag, CObjectReference*>((SObjectTag)tag, std::move(ret)));
|
||||
return CToken(ret);
|
||||
}
|
||||
|
||||
delete ret;
|
||||
return CToken();
|
||||
}
|
||||
|
||||
CToken CSimplePool::GetObj(const SObjectTag& tag)
|
||||
|
|
|
@ -16,6 +16,7 @@ class IObjectStore;
|
|||
class CObjectReference
|
||||
{
|
||||
friend class CToken;
|
||||
friend class CSimplePool;
|
||||
u16 x0_refCount = 0;
|
||||
u16 x2_lockCount = 0;
|
||||
bool x3_loading = false; /* Rightmost bit of lockCount */
|
||||
|
@ -23,7 +24,23 @@ class CObjectReference
|
|||
IObjectStore* xC_objectStore = nullptr;
|
||||
IObj* x10_object = nullptr;
|
||||
CVParamTransfer x14_params;
|
||||
public:
|
||||
|
||||
/** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset.
|
||||
* Reaching 0 indicates the CToken should delete the CObjectReference */
|
||||
u16 RemoveReference()
|
||||
{
|
||||
--x0_refCount;
|
||||
if (x0_refCount == 0)
|
||||
{
|
||||
if (x10_object)
|
||||
Unload();
|
||||
if (IsLoading())
|
||||
CancelLoad();
|
||||
xC_objectStore->ObjectUnreferenced(x4_objTag);
|
||||
}
|
||||
return x0_refCount;
|
||||
}
|
||||
|
||||
CObjectReference(IObjectStore& objStore, std::unique_ptr<IObj>&& obj,
|
||||
const SObjectTag& objTag, CVParamTransfer buildParams)
|
||||
: x4_objTag(objTag), xC_objectStore(&objStore),
|
||||
|
@ -61,21 +78,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/** Mechanism by which CToken decrements 1st ref-count, indicating CToken invalidation or reset.
|
||||
* Reaching 0 indicates the CToken should delete the CObjectReference */
|
||||
u16 RemoveReference()
|
||||
{
|
||||
--x0_refCount;
|
||||
if (x0_refCount == 0)
|
||||
{
|
||||
if (x10_object)
|
||||
Unload();
|
||||
if (IsLoading())
|
||||
CancelLoad();
|
||||
xC_objectStore->ObjectUnreferenced(x4_objTag);
|
||||
}
|
||||
return x0_refCount;
|
||||
}
|
||||
void CancelLoad()
|
||||
{
|
||||
if (xC_objectStore && IsLoading())
|
||||
|
@ -108,6 +110,8 @@ public:
|
|||
{
|
||||
return x4_objTag;
|
||||
}
|
||||
|
||||
public:
|
||||
~CObjectReference()
|
||||
{
|
||||
if (x10_object)
|
||||
|
@ -122,8 +126,25 @@ public:
|
|||
* (default/empty constructor, move constructor/assign) */
|
||||
class CToken
|
||||
{
|
||||
friend class CSimplePool;
|
||||
CObjectReference* x0_objRef = nullptr;
|
||||
bool x4_lockHeld = false;
|
||||
|
||||
void RemoveRef()
|
||||
{
|
||||
if (x0_objRef && x0_objRef->RemoveReference() == 0)
|
||||
{
|
||||
std::default_delete<CObjectReference>()(x0_objRef);
|
||||
x0_objRef = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CToken(CObjectReference* obj)
|
||||
{
|
||||
x0_objRef = obj;
|
||||
++x0_objRef->x0_refCount;
|
||||
}
|
||||
|
||||
public:
|
||||
/* Added to test for non-null state */
|
||||
operator bool() const {return x0_objRef != nullptr;}
|
||||
|
@ -150,14 +171,6 @@ public:
|
|||
return false;
|
||||
return x0_objRef->IsLoaded();
|
||||
}
|
||||
void RemoveRef()
|
||||
{
|
||||
if (x0_objRef && x0_objRef->RemoveReference() == 0)
|
||||
{
|
||||
std::default_delete<CObjectReference>()(x0_objRef);
|
||||
x0_objRef = nullptr;
|
||||
}
|
||||
}
|
||||
IObj* GetObj()
|
||||
{
|
||||
if (!x0_objRef)
|
||||
|
@ -217,11 +230,6 @@ public:
|
|||
++x0_objRef->x0_refCount;
|
||||
Lock();
|
||||
}
|
||||
CToken(CObjectReference* obj)
|
||||
{
|
||||
x0_objRef = obj;
|
||||
++x0_objRef->x0_refCount;
|
||||
}
|
||||
const SObjectTag* GetObjectTag() const
|
||||
{
|
||||
if (!x0_objRef)
|
||||
|
|
|
@ -156,6 +156,7 @@ zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect,
|
|||
|
||||
zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix()
|
||||
{
|
||||
CProjectionState& ref = g_Proj;
|
||||
float rml = g_Proj.x8_right - g_Proj.x4_left;
|
||||
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
||||
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
||||
|
|
|
@ -117,36 +117,26 @@ void CBooModel::UnlockTextures() const
|
|||
|
||||
void CBooModel::DrawAlphaSurfaces(const CModelFlags& flags) const
|
||||
{
|
||||
if (TryLockTextures())
|
||||
{
|
||||
const CBooSurface* surf = x3c_firstSortedSurface;
|
||||
while (surf)
|
||||
{
|
||||
DrawSurface(*surf, flags);
|
||||
surf = surf->m_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::DrawNormalSurfaces(const CModelFlags& flags) const
|
||||
{
|
||||
if (TryLockTextures())
|
||||
{
|
||||
const CBooSurface* surf = x38_firstUnsortedSurface;
|
||||
while (surf)
|
||||
{
|
||||
DrawSurface(*surf, flags);
|
||||
surf = surf->m_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::DrawSurfaces(const CModelFlags& flags) const
|
||||
{
|
||||
if (!(flags.m_flags & 0x4))
|
||||
if (!TryLockTextures())
|
||||
return;
|
||||
|
||||
const CBooSurface* surf = x38_firstUnsortedSurface;
|
||||
while (surf)
|
||||
{
|
||||
|
@ -300,20 +290,29 @@ void CBooModel::UpdateUniformData() const
|
|||
|
||||
void CBooModel::DrawAlpha(const CModelFlags& flags) const
|
||||
{
|
||||
if (TryLockTextures())
|
||||
{
|
||||
UpdateUniformData();
|
||||
DrawAlphaSurfaces(flags);
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::DrawNormal(const CModelFlags& flags) const
|
||||
{
|
||||
if (TryLockTextures())
|
||||
{
|
||||
UpdateUniformData();
|
||||
DrawNormalSurfaces(flags);
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::Draw(const CModelFlags& flags) const
|
||||
{
|
||||
if (TryLockTextures())
|
||||
{
|
||||
UpdateUniformData();
|
||||
DrawSurfaces(flags);
|
||||
}
|
||||
}
|
||||
|
||||
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur)
|
||||
|
@ -378,7 +377,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
|||
{
|
||||
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
||||
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
||||
0, mat.uvAnims.size(), true, true, true);
|
||||
0, mat.uvAnims.size(), false, false, true);
|
||||
matSet.m_shaders.push_back(CGraphics::g_ShaderCacheMgr->buildShader(tag, mat.heclIr, "CMDL", ctx));
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +402,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store)
|
|||
hecl::SBig(aabbPtr[3]), hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
||||
x28_modelInst = std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[0],
|
||||
m_vtxFmt, m_vbo, m_ibo,
|
||||
aabb, flags & 0x2, true);
|
||||
aabb, flags & 0x2, false);
|
||||
}
|
||||
|
||||
void CBooModel::SShader::UnlockTextures()
|
||||
|
@ -465,7 +464,8 @@ CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
|||
const urde::CVParamTransfer& vparms)
|
||||
{
|
||||
IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam();
|
||||
return TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store));
|
||||
CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store));
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,10 +34,10 @@ class CTexture
|
|||
void BuildRGB5A3FromGCN(CInputStream& in);
|
||||
void BuildRGBA8FromGCN(CInputStream& in);
|
||||
void BuildDXT1FromGCN(CInputStream& in);
|
||||
void BuildRGBA8(CInputStream& in);
|
||||
void BuildRGBA8(const void* data);
|
||||
|
||||
public:
|
||||
CTexture(CInputStream& in);
|
||||
CTexture(std::unique_ptr<u8[]>&& in, u32 length);
|
||||
enum class EClampMode
|
||||
{
|
||||
None,
|
||||
|
@ -50,7 +50,9 @@ public:
|
|||
boo::ITexture* GetBooTexture() {return m_booTex;}
|
||||
};
|
||||
|
||||
CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
|
||||
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
|
||||
std::unique_ptr<u8[]>&& in, u32 len,
|
||||
const urde::CVParamTransfer& vparms);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -648,63 +648,64 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in)
|
|||
});
|
||||
}
|
||||
|
||||
void CTexture::BuildRGBA8(CInputStream& in)
|
||||
void CTexture::BuildRGBA8(const void* data)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<atInt8[]> buf = in.readBytes(texelCount * 4);
|
||||
|
||||
m_booToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4);
|
||||
data, texelCount * 4);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
CTexture::CTexture(CInputStream& in)
|
||||
CTexture::CTexture(std::unique_ptr<u8[]>&& in, u32 length)
|
||||
{
|
||||
x0_fmt = ETexelFormat(in.readUint32Big());
|
||||
x4_w = in.readUint16Big();
|
||||
x6_h = in.readUint16Big();
|
||||
x8_mips = in.readUint32Big();
|
||||
std::unique_ptr<u8[]> owned = std::move(in);
|
||||
athena::io::MemoryReader r(owned.get(), length);
|
||||
x0_fmt = ETexelFormat(r.readUint32Big());
|
||||
x4_w = r.readUint16Big();
|
||||
x6_h = r.readUint16Big();
|
||||
x8_mips = r.readUint32Big();
|
||||
|
||||
switch (x0_fmt)
|
||||
{
|
||||
case ETexelFormat::I4:
|
||||
BuildI4FromGCN(in);
|
||||
BuildI4FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::I8:
|
||||
BuildI8FromGCN(in);
|
||||
BuildI8FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::IA4:
|
||||
BuildIA4FromGCN(in);
|
||||
BuildIA4FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::IA8:
|
||||
BuildIA8FromGCN(in);
|
||||
BuildIA8FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::C4:
|
||||
BuildC4FromGCN(in);
|
||||
BuildC4FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::C8:
|
||||
BuildC8FromGCN(in);
|
||||
BuildC8FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::C14X2:
|
||||
BuildC14X2FromGCN(in);
|
||||
BuildC14X2FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::RGB565:
|
||||
BuildRGB565FromGCN(in);
|
||||
BuildRGB565FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::RGB5A3:
|
||||
BuildRGB5A3FromGCN(in);
|
||||
BuildRGB5A3FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::RGBA8:
|
||||
BuildRGBA8FromGCN(in);
|
||||
BuildRGBA8FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::CMPR:
|
||||
BuildDXT1FromGCN(in);
|
||||
BuildDXT1FromGCN(r);
|
||||
break;
|
||||
case ETexelFormat::RGBA8PC:
|
||||
BuildRGBA8(in);
|
||||
BuildRGBA8(owned.get() + 12);
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, "invalid texture type %d for boo", int(x0_fmt));
|
||||
|
@ -716,9 +717,11 @@ void CTexture::Load(int slot, EClampMode clamp) const
|
|||
|
||||
}
|
||||
|
||||
CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
|
||||
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
|
||||
std::unique_ptr<u8[]>&& in, u32 len,
|
||||
const urde::CVParamTransfer& vparms)
|
||||
{
|
||||
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(in));
|
||||
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(std::move(in), len));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue