mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
Direct3D11: Support running out of memory when creating textures (partially)
Failures in mipmap creation, shader resource view creation etc will still cause program exit
This commit is contained in:
parent
4f79864d5e
commit
4377c46826
22
src/Game.c
22
src/Game.c
@ -141,6 +141,17 @@ void Game_CycleViewDistance(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_bool Game_ReduceVRAM(void) {
|
||||||
|
if (Game_UserViewDistance <= 16) return false;
|
||||||
|
Game_UserViewDistance /= 2;
|
||||||
|
Game_UserViewDistance = max(16, Game_UserViewDistance);
|
||||||
|
|
||||||
|
MapRenderer_Refresh();
|
||||||
|
Game_SetViewDistance(Game_UserViewDistance);
|
||||||
|
Chat_AddRaw("&cOut of VRAM! Halving view distance..");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Game_SetViewDistance(int distance) {
|
void Game_SetViewDistance(int distance) {
|
||||||
distance = min(distance, Game_MaxViewDistance);
|
distance = min(distance, Game_MaxViewDistance);
|
||||||
@ -263,16 +274,6 @@ static void HandleOnNewMapLoaded(void* obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleLowVRAMDetected(void* obj) {
|
|
||||||
if (Game_UserViewDistance <= 16) Logger_Abort("Out of video memory!");
|
|
||||||
Game_UserViewDistance /= 2;
|
|
||||||
Game_UserViewDistance = max(16, Game_UserViewDistance);
|
|
||||||
|
|
||||||
MapRenderer_Refresh();
|
|
||||||
Game_SetViewDistance(Game_UserViewDistance);
|
|
||||||
Chat_AddRaw("&cOut of VRAM! Halving view distance..");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HandleInactiveChanged(void* obj) {
|
static void HandleInactiveChanged(void* obj) {
|
||||||
if (WindowInfo.Inactive) {
|
if (WindowInfo.Inactive) {
|
||||||
Chat_AddRaw(LOWPERF_ENTER_MESSAGE);
|
Chat_AddRaw(LOWPERF_ENTER_MESSAGE);
|
||||||
@ -373,7 +374,6 @@ static void Game_Load(void) {
|
|||||||
|
|
||||||
Event_Register_(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
Event_Register_(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
||||||
Event_Register_(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
Event_Register_(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
||||||
Event_Register_(&GfxEvents.LowVRAMDetected, NULL, HandleLowVRAMDetected);
|
|
||||||
Event_Register_(&WindowEvents.Resized, NULL, Game_OnResize);
|
Event_Register_(&WindowEvents.Resized, NULL, Game_OnResize);
|
||||||
Event_Register_(&WindowEvents.Closing, NULL, Game_Free);
|
Event_Register_(&WindowEvents.Closing, NULL, Game_Free);
|
||||||
Event_Register_(&WindowEvents.InactiveChanged, NULL, HandleInactiveChanged);
|
Event_Register_(&WindowEvents.InactiveChanged, NULL, HandleInactiveChanged);
|
||||||
|
@ -55,6 +55,9 @@ extern const char* const FpsLimit_Names[FPS_LIMIT_COUNT];
|
|||||||
|
|
||||||
void Game_ToggleFullscreen(void);
|
void Game_ToggleFullscreen(void);
|
||||||
void Game_CycleViewDistance(void);
|
void Game_CycleViewDistance(void);
|
||||||
|
/* Attempts to reduce VRAM usage (e.g. reducing view distance) */
|
||||||
|
/* Returns false if VRAM cannot be reduced any further */
|
||||||
|
cc_bool Game_ReduceVRAM(void);
|
||||||
|
|
||||||
void Game_SetViewDistance(int distance);
|
void Game_SetViewDistance(int distance);
|
||||||
void Game_UserSetViewDistance(int distance);
|
void Game_UserSetViewDistance(int distance);
|
||||||
|
@ -239,8 +239,16 @@ GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipm
|
|||||||
src = NULL;
|
src = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = ID3D11Device_CreateTexture2D(device, &desc, src, &tex);
|
while ((hr = ID3D11Device_CreateTexture2D(device, &desc, src, &tex)))
|
||||||
if (hr) Logger_Abort2(hr, "Failed to create texture");
|
{
|
||||||
|
if (hr == E_OUTOFMEMORY) {
|
||||||
|
// insufficient VRAM or RAM left
|
||||||
|
if (!Game_ReduceVRAM()) return NULL;
|
||||||
|
} else {
|
||||||
|
// unknown issue, do not even try to handle it
|
||||||
|
Logger_Abort2(hr, "Failed to create texture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hr = ID3D11Device_CreateShaderResourceView(device, tex, NULL, &view);
|
hr = ID3D11Device_CreateShaderResourceView(device, tex, NULL, &view);
|
||||||
if (hr) Logger_Abort2(hr, "Failed to create view");
|
if (hr) Logger_Abort2(hr, "Failed to create view");
|
||||||
|
@ -238,7 +238,7 @@ static cc_bool D3D9_CheckResult(cc_result res, const char* func) {
|
|||||||
if (!res) return true;
|
if (!res) return true;
|
||||||
|
|
||||||
if (res == D3DERR_OUTOFVIDEOMEMORY || res == E_OUTOFMEMORY) {
|
if (res == D3DERR_OUTOFVIDEOMEMORY || res == E_OUTOFMEMORY) {
|
||||||
Event_RaiseVoid(&GfxEvents.LowVRAMDetected);
|
if (!Game_ReduceVRAM()) Logger_Abort("Out of video memory!");
|
||||||
} else {
|
} else {
|
||||||
Logger_Abort2(res, func);
|
Logger_Abort2(res, func);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user