From 072041a63dcc03fafa425caa4ddccf468abd102b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 24 Dec 2019 11:05:15 -0800 Subject: [PATCH] SoftGPU: Convert from 16-bit if unsupported. Should help #12455, but not actually tested on an affected device. --- GPU/Software/SoftGpu.cpp | 86 ++++++++++++++++++++++++---------------- GPU/Software/SoftGpu.h | 3 +- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 7254c2ce11..691a8756aa 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -158,6 +158,38 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for bool g_DarkStalkerStretch; +void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight) { + // TODO: This should probably be converted in a shader instead.. + fbTexBuffer_.resize(srcwidth * srcheight); + FormatBuffer displayBuffer; + displayBuffer.data = Memory::GetPointer(displayFramebuf_); + for (int y = 0; y < srcheight; ++y) { + u32 *buf_line = &fbTexBuffer_[y * srcwidth]; + const u16 *fb_line = &displayBuffer.as16[y * displayStride_]; + + switch (displayFormat_) { + case GE_FORMAT_565: + ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + case GE_FORMAT_5551: + ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + case GE_FORMAT_4444: + ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + default: + ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_); + } + } + + desc.width = srcwidth; + desc.height = srcheight; + desc.initData.push_back((uint8_t *)fbTexBuffer_.data()); +} + // Copies RGBA8 data from RAM to the currently bound render target. void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { if (!draw_) @@ -191,6 +223,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { Draw::Pipeline *pipeline = texColor; if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { u8 *data = Memory::GetPointer(0x04088000); + bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. desc.format = Draw::DataFormat::A1B5G5R5_UNORM_PACK16; @@ -198,10 +231,15 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { // RB swapped, compensate with a shader. desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; pipeline = texColorRBSwizzle; + } else { + ConvertTextureDescFrom16(desc, srcwidth, srcheight); + fillDesc = false; + } + if (fillDesc) { + desc.width = displayStride_ == 0 ? srcwidth : displayStride_; + desc.height = srcheight; + desc.initData.push_back(data); } - desc.width = displayStride_ == 0 ? srcwidth : displayStride_; - desc.height = srcheight; - desc.initData.push_back(data); u0 = 64.5f / 512.0f; u1 = 447.5f / 512.0f; v1 = 16.0f / 272.0f; @@ -217,6 +255,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { desc.format = Draw::DataFormat::R8G8B8A8_UNORM; } else if (displayFormat_ == GE_FORMAT_5551) { u8 *data = Memory::GetPointer(displayFramebuf_); + bool fillDesc = true; desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. @@ -225,40 +264,17 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { // RB swapped, compensate with a shader. desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; pipeline = texColorRBSwizzle; + } else { + ConvertTextureDescFrom16(desc, srcwidth, srcheight); + fillDesc = false; + } + if (fillDesc) { + desc.width = displayStride_ == 0 ? srcwidth : displayStride_; + desc.height = srcheight; + desc.initData.push_back(data); } - desc.width = displayStride_ == 0 ? srcwidth : displayStride_; - desc.height = srcheight; - desc.initData.push_back(data); } else { - // TODO: This should probably be converted in a shader instead.. - fbTexBuffer.resize(srcwidth * srcheight); - FormatBuffer displayBuffer; - displayBuffer.data = Memory::GetPointer(displayFramebuf_); - for (int y = 0; y < srcheight; ++y) { - u32 *buf_line = &fbTexBuffer[y * srcwidth]; - const u16 *fb_line = &displayBuffer.as16[y * displayStride_]; - - switch (displayFormat_) { - case GE_FORMAT_565: - ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - case GE_FORMAT_5551: - ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - case GE_FORMAT_4444: - ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_); - } - } - - desc.width = srcwidth; - desc.height = srcheight; - desc.initData.push_back((uint8_t *)fbTexBuffer.data()); + ConvertTextureDescFrom16(desc, srcwidth, srcheight); u1 = 1.0f; } if (!hasImage) { diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 02660b5576..84626b31c2 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -101,6 +101,7 @@ public: protected: void FastRunLoop(DisplayList &list) override; void CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight); + void ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight); private: bool framebufferDirty_; @@ -113,7 +114,7 @@ private: Draw::Texture *fbTex; Draw::Pipeline *texColor; Draw::Pipeline *texColorRBSwizzle; - std::vector fbTexBuffer; + std::vector fbTexBuffer_; Draw::SamplerState *samplerNearest = nullptr; Draw::SamplerState *samplerLinear = nullptr;