From 6f53a4d0daa81d34890f91fcbfbc3e135953750a Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 20:47:07 +1000 Subject: [PATCH 1/2] TextureCache: Don't crash when conversion pipelines fail to compile --- Source/Core/VideoCommon/TextureCacheBase.cpp | 28 +++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 5fcf667514..fb21603b6a 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -254,6 +254,14 @@ TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTForma { DEBUG_ASSERT(g_ActiveConfig.backend_info.bSupportsPaletteConversion); + const AbstractPipeline* pipeline = g_shader_cache->GetPaletteConversionPipeline(tlutfmt); + if (!pipeline) + { + ERROR_LOG(VIDEO, "Failed to get conversion pipeline for format 0x%02X", + static_cast(tlutfmt)); + return nullptr; + } + TextureConfig new_config = entry->texture->GetConfig(); new_config.levels = 1; new_config.flags |= AbstractTextureFlag_RenderTarget; @@ -293,7 +301,7 @@ TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTForma g_renderer->SetAndDiscardFramebuffer(decoded_entry->framebuffer.get()); g_renderer->SetViewportAndScissor(decoded_entry->texture->GetRect()); - g_renderer->SetPipeline(g_shader_cache->GetPaletteConversionPipeline(tlutfmt)); + g_renderer->SetPipeline(pipeline); g_renderer->SetTexture(1, entry->texture.get()); g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); g_renderer->Draw(0, 3); @@ -314,6 +322,16 @@ TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTForma TextureCacheBase::TCacheEntry* TextureCacheBase::ReinterpretEntry(const TCacheEntry* existing_entry, TextureFormat new_format) { + const AbstractPipeline* pipeline = + g_shader_cache->GetTextureReinterpretPipeline(existing_entry->format.texfmt, new_format); + if (!pipeline) + { + ERROR_LOG(VIDEO, + "Failed to obtain texture reinterpreting pipeline from format 0x%02X to 0x%02X", + static_cast(existing_entry->format.texfmt), static_cast(new_format)); + return nullptr; + } + TextureConfig new_config = existing_entry->texture->GetConfig(); new_config.levels = 1; new_config.flags |= AbstractTextureFlag_RenderTarget; @@ -336,8 +354,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::ReinterpretEntry(const TCacheEn g_renderer->BeginUtilityDrawing(); g_renderer->SetAndDiscardFramebuffer(reinterpreted_entry->framebuffer.get()); g_renderer->SetViewportAndScissor(reinterpreted_entry->texture->GetRect()); - g_renderer->SetPipeline( - g_shader_cache->GetTextureReinterpretPipeline(existing_entry->format.texfmt, new_format)); + g_renderer->SetPipeline(pipeline); g_renderer->SetTexture(0, existing_entry->texture.get()); g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); g_renderer->Draw(0, 3); @@ -432,7 +449,10 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* pale continue; } - entry = ReinterpretEntry(entry, entry_to_update->format.texfmt); + TCacheEntry* reinterpreted_entry = + ReinterpretEntry(entry, entry_to_update->format.texfmt); + if (reinterpreted_entry) + entry = reinterpreted_entry; } if (isPaletteTexture) From 97d81ac97c526f952d8a40060f3cfa86f5f22df2 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Jul 2019 20:57:42 +1000 Subject: [PATCH 2/2] FramebufferShaderGen: Fix format reinterpret shaders on GLES --- Source/Core/VideoCommon/FramebufferShaderGen.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoCommon/FramebufferShaderGen.cpp b/Source/Core/VideoCommon/FramebufferShaderGen.cpp index f944562d9c..5789c0a0d2 100644 --- a/Source/Core/VideoCommon/FramebufferShaderGen.cpp +++ b/Source/Core/VideoCommon/FramebufferShaderGen.cpp @@ -597,29 +597,30 @@ std::string GenerateTextureReinterpretShader(TextureFormat from_format, TextureF case TextureFormat::I8: case TextureFormat::C8: { - ss << " ocol0.rgba = (float(raw_value & 0xFFu) / 255.0).rrrr;\n"; + ss << " float orgba = float(raw_value & 0xFFu) / 255.0;\n"; + ss << " ocol0 = float4(orgba, orgba, orgba, orgba);\n"; } break; case TextureFormat::IA8: { - ss << " ocol0.rgb = (float(raw_value & 0xFFu) / 255.0).rrr;\n"; - ss << " ocol0.a = float((raw_value >> 8) & 0xFFu) / 255.0;\n"; + ss << " float orgb = float(raw_value & 0xFFu) / 255.0;\n"; + ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 8) & 0xFFu) / 255.0);\n"; } break; case TextureFormat::IA4: { - ss << " ocol0.rgb = (float(raw_value & 0xFu) / 15.0).rrr;\n"; - ss << " ocol0.a = float((raw_value >> 4) & 0xFu) / 15.0;\n"; + ss << " float orgb = float(raw_value & 0xFu) / 15.0;\n"; + ss << " ocol0 = float4(orgb, orgb, orgb, float((raw_value >> 4) & 0xFu) / 15.0);\n"; } break; case TextureFormat::RGB565: { - ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0\n"; + ss << " ocol0 = float4(float((raw_value >> 10) & 0x1Fu) / 31.0,\n"; ss << " float((raw_value >> 5) & 0x1Fu) / 31.0,\n"; - ss << " float(raw_value & 0x1Fu) / 31.0,, 1.0);\n"; + ss << " float(raw_value & 0x1Fu) / 31.0, 1.0);\n"; } break;