summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2017-05-29 17:02:09 -0500
committeriwubcode <iwubcode@users.noreply.github.com>2017-11-17 19:47:56 -0600
commit79387dddb24ddf035b70cd9379a42368dcd49e93 (patch)
tree7b783c46e1ffd052842f11112f58c61993f0af1b /Source/Core/VideoBackends/Software
parent84ca9a4aec0048e5ac01caea8f8be9210eb947f6 (diff)
Add support for hybrid XFB
Diffstat (limited to 'Source/Core/VideoBackends/Software')
-rw-r--r--Source/Core/VideoBackends/Software/EfbInterface.cpp34
-rw-r--r--Source/Core/VideoBackends/Software/SWOGLWindow.cpp27
-rw-r--r--Source/Core/VideoBackends/Software/SWOGLWindow.h8
-rw-r--r--Source/Core/VideoBackends/Software/SWRenderer.cpp91
-rw-r--r--Source/Core/VideoBackends/Software/SWRenderer.h9
-rw-r--r--Source/Core/VideoBackends/Software/SWmain.cpp60
-rw-r--r--Source/Core/VideoBackends/Software/Software.vcxproj1
-rw-r--r--Source/Core/VideoBackends/Software/TextureCache.h41
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