diff --git a/plugins/GSdx/GSLinuxDialog.cpp b/plugins/GSdx/GSLinuxDialog.cpp index e56fcb8d6a..6bb04a27d0 100644 --- a/plugins/GSdx/GSLinuxDialog.cpp +++ b/plugins/GSdx/GSLinuxDialog.cpp @@ -380,7 +380,7 @@ void populate_shader_table(GtkWidget* shader_table) InsertWidgetInTable(shader_table , shaderfx_check); InsertWidgetInTable(shader_table , shader_label , shader); InsertWidgetInTable(shader_table , shader_conf_label , shader_conf); - InsertWidgetInTable(shader_table , tv_shader_label, tv_shader); + InsertWidgetInTable(shader_table , tv_shader_label , tv_shader); } void populate_hack_table(GtkWidget* hack_table) @@ -396,6 +396,7 @@ void populate_hack_table(GtkWidget* hack_table) GtkWidget* preload_gs_check = CreateCheckBox("Preload Frame", "preload_frame_with_gs_data"); GtkWidget* hack_fast_inv = CreateCheckBox("Fast Texture Invalidation", "UserHacks_DisablePartialInvalidation"); GtkWidget* hack_depth_check = CreateCheckBox("Disable Depth Emulation", "UserHacks_DisableDepthSupport"); + GtkWidget* hack_cpu_fbcv = CreateCheckBox("Frame Buffer Conversion", "UserHacks_CPU_FB_Conversion"); GtkWidget* hack_auto_flush = CreateCheckBox("Auto Flush Primitives", "UserHacks_AutoFlush"); GtkWidget* hack_unscale_prim = CreateCheckBox("Unscale Point&Line Primitives", "UserHacks_unscale_point_line"); GtkWidget* hack_merge_sprite = CreateCheckBox("Merge Sprite", "UserHacks_merge_pp_sprite"); @@ -422,6 +423,7 @@ void populate_hack_table(GtkWidget* hack_table) AddTooltip(preload_gs_check, IDC_PRELOAD_GS); AddTooltip(hack_fast_inv, IDC_FAST_TC_INV); AddTooltip(hack_depth_check, IDC_TC_DEPTH); + AddTooltip(hack_cpu_fbcv, IDC_CPU_FB_CONVERSION); AddTooltip(hack_auto_flush, IDC_AUTO_FLUSH); AddTooltip(hack_unscale_prim, IDC_UNSCALE_POINT_LINE); AddTooltip(hack_merge_sprite, IDC_MERGE_PP_SPRITE); @@ -434,7 +436,7 @@ void populate_hack_table(GtkWidget* hack_table) // Hack InsertWidgetInTable(hack_table , hack_fast_inv , hack_auto_flush); InsertWidgetInTable(hack_table , hack_depth_check , preload_gs_check); - InsertWidgetInTable(hack_table , hack_wrap_mem); + InsertWidgetInTable(hack_table , hack_wrap_mem , hack_cpu_fbcv); // Upscaling hack InsertWidgetInTable(hack_table , hack_wild_check , align_sprite_check); InsertWidgetInTable(hack_table , hack_unscale_prim , hack_merge_sprite); @@ -448,19 +450,19 @@ void populate_hack_table(GtkWidget* hack_table) void populate_main_table(GtkWidget* main_table) { - GtkWidget* render_label = left_label("Renderer:"); - GtkWidget* render_combo_box = CreateComboBoxFromVector(theApp.m_gs_renderers, "Renderer"); + GtkWidget* render_label = left_label("Renderer:"); + GtkWidget* render_combo_box = CreateComboBoxFromVector(theApp.m_gs_renderers, "Renderer"); GtkWidget* interlace_label = left_label("Interlacing (F5):"); GtkWidget* interlace_combo_box = CreateComboBoxFromVector(theApp.m_gs_interlace, "interlace"); - GtkWidget* filter_label = left_label("Texture Filtering:"); - GtkWidget* filter_combo_box = CreateComboBoxFromVector(theApp.m_gs_bifilter, "filter"); + GtkWidget* filter_label = left_label("Texture Filtering:"); + GtkWidget* filter_combo_box = CreateComboBoxFromVector(theApp.m_gs_bifilter, "filter"); AddTooltip(filter_label, filter_combo_box, IDC_FILTER); s_table_line = 0; InsertWidgetInTable(main_table, render_label, render_combo_box); InsertWidgetInTable(main_table, interlace_label, interlace_combo_box); - InsertWidgetInTable(main_table, filter_label , filter_combo_box); + InsertWidgetInTable(main_table, filter_label, filter_combo_box); } void populate_debug_table(GtkWidget* debug_table) diff --git a/plugins/GSdx/GSSetting.cpp b/plugins/GSdx/GSSetting.cpp index a3aea9aa56..e578d2315c 100644 --- a/plugins/GSdx/GSSetting.cpp +++ b/plugins/GSdx/GSSetting.cpp @@ -122,6 +122,13 @@ const char* dialog_message(int ID, bool* updateText) { case IDC_TC_DEPTH: return "Disable the support of Depth buffer in the texture cache.\n" "It can help to increase speed but it will likely create various glitches."; + case IDC_CPU_FB_CONVERSION: + return "Convert 4-bit and 8-bit frame buffer on the CPU instead of the GPU.\n\n" + "The hack can fix glitches in some games.\n" + "Harry Potter games (Direct3D and OpenGL).\n" + "FIFA Street games (Direct3D).\n" + "Other games might also benefit from this hack especially on Direct3D.\n\n" + "Note: This hack has an impact on performance.\n"; case IDC_AFCOMBO: return "Reduces texture aliasing at extreme viewing angles. High performance impact."; case IDC_AA1: diff --git a/plugins/GSdx/GSSetting.h b/plugins/GSdx/GSSetting.h index 8c0be88db7..90f8594672 100644 --- a/plugins/GSdx/GSSetting.h +++ b/plugins/GSdx/GSSetting.h @@ -63,6 +63,7 @@ enum { IDC_ACCURATE_BLEND_UNIT, IDC_ACCURATE_DATE, IDC_TC_DEPTH, + IDC_CPU_FB_CONVERSION, IDC_CRC_LEVEL, IDC_AFCOMBO, IDC_AA1, diff --git a/plugins/GSdx/GSSettingsDlg.cpp b/plugins/GSdx/GSSettingsDlg.cpp index ef5b9b69c1..267d3fc6ee 100644 --- a/plugins/GSdx/GSSettingsDlg.cpp +++ b/plugins/GSdx/GSSettingsDlg.cpp @@ -698,6 +698,7 @@ void GSHacksDlg::OnInit() CheckDlgButton(m_hWnd, IDC_PRELOAD_GS, theApp.GetConfigB("preload_frame_with_gs_data")); CheckDlgButton(m_hWnd, IDC_ALIGN_SPRITE, theApp.GetConfigB("UserHacks_align_sprite_X")); CheckDlgButton(m_hWnd, IDC_TC_DEPTH, theApp.GetConfigB("UserHacks_DisableDepthSupport")); + CheckDlgButton(m_hWnd, IDC_CPU_FB_CONVERSION, theApp.GetConfigB("UserHacks_CPU_FB_Conversion")); CheckDlgButton(m_hWnd, IDC_FAST_TC_INV, theApp.GetConfigB("UserHacks_DisablePartialInvalidation")); CheckDlgButton(m_hWnd, IDC_AUTO_FLUSH, theApp.GetConfigB("UserHacks_AutoFlush")); CheckDlgButton(m_hWnd, IDC_UNSCALE_POINT_LINE, theApp.GetConfigB("UserHacks_unscale_point_line")); @@ -765,6 +766,7 @@ void GSHacksDlg::OnInit() AddTooltip(IDC_TCOFFSETY2); AddTooltip(IDC_PRELOAD_GS); AddTooltip(IDC_TC_DEPTH); + AddTooltip(IDC_CPU_FB_CONVERSION); AddTooltip(IDC_FAST_TC_INV); AddTooltip(IDC_AUTO_FLUSH); AddTooltip(IDC_UNSCALE_POINT_LINE); @@ -823,6 +825,7 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) 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_DisableDepthSupport", (int)IsDlgButtonChecked(m_hWnd, IDC_TC_DEPTH)); + theApp.SetConfig("UserHacks_CPU_FB_Conversion", (int)IsDlgButtonChecked(m_hWnd, IDC_CPU_FB_CONVERSION)); theApp.SetConfig("UserHacks_DisablePartialInvalidation", (int)IsDlgButtonChecked(m_hWnd, IDC_FAST_TC_INV)); theApp.SetConfig("UserHacks_AutoFlush", (int)IsDlgButtonChecked(m_hWnd, IDC_AUTO_FLUSH)); theApp.SetConfig("UserHacks_unscale_point_line", (int)IsDlgButtonChecked(m_hWnd, IDC_UNSCALE_POINT_LINE)); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index b29cc769ee..857591d886 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -38,6 +38,7 @@ GSTextureCache::GSTextureCache(GSRenderer* r) m_preload_frame = theApp.GetConfigB("preload_frame_with_gs_data"); m_disable_partial_invalidation = theApp.GetConfigB("UserHacks_DisablePartialInvalidation"); m_can_convert_depth = !theApp.GetConfigB("UserHacks_DisableDepthSupport"); + m_cpu_fb_conversion = theApp.GetConfigB("UserHacks_CPU_FB_Conversion"); m_texture_inside_rt = theApp.GetConfigB("UserHacks_TextureInsideRt"); m_wrap_gs_mem = theApp.GetConfigB("wrap_gs_mem"); } else { @@ -46,6 +47,7 @@ GSTextureCache::GSTextureCache(GSRenderer* r) m_preload_frame = false; m_disable_partial_invalidation = false; m_can_convert_depth = true; + m_cpu_fb_conversion = false; m_texture_inside_rt = false; m_wrap_gs_mem = false; } @@ -268,25 +270,21 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con uint32 t_psm = (t->m_dirty_alpha) ? t->m_TEX0.PSM & ~0x1 : t->m_TEX0.PSM; if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t_psm)) { - if (!s_IS_OPENGL && (psm == PSM_PSMT8)) { - // OpenGL can convert the texture directly in the GPU. Not sure we want to keep this - // code for DX. It fixes effect but it is slow (MGS3) - - // It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will - // be slow but - // 1/ it just works :) - // 2/ even with upscaling - // 3/ for both DX and OpenGL - - // Gregory: to avoid a massive slow down for nothing, let's only enable - // this code when CRC is below the FULL level - if (m_crc_hack_level < CRCHackLevel::Full) - Read(t, t->m_valid); - else - dst = t; - } else { + // It is a complex to convert the code in shader. As a reference, let's do it on the CPU, it will be slow but + // 1/ it just works :) + // 2/ even with upscaling + // 3/ for both DX and OpenGL + if (m_cpu_fb_conversion && (psm == PSM_PSMT4 || psm == PSM_PSMT8)) + // Forces 4-bit and 8-bit frame buffer conversion to be done on the CPU instead of the GPU, but performance will be slower. + // There is no dedicated shader to handle 4-bit conversion. + // Direct3D doesn't support 8-bit fb conversion, OpenGL does support it but it doesn't render some corner cases properly. + // The hack can fix glitches in some games. + // Harry Potter games (Direct3D and OpenGL). + // FIFA Street games (Direct3D). + // Other games might also benefit from this hack especially on Direct3D. + Read(t, t->m_valid); + else dst = t; - } break; @@ -298,6 +296,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con dst = t; break; + } else if (m_texture_inside_rt && psm == PSM_PSMCT32 && bw == 1 && bp_end < t->m_end_block && t->m_TEX0.TBP0 < bp) { // Note bw == 1 until we find a generic formulae below dst = t; diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index c24674927a..ef751a81db 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -130,6 +130,7 @@ protected: bool m_preload_frame; uint8* m_temp; bool m_can_convert_depth; + bool m_cpu_fb_conversion; CRCHackLevel m_crc_hack_level; static bool m_disable_partial_invalidation; bool m_texture_inside_rt; diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index 6f68192be2..a00bfed78f 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -429,6 +429,7 @@ void GSdxApp::Init() m_default_configuration["UserHacks_AlphaStencil"] = "0"; m_default_configuration["UserHacks_AutoFlush"] = "0"; m_default_configuration["UserHacks_DisableDepthSupport"] = "0"; + m_default_configuration["UserHacks_CPU_FB_Conversion"] = "0"; m_default_configuration["UserHacks_DisableGsMemClear"] = "0"; m_default_configuration["UserHacks_DisablePartialInvalidation"] = "0"; m_default_configuration["UserHacks_HalfPixelOffset"] = "0"; diff --git a/plugins/GSdx/GSdx.rc b/plugins/GSdx/GSdx.rc index 1ae055b59a..608eef882b 100644 --- a/plugins/GSdx/GSdx.rc +++ b/plugins/GSdx/GSdx.rc @@ -142,6 +142,7 @@ BEGIN CONTROL "Alpha",IDC_ALPHAHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,71,34,8 CONTROL "Alpha Stencil",IDC_ALPHASTENCIL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,71,57,8 CONTROL "Disable Depth Emulation",IDC_TC_DEPTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,84,92,8 + CONTROL "Frame Buffer Conversion",IDC_CPU_FB_CONVERSION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,84,92,8 RTEXT "MSAA:",IDC_MSAA_TEXT,54,99,22,8 COMBOBOX IDC_MSAACB,80,96,116,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP RTEXT "Trilinear Filtering:",IDC_TRI_FILTER_TEXT,16,114,60,8 diff --git a/plugins/GSdx/resource.h b/plugins/GSdx/resource.h index 3a76b8d808..96bbb07ecb 100644 --- a/plugins/GSdx/resource.h +++ b/plugins/GSdx/resource.h @@ -103,6 +103,7 @@ #define IDC_TRI_FILTER_TEXT 2124 #define IDC_UNSCALE_POINT_LINE 2125 #define IDC_MERGE_PP_SPRITE 2126 +#define IDC_CPU_FB_CONVERSION 2127 // Shader: #define IDC_SHADEBOOST 2140 #define IDC_FXAA 2141