Implement black frame insertion

This commit is contained in:
Rodolfo Bogado 2019-04-03 12:35:13 -03:00
parent add5cb3d14
commit b4db92e823
19 changed files with 567 additions and 504 deletions

View file

@ -50,6 +50,7 @@ const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "Dump
false};
const ConfigInfo<bool> GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false};
const ConfigInfo<bool> GFX_COMPILE_SHADERS_ON_STARTUP{ { System::GFX, "Settings", "CompileShaderOnStartup" }, true };
const ConfigInfo<bool> GFX_USE_BLACK_FRAME_INSERTION{ {System::GFX, "Settings", "UseBlackFrameInsertion"}, false};
const ConfigInfo<bool> GFX_USE_FFV1{{System::GFX, "Settings", "UseFFV1"}, false};
const ConfigInfo<std::string> GFX_DUMP_FORMAT{{System::GFX, "Settings", "DumpFormat"}, "avi"};
const ConfigInfo<std::string> GFX_DUMP_CODEC{{System::GFX, "Settings", "DumpCodec"}, ""};

View file

@ -42,6 +42,7 @@ extern const ConfigInfo<bool> GFX_DUMP_EFB_TARGET;
extern const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES;
extern const ConfigInfo<bool> GFX_FREE_LOOK;
extern const ConfigInfo<bool> GFX_COMPILE_SHADERS_ON_STARTUP;
extern const ConfigInfo<bool> GFX_USE_BLACK_FRAME_INSERTION;
extern const ConfigInfo<bool> GFX_USE_FFV1;
extern const ConfigInfo<std::string> GFX_DUMP_FORMAT;
extern const ConfigInfo<std::string> GFX_DUMP_CODEC;

View file

@ -33,6 +33,7 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
Config::GFX_CROP.location,
Config::GFX_USE_XFB.location,
Config::GFX_USE_REAL_XFB.location,
Config::GFX_USE_BLACK_FRAME_INSERTION.location,
Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES.location,
Config::GFX_SHOW_FPS.location,
Config::GFX_SHOW_NETPLAY_PING.location,

View file

@ -44,6 +44,7 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
config_layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, dtm->bEFBAccessEnable);
config_layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, dtm->bSkipEFBCopyToRam);
config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges);
}
void SaveToDTM(Movie::DTMHeader* dtm)

View file

@ -140,6 +140,8 @@ static wxString ws_hack_desc =
static wxString vsync_desc =
_("Wait for vertical blanks in order to reduce tearing.\nDecreases performance if emulation "
"speed is below 100%.\n\nIf unsure, leave this unchecked.");
static wxString bfi_desc =
_("Insert black frames to reduce motion blur in 120hz monitors");
static wxString af_desc =
_("Enable anisotropic filtering.\nEnhances visual quality of textures that are at oblique "
"viewing angles.\nMight cause issues in a small number of games.\n\nIf unsure, select 1x.");
@ -550,6 +552,8 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
{
szr_display->Add(
CreateCheckBox(page_general, _("V-Sync"), (vsync_desc), Config::GFX_VSYNC));
szr_display->Add(
CreateCheckBox(page_general, _("Black Frame insetion"), (bfi_desc), Config::GFX_USE_BLACK_FRAME_INSERTION));
szr_display->Add(CreateCheckBoxRefBool(page_general, _("Use Fullscreen"),
(use_fullscreen_desc),
SConfig::GetInstance().bFullscreen));
@ -1263,6 +1267,9 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
szr_other->Add(Compute_Shader_encoding = CreateCheckBox(
page_hacks, _("Compute Texture Encoding"), (Compute_texture_encoding_desc),
Config::GFX_ENABLE_COMPUTE_TEXTURE_ENCODING));
szr_other->Add(Compute_Shader_encoding = CreateCheckBox(
page_hacks, _("Compute Texture Encoding"), (Compute_texture_encoding_desc),
Config::GFX_ENABLE_COMPUTE_TEXTURE_ENCODING));
wxStaticBoxSizer* const group_other =
new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other"));

View file

@ -733,6 +733,18 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
}
}
void Renderer::InsertBlackFrame()
{
auto rtv = D3D::GetBackBuffer()->GetRTV();
D3D::current_command_list->OMSetRenderTargets(1, &rtv, FALSE, nullptr);
float clear_color[4] = {0.f, 0.f, 0.f, 1.f};
D3D::current_command_list->ClearRenderTargetView(rtv, clear_color, 0, nullptr);
D3D::EndFrame();
D3D::Present();
RestoreAPIState();
D3D::BeginFrame();
}
void Renderer::DrawFrame(const TargetRectangle& target_rc, const EFBRectangle& source_rc, u32 xfb_addr,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, D3DTexture2D* dst_texture, const TargetSize& dst_size, u32 fb_width,
u32 fb_stride, u32 fb_height, float Gamma)

View file

@ -48,7 +48,7 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override;
void SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc, u64 ticks, float gamma) override;
void InsertBlackFrame();
void ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha_enable, bool z_enable, u32 color, u32 z) override;
void ReinterpretPixelData(unsigned int conv_type) override;

View file

@ -723,6 +723,20 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
m_post_processor->ReloadShaders();
}
void Renderer::InsertBlackFrame()
{
ResetAPIState();
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
float ClearColor[4] = {0.f, 0.f, 0.f, 1.f};
D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), ClearColor);
D3D::EndFrame();
D3D::Present();
D3D::BeginFrame();
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
FramebufferManager::GetEFBDepthTexture()->GetDSV());
Renderer::RestoreAPIState();
}
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
void Renderer::ResetAPIState()
{

View file

@ -45,7 +45,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 = 1.0f) override;
void InsertBlackFrame();
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override;
void ReinterpretPixelData(unsigned int convtype) override;

View file

@ -2,20 +2,20 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <list>
#include <d3dx9.h>
#include <cinttypes>
#include <d3dx9.h>
#include <list>
#include <memory>
#include "Common/StringUtil.h"
#include "Common/Common.h"
#include "Common/Atomic.h"
#include "Common/Common.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
#include "Common/Thread.h"
#include "Common/Timer.h"
#include "Core/Core.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/Movie.h"
@ -24,17 +24,17 @@
#include "VideoBackends/DX9/PerfQuery.h"
#include "VideoBackends/DX9/PixelShaderCache.h"
#include "VideoBackends/DX9/Render.h"
#include "VideoBackends/DX9/VertexManager.h"
#include "VideoBackends/DX9/VertexShaderCache.h"
#include "VideoBackends/DX9/TextureCache.h"
#include "VideoBackends/DX9/TextureConverter.h"
#include "VideoBackends/DX9/VertexManager.h"
#include "VideoBackends/DX9/VertexShaderCache.h"
#include "VideoCommon/AVIDump.h"
#include "VideoCommon/Debugger.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/FPSCounter.h"
#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/BPStructs.h"
#include "VideoCommon/Debugger.h"
#include "VideoCommon/FPSCounter.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/OpcodeDecoding.h"
#include "VideoCommon/PixelEngine.h"
@ -47,7 +47,6 @@
namespace DX9
{
static LPDIRECT3DSURFACE9 m_screen_shoot_mem_surface = nullptr;
// GX pipeline state
struct GXPipelineState
@ -97,7 +96,7 @@ void Renderer::TeardownDeviceObjects()
}
// Init functions
Renderer::Renderer(void *&window_handle)
Renderer::Renderer(void*& window_handle)
{
int fullScreenRes, w_temp, h_temp;
// Multisample Anti-aliasing hasn't been implemented yet use supersamling instead
@ -108,17 +107,19 @@ Renderer::Renderer(void *&window_handle)
w_temp = client.right - client.left;
h_temp = client.bottom - client.top;
for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++)
for (fullScreenRes = 0;
fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size();
fullScreenRes++)
{
if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) &&
(D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp))
(D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp))
break;
}
if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size())
fullScreenRes = 0;
D3D::Create(g_ActiveConfig.iAdapter, (HWND)window_handle,
fullScreenRes, backbuffer_mm_mode, false);
D3D::Create(g_ActiveConfig.iAdapter, (HWND)window_handle, fullScreenRes, backbuffer_mm_mode,
false);
// Decide framebuffer size
m_backbuffer_width = D3D::GetBackBufferWidth();
@ -188,20 +189,24 @@ void Renderer::Init()
vp.Height = m_target_height;
D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
D3D::dev->CreateOffscreenPlainSurface(m_backbuffer_width, m_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &m_screen_shoot_mem_surface, NULL);
D3D::dev->CreateOffscreenPlainSurface(m_backbuffer_width, m_backbuffer_height, D3DFMT_X8R8G8B8,
D3DPOOL_SYSTEMMEM, &m_screen_shoot_mem_surface, NULL);
D3D::BeginFrame();
// Initial state setup
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
D3D::SetRenderState(D3DRS_FILLMODE,
g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED |
D3DCOLORWRITEENABLE_GREEN |
D3DCOLORWRITEENABLE_BLUE);
D3D::SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
m_fMax_Point_Size = D3D::GetCaps().MaxPointSize;
// Handle VSync on/off
// Handle VSync on/off
m_vsync = g_ActiveConfig.IsVSync();
m_bColorMaskChanged = true;
m_bBlendModeChanged = true;
@ -219,11 +224,13 @@ Renderer::~Renderer()
D3D::Close();
}
void Renderer::RenderText(const std::string &text, int left, int top, u32 color)
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
TargetRectangle trc = GetTargetRectangle();
D3D::font.DrawTextScaled((float)(trc.left + left + 1), (float)(trc.top + top + 1), 20, 20, 0.0f, color & 0xFF000000, text.c_str());
D3D::font.DrawTextScaled((float)(trc.left + left), (float)(trc.top + top), 20, 20, 0.0f, color, text.c_str());
D3D::font.DrawTextScaled((float)(trc.left + left + 1), (float)(trc.top + top + 1), 20, 20, 0.0f,
color & 0xFF000000, text.c_str());
D3D::font.DrawTextScaled((float)(trc.left + left), (float)(trc.top + top), 20, 20, 0.0f, color,
text.c_str());
}
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
@ -236,7 +243,7 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
return result;
}
}
} // namespace DX9
void formatBufferDump(const u8* in, u8* out, int w, int h, int p)
{
@ -254,7 +261,6 @@ void formatBufferDump(const u8* in, u8* out, int w, int h, int p)
namespace DX9
{
// With D3D, we have to resize the backbuffer if the window changed
// size.
bool Renderer::CheckForResize()
@ -264,15 +270,16 @@ bool Renderer::CheckForResize()
int client_width = rcWindow.right - rcWindow.left;
int client_height = rcWindow.bottom - rcWindow.top;
POINT originPoint = { 0, 0 };
POINT originPoint = {0, 0};
ClientToScreen(D3D::hWnd, &originPoint);
g_renderer->SetWindowRectangle(originPoint.x, originPoint.x + client_width, originPoint.y, originPoint.y + client_height);
g_renderer->SetWindowRectangle(originPoint.x, originPoint.x + client_width, originPoint.y,
originPoint.y + client_height);
// Sanity check
bool resized = (client_width != g_renderer->GetBackbufferWidth()
|| client_height != g_renderer->GetBackbufferHeight()
|| m_vsync != g_ActiveConfig.IsVSync()) &&
client_width >= 4 && client_height >= 4;
bool resized =
(client_width != g_renderer->GetBackbufferWidth() ||
client_height != g_renderer->GetBackbufferHeight() || m_vsync != g_ActiveConfig.IsVSync()) &&
client_width >= 4 && client_height >= 4;
return resized;
}
@ -328,9 +335,12 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
ret |= 0xFF000000;
}
if (alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE
else if (alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF
else return (ret & 0x00FFFFFF); // GX_READ_00
if (alpha_read_mode.ReadMode == 2)
return ret; // GX_READ_NONE
else if (alpha_read_mode.ReadMode == 1)
return (ret | 0xFF000000); // GX_READ_FF
else
return (ret & 0x00FFFFFF); // GX_READ_00
}
return poke_data;
}
@ -344,7 +354,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
vp.Width = GetTargetWidth();
vp.Height = GetTargetHeight();
if (xfmem.viewport.zRange < 0.0f)
{
vp.MinZ = 1.0f - GX_MAX_DEPTH;
@ -352,8 +361,10 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
}
else
{
float nearz = xfmem.viewport.farZ - MathUtil::Clamp<float>(xfmem.viewport.zRange, 0.0f, 16777215.0f);
// Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
float nearz =
xfmem.viewport.farZ - MathUtil::Clamp<float>(xfmem.viewport.zRange, 0.0f, 16777215.0f);
// Some games set invalids values for z min and z max so fix them to the max an min alowed and
// let the shaders do this work
vp.MaxZ = 1.0f - (MathUtil::Clamp<float>(nearz, 0.0f, 16777215.0f) / 16777216.0f);
vp.MinZ = 1.0f - (MathUtil::Clamp<float>(xfmem.viewport.farZ, 0.0f, 16777215.0f) / 16777216.0f);
}
@ -374,12 +385,14 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false);
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
}
D3D::DrawEFBPokeQuads(type, points, num_points, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
D3D::DrawEFBPokeQuads(type, points, num_points, PixelShaderCache::GetClearProgram(),
VertexShaderCache::GetClearVertexShader());
RestoreAPIState();
}
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z)
{
// Reset rendering pipeline while keeping color masks and depth buffer settings
ResetAPIState();
@ -408,7 +421,9 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
vp.MinZ = 1.0f - GX_MAX_DEPTH;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
D3D::drawClearQuad(color, (0xFFFFFF - (z & 0xFFFFFF)) / 16777216.0f, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
D3D::drawClearQuad(color, (0xFFFFFF - (z & 0xFFFFFF)) / 16777216.0f,
PixelShaderCache::GetClearProgram(),
VertexShaderCache::GetClearVertexShader());
RestoreAPIState();
FramebufferManager::InvalidateEFBCache();
@ -420,11 +435,14 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
SetRect(&source, 0, 0, GetTargetWidth(), GetTargetHeight());
LPDIRECT3DPIXELSHADER9 pixel_shader;
if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6();
else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8();
if (convtype == 0)
pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6();
else if (convtype == 2)
pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8();
else
{
ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d",
convtype);
return;
}
@ -440,10 +458,9 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source,
GetTargetWidth(), GetTargetHeight(),
GetTargetWidth(), GetTargetHeight(),
pixel_shader, VertexShaderCache::GetSimpleVertexShader(0));
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, GetTargetWidth(),
GetTargetHeight(), GetTargetWidth(), GetTargetHeight(), pixel_shader,
VertexShaderCache::GetSimpleVertexShader(0));
FramebufferManager::SwapReinterpretTexture();
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
RestoreAPIState();
@ -451,7 +468,8 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
}
// This function has the final picture. We adjust the aspect ratio here.
void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks, float Gamma)
void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
const EFBRectangle& rc, u64 ticks, float Gamma)
{
if ((!m_xfb_written && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight)
{
@ -460,7 +478,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
}
u32 xfbCount = 0;
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount);
const XFBSourceBase* const* xfbSourceList =
FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
Core::Callback_VideoCopiedToXFB(false);
@ -506,7 +525,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{
if (g_ActiveConfig.iStereoMode == STEREO_SHADER)
{
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN);
D3D::SetRenderState(D3DRS_COLORWRITEENABLE,
D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN);
}
else if (g_ActiveConfig.iStereoMode == STEREO_TAB)
{
@ -519,7 +539,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
Width = Width / 2;
}
VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iStereoDepth, 0.0f);
VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iStereoConvergence, 0.0f);
VertexShaderManager::RotateView(-0.0001f * g_ActiveConfig.iStereoConvergence, 0.0f);
}
else
{
@ -537,7 +557,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
X = X / 2;
Width = Width / 2;
}
VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iStereoDepth, 0.0f);
VertexShaderManager::TranslateView(0.001f * g_ActiveConfig.iStereoDepth, 0.0f);
VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iStereoConvergence, 0.0f);
}
m_b3D_RightFrame = !m_b3D_RightFrame;
@ -594,12 +614,12 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// The following code disables auto stretch. Kept for reference.
// scale draw area for a 1 to 1 pixel mapping with the draw target
//float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight();
//float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth();
//drawRc.top *= vScale;
//drawRc.bottom *= vScale;
//drawRc.left *= hScale;
//drawRc.right *= hScale;
// float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight();
// float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth();
// drawRc.top *= vScale;
// drawRc.bottom *= vScale;
// drawRc.left *= hScale;
// drawRc.right *= hScale;
sourceRc.right -= Renderer::EFBToScaledX(fbStride - fbWidth);
}
@ -615,19 +635,18 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{
multisamplemode = std::max(std::min((targetRc.GetWidth() / Width) - 1, 2), 0);
}
D3D::drawShadedTexQuad(read_texture, targetRc.AsRECT(),
Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
Width, Height,
PixelShaderCache::GetColorCopyProgram(multisamplemode),
VertexShaderCache::GetSimpleVertexShader(multisamplemode), Gamma);
D3D::drawShadedTexQuad(read_texture, targetRc.AsRECT(), Renderer::GetTargetWidth(),
Renderer::GetTargetHeight(), Width, Height,
PixelShaderCache::GetColorCopyProgram(multisamplemode),
VertexShaderCache::GetSimpleVertexShader(multisamplemode), Gamma);
}
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
if (g_ActiveConfig.iStereoMode == STEREO_SHADER)
{
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED |
D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
}
X = Tr.left;
@ -648,14 +667,17 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{
int source_width = GetTargetRectangle().GetWidth();
int source_height = GetTargetRectangle().GetHeight();
if (SUCCEEDED(D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(), m_screen_shoot_mem_surface)))
if (SUCCEEDED(
D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(), m_screen_shoot_mem_surface)))
{
D3DLOCKED_RECT rect;
if (SUCCEEDED(m_screen_shoot_mem_surface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
if (SUCCEEDED(m_screen_shoot_mem_surface->LockRect(&rect, GetTargetRectangle().AsRECT(),
D3DLOCK_NO_DIRTY_UPDATE |
D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
{
AVIDump::Frame state = AVIDump::FetchState(ticks);
DumpFrameData(reinterpret_cast<const u8*>(rect.pBits), source_width, source_height,
rect.Pitch, state, false, true);
rect.Pitch, state, false, true);
FinishFrameData();
m_screen_shoot_mem_surface->UnlockRect();
@ -692,13 +714,14 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
m_backbuffer_height = D3D::GetBackBufferHeight();
if (m_screen_shoot_mem_surface)
m_screen_shoot_mem_surface->Release();
D3D::dev->CreateOffscreenPlainSurface(m_backbuffer_width, m_backbuffer_height,
D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &m_screen_shoot_mem_surface, NULL);
D3D::dev->CreateOffscreenPlainSurface(m_backbuffer_width, m_backbuffer_height, D3DFMT_X8R8G8B8,
D3DPOOL_SYSTEMMEM, &m_screen_shoot_mem_surface, NULL);
}
bool xfbchanged = false;
if (FramebufferManagerBase::LastXfbWidth() != fbStride || FramebufferManagerBase::LastXfbHeight() != fbHeight)
if (FramebufferManagerBase::LastXfbWidth() != fbStride ||
FramebufferManagerBase::LastXfbHeight() != fbHeight)
{
xfbchanged = true;
unsigned int w = (fbStride < 1 || fbStride > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbStride;
@ -709,11 +732,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
u32 newAA = g_ActiveConfig.iMultisamples - 1;
if (CalculateTargetSize((newAA % 3) + 1)
|| xfbchanged
|| windowResized
|| m_last_efb_scale != g_ActiveConfig.iEFBScale
|| m_LastAA != newAA)
if (CalculateTargetSize((newAA % 3) + 1) || xfbchanged || windowResized ||
m_last_efb_scale != g_ActiveConfig.iEFBScale || m_LastAA != newAA)
{
m_LastAA = newAA;
@ -731,7 +751,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// device objects lost, so recreate all of them
SetupDeviceObjects();
}
}
else
{
@ -759,6 +778,19 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
}
void Renderer::InsertBlackFrame() {
ResetAPIState();
D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
D3D::EndFrame();
D3D::Present();
D3D::BeginFrame();
RestoreAPIState();
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
}
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
void Renderer::ResetAPIState()
{
@ -768,13 +800,16 @@ void Renderer::ResetAPIState()
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED |
D3DCOLORWRITEENABLE_GREEN |
D3DCOLORWRITEENABLE_BLUE);
}
void Renderer::RestoreAPIState()
{
// Gets us back into a more game-like state.
D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
D3D::SetRenderState(D3DRS_FILLMODE,
g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
m_bColorMaskChanged = true;
m_bGenerationModeChanged = true;
@ -838,10 +873,13 @@ void Renderer::_SetViewport()
}
else
{
float nearz = xfmem.viewport.farZ - MathUtil::Clamp<float>(xfmem.viewport.zRange, 0.0f, 16777215.0f);
// Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
float nearz =
xfmem.viewport.farZ - MathUtil::Clamp<float>(xfmem.viewport.zRange, 0.0f, 16777215.0f);
// Some games set invalids values for z min and z max so fix them to the max an min alowed and
// let the shaders do this work
m_vp.MaxZ = 1.0f - (MathUtil::Clamp<float>(nearz, 0.0f, 16777215.0f) / 16777216.0f);
m_vp.MinZ = 1.0f - (MathUtil::Clamp<float>(xfmem.viewport.farZ, 0.0f, 16777215.0f) / 16777216.0f);
m_vp.MinZ =
1.0f - (MathUtil::Clamp<float>(xfmem.viewport.farZ, 0.0f, 16777215.0f) / 16777216.0f);
}
}
if (m_bViewPortChanged)
@ -893,8 +931,9 @@ void Renderer::ApplyState(bool bUseDstAlpha)
if (bUseDstAlpha)
{
// If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable)
// Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24)
// We must disable blend because we want to write alpha value directly to the alpha channel without modifications.
// Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format
// == PEControl::RGBA6_Z24) We must disable blend because we want to write alpha value directly
// to the alpha channel without modifications.
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
if (s_gx_state.zmode.testenable.Value() && s_gx_state.zmode.updateenable.Value())
@ -930,7 +969,7 @@ void Renderer::SetScissorRect(const EFBRectangle& rc)
{
m_ScissorRect = rc;
m_bScissorRectChanged = true;
}
}
void Renderer::_SetColorMask()
{
@ -945,7 +984,8 @@ void Renderer::_SetColorMask()
}
void Renderer::SetBlendingState(const BlendingState& state)
{
m_bColorMaskChanged = m_bColorMaskChanged || state.colorupdate != s_gx_state.blend.colorupdate || state.alphaupdate != s_gx_state.blend.alphaupdate;
m_bColorMaskChanged = m_bColorMaskChanged || state.colorupdate != s_gx_state.blend.colorupdate ||
state.alphaupdate != s_gx_state.blend.alphaupdate;
m_bBlendModeChanged = m_bBlendModeChanged || state.hex != s_gx_state.blend.hex;
s_gx_state.blend.hex = state.hex;
}
@ -961,40 +1001,40 @@ void Renderer::_SetBlendMode()
return;
}
// Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1.
//really useful for debugging shader and blending errors
// Our render target always uses an alpha channel, so we need to override the blend functions to
// assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel
// is assumed to always be 1.
// really useful for debugging shader and blending errors
bool use_DstAlpha = s_gx_state.blend.dstalpha != 0;
bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
const D3DBLEND d3dSrcFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_INVDESTCOLOR,
(use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA,
(use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA
};
const D3DBLEND d3dDestFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVSRCCOLOR,
(use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA,
(use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA
};
const D3DBLEND d3dSrcFactors[8] = {D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_INVDESTCOLOR,
(use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA,
(use_DualSource) ? D3DBLEND_INVSRCCOLOR2 :
D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA};
const D3DBLEND d3dDestFactors[8] = {D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVSRCCOLOR,
(use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA,
(use_DualSource) ? D3DBLEND_INVSRCCOLOR2 :
D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA};
bool blend_enable = s_gx_state.blend.blendenable;
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable);
D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction);
D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE,
blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction);
if (blend_enable)
{
D3DBLENDOP op = s_gx_state.blend.subtract.Value() != 0 ? D3DBLENDOP_REVSUBTRACT : D3DBLENDOP_ADD;
D3DBLENDOP op =
s_gx_state.blend.subtract.Value() != 0 ? D3DBLENDOP_REVSUBTRACT : D3DBLENDOP_ADD;
u32 srcidx = static_cast<u32>(s_gx_state.blend.srcfactor);
u32 dstidx = static_cast<u32>(s_gx_state.blend.dstfactor);
D3D::SetRenderState(D3DRS_BLENDOP, op);
@ -1021,13 +1061,7 @@ void Renderer::SetRasterizationState(const RasterizationState& state)
void Renderer::_SetGenerationMode()
{
m_bGenerationModeChanged = false;
static const D3DCULL d3dCullModes[4] =
{
D3DCULL_NONE,
D3DCULL_CCW,
D3DCULL_CW,
D3DCULL_CCW
};
static const D3DCULL d3dCullModes[4] = {D3DCULL_NONE, D3DCULL_CCW, D3DCULL_CW, D3DCULL_CCW};
D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[s_gx_state.raster.cullmode.Value()]);
}
@ -1040,17 +1074,9 @@ void Renderer::SetDepthState(const DepthState& state)
void Renderer::_SetDepthMode()
{
m_bDepthModeChanged = false;
static const D3DCMPFUNC d3dCmpFuncs[8] =
{
D3DCMP_NEVER,
D3DCMP_GREATER,
D3DCMP_EQUAL,
D3DCMP_GREATEREQUAL,
D3DCMP_LESS,
D3DCMP_NOTEQUAL,
D3DCMP_LESSEQUAL,
D3DCMP_ALWAYS
};
static const D3DCMPFUNC d3dCmpFuncs[8] = {D3DCMP_NEVER, D3DCMP_GREATER, D3DCMP_EQUAL,
D3DCMP_GREATEREQUAL, D3DCMP_LESS, D3DCMP_NOTEQUAL,
D3DCMP_LESSEQUAL, D3DCMP_ALWAYS};
D3D::SetRenderState(D3DRS_ZENABLE, s_gx_state.zmode.testenable.Value());
if (s_gx_state.zmode.testenable.Value())
@ -1060,7 +1086,7 @@ void Renderer::_SetDepthMode()
}
else
{
// if the test is disabled write is disabled too
// if the test is disabled write is disabled too
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
}
@ -1086,65 +1112,23 @@ void Renderer::_SetLogicOpMode()
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
static const D3DBLENDOP d3dLogicOpop[16] =
{
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_SUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_REVSUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD
};
static const D3DBLEND d3dLogicOpSrcFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_DESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_ZERO,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE
};
static const D3DBLEND d3dLogicOpDestFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_ZERO,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE
};
static const D3DBLENDOP d3dLogicOpop[16] = {
D3DBLENDOP_ADD, D3DBLENDOP_ADD, D3DBLENDOP_SUBTRACT, D3DBLENDOP_ADD,
D3DBLENDOP_REVSUBTRACT, D3DBLENDOP_ADD, D3DBLENDOP_MAX, D3DBLENDOP_ADD,
D3DBLENDOP_MAX, D3DBLENDOP_MAX, D3DBLENDOP_ADD, D3DBLENDOP_ADD,
D3DBLENDOP_ADD, D3DBLENDOP_ADD, D3DBLENDOP_ADD, D3DBLENDOP_ADD};
static const D3DBLEND d3dLogicOpSrcFactors[16] = {
D3DBLEND_ZERO, D3DBLEND_DESTCOLOR, D3DBLEND_ONE, D3DBLEND_ONE,
D3DBLEND_DESTCOLOR, D3DBLEND_ZERO, D3DBLEND_INVDESTCOLOR, D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE};
static const D3DBLEND d3dLogicOpDestFactors[16] = {
D3DBLEND_ZERO, D3DBLEND_ZERO, D3DBLEND_INVSRCCOLOR, D3DBLEND_ZERO,
D3DBLEND_ONE, D3DBLEND_ONE, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE,
D3DBLEND_INVDESTCOLOR, D3DBLEND_SRCCOLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE};
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, s_gx_state.blend.logicopenable.Value());
if( s_gx_state.blend.logicopenable.Value())
if (s_gx_state.blend.logicopenable.Value())
{
D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[s_gx_state.blend.logicmode.Value()]);
D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[s_gx_state.blend.logicmode.Value()]);
@ -1159,18 +1143,11 @@ void Renderer::SetInterlacingMode()
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
{
static const D3DTEXTUREFILTERTYPE d3dFilters[2] =
{
D3DTEXF_POINT,
D3DTEXF_LINEAR
static const D3DTEXTUREFILTERTYPE d3dFilters[2] = {D3DTEXF_POINT, D3DTEXF_LINEAR};
static const D3DTEXTUREADDRESS d3dClamps[4] = {
D3DTADDRESS_CLAMP, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
D3DTADDRESS_WRAP // reserved
};
static const D3DTEXTUREADDRESS d3dClamps[4] =
{
D3DTADDRESS_CLAMP,
D3DTADDRESS_WRAP,
D3DTADDRESS_MIRROR,
D3DTADDRESS_WRAP //reserved
};
D3DTEXTUREFILTERTYPE min = d3dFilters[static_cast<u32>(state.min_filter.Value())];
D3DTEXTUREFILTERTYPE mag = d3dFilters[static_cast<u32>(state.mag_filter.Value())];

View file

@ -43,7 +43,7 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks, float Gamma = 1.0f);
void InsertBlackFrame();
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
void ReinterpretPixelData(unsigned int convtype);

File diff suppressed because it is too large Load diff

View file

@ -101,7 +101,7 @@ public:
void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks,
float Gamma) override;
void InsertBlackFrame();
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z) override;

