diff options
| author | iwubcode <iwubcode@users.noreply.github.com> | 2017-05-29 17:02:09 -0500 |
|---|---|---|
| committer | iwubcode <iwubcode@users.noreply.github.com> | 2017-11-17 19:47:56 -0600 |
| commit | 79387dddb24ddf035b70cd9379a42368dcd49e93 (patch) | |
| tree | 7b783c46e1ffd052842f11112f58c61993f0af1b /Source/Core/VideoBackends/Software | |
| parent | 84ca9a4aec0048e5ac01caea8f8be9210eb947f6 (diff) | |
Add support for hybrid XFB
Diffstat (limited to 'Source/Core/VideoBackends/Software')
| -rw-r--r-- | Source/Core/VideoBackends/Software/EfbInterface.cpp | 34 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWOGLWindow.cpp | 27 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWOGLWindow.h | 8 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWRenderer.cpp | 91 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWRenderer.h | 9 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWmain.cpp | 60 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/Software.vcxproj | 1 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/TextureCache.h | 41 |
8 files changed, 73 insertions, 198 deletions
diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index 9f6af90c0d..411839c852 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -520,15 +520,6 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe // Scanline buffer, leave room for borders yuv444 scanline[EFB_WIDTH + 2]; - // our internal yuv444 type is not normalized, so black is {0, 0, 0} instead of {16, 128, 128} - yuv444 black; - black.Y = 0; - black.U = 0; - black.V = 0; - - scanline[0] = black; // black border at start - scanline[right + 1] = black; // black border at end - for (u16 y = sourceRc.top; y < sourceRc.bottom; y++) { // Get a scanline of YUV pixels in 4:4:4 format @@ -538,6 +529,10 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe scanline[i] = GetColorYUV(x, y); } + // Flipper clamps the border colors + scanline[0] = scanline[1]; + scanline[right + 1] = scanline[right]; + // And Downsample them to 4:2:2 for (int i = 1, x = left; x < right; i += 2, x += 2) { @@ -562,26 +557,7 @@ void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRe // main memory or doing a yuyv conversion void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { - if (fbWidth * fbHeight > MAX_XFB_WIDTH * MAX_XFB_HEIGHT) - { - ERROR_LOG(VIDEO, "Framebuffer is too large: %ix%i", fbWidth, fbHeight); - return; - } - - size_t textureAddress = 0; - const int left = sourceRc.left; - const int right = sourceRc.right; - - for (u16 y = sourceRc.top; y < sourceRc.bottom; y++) - { - for (u16 x = left; x < right; x++) - { - const u32 color = Common::swap32(GetColor(x, y) | 0xFF); - - std::memcpy(&texture[textureAddress], &color, sizeof(u32)); - textureAddress += sizeof(u32); - } - } + // TODO: Upload directly to texture cache. } bool ZCompare(u16 x, u16 y, u32 z) diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index 9d42ff5790..52b2fb02cd 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -9,6 +9,7 @@ #include "Common/Logging/Log.h" #include "VideoBackends/Software/SWOGLWindow.h" +#include "VideoCommon/AbstractTexture.h" std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance; @@ -53,9 +54,9 @@ void SWOGLWindow::Prepare() std::string frag_shader = "in vec2 TexCoord;\n" "out vec4 ColorOut;\n" - "uniform sampler2D Texture;\n" + "uniform sampler2DArray samp;\n" "void main() {\n" - " ColorOut = texture(Texture, TexCoord);\n" + " ColorOut = texture(samp, vec3(TexCoord, 0.0));\n" "}\n"; std::string vertex_shader = "out vec2 TexCoord;\n" @@ -74,12 +75,9 @@ void SWOGLWindow::Prepare() glUseProgram(m_image_program); - glUniform1i(glGetUniformLocation(m_image_program, "Texture"), 0); + glUniform1i(glGetUniformLocation(m_image_program, "samp"), 0); - glGenTextures(1, &m_image_texture); - glBindTexture(GL_TEXTURE_2D, m_image_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment glGenVertexArrays(1, &m_image_vao); } @@ -89,23 +87,19 @@ void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color) m_text.push_back({text, x, y, color}); } -void SWOGLWindow::ShowImage(const u8* data, int stride, int width, int height, float aspect) +void SWOGLWindow::ShowImage(AbstractTexture* image, float aspect) { - GLInterface->MakeCurrent(); - GLInterface->Update(); - Prepare(); + GLInterface->Update(); // just updates the render window position and the backbuffer size GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth(); GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight(); glViewport(0, 0, glWidth, glHeight); - glBindTexture(GL_TEXTURE_2D, m_image_texture); + image->Bind(0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glUseProgram(m_image_program); @@ -119,7 +113,6 @@ void SWOGLWindow::ShowImage(const u8* data, int stride, int width, int height, f m_text.clear(); GLInterface->Swap(); - GLInterface->ClearCurrent(); } int SWOGLWindow::PeekMessages() diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.h b/Source/Core/VideoBackends/Software/SWOGLWindow.h index 110642b3f8..3b5d623846 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.h +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.h @@ -10,17 +10,20 @@ #include "Common/CommonTypes.h" +class AbstractTexture; + class SWOGLWindow { public: static void Init(void* window_handle); static void Shutdown(); + void Prepare(); // Will be printed on the *next* image void PrintText(const std::string& text, int x, int y, u32 color); // Image to show, will be swapped immediately - void ShowImage(const u8* data, int stride, int width, int height, float aspect); + void ShowImage(AbstractTexture* image, float aspect); int PeekMessages(); @@ -28,7 +31,6 @@ public: private: SWOGLWindow() {} - void Prepare(); struct TextData { @@ -40,5 +42,5 @@ private: bool m_init{false}; - u32 m_image_program, m_image_texture, m_image_vao; + u32 m_image_program, m_image_vao; }; diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index dc378cbede..9074a429b9 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -23,26 +23,13 @@ #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" -static u8* s_xfbColorTexture[2]; -static int s_currentColorTexture = 0; - SWRenderer::SWRenderer() : ::Renderer(static_cast<int>(MAX_XFB_WIDTH), static_cast<int>(MAX_XFB_HEIGHT)) { } -SWRenderer::~SWRenderer() -{ - delete[] s_xfbColorTexture[0]; - delete[] s_xfbColorTexture[1]; -} - void SWRenderer::Init() { - s_xfbColorTexture[0] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4]; - s_xfbColorTexture[1] = new u8[MAX_XFB_WIDTH * MAX_XFB_HEIGHT * 4]; - - s_currentColorTexture = 0; } void SWRenderer::Shutdown() @@ -55,80 +42,16 @@ void SWRenderer::RenderText(const std::string& pstr, int left, int top, u32 colo SWOGLWindow::s_instance->PrintText(pstr, left, top, color); } -u8* SWRenderer::GetNextColorTexture() -{ - return s_xfbColorTexture[!s_currentColorTexture]; -} - -u8* SWRenderer::GetCurrentColorTexture() -{ - return s_xfbColorTexture[s_currentColorTexture]; -} - -void SWRenderer::SwapColorTexture() -{ - s_currentColorTexture = !s_currentColorTexture; -} - -void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed* xfb, u32 fbWidth, u32 fbHeight) -{ - if (fbWidth * fbHeight > MAX_XFB_WIDTH * MAX_XFB_HEIGHT) - { - ERROR_LOG(VIDEO, "Framebuffer is too large: %ix%i", fbWidth, fbHeight); - return; - } - - u32 offset = 0; - u8* TexturePointer = GetNextColorTexture(); - - for (u16 y = 0; y < fbHeight; y++) - { - for (u16 x = 0; x < fbWidth; x += 2) - { - // We do this one color sample (aka 2 RGB pixles) at a time - int Y1 = xfb[x].Y - 16; - int Y2 = xfb[x + 1].Y - 16; - int U = int(xfb[x].UV) - 128; - int V = int(xfb[x + 1].UV) - 128; - - // We do the inverse BT.601 conversion for YCbCr to RGB - // http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion - TexturePointer[offset++] = MathUtil::Clamp(int(1.164f * Y1 + 1.596f * V), 0, 255); - TexturePointer[offset++] = - MathUtil::Clamp(int(1.164f * Y1 - 0.392f * U - 0.813f * V), 0, 255); - TexturePointer[offset++] = MathUtil::Clamp(int(1.164f * Y1 + 2.017f * U), 0, 255); - TexturePointer[offset++] = 255; - - TexturePointer[offset++] = MathUtil::Clamp(int(1.164f * Y2 + 1.596f * V), 0, 255); - TexturePointer[offset++] = - MathUtil::Clamp(int(1.164f * Y2 - 0.392f * U - 0.813f * V), 0, 255); - TexturePointer[offset++] = MathUtil::Clamp(int(1.164f * Y2 + 2.017f * U), 0, 255); - TexturePointer[offset++] = 255; - } - xfb += fbWidth; - } - SwapColorTexture(); -} - // Called on the GPU thread -void SWRenderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, - const EFBRectangle& rc, u64 ticks, float Gamma) +void SWRenderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks, float Gamma) { - if (g_ActiveConfig.bUseXFB) - { - EfbInterface::yuv422_packed* xfb = (EfbInterface::yuv422_packed*)Memory::GetPointer(xfbAddr); - UpdateColorTexture(xfb, fbWidth, fbHeight); - } - else - { - EfbInterface::BypassXFB(GetCurrentColorTexture(), fbWidth, fbHeight, rc, Gamma); - } + SWOGLWindow::s_instance->ShowImage(texture, 1.0); // Save screenshot if (IsFrameDumping()) { AVIDump::Frame state = AVIDump::FetchState(ticks); - DumpFrameData(GetCurrentColorTexture(), fbWidth, fbHeight, fbWidth * 4, state); + //DumpFrameData(GetCurrentColorTexture(), fbWidth, fbHeight, fbWidth * 4, state); FinishFrameData(); } @@ -136,15 +59,9 @@ void SWRenderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, DrawDebugText(); - SWOGLWindow::s_instance->ShowImage(GetCurrentColorTexture(), fbWidth * 4, fbWidth, fbHeight, 1.0); + SWOGLWindow::s_instance->ShowImage(texture, 1.0); UpdateActiveConfig(); - - // virtual XFB is not supported - if (g_ActiveConfig.bUseXFB) - { - Config::SetCurrent(Config::GFX_USE_REAL_XFB, true); - } } u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index b19b9841fd..e30e490bd7 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -14,16 +14,10 @@ class SWRenderer : public Renderer { public: SWRenderer(); - ~SWRenderer() override; static void Init(); static void Shutdown(); - static u8* GetNextColorTexture(); - static u8* GetCurrentColorTexture(); - void SwapColorTexture(); - void UpdateColorTexture(EfbInterface::yuv422_packed* xfb, u32 fbWidth, u32 fbHeight); - void RenderText(const std::string& pstr, int left, int top, u32 color) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {} @@ -32,8 +26,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override; - void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, - u64 ticks, float Gamma) override; + void SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks, float Gamma) override; void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index dff26e6d86..26a649b010 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -8,16 +8,17 @@ #include <utility> #include "Common/CommonTypes.h" +#include "Common/GL/GLInterfaceBase.h" #include "VideoBackends/Software/Clipper.h" #include "VideoBackends/Software/DebugUtil.h" -#include "VideoBackends/Software/EfbCopy.h" #include "VideoBackends/Software/EfbInterface.h" #include "VideoBackends/Software/Rasterizer.h" #include "VideoBackends/Software/SWOGLWindow.h" #include "VideoBackends/Software/SWRenderer.h" #include "VideoBackends/Software/SWTexture.h" #include "VideoBackends/Software/SWVertexLoader.h" +#include "VideoBackends/Software/TextureCache.h" #include "VideoBackends/Software/VideoBackend.h" #include "VideoCommon/FramebufferManagerBase.h" @@ -46,58 +47,6 @@ public: bool IsFlushed() const override { return true; } }; -class TextureCache : public TextureCacheBase -{ -public: - bool CompileShaders() override { return true; } - void DeleteShaders() override {} - void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, - TLUTFormat format) override - { - } - void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, - u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, - bool scale_by_half) override - { - EfbCopy::CopyEfb(); - } - -private: - std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override - { - return std::make_unique<SWTexture>(config); - } - - void CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, const EFBRectangle& src_rect, - bool scale_by_half, unsigned int cbuf_id, const float* colmat) override - { - EfbCopy::CopyEfb(); - } -}; - -class XFBSource : public XFBSourceBase -{ - void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) override {} - void CopyEFB(float Gamma) override {} -}; - -class FramebufferManager : public FramebufferManagerBase -{ - std::unique_ptr<XFBSourceBase> CreateXFBSource(unsigned int target_width, - unsigned int target_height, - unsigned int layers) override - { - return std::make_unique<XFBSource>(); - } - - std::pair<u32, u32> GetTargetSize() const override { return std::make_pair(0, 0); } - void CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, - float Gamma = 1.0f) override - { - EfbCopy::CopyEfb(); - } -}; - std::string VideoSoftware::GetName() const { return "Software Renderer"; @@ -123,6 +72,7 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsBPTCTextures = false; + g_Config.backend_info.bSupportsCopyToVram = false; // aamodes g_Config.backend_info.AAModes = {1}; @@ -169,12 +119,14 @@ void VideoSoftware::Video_Cleanup() // This is called after Video_Initialize() from the Core void VideoSoftware::Video_Prepare() { + GLInterface->MakeCurrent(); + SWOGLWindow::s_instance->Prepare(); + g_renderer = std::make_unique<SWRenderer>(); g_vertex_manager = std::make_unique<SWVertexLoader>(); g_perf_query = std::make_unique<PerfQuery>(); g_texture_cache = std::make_unique<TextureCache>(); SWRenderer::Init(); - g_framebuffer_manager = std::make_unique<FramebufferManager>(); } unsigned int VideoSoftware::PeekMessages() diff --git a/Source/Core/VideoBackends/Software/Software.vcxproj b/Source/Core/VideoBackends/Software/Software.vcxproj index bf13233d67..36d833ba2c 100644 --- a/Source/Core/VideoBackends/Software/Software.vcxproj +++ b/Source/Core/VideoBackends/Software/Software.vcxproj @@ -65,6 +65,7 @@ <ClInclude Include="SWTexture.h" /> <ClInclude Include="SWVertexLoader.h" /> <ClInclude Include="Tev.h" /> + <ClInclude Include="TextureCache.h" /> <ClInclude Include="TextureEncoder.h" /> <ClInclude Include="TextureSampler.h" /> <ClInclude Include="TransformUnit.h" /> diff --git a/Source/Core/VideoBackends/Software/TextureCache.h b/Source/Core/VideoBackends/Software/TextureCache.h new file mode 100644 index 0000000000..82c2ce9f55 --- /dev/null +++ b/Source/Core/VideoBackends/Software/TextureCache.h @@ -0,0 +1,41 @@ +#pragma once + +#include <memory> + +#include "VideoBackends/Software/EfbCopy.h" +#include "VideoBackends/Software/SWTexture.h" +#include "VideoCommon/TextureCacheBase.h" + +namespace SW +{ + +class TextureCache : public TextureCacheBase +{ +public: + bool CompileShaders() override { return true; } + void DeleteShaders() override {} + void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, + TLUTFormat format) override + { + } + void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) override + { + EfbCopy::CopyEfb(); + } + +private: + std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override + { + return std::make_unique<SWTexture>(config); + } + + void CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, const EFBRectangle& src_rect, + bool scale_by_half, unsigned int cbuf_id, const float* colmat) override + { + EfbCopy::CopyEfb(); + } +}; + +} // namespace SW |
