mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1078 from PCSX2/gsdx-unsafe-fbmask
Gsdx unsafe fbmask
This commit is contained in:
commit
7c7de87fcf
|
@ -351,6 +351,7 @@ void populate_hack_table(GtkWidget* hack_table)
|
||||||
GtkWidget* hack_tco_entry = CreateTextBox("UserHacks_TCOffset");
|
GtkWidget* hack_tco_entry = CreateTextBox("UserHacks_TCOffset");
|
||||||
GtkWidget* align_sprite_check = CreateCheckBox("Align sprite hack", "UserHacks_align_sprite_X");
|
GtkWidget* align_sprite_check = CreateCheckBox("Align sprite hack", "UserHacks_align_sprite_X");
|
||||||
GtkWidget* preload_gs_check = CreateCheckBox("Preload Frame", "preload_frame_with_gs_data");
|
GtkWidget* preload_gs_check = CreateCheckBox("Preload Frame", "preload_frame_with_gs_data");
|
||||||
|
GtkWidget* hack_unsafe_fbmask = CreateCheckBox("Fast Accurate Blending", "UserHacks_unsafe_fbmask");
|
||||||
|
|
||||||
GtkWidget* hack_sprite_box = CreateComboBoxFromVector(theApp.m_gs_hack, "UserHacks_SpriteHack");
|
GtkWidget* hack_sprite_box = CreateComboBoxFromVector(theApp.m_gs_hack, "UserHacks_SpriteHack");
|
||||||
GtkWidget* hack_sprite_label = left_label("Alpha-Sprite Hack:");
|
GtkWidget* hack_sprite_label = left_label("Alpha-Sprite Hack:");
|
||||||
|
@ -375,6 +376,7 @@ void populate_hack_table(GtkWidget* hack_table)
|
||||||
InsertWidgetInTable(hack_table , hack_enble_check);
|
InsertWidgetInTable(hack_table , hack_enble_check);
|
||||||
InsertWidgetInTable(hack_table , hack_wild_check , align_sprite_check);
|
InsertWidgetInTable(hack_table , hack_wild_check , align_sprite_check);
|
||||||
InsertWidgetInTable(hack_table , hack_offset_check , preload_gs_check);
|
InsertWidgetInTable(hack_table , hack_offset_check , preload_gs_check);
|
||||||
|
InsertWidgetInTable(hack_table , hack_unsafe_fbmask);
|
||||||
InsertWidgetInTable(hack_table , hack_sprite_label , hack_sprite_box );
|
InsertWidgetInTable(hack_table , hack_sprite_label , hack_sprite_box );
|
||||||
InsertWidgetInTable(hack_table , stretch_hack_label , stretch_hack_box );
|
InsertWidgetInTable(hack_table , stretch_hack_label , stretch_hack_box );
|
||||||
InsertWidgetInTable(hack_table , hack_skipdraw_label , hack_skipdraw_spin);
|
InsertWidgetInTable(hack_table , hack_skipdraw_label , hack_skipdraw_spin);
|
||||||
|
|
|
@ -34,6 +34,7 @@ GSRendererOGL::GSRendererOGL()
|
||||||
UserHacks_TCOffset = theApp.GetConfig("UserHacks_TCOffset", 0);
|
UserHacks_TCOffset = theApp.GetConfig("UserHacks_TCOffset", 0);
|
||||||
UserHacks_TCO_x = (UserHacks_TCOffset & 0xFFFF) / -1000.0f;
|
UserHacks_TCO_x = (UserHacks_TCOffset & 0xFFFF) / -1000.0f;
|
||||||
UserHacks_TCO_y = ((UserHacks_TCOffset >> 16) & 0xFFFF) / -1000.0f;
|
UserHacks_TCO_y = ((UserHacks_TCOffset >> 16) & 0xFFFF) / -1000.0f;
|
||||||
|
UserHacks_unsafe_fbmask = theApp.GetConfig("UserHacks_unsafe_fbmask", false);
|
||||||
|
|
||||||
m_prim_overlap = PRIM_OVERLAP_UNKNOW;
|
m_prim_overlap = PRIM_OVERLAP_UNKNOW;
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ GSRendererOGL::GSRendererOGL()
|
||||||
UserHacks_TCOffset = 0;
|
UserHacks_TCOffset = 0;
|
||||||
UserHacks_TCO_x = 0;
|
UserHacks_TCO_x = 0;
|
||||||
UserHacks_TCO_y = 0;
|
UserHacks_TCO_y = 0;
|
||||||
|
UserHacks_unsafe_fbmask = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,12 +301,39 @@ bool GSRendererOGL::EmulateTextureShuffleAndFbmask(GSDeviceOGL::PSSelector& ps_s
|
||||||
ps_sel.fbmask = m_sw_blending && (~ff_fbmask & ~zero_fbmask & 0xF);
|
ps_sel.fbmask = m_sw_blending && (~ff_fbmask & ~zero_fbmask & 0xF);
|
||||||
|
|
||||||
if (ps_sel.fbmask) {
|
if (ps_sel.fbmask) {
|
||||||
|
ps_cb.FbMask = fbmask_v.u8to32();
|
||||||
|
// Only alpha is special here, I think we can take a very unsafe shortcut
|
||||||
|
// Alpha isn't blended on the GS but directly copyied into the RT.
|
||||||
|
//
|
||||||
|
// Behavior is clearly undefined however there is a high probability that
|
||||||
|
// it will work. Masked bit will be constant and normally the same everywhere
|
||||||
|
// RT/FS output/Cached value.
|
||||||
|
//
|
||||||
|
// Just to be sure let's add a new safe hack for unsafe access :)
|
||||||
|
//
|
||||||
|
// Here the GL spec quote to emphasize the unexpected behavior.
|
||||||
|
/*
|
||||||
|
- If a texel has been written, then in order to safely read the result
|
||||||
|
a texel fetch must be in a subsequent Draw separated by the command
|
||||||
|
|
||||||
|
void TextureBarrier(void);
|
||||||
|
|
||||||
|
TextureBarrier() will guarantee that writes have completed and caches
|
||||||
|
have been invalidated before subsequent Draws are executed.
|
||||||
|
*/
|
||||||
|
if (!(~ff_fbmask & ~zero_fbmask & 0x7) && UserHacks_unsafe_fbmask) {
|
||||||
|
GL_INS("FBMASK Unsafe SW emulated fb_mask:%x on %d bits format", m_context->FRAME.FBMSK,
|
||||||
|
(GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 2) ? 16 : 32);
|
||||||
|
m_unsafe_fbmask = true;
|
||||||
|
require_barrier = false;
|
||||||
|
} else {
|
||||||
|
// The safe and accurate path (but slow)
|
||||||
GL_INS("FBMASK SW emulated fb_mask:%x on %d bits format", m_context->FRAME.FBMSK,
|
GL_INS("FBMASK SW emulated fb_mask:%x on %d bits format", m_context->FRAME.FBMSK,
|
||||||
(GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 2) ? 16 : 32);
|
(GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 2) ? 16 : 32);
|
||||||
ps_cb.FbMask = fbmask_v.u8to32();
|
|
||||||
require_barrier = true;
|
require_barrier = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return require_barrier;
|
return require_barrier;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +387,7 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, bool DATE_G
|
||||||
((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
|
((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
|
||||||
case ACC_BLEND_CCLIP_DALPHA: sw_blending |= (ALPHA.C == 1) || (m_env.COLCLAMP.CLAMP == 0);
|
case ACC_BLEND_CCLIP_DALPHA: sw_blending |= (ALPHA.C == 1) || (m_env.COLCLAMP.CLAMP == 0);
|
||||||
case ACC_BLEND_SPRITE: sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS;
|
case ACC_BLEND_SPRITE: sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS;
|
||||||
case ACC_BLEND_FREE: sw_blending |= ps_sel.fbmask || impossible_or_free_blend;
|
case ACC_BLEND_FREE: sw_blending |= (ps_sel.fbmask && !m_unsafe_fbmask) || impossible_or_free_blend; // blending is only free when we use slow fbmask
|
||||||
default: sw_blending |= accumulation_blend;
|
default: sw_blending |= accumulation_blend;
|
||||||
}
|
}
|
||||||
// SW Blending
|
// SW Blending
|
||||||
|
@ -566,7 +595,12 @@ void GSRendererOGL::SendDraw(bool require_barrier)
|
||||||
{
|
{
|
||||||
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
|
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
|
||||||
|
|
||||||
if (!require_barrier) {
|
if (!require_barrier && m_unsafe_fbmask) {
|
||||||
|
// Not safe but still worth to take some precautions.
|
||||||
|
ASSERT(GLLoader::found_GL_ARB_texture_barrier);
|
||||||
|
glTextureBarrier();
|
||||||
|
dev->DrawIndexedPrimitive();
|
||||||
|
} else if (!require_barrier) {
|
||||||
dev->DrawIndexedPrimitive();
|
dev->DrawIndexedPrimitive();
|
||||||
} else if (m_prim_overlap == PRIM_OVERLAP_NO) {
|
} else if (m_prim_overlap == PRIM_OVERLAP_NO) {
|
||||||
ASSERT(GLLoader::found_GL_ARB_texture_barrier);
|
ASSERT(GLLoader::found_GL_ARB_texture_barrier);
|
||||||
|
@ -621,6 +655,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
||||||
bool DATE_GL45 = false;
|
bool DATE_GL45 = false;
|
||||||
|
|
||||||
bool require_barrier = false; // For accurate option
|
bool require_barrier = false; // For accurate option
|
||||||
|
m_unsafe_fbmask = false;
|
||||||
|
|
||||||
ASSERT(m_dev != NULL);
|
ASSERT(m_dev != NULL);
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,11 @@ class GSRendererOGL : public GSRendererHW
|
||||||
bool m_accurate_date;
|
bool m_accurate_date;
|
||||||
int m_sw_blending;
|
int m_sw_blending;
|
||||||
PRIM_OVERLAP m_prim_overlap;
|
PRIM_OVERLAP m_prim_overlap;
|
||||||
|
bool m_unsafe_fbmask;
|
||||||
|
|
||||||
unsigned int UserHacks_TCOffset;
|
unsigned int UserHacks_TCOffset;
|
||||||
float UserHacks_TCO_x, UserHacks_TCO_y;
|
float UserHacks_TCO_x, UserHacks_TCO_y;
|
||||||
|
bool UserHacks_unsafe_fbmask;
|
||||||
|
|
||||||
GSDeviceOGL::VSConstantBuffer vs_cb;
|
GSDeviceOGL::VSConstantBuffer vs_cb;
|
||||||
GSDeviceOGL::PSConstantBuffer ps_cb;
|
GSDeviceOGL::PSConstantBuffer ps_cb;
|
||||||
|
|
|
@ -102,6 +102,9 @@ const char* dialog_message(int ID, bool* updateText) {
|
||||||
"High:\nExtend it to destination alpha blending and color wrapping. (help shadow and fog effect). A good CPU is required.\n\n"
|
"High:\nExtend it to destination alpha blending and color wrapping. (help shadow and fog effect). A good CPU is required.\n\n"
|
||||||
"Full:\nExcept few cases, the blending unit will be fully emulated by the shader. It is ultra slow! It is intended for debug.\n\n"
|
"Full:\nExcept few cases, the blending unit will be fully emulated by the shader. It is ultra slow! It is intended for debug.\n\n"
|
||||||
"Ultra:\nThe blending unit will be completely emulated by the shader. It is ultra slow! It is intended for debug.";
|
"Ultra:\nThe blending unit will be completely emulated by the shader. It is ultra slow! It is intended for debug.";
|
||||||
|
case IDC_UNSAFE_FBMASK:
|
||||||
|
return "Relies on undefined hardware behavior to accelerate accurate blending operation.\n\n"
|
||||||
|
"It provides a major boost on the Xenosaga Series.\n";
|
||||||
case IDC_TC_DEPTH:
|
case IDC_TC_DEPTH:
|
||||||
return "Allows the conversion of Depth buffer from/to Color buffer. It is used for blur & depth of field effects";
|
return "Allows the conversion of Depth buffer from/to Color buffer. It is used for blur & depth of field effects";
|
||||||
case IDC_AFCOMBO:
|
case IDC_AFCOMBO:
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum {
|
||||||
IDC_TCOFFSETY2,
|
IDC_TCOFFSETY2,
|
||||||
IDC_PALTEX,
|
IDC_PALTEX,
|
||||||
IDC_ACCURATE_BLEND_UNIT,
|
IDC_ACCURATE_BLEND_UNIT,
|
||||||
|
IDC_UNSAFE_FBMASK,
|
||||||
IDC_ACCURATE_DATE,
|
IDC_ACCURATE_DATE,
|
||||||
IDC_TC_DEPTH,
|
IDC_TC_DEPTH,
|
||||||
IDC_CRC_LEVEL,
|
IDC_CRC_LEVEL,
|
||||||
|
|
|
@ -658,6 +658,8 @@ void GSHacksDlg::OnInit()
|
||||||
CheckDlgButton(m_hWnd, IDC_ALPHASTENCIL, theApp.GetConfig("UserHacks_AlphaStencil", 0));
|
CheckDlgButton(m_hWnd, IDC_ALPHASTENCIL, theApp.GetConfig("UserHacks_AlphaStencil", 0));
|
||||||
CheckDlgButton(m_hWnd, IDC_PRELOAD_GS, theApp.GetConfig("preload_frame_with_gs_data", 0));
|
CheckDlgButton(m_hWnd, IDC_PRELOAD_GS, theApp.GetConfig("preload_frame_with_gs_data", 0));
|
||||||
CheckDlgButton(m_hWnd, IDC_ALIGN_SPRITE, theApp.GetConfig("UserHacks_align_sprite_X", 0));
|
CheckDlgButton(m_hWnd, IDC_ALIGN_SPRITE, theApp.GetConfig("UserHacks_align_sprite_X", 0));
|
||||||
|
CheckDlgButton(m_hWnd, IDC_UNSAFE_FBMASK, theApp.GetConfig("UserHacks_unsafe_fbmask", 0));
|
||||||
|
|
||||||
|
|
||||||
ComboBoxInit(IDC_ROUND_SPRITE, theApp.m_gs_hack, theApp.GetConfig("UserHacks_round_sprite_offset", 0));
|
ComboBoxInit(IDC_ROUND_SPRITE, theApp.m_gs_hack, theApp.GetConfig("UserHacks_round_sprite_offset", 0));
|
||||||
ComboBoxInit(IDC_SPRITEHACK, theApp.m_gs_hack, theApp.GetConfig("UserHacks_SpriteHack", 0));
|
ComboBoxInit(IDC_SPRITEHACK, theApp.m_gs_hack, theApp.GetConfig("UserHacks_SpriteHack", 0));
|
||||||
|
@ -673,6 +675,8 @@ void GSHacksDlg::OnInit()
|
||||||
|
|
||||||
ShowWindow(GetDlgItem(m_hWnd, IDC_ALPHASTENCIL), ogl ? SW_HIDE : SW_SHOW);
|
ShowWindow(GetDlgItem(m_hWnd, IDC_ALPHASTENCIL), ogl ? SW_HIDE : SW_SHOW);
|
||||||
ShowWindow(GetDlgItem(m_hWnd, IDC_ALPHAHACK), ogl ? SW_HIDE : SW_SHOW);
|
ShowWindow(GetDlgItem(m_hWnd, IDC_ALPHAHACK), ogl ? SW_HIDE : SW_SHOW);
|
||||||
|
ShowWindow(GetDlgItem(m_hWnd, IDC_UNSAFE_FBMASK), ogl ? SW_SHOW : SW_HIDE);
|
||||||
|
|
||||||
|
|
||||||
AddTooltip(IDC_SKIPDRAWHACKEDIT);
|
AddTooltip(IDC_SKIPDRAWHACKEDIT);
|
||||||
AddTooltip(IDC_SKIPDRAWHACK);
|
AddTooltip(IDC_SKIPDRAWHACK);
|
||||||
|
@ -689,6 +693,7 @@ void GSHacksDlg::OnInit()
|
||||||
AddTooltip(IDC_TCOFFSETY);
|
AddTooltip(IDC_TCOFFSETY);
|
||||||
AddTooltip(IDC_TCOFFSETY2);
|
AddTooltip(IDC_TCOFFSETY2);
|
||||||
AddTooltip(IDC_PRELOAD_GS);
|
AddTooltip(IDC_PRELOAD_GS);
|
||||||
|
AddTooltip(IDC_UNSAFE_FBMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSHacksDlg::UpdateControls()
|
void GSHacksDlg::UpdateControls()
|
||||||
|
@ -723,6 +728,8 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
theApp.SetConfig("UserHacks_AlphaStencil", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHASTENCIL));
|
theApp.SetConfig("UserHacks_AlphaStencil", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHASTENCIL));
|
||||||
theApp.SetConfig("preload_frame_with_gs_data", (int)IsDlgButtonChecked(m_hWnd, IDC_PRELOAD_GS));
|
theApp.SetConfig("preload_frame_with_gs_data", (int)IsDlgButtonChecked(m_hWnd, IDC_PRELOAD_GS));
|
||||||
theApp.SetConfig("Userhacks_align_sprite_X", (int)IsDlgButtonChecked(m_hWnd, IDC_ALIGN_SPRITE));
|
theApp.SetConfig("Userhacks_align_sprite_X", (int)IsDlgButtonChecked(m_hWnd, IDC_ALIGN_SPRITE));
|
||||||
|
theApp.SetConfig("UserHacks_unsafe_fbmask", (int)IsDlgButtonChecked(m_hWnd, IDC_UNSAFE_FBMASK));
|
||||||
|
|
||||||
|
|
||||||
unsigned int TCOFFSET = SendMessage(GetDlgItem(m_hWnd, IDC_TCOFFSETX), UDM_GETPOS, 0, 0) & 0xFFFF;
|
unsigned int TCOFFSET = SendMessage(GetDlgItem(m_hWnd, IDC_TCOFFSETX), UDM_GETPOS, 0, 0) & 0xFFFF;
|
||||||
TCOFFSET |= (SendMessage(GetDlgItem(m_hWnd, IDC_TCOFFSETY), UDM_GETPOS, 0, 0) & 0xFFFF) << 16;
|
TCOFFSET |= (SendMessage(GetDlgItem(m_hWnd, IDC_TCOFFSETY), UDM_GETPOS, 0, 0) & 0xFFFF) << 16;
|
||||||
|
|
|
@ -105,6 +105,7 @@ BEGIN
|
||||||
CONTROL "Half-pixel Offset",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,51,70,8
|
CONTROL "Half-pixel Offset",IDC_OFFSETHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,51,70,8
|
||||||
COMBOBOX IDC_MSAACB,88,17,58,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_MSAACB,88,17,58,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
CONTROL "Wild Arms Offset",IDC_WILDHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,64,70,8
|
CONTROL "Wild Arms Offset",IDC_WILDHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,64,70,8
|
||||||
|
CONTROL "Fast accurate blending",IDC_UNSAFE_FBMASK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,77,90,8
|
||||||
CONTROL "Alpha Stencil",IDC_ALPHASTENCIL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,77,57,8
|
CONTROL "Alpha Stencil",IDC_ALPHASTENCIL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,77,57,8
|
||||||
CONTROL "Align Sprite",IDC_ALIGN_SPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,51,58,8
|
CONTROL "Align Sprite",IDC_ALIGN_SPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,51,58,8
|
||||||
RTEXT "TC Offset X:",IDC_STATIC,40,146,44,8
|
RTEXT "TC Offset X:",IDC_STATIC,40,146,44,8
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
#define IDC_MIPMAP 2084
|
#define IDC_MIPMAP 2084
|
||||||
#define IDC_PRELOAD_GS 2085
|
#define IDC_PRELOAD_GS 2085
|
||||||
#define IDC_TVSHADER 2086
|
#define IDC_TVSHADER 2086
|
||||||
|
#define IDC_UNSAFE_FBMASK 2087
|
||||||
#define IDR_CONVERT_FX 10000
|
#define IDR_CONVERT_FX 10000
|
||||||
#define IDR_TFX_FX 10001
|
#define IDR_TFX_FX 10001
|
||||||
#define IDR_MERGE_FX 10002
|
#define IDR_MERGE_FX 10002
|
||||||
|
@ -107,7 +108,7 @@
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 10013
|
#define _APS_NEXT_RESOURCE_VALUE 10013
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||||
#define _APS_NEXT_CONTROL_VALUE 2087
|
#define _APS_NEXT_CONTROL_VALUE 2088
|
||||||
#define _APS_NEXT_SYMED_VALUE 5000
|
#define _APS_NEXT_SYMED_VALUE 5000
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue