From 9f7651b6fed268c4dd22d31ecd41ed2ba409e7a3 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Thu, 8 Sep 2022 17:30:31 +0200 Subject: [PATCH] Latte: Fix infinite loop in special state clearAsDepth() This broke while refactoring code for the 2.0 release. Resolves Tokyo Mirage Session and Pokken freezing on boot. Probably also affects some other games Also updated .gitignore --- .gitignore | 1 + .../Renderer/OpenGL/OpenGLRendererCore.cpp | 48 ++++++++++--------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index ce7f91c2..293864a8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ bin/mlc01/* bin/settings.xml bin/title_list_cache.xml bin/debugger/* +bin/sdcard/* !bin/shaderCache/info.txt bin/shaderCache/* diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp index 151f54f9..f9f61646 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp @@ -551,34 +551,36 @@ void LatteDraw_handleSpecialState8_clearAsDepth() while (true) { LatteTextureView* view = LatteTC_LookupTextureByData(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, 1, sliceIndex, 1, &searchIndex); - if (view != nullptr) + if (!view) { - sint32 effectiveClearWidth = view->baseTexture->width; - sint32 effectiveClearHeight = view->baseTexture->height; - LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0); + // should we clear in RAM instead? + break; + } + sint32 effectiveClearWidth = view->baseTexture->width; + sint32 effectiveClearHeight = view->baseTexture->height; + LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0); - // hacky way to get clear color - float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST + // hacky way to get clear color + float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST - uint8 clearColor[4] = { 0 }; - clearColor[0] = (uint8)(regClearColor[0] * 255.0f); - clearColor[1] = (uint8)(regClearColor[1] * 255.0f); - clearColor[2] = (uint8)(regClearColor[2] * 255.0f); - clearColor[3] = (uint8)(regClearColor[3] * 255.0f); + uint8 clearColor[4] = { 0 }; + clearColor[0] = (uint8)(regClearColor[0] * 255.0f); + clearColor[1] = (uint8)(regClearColor[1] * 255.0f); + clearColor[2] = (uint8)(regClearColor[2] * 255.0f); + clearColor[3] = (uint8)(regClearColor[3] * 255.0f); - // todo - use fragment shader software emulation (evoke for one pixel) to determine clear color - // todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight + // todo - use fragment shader software emulation (evoke for one pixel) to determine clear color + // todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - //cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer - if (glClearTexSubImage) - glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); - } - else - { - g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]); - } + if (g_renderer->GetType() == RendererAPI::OpenGL) + { + //cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer + if (glClearTexSubImage) + glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); + } + else + { + g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]); } } }