mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
VideoSW: Use more VideoCommon
Now we require lots of empty functions, but this removes by far more duplicated code.
This commit is contained in:
@@ -76,8 +76,6 @@
|
|||||||
|
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
|
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
|
||||||
|
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
#include "VideoCommon/VideoConfig.h"
|
#include "VideoCommon/VideoConfig.h"
|
||||||
|
|
||||||
|
|||||||
@@ -31,13 +31,16 @@ IntegerSetting<T>::IntegerSetting(wxWindow* parent, const wxString& label, T& se
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& _ininame) :
|
SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& ininame) :
|
||||||
wxDialog(parent, wxID_ANY,
|
wxDialog(parent, wxID_ANY,
|
||||||
wxString(wxString::Format(_("Dolphin %s Graphics Configuration"), title))),
|
wxString(wxString::Format(_("Dolphin %s Graphics Configuration"), title)))
|
||||||
vconfig(g_SWVideoConfig),
|
|
||||||
ininame(_ininame)
|
|
||||||
{
|
{
|
||||||
vconfig.Load((File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini").c_str());
|
VideoConfig& vconfig = g_ActiveConfig;
|
||||||
|
|
||||||
|
if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini"))
|
||||||
|
vconfig.Load(File::GetUserPath(D_CONFIG_IDX) + "GFX.ini");
|
||||||
|
else
|
||||||
|
vconfig.Load(File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini");
|
||||||
|
|
||||||
wxNotebook* const notebook = new wxNotebook(this, wxID_ANY);
|
wxNotebook* const notebook = new wxNotebook(this, wxID_ANY);
|
||||||
|
|
||||||
@@ -77,7 +80,7 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std
|
|||||||
}
|
}
|
||||||
|
|
||||||
// xfb
|
// xfb
|
||||||
szr_rendering->Add(new SettingCheckBox(page_general, _("Bypass XFB"), "", vconfig.bBypassXFB));
|
szr_rendering->Add(new SettingCheckBox(page_general, _("Bypass XFB"), "", vconfig.bUseXFB, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - info
|
// - info
|
||||||
@@ -87,7 +90,7 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std
|
|||||||
wxGridSizer* const szr_info = new wxGridSizer(2, 5, 5);
|
wxGridSizer* const szr_info = new wxGridSizer(2, 5, 5);
|
||||||
group_info->Add(szr_info, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_info->Add(szr_info, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
szr_info->Add(new SettingCheckBox(page_general, _("Various Statistics"), "", vconfig.bShowStats));
|
szr_info->Add(new SettingCheckBox(page_general, _("Various Statistics"), "", vconfig.bOverlayStats));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - utility
|
// - utility
|
||||||
@@ -117,8 +120,8 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std
|
|||||||
wxFlexGridSizer* const szr_misc = new wxFlexGridSizer(2, 5, 5);
|
wxFlexGridSizer* const szr_misc = new wxFlexGridSizer(2, 5, 5);
|
||||||
group_misc->Add(szr_misc, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_misc->Add(szr_misc, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
szr_misc->Add(new U32Setting(page_general, _("Start"), vconfig.drawStart, 0, 100000));
|
szr_misc->Add(new IntegerSetting<int>(page_general, _("Start"), vconfig.drawStart, 0, 100000));
|
||||||
szr_misc->Add(new U32Setting(page_general, _("End"), vconfig.drawEnd, 0, 100000));
|
szr_misc->Add(new IntegerSetting<int>(page_general, _("End"), vconfig.drawEnd, 0, 100000));
|
||||||
}
|
}
|
||||||
|
|
||||||
page_general->SetSizerAndFit(szr_general);
|
page_general->SetSizerAndFit(szr_general);
|
||||||
@@ -136,5 +139,5 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std
|
|||||||
|
|
||||||
SoftwareVideoConfigDialog::~SoftwareVideoConfigDialog()
|
SoftwareVideoConfigDialog::~SoftwareVideoConfigDialog()
|
||||||
{
|
{
|
||||||
g_SWVideoConfig.Save((File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini").c_str());
|
g_ActiveConfig.Save((File::GetUserPath(D_CONFIG_IDX) + "GFX.ini").c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
|
#include "VideoCommon/VideoConfig.h"
|
||||||
|
|
||||||
class SoftwareVideoConfigDialog : public wxDialog
|
class SoftwareVideoConfigDialog : public wxDialog
|
||||||
{
|
{
|
||||||
@@ -37,8 +37,4 @@ public:
|
|||||||
}
|
}
|
||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
SWVideoConfig& vconfig;
|
|
||||||
std::string ininame;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ private:
|
|||||||
T& m_setting;
|
T& m_setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IntegerSetting<u32> U32Setting;
|
|
||||||
|
|
||||||
class SettingChoice : public wxChoice
|
class SettingChoice : public wxChoice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1,178 +0,0 @@
|
|||||||
// Copyright 2009 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
|
||||||
#include "Core/Core.h"
|
|
||||||
#include "Core/HW/Memmap.h"
|
|
||||||
|
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/EfbCopy.h"
|
|
||||||
#include "VideoBackends/Software/EfbInterface.h"
|
|
||||||
#include "VideoBackends/Software/Rasterizer.h"
|
|
||||||
#include "VideoBackends/Software/Tev.h"
|
|
||||||
|
|
||||||
#include "VideoCommon/BoundingBox.h"
|
|
||||||
#include "VideoCommon/PixelEngine.h"
|
|
||||||
#include "VideoCommon/TextureDecoder.h"
|
|
||||||
#include "VideoCommon/VideoCommon.h"
|
|
||||||
|
|
||||||
|
|
||||||
void InitBPMemory()
|
|
||||||
{
|
|
||||||
memset(&bpmem, 0, sizeof(bpmem));
|
|
||||||
bpmem.bpMask = 0xFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SWLoadBPReg(u32 value)
|
|
||||||
{
|
|
||||||
//handle the mask register
|
|
||||||
int address = value >> 24;
|
|
||||||
int oldval = ((u32*)&bpmem)[address];
|
|
||||||
int newval = (oldval & ~bpmem.bpMask) | (value & bpmem.bpMask);
|
|
||||||
|
|
||||||
((u32*)&bpmem)[address] = newval;
|
|
||||||
|
|
||||||
//reset the mask register
|
|
||||||
if (address != 0xFE)
|
|
||||||
bpmem.bpMask = 0xFFFFFF;
|
|
||||||
|
|
||||||
SWBPWritten(address, newval);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SWBPWritten(int address, int newvalue)
|
|
||||||
{
|
|
||||||
switch (address)
|
|
||||||
{
|
|
||||||
case BPMEM_SCISSORTL:
|
|
||||||
case BPMEM_SCISSORBR:
|
|
||||||
case BPMEM_SCISSOROFFSET:
|
|
||||||
Rasterizer::SetScissor();
|
|
||||||
break;
|
|
||||||
case BPMEM_SETDRAWDONE: // This is called when the game is done drawing (eg: like in DX: Begin(); Draw(); End();)
|
|
||||||
switch (bpmem.drawdone & 0xFF)
|
|
||||||
{
|
|
||||||
case 0x02:
|
|
||||||
PixelEngine::SetFinish(); // may generate interrupt
|
|
||||||
DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bpmem.drawdone & 0xFFFF));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
WARN_LOG(VIDEO, "GXSetDrawDone ??? (value 0x%02X)", (bpmem.drawdone & 0xFFFF));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
|
|
||||||
DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bpmem.petoken & 0xFFFF));
|
|
||||||
PixelEngine::SetToken(static_cast<u16>(bpmem.petokenint & 0xFFFF), false);
|
|
||||||
break;
|
|
||||||
case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
|
|
||||||
DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bpmem.petokenint & 0xFFFF));
|
|
||||||
PixelEngine::SetToken(static_cast<u16>(bpmem.petokenint & 0xFFFF), true);
|
|
||||||
break;
|
|
||||||
case BPMEM_TRIGGER_EFB_COPY:
|
|
||||||
EfbCopy::CopyEfb();
|
|
||||||
break;
|
|
||||||
case BPMEM_CLEARBBOX1:
|
|
||||||
BoundingBox::coords[BoundingBox::LEFT] = newvalue >> 10;
|
|
||||||
BoundingBox::coords[BoundingBox::RIGHT] = newvalue & 0x3ff;
|
|
||||||
break;
|
|
||||||
case BPMEM_CLEARBBOX2:
|
|
||||||
BoundingBox::coords[BoundingBox::TOP] = newvalue >> 10;
|
|
||||||
BoundingBox::coords[BoundingBox::BOTTOM] = newvalue & 0x3ff;
|
|
||||||
break;
|
|
||||||
case BPMEM_CLEAR_PIXEL_PERF:
|
|
||||||
// TODO: I didn't test if the value written to this register affects the amount of cleared registers
|
|
||||||
memset(EfbInterface::perf_values, 0, sizeof(EfbInterface::perf_values));
|
|
||||||
break;
|
|
||||||
case BPMEM_LOADTLUT0: // This one updates bpmem.tlutXferSrc, no need to do anything here.
|
|
||||||
break;
|
|
||||||
case BPMEM_LOADTLUT1: // Load a Texture Look Up Table
|
|
||||||
{
|
|
||||||
u32 tlutTMemAddr = (newvalue & 0x3FF) << 9;
|
|
||||||
u32 tlutXferCount = (newvalue & 0x1FFC00) >> 5;
|
|
||||||
u32 addr = bpmem.tmem_config.tlut_src << 5;
|
|
||||||
|
|
||||||
// The GameCube ignores the upper bits of this address. Some games (WW, MKDD) set them.
|
|
||||||
if (!SConfig::GetInstance().bWii)
|
|
||||||
addr = addr & 0x01FFFFFF;
|
|
||||||
|
|
||||||
Memory::CopyFromEmu(texMem + tlutTMemAddr, addr, tlutXferCount);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case BPMEM_PRELOAD_MODE:
|
|
||||||
if (newvalue != 0)
|
|
||||||
{
|
|
||||||
// TODO: Not quite sure if this is completely correct (likely not)
|
|
||||||
// NOTE: libogc's implementation of GX_PreloadEntireTexture seems flawed, so it's not necessarily a good reference for RE'ing this feature.
|
|
||||||
|
|
||||||
BPS_TmemConfig& tmem_cfg = bpmem.tmem_config;
|
|
||||||
u32 src_addr = tmem_cfg.preload_addr << 5; // TODO: Should we add mask here on GC?
|
|
||||||
u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE;
|
|
||||||
u32 tmem_addr_even = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE;
|
|
||||||
|
|
||||||
if (tmem_cfg.preload_tile_info.type != 3)
|
|
||||||
{
|
|
||||||
if (tmem_addr_even + size > TMEM_SIZE)
|
|
||||||
size = TMEM_SIZE - tmem_addr_even;
|
|
||||||
|
|
||||||
Memory::CopyFromEmu(texMem + tmem_addr_even, src_addr, size);
|
|
||||||
}
|
|
||||||
else // RGBA8 tiles (and CI14, but that might just be stupid libogc!)
|
|
||||||
{
|
|
||||||
u8* src_ptr = Memory::GetPointer(src_addr);
|
|
||||||
|
|
||||||
// AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for everything
|
|
||||||
u32 tmem_addr_odd = tmem_cfg.preload_tmem_odd * TMEM_LINE_SIZE;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < tmem_cfg.preload_tile_info.count; ++i)
|
|
||||||
{
|
|
||||||
if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE ||
|
|
||||||
tmem_addr_odd + TMEM_LINE_SIZE > TMEM_SIZE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE);
|
|
||||||
memcpy(texMem + tmem_addr_odd, src_ptr + TMEM_LINE_SIZE, TMEM_LINE_SIZE);
|
|
||||||
tmem_addr_even += TMEM_LINE_SIZE;
|
|
||||||
tmem_addr_odd += TMEM_LINE_SIZE;
|
|
||||||
src_ptr += TMEM_LINE_SIZE * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BPMEM_TEV_COLOR_RA:
|
|
||||||
case BPMEM_TEV_COLOR_RA + 2:
|
|
||||||
case BPMEM_TEV_COLOR_RA + 4:
|
|
||||||
case BPMEM_TEV_COLOR_RA + 6:
|
|
||||||
{
|
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
|
||||||
bool is_konst = reg.type_ra != 0;
|
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::ALP_C, is_konst, static_cast<s16>(reg.alpha));
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::RED_C, is_konst, static_cast<s16>(reg.red));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case BPMEM_TEV_COLOR_BG:
|
|
||||||
case BPMEM_TEV_COLOR_BG + 2:
|
|
||||||
case BPMEM_TEV_COLOR_BG + 4:
|
|
||||||
case BPMEM_TEV_COLOR_BG + 6:
|
|
||||||
{
|
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
|
||||||
bool is_konst = reg.type_bg != 0;
|
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::GRN_C, is_konst, static_cast<s16>(reg.green));
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::BLU_C, is_konst, static_cast<s16>(reg.blue));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright 2008 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "VideoCommon/BPMemory.h"
|
|
||||||
|
|
||||||
void InitBPMemory();
|
|
||||||
void SWBPWritten(int address, int newvalue);
|
|
||||||
void SWLoadBPReg(u32 value);
|
|
||||||
@@ -1,24 +1,17 @@
|
|||||||
set(SRCS BPMemLoader.cpp
|
set(SRCS Clipper.cpp
|
||||||
CPMemLoader.cpp
|
|
||||||
Clipper.cpp
|
|
||||||
DebugUtil.cpp
|
DebugUtil.cpp
|
||||||
EfbCopy.cpp
|
EfbCopy.cpp
|
||||||
EfbInterface.cpp
|
EfbInterface.cpp
|
||||||
OpcodeDecoder.cpp
|
|
||||||
Rasterizer.cpp
|
Rasterizer.cpp
|
||||||
SWCommandProcessor.cpp
|
|
||||||
SWOGLWindow.cpp
|
SWOGLWindow.cpp
|
||||||
SWRenderer.cpp
|
SWRenderer.cpp
|
||||||
SWStatistics.cpp
|
|
||||||
SWVertexLoader.cpp
|
SWVertexLoader.cpp
|
||||||
SWVideoConfig.cpp
|
|
||||||
SWmain.cpp
|
SWmain.cpp
|
||||||
SetupUnit.cpp
|
SetupUnit.cpp
|
||||||
Tev.cpp
|
Tev.cpp
|
||||||
TextureEncoder.cpp
|
TextureEncoder.cpp
|
||||||
TextureSampler.cpp
|
TextureSampler.cpp
|
||||||
TransformUnit.cpp
|
TransformUnit.cpp)
|
||||||
XFMemLoader.cpp)
|
|
||||||
|
|
||||||
set(LIBS videocommon
|
set(LIBS videocommon
|
||||||
SOIL
|
SOIL
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
// Copyright 2009 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "Common/CommonFuncs.h"
|
|
||||||
#include "Core/HW/Memmap.h"
|
|
||||||
#include "VideoBackends/Software/CPMemLoader.h"
|
|
||||||
#include "VideoCommon/VideoCommon.h"
|
|
||||||
|
|
||||||
|
|
||||||
void SWLoadCPReg(u32 sub_cmd, u32 value)
|
|
||||||
{
|
|
||||||
switch (sub_cmd & 0xF0)
|
|
||||||
{
|
|
||||||
case 0x30:
|
|
||||||
g_main_cp_state.matrix_index_a.Hex = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x40:
|
|
||||||
g_main_cp_state.matrix_index_b.Hex = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x50:
|
|
||||||
g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
|
|
||||||
g_main_cp_state.vtx_desc.Hex |= value;
|
|
||||||
g_main_cp_state.bases_dirty = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x60:
|
|
||||||
g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
|
|
||||||
g_main_cp_state.vtx_desc.Hex |= (u64)value << 17;
|
|
||||||
g_main_cp_state.bases_dirty = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x70:
|
|
||||||
_assert_((sub_cmd & 0x0F) < 8);
|
|
||||||
g_main_cp_state.vtx_attr[sub_cmd & 7].g0.Hex = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80:
|
|
||||||
_assert_((sub_cmd & 0x0F) < 8);
|
|
||||||
g_main_cp_state.vtx_attr[sub_cmd & 7].g1.Hex = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x90:
|
|
||||||
_assert_((sub_cmd & 0x0F) < 8);
|
|
||||||
g_main_cp_state.vtx_attr[sub_cmd & 7].g2.Hex = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Pointers to vertex arrays in GC RAM
|
|
||||||
case 0xA0:
|
|
||||||
g_main_cp_state.array_bases[sub_cmd & 0xF] = value;
|
|
||||||
g_main_cp_state.bases_dirty = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xB0:
|
|
||||||
g_main_cp_state.array_strides[sub_cmd & 0xF] = value & 0xFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// Copyright 2008 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "VideoCommon/CPMemory.h"
|
|
||||||
|
|
||||||
void SWLoadCPReg(u32 sub_cmd, u32 value);
|
|
||||||
@@ -36,12 +36,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/Clipper.h"
|
#include "VideoBackends/Software/Clipper.h"
|
||||||
#include "VideoBackends/Software/NativeVertexFormat.h"
|
#include "VideoBackends/Software/NativeVertexFormat.h"
|
||||||
#include "VideoBackends/Software/Rasterizer.h"
|
#include "VideoBackends/Software/Rasterizer.h"
|
||||||
#include "VideoBackends/Software/SWStatistics.h"
|
|
||||||
#include "VideoBackends/Software/XFMemLoader.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
|
#include "VideoCommon/Statistics.h"
|
||||||
|
#include "VideoCommon/XFMemory.h"
|
||||||
|
|
||||||
namespace Clipper
|
namespace Clipper
|
||||||
{
|
{
|
||||||
@@ -56,13 +57,6 @@ namespace Clipper
|
|||||||
static OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES];
|
static OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES];
|
||||||
static OutputVertexData *Vertices[NUM_INDICES];
|
static OutputVertexData *Vertices[NUM_INDICES];
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
|
||||||
{
|
|
||||||
p.DoArray(m_ViewOffset);
|
|
||||||
for (auto& ClippedVertice : ClippedVertices)
|
|
||||||
ClippedVertice.DoState(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i)
|
for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i)
|
||||||
@@ -220,7 +214,7 @@ namespace Clipper
|
|||||||
POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1);
|
POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1);
|
||||||
POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1);
|
POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1);
|
||||||
|
|
||||||
INCSTAT(swstats.thisFrame.numTrianglesClipped);
|
INCSTAT(stats.thisFrame.numTrianglesClipped);
|
||||||
|
|
||||||
// transform the poly in inlist into triangles
|
// transform the poly in inlist into triangles
|
||||||
indices[0] = inlist[0];
|
indices[0] = inlist[0];
|
||||||
@@ -287,7 +281,7 @@ namespace Clipper
|
|||||||
|
|
||||||
void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
|
void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
|
||||||
{
|
{
|
||||||
INCSTAT(swstats.thisFrame.numTrianglesIn)
|
INCSTAT(stats.thisFrame.numTrianglesIn)
|
||||||
|
|
||||||
bool backface;
|
bool backface;
|
||||||
|
|
||||||
@@ -411,7 +405,7 @@ namespace Clipper
|
|||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
INCSTAT(swstats.thisFrame.numTrianglesRejected)
|
INCSTAT(stats.thisFrame.numTrianglesRejected)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,13 +425,13 @@ namespace Clipper
|
|||||||
|
|
||||||
if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing
|
if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing
|
||||||
{
|
{
|
||||||
INCSTAT(swstats.thisFrame.numTrianglesCulled)
|
INCSTAT(stats.thisFrame.numTrianglesCulled)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing
|
if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing
|
||||||
{
|
{
|
||||||
INCSTAT(swstats.thisFrame.numTrianglesCulled)
|
INCSTAT(stats.thisFrame.numTrianglesCulled)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct OutputVertexData;
|
struct OutputVertexData;
|
||||||
class PointerWrap;
|
|
||||||
|
|
||||||
namespace Clipper
|
namespace Clipper
|
||||||
{
|
{
|
||||||
@@ -20,6 +19,4 @@ namespace Clipper
|
|||||||
bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface);
|
bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface);
|
||||||
|
|
||||||
void PerspectiveDivide(OutputVertexData *vertex);
|
void PerspectiveDivide(OutputVertexData *vertex);
|
||||||
|
|
||||||
void DoState(PointerWrap &p);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,16 @@
|
|||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/DebugUtil.h"
|
#include "VideoBackends/Software/DebugUtil.h"
|
||||||
#include "VideoBackends/Software/EfbInterface.h"
|
#include "VideoBackends/Software/EfbInterface.h"
|
||||||
#include "VideoBackends/Software/SWCommandProcessor.h"
|
|
||||||
#include "VideoBackends/Software/SWRenderer.h"
|
#include "VideoBackends/Software/SWRenderer.h"
|
||||||
#include "VideoBackends/Software/SWStatistics.h"
|
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
|
||||||
#include "VideoBackends/Software/TextureSampler.h"
|
#include "VideoBackends/Software/TextureSampler.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/Fifo.h"
|
#include "VideoCommon/Fifo.h"
|
||||||
#include "VideoCommon/ImageWrite.h"
|
#include "VideoCommon/ImageWrite.h"
|
||||||
|
#include "VideoCommon/Statistics.h"
|
||||||
|
#include "VideoCommon/VideoConfig.h"
|
||||||
|
|
||||||
namespace DebugUtil
|
namespace DebugUtil
|
||||||
{
|
{
|
||||||
@@ -109,7 +107,7 @@ void DumpActiveTextures()
|
|||||||
{
|
{
|
||||||
SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.png",
|
SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.png",
|
||||||
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip);
|
stats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +124,7 @@ void DumpActiveTextures()
|
|||||||
{
|
{
|
||||||
SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.png",
|
SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.png",
|
||||||
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip);
|
stats.thisFrame.numDrawnObjects, stageNum, texmap, mip), texmap, mip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,13 +152,6 @@ static void DumpEfb(const std::string& filename)
|
|||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DumpColorTexture(const std::string& filename, u32 width, u32 height)
|
|
||||||
{
|
|
||||||
TextureToPng(SWRenderer::GetCurrentColorTexture(), width * 4, filename, width, height, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
|
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
|
||||||
{
|
{
|
||||||
int buffer = bufferBase + subBuffer;
|
int buffer = bufferBase + subBuffer;
|
||||||
@@ -202,7 +193,7 @@ void OnObjectBegin()
|
|||||||
{
|
{
|
||||||
if (!g_bSkipCurrentFrame)
|
if (!g_bSkipCurrentFrame)
|
||||||
{
|
{
|
||||||
if (g_SWVideoConfig.bDumpTextures && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
|
if (g_ActiveConfig.bDumpTextures && stats.thisFrame.numDrawnObjects >= g_ActiveConfig.drawStart && stats.thisFrame.numDrawnObjects < g_ActiveConfig.drawEnd)
|
||||||
DumpActiveTextures();
|
DumpActiveTextures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,10 +202,10 @@ void OnObjectEnd()
|
|||||||
{
|
{
|
||||||
if (!g_bSkipCurrentFrame)
|
if (!g_bSkipCurrentFrame)
|
||||||
{
|
{
|
||||||
if (g_SWVideoConfig.bDumpObjects && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
|
if (g_ActiveConfig.bDumpObjects && stats.thisFrame.numDrawnObjects >= g_ActiveConfig.drawStart && stats.thisFrame.numDrawnObjects < g_ActiveConfig.drawEnd)
|
||||||
DumpEfb(StringFromFormat("%sobject%i.png",
|
DumpEfb(StringFromFormat("%sobject%i.png",
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects));
|
stats.thisFrame.numDrawnObjects));
|
||||||
|
|
||||||
for (int i = 0; i < NUM_OBJECT_BUFFERS; i++)
|
for (int i = 0; i < NUM_OBJECT_BUFFERS; i++)
|
||||||
{
|
{
|
||||||
@@ -223,7 +214,7 @@ void OnObjectEnd()
|
|||||||
DrawnToBuffer[i] = false;
|
DrawnToBuffer[i] = false;
|
||||||
std::string filename = StringFromFormat("%sobject%i_%s(%i).png",
|
std::string filename = StringFromFormat("%sobject%i_%s(%i).png",
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
|
||||||
swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]);
|
stats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]);
|
||||||
|
|
||||||
TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
|
TextureToPng((u8*)ObjectBuffer[i], EFB_WIDTH * 4, filename, EFB_WIDTH, EFB_HEIGHT, true);
|
||||||
memset(ObjectBuffer[i], 0, EFB_WIDTH * EFB_HEIGHT * sizeof(u32));
|
memset(ObjectBuffer[i], 0, EFB_WIDTH * EFB_HEIGHT * sizeof(u32));
|
||||||
@@ -231,20 +222,7 @@ void OnObjectEnd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
swstats.thisFrame.numDrawnObjects++;
|
stats.thisFrame.numDrawnObjects++;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If frame dumping is enabled, dump whatever is drawn to the screen.
|
|
||||||
void OnFrameEnd(u32 width, u32 height)
|
|
||||||
{
|
|
||||||
if (!g_bSkipCurrentFrame)
|
|
||||||
{
|
|
||||||
if (SConfig::GetInstance().m_DumpFrames)
|
|
||||||
{
|
|
||||||
DumpColorTexture(StringFromFormat("%sframe%i_color.png",
|
|
||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount), width, height);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ namespace DebugUtil
|
|||||||
void OnObjectBegin();
|
void OnObjectBegin();
|
||||||
void OnObjectEnd();
|
void OnObjectEnd();
|
||||||
|
|
||||||
void OnFrameEnd(u32 width, u32 height);
|
|
||||||
|
|
||||||
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name);
|
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name);
|
||||||
|
|
||||||
void DrawTempBuffer(u8 *color, int buffer);
|
void DrawTempBuffer(u8 *color, int buffer);
|
||||||
|
|||||||
@@ -5,15 +5,13 @@
|
|||||||
#include "Common/GL/GLInterfaceBase.h"
|
#include "Common/GL/GLInterfaceBase.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/DebugUtil.h"
|
#include "VideoBackends/Software/DebugUtil.h"
|
||||||
#include "VideoBackends/Software/EfbCopy.h"
|
#include "VideoBackends/Software/EfbCopy.h"
|
||||||
#include "VideoBackends/Software/EfbInterface.h"
|
#include "VideoBackends/Software/EfbInterface.h"
|
||||||
#include "VideoBackends/Software/SWCommandProcessor.h"
|
|
||||||
#include "VideoBackends/Software/SWRenderer.h"
|
#include "VideoBackends/Software/SWRenderer.h"
|
||||||
#include "VideoBackends/Software/SWStatistics.h"
|
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
|
||||||
#include "VideoBackends/Software/TextureEncoder.h"
|
#include "VideoBackends/Software/TextureEncoder.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/Fifo.h"
|
#include "VideoCommon/Fifo.h"
|
||||||
|
|
||||||
static const float s_gammaLUT[] =
|
static const float s_gammaLUT[] =
|
||||||
@@ -33,31 +31,9 @@ namespace EfbCopy
|
|||||||
INFO_LOG(VIDEO, "xfbaddr: %x, fbwidth: %i, fbheight: %i, source: (%i, %i, %i, %i), Gamma %f",
|
INFO_LOG(VIDEO, "xfbaddr: %x, fbwidth: %i, fbheight: %i, source: (%i, %i, %i, %i), Gamma %f",
|
||||||
xfbAddr, fbWidth, fbHeight, sourceRc.top, sourceRc.left, sourceRc.bottom, sourceRc.right, Gamma);
|
xfbAddr, fbWidth, fbHeight, sourceRc.top, sourceRc.left, sourceRc.bottom, sourceRc.right, Gamma);
|
||||||
|
|
||||||
if (!g_SWVideoConfig.bBypassXFB)
|
EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed*) Memory::GetPointer(xfbAddr);
|
||||||
{
|
|
||||||
EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed *) Memory::GetPointer(xfbAddr);
|
|
||||||
|
|
||||||
EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma);
|
EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Ask SWRenderer for the next color texture
|
|
||||||
u8 *colorTexture = SWRenderer::GetNextColorTexture();
|
|
||||||
|
|
||||||
EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);
|
|
||||||
|
|
||||||
// Tell SWRenderer we are now finished with it.
|
|
||||||
SWRenderer::SwapColorTexture();
|
|
||||||
|
|
||||||
// FifoPlayer is broken and never calls BeginFrame/EndFrame.
|
|
||||||
// Hence, we manually force a swap now. This emulates the behavior
|
|
||||||
// of hardware backends with XFB emulation disabled.
|
|
||||||
// TODO: Fix FifoPlayer by making proper use of VideoInterface!
|
|
||||||
// This requires careful synchronization since GPU commands
|
|
||||||
// are processed on a different thread than VI commands.
|
|
||||||
SWRenderer::Swap(fbWidth, fbHeight);
|
|
||||||
DebugUtil::OnFrameEnd(fbWidth, fbHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyToRam()
|
static void CopyToRam()
|
||||||
@@ -67,7 +43,7 @@ namespace EfbCopy
|
|||||||
TextureEncoder::Encode(dest_ptr);
|
TextureEncoder::Encode(dest_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearEfb()
|
void ClearEfb()
|
||||||
{
|
{
|
||||||
u32 clearColor = (bpmem.clearcolorAR & 0xff) << 24 | bpmem.clearcolorGB << 8 | (bpmem.clearcolorAR & 0xff00) >> 8;
|
u32 clearColor = (bpmem.clearcolorAR & 0xff) << 24 | bpmem.clearcolorGB << 8 | (bpmem.clearcolorAR & 0xff00) >> 8;
|
||||||
|
|
||||||
@@ -128,11 +104,6 @@ namespace EfbCopy
|
|||||||
{
|
{
|
||||||
CopyToRam(); // FIXME: should use the rectangle we have already created above
|
CopyToRam(); // FIXME: should use the rectangle we have already created above
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpmem.triggerEFBCopy.clear)
|
|
||||||
{
|
|
||||||
ClearEfb();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
namespace EfbCopy
|
namespace EfbCopy
|
||||||
{
|
{
|
||||||
// Copy the EFB to RAM as a texture format or XFB
|
// Copy the EFB to RAM as a texture format or XFB
|
||||||
// Clear the EFB if needed
|
|
||||||
void CopyEfb();
|
void CopyEfb();
|
||||||
|
|
||||||
|
void ClearEfb();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
|
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/EfbInterface.h"
|
#include "VideoBackends/Software/EfbInterface.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/LookUpTables.h"
|
#include "VideoCommon/LookUpTables.h"
|
||||||
#include "VideoCommon/PixelEngine.h"
|
#include "VideoCommon/PixelEngine.h"
|
||||||
|
|
||||||
@@ -31,11 +31,6 @@ namespace EfbInterface
|
|||||||
return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START;
|
return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
|
||||||
{
|
|
||||||
p.DoArray(efb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetPixelAlphaOnly(u32 offset, u8 a)
|
static void SetPixelAlphaOnly(u32 offset, u8 a)
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ namespace EfbInterface
|
|||||||
void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma);
|
void CopyToXFB(yuv422_packed* xfb_in_ram, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma);
|
||||||
void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma);
|
void BypassXFB(u8* texture, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma);
|
||||||
|
|
||||||
void DoState(PointerWrap &p);
|
|
||||||
|
|
||||||
extern u32 perf_values[PQ_NUM_MEMBERS];
|
extern u32 perf_values[PQ_NUM_MEMBERS];
|
||||||
inline void IncPerfCounterQuadCount(PerfQueryType type)
|
inline void IncPerfCounterQuadCount(PerfQueryType type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,16 +77,4 @@ struct OutputVertexData
|
|||||||
#undef LINTERP
|
#undef LINTERP
|
||||||
#undef LINTERP_INT
|
#undef LINTERP_INT
|
||||||
}
|
}
|
||||||
void DoState(PointerWrap &p)
|
|
||||||
{
|
|
||||||
mvPosition.DoState(p);
|
|
||||||
p.Do(projectedPosition);
|
|
||||||
screenPosition.DoState(p);
|
|
||||||
for (auto& vec : normal)
|
|
||||||
vec.DoState(p);
|
|
||||||
p.DoArray(color, sizeof color);
|
|
||||||
for (auto& vec : texCoords)
|
|
||||||
vec.DoState(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,304 +0,0 @@
|
|||||||
// Copyright 2009 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
#include "Core/HW/Memmap.h"
|
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/CPMemLoader.h"
|
|
||||||
#include "VideoBackends/Software/DebugUtil.h"
|
|
||||||
#include "VideoBackends/Software/OpcodeDecoder.h"
|
|
||||||
#include "VideoBackends/Software/SWCommandProcessor.h"
|
|
||||||
#include "VideoBackends/Software/SWStatistics.h"
|
|
||||||
#include "VideoBackends/Software/SWVertexLoader.h"
|
|
||||||
#include "VideoBackends/Software/SWVideoConfig.h"
|
|
||||||
#include "VideoBackends/Software/XFMemLoader.h"
|
|
||||||
#include "VideoCommon/Fifo.h"
|
|
||||||
#include "VideoCommon/VertexLoaderUtils.h"
|
|
||||||
|
|
||||||
typedef void (*DecodingFunction)(u32);
|
|
||||||
|
|
||||||
namespace OpcodeDecoder
|
|
||||||
{
|
|
||||||
static DecodingFunction currentFunction = nullptr;
|
|
||||||
static u32 minCommandSize;
|
|
||||||
static u16 streamSize;
|
|
||||||
static u16 streamAddress;
|
|
||||||
static bool readOpcode;
|
|
||||||
static SWVertexLoader vertexLoader;
|
|
||||||
static bool inObjectStream;
|
|
||||||
static u8 lastPrimCmd;
|
|
||||||
|
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
|
||||||
{
|
|
||||||
p.Do(minCommandSize);
|
|
||||||
// Not sure what is wrong with this. Something(s) in here is causing Dolphin to crash/hang when loading states saved from another run of Dolphin. Doesn't seem too important anyway...
|
|
||||||
//vertexLoader.DoState(p);
|
|
||||||
p.Do(readOpcode);
|
|
||||||
p.Do(inObjectStream);
|
|
||||||
p.Do(lastPrimCmd);
|
|
||||||
p.Do(streamSize);
|
|
||||||
p.Do(streamAddress);
|
|
||||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
|
||||||
ResetDecoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DecodePrimitiveStream(u32 iBufferSize)
|
|
||||||
{
|
|
||||||
u32 vertexSize = vertexLoader.GetVertexSize();
|
|
||||||
|
|
||||||
bool skipPrimitives = g_bSkipCurrentFrame ||
|
|
||||||
swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawStart ||
|
|
||||||
swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawEnd;
|
|
||||||
|
|
||||||
if (skipPrimitives)
|
|
||||||
{
|
|
||||||
while (streamSize > 0 && iBufferSize >= vertexSize)
|
|
||||||
{
|
|
||||||
g_video_buffer_read_ptr += vertexSize;
|
|
||||||
iBufferSize -= vertexSize;
|
|
||||||
streamSize--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (streamSize > 0 && iBufferSize >= vertexSize)
|
|
||||||
{
|
|
||||||
vertexLoader.LoadVertex();
|
|
||||||
iBufferSize -= vertexSize;
|
|
||||||
streamSize--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (streamSize == 0)
|
|
||||||
{
|
|
||||||
// return to normal command processing
|
|
||||||
ResetDecoding();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReadXFData(u32 iBufferSize)
|
|
||||||
{
|
|
||||||
_assert_msg_(VIDEO, iBufferSize >= (u32)(streamSize * 4), "Underflow during standard opcode decoding");
|
|
||||||
|
|
||||||
u32 pData[16];
|
|
||||||
for (int i = 0; i < streamSize; i++)
|
|
||||||
pData[i] = DataRead<u32>();
|
|
||||||
SWLoadXFReg(streamSize, streamAddress, pData);
|
|
||||||
|
|
||||||
// return to normal command processing
|
|
||||||
ResetDecoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ExecuteDisplayList(u32 addr, u32 count)
|
|
||||||
{
|
|
||||||
u8 *videoDataSave = g_video_buffer_read_ptr;
|
|
||||||
|
|
||||||
u8 *dlStart = Memory::GetPointer(addr);
|
|
||||||
|
|
||||||
g_video_buffer_read_ptr = dlStart;
|
|
||||||
|
|
||||||
while (OpcodeDecoder::CommandRunnable(count))
|
|
||||||
{
|
|
||||||
OpcodeDecoder::Run(count);
|
|
||||||
|
|
||||||
// if data was read by the opcode decoder then the video data pointer changed
|
|
||||||
u32 readCount = (u32)(g_video_buffer_read_ptr - dlStart);
|
|
||||||
dlStart = g_video_buffer_read_ptr;
|
|
||||||
|
|
||||||
_assert_msg_(VIDEO, count >= readCount, "Display list underrun");
|
|
||||||
|
|
||||||
count -= readCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_video_buffer_read_ptr = videoDataSave;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DecodeStandard(u32 bufferSize)
|
|
||||||
{
|
|
||||||
_assert_msg_(VIDEO, CommandRunnable(bufferSize), "Underflow during standard opcode decoding");
|
|
||||||
|
|
||||||
int Cmd = DataRead<u8>();
|
|
||||||
|
|
||||||
if (Cmd == GX_NOP)
|
|
||||||
return;
|
|
||||||
// Causes a SIGBUS error on Android
|
|
||||||
// XXX: Investigate
|
|
||||||
#ifndef ANDROID
|
|
||||||
// check if switching in or out of an object
|
|
||||||
// only used for debugging
|
|
||||||
if (inObjectStream && (Cmd & 0x87) != lastPrimCmd)
|
|
||||||
{
|
|
||||||
inObjectStream = false;
|
|
||||||
DebugUtil::OnObjectEnd();
|
|
||||||
}
|
|
||||||
if (Cmd & 0x80 && !inObjectStream)
|
|
||||||
{
|
|
||||||
inObjectStream = true;
|
|
||||||
lastPrimCmd = Cmd & 0x87;
|
|
||||||
DebugUtil::OnObjectBegin();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
switch (Cmd)
|
|
||||||
{
|
|
||||||
case GX_NOP:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_CP_REG: //0x08
|
|
||||||
{
|
|
||||||
u32 SubCmd = DataRead<u8>();
|
|
||||||
u32 Value = DataRead<u32>();
|
|
||||||
SWLoadCPReg(SubCmd, Value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_XF_REG:
|
|
||||||
{
|
|
||||||
u32 Cmd2 = DataRead<u32>();
|
|
||||||
streamSize = ((Cmd2 >> 16) & 15) + 1;
|
|
||||||
streamAddress = Cmd2 & 0xFFFF;
|
|
||||||
currentFunction = ReadXFData;
|
|
||||||
minCommandSize = streamSize * 4;
|
|
||||||
readOpcode = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_INDX_A: //used for position matrices
|
|
||||||
SWLoadIndexedXF(DataRead<u32>(), 0xC);
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_B: //used for normal matrices
|
|
||||||
SWLoadIndexedXF(DataRead<u32>(), 0xD);
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_C: //used for postmatrices
|
|
||||||
SWLoadIndexedXF(DataRead<u32>(), 0xE);
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_D: //used for lights
|
|
||||||
SWLoadIndexedXF(DataRead<u32>(), 0xF);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_CMD_CALL_DL:
|
|
||||||
{
|
|
||||||
u32 dwAddr = DataRead<u32>();
|
|
||||||
u32 dwCount = DataRead<u32>();
|
|
||||||
ExecuteDisplayList(dwAddr, dwCount);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x44:
|
|
||||||
// zelda 4 swords calls it and checks the metrics registers after that
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
|
|
||||||
DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_BP_REG: //0x61
|
|
||||||
{
|
|
||||||
u32 cmd = DataRead<u32>();
|
|
||||||
SWLoadBPReg(cmd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// draw primitives
|
|
||||||
default:
|
|
||||||
if ((Cmd & 0xC0) == 0x80)
|
|
||||||
{
|
|
||||||
u8 vatIndex = Cmd & GX_VAT_MASK;
|
|
||||||
u8 primitiveType = (Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
|
|
||||||
vertexLoader.SetFormat(vatIndex, primitiveType);
|
|
||||||
|
|
||||||
// switch to primitive processing
|
|
||||||
streamSize = DataRead<u16>();
|
|
||||||
currentFunction = DecodePrimitiveStream;
|
|
||||||
minCommandSize = vertexLoader.GetVertexSize();
|
|
||||||
readOpcode = false;
|
|
||||||
|
|
||||||
INCSTAT(swstats.thisFrame.numPrimatives);
|
|
||||||
DEBUG_LOG(VIDEO, "Draw begin");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PanicAlert("GFX: Unknown Opcode (0x%x).\n", Cmd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
inObjectStream = false;
|
|
||||||
lastPrimCmd = 0;
|
|
||||||
ResetDecoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetDecoding()
|
|
||||||
{
|
|
||||||
currentFunction = DecodeStandard;
|
|
||||||
minCommandSize = 1;
|
|
||||||
readOpcode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommandRunnable(u32 iBufferSize)
|
|
||||||
{
|
|
||||||
if (iBufferSize < minCommandSize)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (readOpcode)
|
|
||||||
{
|
|
||||||
u8 Cmd = DataPeek<u8>(0);
|
|
||||||
u32 minSize = 1;
|
|
||||||
|
|
||||||
switch (Cmd)
|
|
||||||
{
|
|
||||||
case GX_LOAD_CP_REG: //0x08
|
|
||||||
minSize = 6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_XF_REG:
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_INDX_A: //used for position matrices
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_B: //used for normal matrices
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_C: //used for postmatrices
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
case GX_LOAD_INDX_D: //used for lights
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_CMD_CALL_DL:
|
|
||||||
minSize = 9;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GX_LOAD_BP_REG: //0x61
|
|
||||||
minSize = 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// draw primitives
|
|
||||||
default:
|
|
||||||
if ((Cmd & 0xC0) == 0x80)
|
|
||||||
minSize = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (iBufferSize >= minSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Run(u32 iBufferSize)
|
|
||||||
{
|
|
||||||
currentFunction(iBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// Copyright 2009 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
class PointerWrap;
|
|
||||||
|
|
||||||
namespace OpcodeDecoder
|
|
||||||
{
|
|
||||||
|
|
||||||
#define GX_NOP 0x00
|
|
||||||
|
|
||||||
#define GX_LOAD_BP_REG 0x61
|
|
||||||
#define GX_LOAD_CP_REG 0x08
|
|
||||||
#define GX_LOAD_XF_REG 0x10
|
|
||||||
#define GX_LOAD_INDX_A 0x20
|
|
||||||
#define GX_LOAD_INDX_B 0x28
|
|
||||||
#define GX_LOAD_INDX_C 0x30
|
|
||||||
#define GX_LOAD_INDX_D 0x38
|
|
||||||
|
|
||||||
#define GX_CMD_CALL_DL 0x40
|
|
||||||
#define GX_CMD_INVL_VC 0x48
|
|
||||||
|
|
||||||
#define GX_PRIMITIVE_MASK 0x38
|
|
||||||
#define GX_PRIMITIVE_SHIFT 3
|
|
||||||
#define GX_VAT_MASK 0x07
|
|
||||||
|
|
||||||
// These values are the values extracted using GX_PRIMITIVE_MASK
|
|
||||||
// and GX_PRIMITIVE_SHIFT.
|
|
||||||
// GX_DRAW_QUADS_2 behaves the same way as GX_DRAW_QUADS.
|
|
||||||
#define GX_DRAW_QUADS 0x0 //0x80
|
|
||||||
#define GX_DRAW_QUADS_2 0x1 //0x88
|
|
||||||
#define GX_DRAW_TRIANGLES 0x2 //0x90
|
|
||||||
#define GX_DRAW_TRIANGLE_STRIP 0x3 //0x98
|
|
||||||
#define GX_DRAW_TRIANGLE_FAN 0x4 //0xA0
|
|
||||||
#define GX_DRAW_LINES 0x5 //0xA8
|
|
||||||
#define GX_DRAW_LINE_STRIP 0x6 //0xB0
|
|
||||||
#define GX_DRAW_POINTS 0x7 //0xB8
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
void ResetDecoding();
|
|
||||||
|
|
||||||
bool CommandRunnable(u32 iBufferSize);
|
|
||||||
|
|
||||||
void Run(u32 iBufferSize);
|
|
||||||
|
|
||||||
void DoState(PointerWrap &p);
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user