View file

@ -22,22 +22,22 @@ public:
static u8* GetNextColorTexture();
static u8* GetCurrentColorTexture();
void SwapColorTexture();
void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight);
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
{};
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override{};
u16 BBoxRead(int index) override;
void BBoxWrite(int index, u16 value) override;
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(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,
u64 ticks, float Gamma) override;
void InsertBlackFrame() override{};
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
u32 color, u32 z) override;
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override;
void ReinterpretPixelData(unsigned int convtype) override
{}
void ReinterpretPixelData(unsigned int convtype) override {}
};

View file

@ -44,10 +44,10 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override;
void SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc,
u64 ticks, float gamma) override;
u64 ticks, float gamma) override;
void InsertBlackFrame() override {};
void ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha_enable, bool z_enable,
u32 color, u32 z) override;
u32 color, u32 z) override;
void ReinterpretPixelData(unsigned int convtype) override;
@ -89,27 +89,32 @@ private:
// Transitions EFB / XFB buffers to SHADER_READ_ONLY, ready for presenting / dumping.
// If MSAA is enabled, and XFB is disabled, also resolves the EFB buffer.
void TransitionBuffersForSwap(const TargetRectangle& scaled_rect,
const XFBSourceBase* const* xfb_sources, u32 xfb_count);
const XFBSourceBase* const* xfb_sources, u32 xfb_count);
// Draw either the EFB, or specified XFB sources to the currently-bound framebuffer.
void DrawFrame(const TargetRectangle& target_rc, const TargetRectangle& scaled_source_rc, u32 xfb_addr,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, Texture2D* dst_texture, const TargetSize& dst_size, u32 fb_width,
u32 fb_stride, u32 fb_height, float Gamma);
void DrawEFB(const TargetRectangle& t_rc, const TargetRectangle& scaled_source_rc, Texture2D* dst_texture, const TargetSize& dst_size, float Gamma);
void DrawFrame(const TargetRectangle& target_rc, const TargetRectangle& scaled_source_rc,
u32 xfb_addr, const XFBSourceBase* const* xfb_sources, u32 xfb_count,
Texture2D* dst_texture, const TargetSize& dst_size, u32 fb_width, u32 fb_stride,
u32 fb_height, float Gamma);
void DrawEFB(const TargetRectangle& t_rc, const TargetRectangle& scaled_source_rc,
Texture2D* dst_texture, const TargetSize& dst_size, float Gamma);
void DrawVirtualXFB(const TargetRectangle& target_rc, u32 xfb_addr,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, Texture2D* dst_texture, const TargetSize& dst_size, u32 fb_width,
u32 fb_stride, u32 fb_height, float Gamma);
void DrawRealXFB(const TargetRectangle& target_rect,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width,
u32 fb_stride, u32 fb_height, Texture2D* dst_texture, const TargetSize& dst_size, float Gamma);
const XFBSourceBase* const* xfb_sources, u32 xfb_count,
Texture2D* dst_texture, const TargetSize& dst_size, u32 fb_width,
u32 fb_stride, u32 fb_height, float Gamma);
void DrawRealXFB(const TargetRectangle& target_rect, const XFBSourceBase* const* xfb_sources,
u32 xfb_count, u32 fb_width, u32 fb_stride, u32 fb_height,
Texture2D* dst_texture, const TargetSize& dst_size, float Gamma);
// Draw the frame, as well as the OSD to the swap chain.
void DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, const XFBSourceBase* const* xfb_sources,
u32 xfb_count, u32 fb_width, u32 fb_stride, u32 fb_height, float gamma);
void DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width,
u32 fb_stride, u32 fb_height, float gamma);
// Draw the frame only to the screenshot buffer.
bool DrawFrameDump(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, const XFBSourceBase* const* xfb_sources,
u32 xfb_count, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks);
bool DrawFrameDump(const TargetRectangle& scaled_efb_rect, u32 xfb_addr,
const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width,
u32 fb_stride, u32 fb_height, u64 ticks);
// Sets up renderer state to permit framedumping.
// Ideally we would have EndFrameDumping be a virtual method of Renderer, but due to various
@ -133,9 +138,9 @@ private:
void FlushFrameDump();
// Copies/scales an image to the currently-bound framebuffer.
void BlitScreen(const TargetRectangle& dst_rect,
const TargetRectangle& src_rect, TargetSize src_size, const Texture2D* src_tex, const Texture2D* src_depth_tex,
const TargetSize& dst_size, Texture2D* dst_texture, float Gamma);
void BlitScreen(const TargetRectangle& dst_rect, const TargetRectangle& src_rect,
TargetSize src_size, const Texture2D* src_tex, const Texture2D* src_depth_tex,
const TargetSize& dst_size, Texture2D* dst_texture, float Gamma);
bool ResizeFrameDumpBuffer(u32 new_width, u32 new_height);
void DestroyFrameDumpResources();
@ -174,4 +179,4 @@ private:
size_t m_current_frame_dump_image = FRAME_DUMP_BUFFERED_FRAMES - 1;
bool m_frame_dumping_active = false;
};
}
} // namespace Vulkan

View file

@ -785,7 +785,11 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
frameCount++;
GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true);
if (g_ActiveConfig.bBlackFrameInsertion)
{
InsertBlackFrame();
frameCount++;
}
// Begin new frame
// Set default viewport and scissor, for the clear to work correctly
// New frame

View file

@ -140,7 +140,7 @@ public:
// Finish up the current frame, print some stats
void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks, float Gamma = 1.0f);
virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks, float Gamma = 1.0f) = 0;
virtual void InsertBlackFrame() = 0;
PEControl::PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; }
void StorePixelFormat(PEControl::PixelFormat new_format) { m_prev_efb_format = new_format; }

View file

@ -87,6 +87,7 @@ void VideoConfig::Refresh()
bCrop = Config::Get(Config::GFX_CROP);
bUseXFB = Config::Get(Config::GFX_USE_XFB);
bUseRealXFB = Config::Get(Config::GFX_USE_REAL_XFB);
bBlackFrameInsertion = Config::Get(Config::GFX_USE_BLACK_FRAME_INSERTION);
iSafeTextureCache_ColorSamples = Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES);
bShowFPS = Config::Get(Config::GFX_SHOW_FPS);
bShowNetPlayPing = Config::Get(Config::GFX_SHOW_NETPLAY_PING);

View file

@ -117,7 +117,7 @@ struct VideoConfig final
bool bCrop; // Aspect ratio controls.
bool bUseXFB;
bool bUseRealXFB;
bool bBlackFrameInsertion;
// OpenCL/OpenMP
bool bEnableOpenCL;
bool bOMPDecoder;