mirror of
https://github.com/Tinob/Ishiiruka.git
synced 2024-06-16 03:17:27 -04:00
Implement black frame insertion
This commit is contained in:
parent
add5cb3d14
commit
b4db92e823
|
@ -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"}, ""};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())];
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -117,7 +117,7 @@ struct VideoConfig final
|
|||
bool bCrop; // Aspect ratio controls.
|
||||
bool bUseXFB;
|
||||
bool bUseRealXFB;
|
||||
|
||||
bool bBlackFrameInsertion;
|
||||
// OpenCL/OpenMP
|
||||
bool bEnableOpenCL;
|
||||
bool bOMPDecoder;
|
||||
|
|
Loading…
Reference in a new issue