Merge pull request #1269 from LukeUsher/optimize-gethostresource
Pass iterator around to minimize map lookups:
This commit is contained in:
commit
730f993bf6
|
@ -1,4 +1,4 @@
|
|||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
// ******************************************************************
|
||||
// *
|
||||
|
@ -85,7 +85,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID);
|
|||
static DWORD WINAPI EmuCreateDeviceProxy(LPVOID);
|
||||
static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static DWORD WINAPI EmuUpdateTickCount(LPVOID);
|
||||
static inline void EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource, DWORD D3DUsage, int iTextureStage, DWORD dwSize);
|
||||
static void UpdateCurrentMSpFAndFPS(); // Used for benchmarking/fps count
|
||||
|
||||
// Static Variable(s)
|
||||
|
@ -744,7 +743,9 @@ typedef struct {
|
|||
std::chrono::time_point<std::chrono::high_resolution_clock> lastUpdate;
|
||||
} resource_info_t;
|
||||
|
||||
std::unordered_map <resource_key_t, resource_info_t> g_XboxDirect3DResources;
|
||||
typedef std::unordered_map<resource_key_t, resource_info_t> xbox_resource_map_t;
|
||||
xbox_resource_map_t g_XboxDirect3DResources;
|
||||
static inline resource_info_t* EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource, DWORD D3DUsage, int iTextureStage, DWORD dwSize);
|
||||
|
||||
bool IsResourceAPixelContainer(XTL::X_D3DResource* pXboxResource)
|
||||
{
|
||||
|
@ -781,23 +782,25 @@ resource_key_t GetHostResourceKey(XTL::X_D3DResource* pXboxResource)
|
|||
return key;
|
||||
}
|
||||
|
||||
void FreeHostResource(resource_key_t key)
|
||||
xbox_resource_map_t::iterator GetHostResourceIterator(XTL::X_D3DResource* pXboxResource)
|
||||
{
|
||||
return g_XboxDirect3DResources.find(GetHostResourceKey(pXboxResource));
|
||||
}
|
||||
|
||||
void FreeHostResource(xbox_resource_map_t::iterator it)
|
||||
{
|
||||
// Release the host resource and remove it from the list
|
||||
auto hostResourceIterator = g_XboxDirect3DResources.find(key);
|
||||
if (hostResourceIterator != g_XboxDirect3DResources.end()) {
|
||||
if (hostResourceIterator->second.pHostResource) {
|
||||
(hostResourceIterator->second.pHostResource)->Release();
|
||||
if (it != g_XboxDirect3DResources.end()) {
|
||||
if (it->second.pHostResource) {
|
||||
(it->second.pHostResource)->Release();
|
||||
}
|
||||
|
||||
g_XboxDirect3DResources.erase(hostResourceIterator);
|
||||
g_XboxDirect3DResources.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void ForceResourceRehash(XTL::X_D3DResource* pXboxResource)
|
||||
void ForceResourceRehash(xbox_resource_map_t::iterator it)
|
||||
{
|
||||
auto key = GetHostResourceKey(pXboxResource);
|
||||
auto it = g_XboxDirect3DResources.find(key);
|
||||
if (it != g_XboxDirect3DResources.end() && it->second.pHostResource) {
|
||||
it->second.forceRehash = true;
|
||||
}
|
||||
|
@ -808,19 +811,23 @@ XTL::IDirect3DResource *GetHostResource(XTL::X_D3DResource *pXboxResource, DWORD
|
|||
if (pXboxResource == NULL || pXboxResource->Data == NULL)
|
||||
return nullptr;
|
||||
|
||||
EmuVerifyResourceIsRegistered(pXboxResource, D3DUsage, iTextureStage, /*dwSize=*/0);
|
||||
auto info = EmuVerifyResourceIsRegistered(pXboxResource, D3DUsage, iTextureStage, /*dwSize=*/0);
|
||||
|
||||
if (pXboxResource->Lock == X_D3DRESOURCE_LOCK_PALETTE)
|
||||
return nullptr;
|
||||
|
||||
auto key = GetHostResourceKey(pXboxResource);
|
||||
auto it = g_XboxDirect3DResources.find(key);
|
||||
if (it == g_XboxDirect3DResources.end() || !it->second.pHostResource) {
|
||||
EmuWarning("GetHostResource: Resource not registered or does not have a host counterpart!");
|
||||
if (pXboxResource->Lock == X_D3DRESOURCE_LOCK_PALETTE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return it->second.pHostResource;
|
||||
if (info == nullptr) {
|
||||
EmuWarning("GetHostResource: Resource not registered");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!info->pHostResource) {
|
||||
EmuWarning("GetHostResource: Resource does not have a host counterpart!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return info->pHostResource;
|
||||
}
|
||||
|
||||
// Forward declaration of CxbxGetPixelContainerMeasures to prevent
|
||||
|
@ -862,9 +869,8 @@ size_t GetXboxResourceSize(XTL::X_D3DResource* pXboxResource)
|
|||
|
||||
}
|
||||
|
||||
bool HostResourceRequiresUpdate(resource_key_t key, DWORD dwSize)
|
||||
bool HostResourceRequiresUpdate(xbox_resource_map_t::iterator it, DWORD dwSize)
|
||||
{
|
||||
auto it = g_XboxDirect3DResources.find(key);
|
||||
if (it == g_XboxDirect3DResources.end() || !it->second.pXboxResource) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2311,40 +2317,46 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
|
|||
|
||||
// check if a resource has been registered yet (if not, register it)
|
||||
void CreateHostResource(XTL::X_D3DResource *pResource, DWORD D3DUsage, int iTextureStage, DWORD dwSize); // Forward declartion to prevent restructure of code
|
||||
static void EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource, DWORD D3DUsage = 0, int iTextureStage = 0, DWORD dwSize = 0)
|
||||
static resource_info_t* EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource, DWORD D3DUsage = 0, int iTextureStage = 0, DWORD dwSize = 0)
|
||||
{
|
||||
// Skip resources without data
|
||||
if (pResource->Data == NULL)
|
||||
return;
|
||||
if (pResource->Data == NULL) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto key = GetHostResourceKey(pResource);
|
||||
auto it = g_XboxDirect3DResources.find(key);
|
||||
auto it = GetHostResourceIterator(pResource);
|
||||
if (it != g_XboxDirect3DResources.end()) {
|
||||
// Don't trash RenderTargets
|
||||
// this fixes an issue where CubeMaps were broken because the surface Set in GetCubeMapSurface
|
||||
// would be overwritten by the surface created in SetRenderTarget
|
||||
if (D3DUsage == D3DUSAGE_RENDERTARGET) {
|
||||
return;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
//check if the same key existed in the HostResource map already. if there is a old pXboxResource in the map with the same key but different resource address, it must be freed first.
|
||||
|
||||
if (it->second.pXboxResource != pResource) {
|
||||
//printf("EmuVerifyResourceIsRegistered passed in XboxResource collipse HostResource map!! key : %llX , map pXboxResource : %08X , passed in pResource : %08X \n", key, it->second.pXboxResource, pResource);
|
||||
FreeHostResource(key);
|
||||
FreeHostResource(it);
|
||||
}
|
||||
else
|
||||
if (!HostResourceRequiresUpdate(key, dwSize)) {
|
||||
return;
|
||||
if (!HostResourceRequiresUpdate(it, dwSize)) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
FreeHostResource(key);
|
||||
} else {
|
||||
resource_info_t newResource;
|
||||
g_XboxDirect3DResources[key] = newResource;
|
||||
FreeHostResource(it);
|
||||
CreateHostResource(pResource, D3DUsage, iTextureStage, dwSize);
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
CreateHostResource(pResource, D3DUsage, iTextureStage, dwSize);
|
||||
it = GetHostResourceIterator(pResource);
|
||||
|
||||
if (it != g_XboxDirect3DResources.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -5547,7 +5559,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
|
|||
LOG_FUNC_ONE_ARG(pThis);
|
||||
|
||||
// Backup the key now, as the Xbox resource may be wiped out by the following release call!
|
||||
auto key = GetHostResourceKey(pThis);
|
||||
auto it = GetHostResourceIterator(pThis);
|
||||
|
||||
// Call the Xbox version of D3DResource_Release and store the result
|
||||
XB_trampoline(ULONG, WINAPI, D3DResource_Release, (X_D3DResource*));
|
||||
|
@ -5571,7 +5583,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
|
|||
}
|
||||
|
||||
// Also release the host copy (if it exists!)
|
||||
FreeHostResource(key);
|
||||
FreeHostResource(it);
|
||||
}
|
||||
|
||||
return uRet;
|
||||
|
@ -6825,7 +6837,7 @@ VOID WINAPI XTL::EMUPATCH(Lock2DSurface)
|
|||
XB_Lock2DSurface(pPixelContainer, FaceType, Level, pLockedRect, pRect, Flags);
|
||||
|
||||
// Mark the resource as modified
|
||||
ForceResourceRehash(pPixelContainer);
|
||||
ForceResourceRehash(GetHostResourceIterator(pPixelContainer));
|
||||
}
|
||||
|
||||
|
||||
|
@ -6857,7 +6869,7 @@ VOID WINAPI XTL::EMUPATCH(Lock3DSurface)
|
|||
XB_Lock3DSurface(pPixelContainer, Level, pLockedVolume, pBox, Flags);
|
||||
|
||||
// Mark the resource as modified
|
||||
ForceResourceRehash(pPixelContainer);
|
||||
ForceResourceRehash(GetHostResourceIterator(pPixelContainer));
|
||||
}
|
||||
|
||||
|
||||
|
@ -8178,7 +8190,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetPalette)
|
|||
if (Stage < TEXTURE_STAGES) {
|
||||
if (g_pCurrentPalette[Stage] != GetDataFromXboxResource(pPalette) && XTL::EmuD3DActiveTexture[Stage] != nullptr) {
|
||||
// If the palette for a texture has changed, we need to re-convert the texture
|
||||
FreeHostResource(GetHostResourceKey(XTL::EmuD3DActiveTexture[Stage]));
|
||||
FreeHostResource(GetHostResourceIterator(XTL::EmuD3DActiveTexture[Stage]));
|
||||
}
|
||||
|
||||
// Cache palette data and size
|
||||
|
@ -8211,7 +8223,7 @@ VOID WINAPI XTL::EMUPATCH(D3DPalette_Lock)
|
|||
// Check if this palette is in use by a texture stage, and force it to be re-converted if yes
|
||||
for (int i = 0; i < TEXTURE_STAGES; i++) {
|
||||
if (EmuD3DActiveTexture[i] != nullptr && g_pCurrentPalette[i] == GetDataFromXboxResource(pThis)) {
|
||||
FreeHostResource(GetHostResourceKey(EmuD3DActiveTexture[i]));
|
||||
FreeHostResource(GetHostResourceIterator(EmuD3DActiveTexture[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8238,7 +8250,7 @@ XTL::D3DCOLOR * WINAPI XTL::EMUPATCH(D3DPalette_Lock2)
|
|||
// Check if this palette is in use by a texture stage, and force it to be re-converted if yes
|
||||
for (int i = 0; i < TEXTURE_STAGES; i++) {
|
||||
if (EmuD3DActiveTexture[i] != nullptr && g_pCurrentPalette[i] == GetDataFromXboxResource(pThis)) {
|
||||
FreeHostResource(GetHostResourceKey(EmuD3DActiveTexture[i]));
|
||||
FreeHostResource(GetHostResourceIterator(EmuD3DActiveTexture[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue