You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
9.7 KiB
C++
330 lines
9.7 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H
|
|
#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H
|
|
#pragma once
|
|
|
|
|
|
#include "ITextureStreamer.h"
|
|
|
|
#include <AzCore/Jobs/LegacyJobExecutor.h>
|
|
|
|
//#define TEXSTRM_DEFER_UMR
|
|
|
|
ILINE int bsel(bool c, int t, int f)
|
|
{
|
|
PREFAST_SUPPRESS_WARNING(6323)
|
|
return isel(-(int)c, f, t);
|
|
}
|
|
|
|
struct SPlanningMemoryState
|
|
{
|
|
ptrdiff_t nMemStreamed;
|
|
ptrdiff_t nStaticTexUsage;
|
|
ptrdiff_t nPhysicalLimit;
|
|
ptrdiff_t nTargetPhysicalLimit;
|
|
ptrdiff_t nMemLimit;
|
|
ptrdiff_t nMemFreeSlack;
|
|
ptrdiff_t nUnknownPoolUsage;
|
|
ptrdiff_t nMemBoundStreamed;
|
|
ptrdiff_t nMemBoundStreamedPers;
|
|
ptrdiff_t nMemTemp;
|
|
ptrdiff_t nMemFreeLower;
|
|
ptrdiff_t nMemFreeUpper;
|
|
ptrdiff_t nStreamLimit;
|
|
ptrdiff_t nStreamMid;
|
|
ptrdiff_t nStreamDelta;
|
|
};
|
|
|
|
struct SPlanningUMRState
|
|
{
|
|
int32 arrRoundIds[MAX_PREDICTION_ZONES];
|
|
};
|
|
|
|
struct SPlanningAction
|
|
{
|
|
enum
|
|
{
|
|
Unknown,
|
|
Relink,
|
|
Abort,
|
|
};
|
|
|
|
SPlanningAction()
|
|
: eAction(Unknown)
|
|
{
|
|
}
|
|
|
|
SPlanningAction(int action, size_t texture, uint8 mip = 0)
|
|
: nTexture((uint16)texture)
|
|
, nMip(mip)
|
|
, eAction((uint8)action)
|
|
{
|
|
}
|
|
|
|
uint16 nTexture;
|
|
uint8 nMip;
|
|
uint8 eAction;
|
|
};
|
|
|
|
typedef DynArray<std::pair<CTexture*, int> > TPlanningTextureReqVec;
|
|
typedef DynArray<SPlanningAction> TPlanningActionVec;
|
|
|
|
struct SPlanningSortState
|
|
{
|
|
// In
|
|
TStreamerTextureVec* pTextures;
|
|
size_t nStreamLimit;
|
|
int32 arrRoundIds[MAX_PREDICTION_ZONES];
|
|
int nFrameId;
|
|
int nBias;
|
|
int fpMinBias;
|
|
int fpMaxBias;
|
|
int fpMinMip;
|
|
SPlanningMemoryState memState;
|
|
|
|
// In/Out
|
|
size_t nTextures;
|
|
|
|
// Out
|
|
size_t nBalancePoint;
|
|
size_t nOnScreenPoint;
|
|
size_t nPrecachedTexs;
|
|
size_t nListSize;
|
|
TPlanningTextureReqVec* pRequestList;
|
|
TStreamerTextureVec* pTrimmableList;
|
|
TStreamerTextureVec* pUnlinkList;
|
|
TPlanningActionVec* pActionList;
|
|
};
|
|
|
|
struct SPlanningScheduleState
|
|
{
|
|
int nFrameId;
|
|
|
|
int nBias;
|
|
SPlanningMemoryState memState;
|
|
|
|
TPlanningTextureReqVec requestList;
|
|
TStreamerTextureVec trimmableList;
|
|
TStreamerTextureVec unlinkList;
|
|
TPlanningActionVec actionList;
|
|
size_t nBalancePoint;
|
|
size_t nOnScreenPoint;
|
|
};
|
|
|
|
struct SPlanningUpdateMipRequest
|
|
{
|
|
CTexture* pTexture;
|
|
float fMipFactor;
|
|
int nFlags;
|
|
int nUpdateId;
|
|
};
|
|
|
|
struct SPlanningTextureOrderKey
|
|
{
|
|
// 1 force stream high res
|
|
// 1 high priority
|
|
// 1 is visible
|
|
// 1 is in zone[0]
|
|
// 1 is in zone[1]
|
|
// 16 fp min mip cur, biased
|
|
CTexture* pTexture;
|
|
uint32 nKey;
|
|
|
|
uint16 nWidth;
|
|
uint16 nHeight;
|
|
|
|
uint8 nMips : 4;
|
|
uint8 nMipsPersistent : 4;
|
|
uint8 nCurMip;
|
|
uint8 nFormatCode;
|
|
uint8 eTF;
|
|
|
|
uint32 nPersistentSize : 31;
|
|
uint32 bIsStreaming : 1;
|
|
|
|
uint32 bUnloaded : 1;
|
|
uint32 nIsComposite : 1;
|
|
uint32 nStreamPrio : 3;
|
|
uint32 nSlicesMinus1 : 9;
|
|
uint32 nSlicesPotMinus1 : 9;
|
|
|
|
enum
|
|
{
|
|
InBudgetMask = 0xffffffff ^ ((1 << 30) | (1 << 29)),
|
|
OverBudgetMask = 0xffffffff,
|
|
PackedFpBias = 0x7f00
|
|
};
|
|
|
|
bool IsForceStreamHighRes() const { return (nKey & (1 << 31)) == 0; }
|
|
bool IsHighPriority() const { return (nKey & (1 << 30)) == 0; }
|
|
bool IsVisible() const { return (nKey & (1 << 29)) == 0; }
|
|
bool IsInZone(int z) const { return (nKey & (1 << (28 - z))) == 0; }
|
|
bool IsPrecached() const { return (nKey & ((1 << 31) | (1 << 28) | (1 << 27))) != ((1 << 31) | (1 << 28) | (1 << 27)); }
|
|
int GetFpMinMipCur() const { return static_cast<int16>(static_cast<int>(nKey & 0xffff) - PackedFpBias); }
|
|
uint16 GetFpMinMipCurBiased() const { return (uint16)nKey; }
|
|
|
|
SPlanningTextureOrderKey() {}
|
|
SPlanningTextureOrderKey(CTexture* pTex, int nFrameId, const int nZoneIds[])
|
|
{
|
|
nKey =
|
|
(pTex->IsForceStreamHighRes() ? 0 : (1 << 31)) |
|
|
(pTex->IsStreamHighPriority() ? 0 : (1 << 30)) |
|
|
(pTex->GetAccessFrameIdNonVirtual() >= nFrameId ? 0 : (1 << 29)) |
|
|
(pTex->GetStreamRoundInfo(0).nRoundUpdateId >= nZoneIds[0] ? 0 : (1 << 28)) |
|
|
(pTex->GetStreamRoundInfo(1).nRoundUpdateId >= nZoneIds[1] ? 0 : (1 << 27)) |
|
|
static_cast<uint16>(pTex->GetRequiredMipNonVirtualFP() + PackedFpBias);
|
|
|
|
pTexture = pTex;
|
|
|
|
nWidth = pTex->GetWidthNonVirtual();
|
|
nHeight = pTex->GetHeightNonVirtual();
|
|
nMips = pTex->GetNumMipsNonVirtual();
|
|
nMipsPersistent = bsel(pTex->IsForceStreamHighRes(), pTex->GetNumMipsNonVirtual(), pTex->GetNumPersistentMips());
|
|
nFormatCode = pTex->StreamGetFormatCode();
|
|
|
|
uint32 nSlices = pTex->StreamGetNumSlices();
|
|
nSlicesMinus1 = nSlices - 1;
|
|
nSlicesPotMinus1 = (1u << (32 - (nSlices > 1 ? countLeadingZeros32(nSlices - 1) : 32))) - 1;
|
|
|
|
nCurMip = pTex->StreamGetLoadedMip();
|
|
eTF = pTex->GetDstFormat();
|
|
nPersistentSize = pTex->GetPersistentSize();
|
|
bIsStreaming = pTex->IsStreaming();
|
|
bUnloaded = pTex->IsUnloaded();
|
|
nStreamPrio = pTex->StreamGetPriority();
|
|
nIsComposite = 0;
|
|
}
|
|
};
|
|
|
|
struct SPlanningRequestIdent
|
|
{
|
|
SPlanningRequestIdent() {}
|
|
SPlanningRequestIdent(uint32 sortKey, int key, int mip)
|
|
: nSortKey(sortKey)
|
|
, nKey(key)
|
|
, nMip(mip)
|
|
{
|
|
}
|
|
|
|
uint32 nSortKey;
|
|
int nKey : 27;
|
|
int nMip : 5;
|
|
};
|
|
|
|
class CPlanningTextureStreamer
|
|
: public ITextureStreamer
|
|
{
|
|
public:
|
|
CPlanningTextureStreamer();
|
|
|
|
public:
|
|
virtual void BeginUpdateSchedule();
|
|
virtual void ApplySchedule(EApplyScheduleFlags asf);
|
|
|
|
virtual bool BeginPrepare(CTexture* pTexture, const char* sFilename, uint32 nFlags);
|
|
virtual void EndPrepare(STexStreamPrepState*& pState);
|
|
|
|
virtual void Precache(CTexture* pTexture);
|
|
virtual void UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId, const int nCounter);
|
|
|
|
virtual void OnTextureDestroy(CTexture* pTexture);
|
|
|
|
virtual void FlagOutOfMemory();
|
|
virtual void Flush();
|
|
|
|
virtual bool IsOverflowing() const;
|
|
virtual float GetBias() const { return m_nBias / 256.0f; }
|
|
|
|
public: // Job entry points - do not call directly!
|
|
void Job_UpdateEntry();
|
|
|
|
private:
|
|
enum State
|
|
{
|
|
S_Idle,
|
|
S_QueuedForUpdate,
|
|
S_Updating,
|
|
S_QueuedForSync,
|
|
S_QueuedForSchedule,
|
|
S_QueuedForScheduleDiscard,
|
|
};
|
|
|
|
typedef DynArray<SPlanningUpdateMipRequest> UpdateMipRequestVec;
|
|
|
|
private:
|
|
SPlanningMemoryState GetMemoryState();
|
|
|
|
void StartUpdateJob();
|
|
|
|
void Job_UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId);
|
|
void Job_Sort();
|
|
int Job_Bias(SPlanningSortState& sortState, SPlanningTextureOrderKey* pKeys, size_t nNumPrecachedTexs, size_t nStreamLimit);
|
|
size_t Job_Plan(SPlanningSortState& sortState, const SPlanningTextureOrderKey* pKeys, size_t nTextures, size_t nNumPrecachedTexs, size_t nBalancePoint, int nMinMip, int fpSortStateBias);
|
|
void Job_InitKeys(SPlanningTextureOrderKey* pKeys, CTexture** pTexs, size_t nTextures, int nFrameId, const int nZoneIds[]);
|
|
void Job_CommitKeys(CTexture** pTextures, SPlanningTextureOrderKey* pKeys, size_t nTextures);
|
|
void Job_ConfigureSchedule();
|
|
void SyncWithJob_Locked();
|
|
|
|
private:
|
|
#ifndef NULL_RENDERER
|
|
bool TryBegin_FromDisk(CTexture* pTex, uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint,
|
|
TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx,
|
|
int& nNumSubmittedLoad, size_t& nAmtSubmittedLoad);
|
|
bool TryBegin_Composite(CTexture* pTex, uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint,
|
|
TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx,
|
|
int& nNumSubmittedLoad, size_t& nAmtSubmittedLoad);
|
|
#endif
|
|
|
|
#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY)
|
|
bool TrimTexture(int nBias, TStreamerTextureVec& trimmable, STexPool* pPrioritise);
|
|
#endif
|
|
ptrdiff_t TrimTextures(ptrdiff_t nRequired, int nBias, TStreamerTextureVec& trimmable);
|
|
ptrdiff_t KickTextures(CTexture** pTextures, ptrdiff_t nRequired, int nBalancePoint, int& nKickIdx);
|
|
void Job_CheckEnqueueForStreaming(CTexture* pTexture, const float fMipFactor, bool bHighPriority);
|
|
|
|
private:
|
|
CryCriticalSection m_lock;
|
|
std::vector<SPlanningTextureOrderKey> m_keys;
|
|
int m_nRTList;
|
|
int m_nJobList;
|
|
|
|
volatile State m_state;
|
|
|
|
AZ::LegacyJobExecutor m_jobExecutor;
|
|
SPlanningUMRState m_umrState;
|
|
SPlanningSortState m_sortState;
|
|
|
|
#if defined(TEXSTRM_DEFER_UMR)
|
|
UpdateMipRequestVec m_updateMipRequests[2];
|
|
#endif
|
|
|
|
SPlanningScheduleState m_schedule;
|
|
|
|
int m_nBias;
|
|
int m_nStreamAllocFails;
|
|
bool m_bOverBudget;
|
|
size_t m_nPrevListSize;
|
|
};
|
|
|
|
struct SPlanningTextureRequestOrder
|
|
{
|
|
bool operator () (const SPlanningRequestIdent& a, const SPlanningRequestIdent& b) const
|
|
{
|
|
return a.nSortKey < b.nSortKey;
|
|
}
|
|
};
|
|
|
|
#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H
|