mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 22:09:19 -07:00
72e3f1ecec
Making changes to ConfigManager.h has always been a pain, because it means rebuilding half of Dolphin, since a lot of files depend on and include this header. However, it turns out some includes are unnecessary. This commit removes ConfigManager includes from files which don't contain SConfig or GPUDeterminismMode or GPU_DETERMINISM (which means the ConfigManager include is not used). (I've also had to get rid of some indirect includes.)
196 lines
4.9 KiB
C++
196 lines
4.9 KiB
C++
// Copyright 2009 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <algorithm>
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <string>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/FileUtil.h"
|
|
#include "Common/Logging/Log.h"
|
|
#include "Common/StringUtil.h"
|
|
|
|
#include "Core/HW/Memmap.h"
|
|
|
|
#include "VideoBackends/Software/EfbCopy.h"
|
|
#include "VideoBackends/Software/SWOGLWindow.h"
|
|
#include "VideoBackends/Software/SWRenderer.h"
|
|
|
|
#include "VideoCommon/BoundingBox.h"
|
|
#include "VideoCommon/Fifo.h"
|
|
#include "VideoCommon/ImageWrite.h"
|
|
#include "VideoCommon/OnScreenDisplay.h"
|
|
#include "VideoCommon/VideoConfig.h"
|
|
|
|
static u8* s_xfbColorTexture[2];
|
|
static int s_currentColorTexture = 0;
|
|
|
|
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()
|
|
{
|
|
g_Config.bRunning = false;
|
|
UpdateActiveConfig();
|
|
}
|
|
|
|
void SWRenderer::RenderText(const std::string& pstr, int left, int top, u32 color)
|
|
{
|
|
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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
// Save screenshot
|
|
if (IsFrameDumping())
|
|
{
|
|
AVIDump::Frame state = AVIDump::FetchState(ticks);
|
|
DumpFrameData(GetCurrentColorTexture(), fbWidth, fbHeight, fbWidth * 4, state);
|
|
FinishFrameData();
|
|
}
|
|
|
|
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
|
|
|
|
DrawDebugText();
|
|
|
|
SWOGLWindow::s_instance->ShowImage(GetCurrentColorTexture(), fbWidth * 4, fbWidth, fbHeight, 1.0);
|
|
|
|
UpdateActiveConfig();
|
|
|
|
// virtual XFB is not supported
|
|
if (g_ActiveConfig.bUseXFB)
|
|
g_ActiveConfig.bUseRealXFB = true;
|
|
}
|
|
|
|
u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
|
{
|
|
u32 value = 0;
|
|
|
|
switch (type)
|
|
{
|
|
case PEEK_Z:
|
|
{
|
|
value = EfbInterface::GetDepth(x, y);
|
|
break;
|
|
}
|
|
case PEEK_COLOR:
|
|
{
|
|
const u32 color = EfbInterface::GetColor(x, y);
|
|
|
|
// rgba to argb
|
|
value = (color >> 8) | (color & 0xff) << 24;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
u16 SWRenderer::BBoxRead(int index)
|
|
{
|
|
return BoundingBox::coords[index];
|
|
}
|
|
|
|
void SWRenderer::BBoxWrite(int index, u16 value)
|
|
{
|
|
BoundingBox::coords[index] = value;
|
|
}
|
|
|
|
TargetRectangle SWRenderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
|
{
|
|
TargetRectangle result;
|
|
result.left = rc.left;
|
|
result.top = rc.top;
|
|
result.right = rc.right;
|
|
result.bottom = rc.bottom;
|
|
return result;
|
|
}
|
|
|
|
void SWRenderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable,
|
|
bool zEnable, u32 color, u32 z)
|
|
{
|
|
EfbCopy::ClearEfb();
|
|
}
|