diff --git a/Source/Core/VideoCommon/Src/NativeVertexWriter.h b/Source/Core/VideoCommon/Src/NativeVertexWriter.h index 1bbc8033aa..bd9d2d3f14 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexWriter.h +++ b/Source/Core/VideoCommon/Src/NativeVertexWriter.h @@ -25,6 +25,7 @@ namespace VertexManager void AddVertices(int primitive, int numvertices); void Flush(); // flushes the current buffer int GetRemainingSize(); // remaining space in the current buffer. +int GetRemainingVertices(int primitive); // remaining number of vertices that can be processed in one AddVertices call // TODO: move, rename. extern u8* s_pCurBufferPointer; diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index a2a70483c6..5981fde36d 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -602,9 +602,12 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) int startv = 0, extraverts = 0; int v = 0; + int remainingVerts2 = VertexManager::GetRemainingVertices(primitive); while (v < count) { int remainingVerts = VertexManager::GetRemainingSize() / native_stride; + if (remainingVerts2 - v + startv < remainingVerts) + remainingVerts = remainingVerts2 - v + startv; if (remainingVerts < granularity) { INCSTAT(stats.thisFrame.numBufferSplits); // This buffer full - break current primitive and flush, to switch to the next buffer. @@ -612,6 +615,7 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) if (v - startv > 0) VertexManager::AddVertices(primitive, v - startv + extraverts); VertexManager::Flush(); + remainingVerts2 = VertexManager::GetRemainingVertices(primitive); // Why does this need to be so complicated? switch (primitive) { case 3: // triangle strip, copy last two vertices diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 11364e3808..92f6b55b6e 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -53,9 +53,10 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "wideScreenHack", &bWidescreenHack, false); iniFile.Get("Settings", "AspectRatio", &iAspectRatio, (int)ASPECT_AUTO); iniFile.Get("Settings", "Crop", &bCrop, false); - iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); + iniFile.Get("Settings", "UseXFB", &bUseXFB, true); iniFile.Get("Settings", "UseRealXFB", &bUseRealXFB, 0); iniFile.Get("Settings", "AutoScale", &bAutoScale, true); + iniFile.Get("Settings", "UseNativeMips", &bUseNativeMips, true); iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings //Safe texture cache params @@ -141,6 +142,8 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.Get("Video", "FIFOBPHack", &bFIFOBPhack, false); if (iniFile.Exists("Video", "ProjectionHack")) iniFile.Get("Video", "ProjectionHack", &iPhackvalue, 0); + if (iniFile.Exists("Video", "UseNativeMips")) + iniFile.Get("Video", "UseNativeMips", &bUseNativeMips, true); } void VideoConfig::Save(const char *ini_file) @@ -156,6 +159,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "UseXFB", bUseXFB); iniFile.Set("Settings", "UseRealXFB", bUseRealXFB); iniFile.Set("Settings", "AutoScale", bAutoScale); + iniFile.Set("Settings", "UseNativeMips", bUseNativeMips); iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); //safe texture cache params diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 75d39f9afa..8740590727 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -76,6 +76,7 @@ struct VideoConfig bool bUseXFB; bool bUseRealXFB; bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly. + bool bUseNativeMips; // Enhancements int iMultisampleMode; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp index d4a67be810..ec54866823 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp @@ -175,7 +175,7 @@ struct TabAdvanced : public W32Util::Tab Button_SetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY), !g_Config.bEFBCopyDisable); Button_SetCheck(GetDlgItem(hDlg,IDC_ENABLEXFB),g_Config.bUseXFB); Button_SetCheck(GetDlgItem(hDlg,IDC_ENABLEREALXFB),g_Config.bUseRealXFB); - + Button_SetCheck(GetDlgItem(hDlg,IDC_USENATIVEMIPS),g_Config.bUseNativeMips); if(g_Config.bCopyEFBToTexture) Button_SetCheck(GetDlgItem(hDlg,IDC_EFBTOTEX), true); else @@ -237,6 +237,7 @@ struct TabAdvanced : public W32Util::Tab g_Config.bCopyEFBToTexture = Button_GetCheck(GetDlgItem(hDlg,IDC_EFBTORAM)) ? false : true; g_Config.bUseXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEXFB)) ? true : false; g_Config.bUseRealXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEREALXFB)) ? true : false; + g_Config.bUseNativeMips = Button_GetCheck(GetDlgItem(hDlg, IDC_USENATIVEMIPS)) ? true : false; g_Config.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str()); if( D3D::dev != NULL ) { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index a0f3b30d5a..94d920df80 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -283,7 +283,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); entry.isNonPow2 = false; int TexLevels = (width > height)?width:height; - TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : ((isPow2 && g_ActiveConfig.bForceFiltering)? 0 : 1); + TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : ((isPow2)? 0 : 1); if(TexLevels > maxlevel && maxlevel > 0) TexLevels = maxlevel; if (!skip_texture_create) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 64b39efcc5..4b1b2fa266 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -53,7 +53,7 @@ static int lastPrimitive; static u8 *LocalVBuffer; static u16 *TIBuffer; static u16 *LIBuffer; -static u16 *PIBuffer; +static u16 *PIBuffer; #define MAXVBUFFERSIZE 0x50000 #define MAXIBUFFERSIZE 0xFFFF static bool Flushed=false; @@ -118,9 +118,27 @@ int GetRemainingSize() return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer); } +int GetRemainingVertices(int primitive) +{ + switch (primitive) + { + case GX_DRAW_QUADS: + case GX_DRAW_TRIANGLES: + case GX_DRAW_TRIANGLE_STRIP: + case GX_DRAW_TRIANGLE_FAN: + return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen())/3; + case GX_DRAW_LINE_STRIP: + case GX_DRAW_LINES: + return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen())/2; + case GX_DRAW_POINTS: + return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); + default: return 0; + } +} + void AddVertices(int _primitive, int _numVertices) { - if (_numVertices < 0) + if (_numVertices <= 0) return; switch (_primitive) { @@ -128,7 +146,7 @@ void AddVertices(int _primitive, int _numVertices) case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_FAN: - if(MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 2 * _numVertices) + if(MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices) Flush(); break; case GX_DRAW_LINE_STRIP: @@ -250,7 +268,7 @@ void Flush() tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8), + (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips, (tex.texMode1[i&3].max_lod >> 4)); if (tentry) { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.h b/Source/Plugins/Plugin_VideoDX9/Src/resource.h index 7c3335c305..0abef13981 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.h @@ -43,6 +43,7 @@ #define IDC_RADIO3 1043 #define IDC_SAFE_TEXTURE_CACHE_FAST 1043 #define IDC_CHECK1 1100 +#define IDC_USENATIVEMIPS 1100 #define IDC_STATIC -1 // Next default values for new objects diff --git a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc index dea9773985..a6142ff928 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX9/Src/resource.rc @@ -79,6 +79,7 @@ BEGIN CONTROL "Centered",IDC_TEXFMT_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,114,183,52,10 CONTROL "Enable XFB",IDC_ENABLEXFB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,71,81,8 CONTROL "Enable Real XFB",IDC_ENABLEREALXFB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,114,71,81,8 + CONTROL "Use Native Mips",IDC_USENATIVEMIPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,83,67,10 END IDD_ENHANCEMENTS DIALOGEX 0, 0, 224, 175 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 0471a231f6..38d42f13ec 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -44,6 +44,7 @@ BEGIN_EVENT_TABLE(GFXConfigDialogOGL,wxDialog) EVT_CHECKBOX(ID_USEXFB, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_USEREALXFB, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_FORCEFILTERING, GFXConfigDialogOGL::GeneralSettingsChanged) + EVT_CHECKBOX(ID_USENATIVEMIPS, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_AUTOSCALE, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_WIDESCREENHACK, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHOICE(ID_ASPECT, GFXConfigDialogOGL::GeneralSettingsChanged) @@ -200,7 +201,7 @@ void GFXConfigDialogOGL::InitializeGUIValues() m_UseRealXFB->SetValue(g_Config.bUseRealXFB); m_AutoScale->SetValue(g_Config.bAutoScale); m_WidescreenHack->SetValue(g_Config.bWidescreenHack); - + m_UseNativeMips->SetValue(g_Config.bUseNativeMips); // Enhancements m_MaxAnisotropyCB->SetSelection(g_Config.iMaxAnisotropy - 1); m_ForceFiltering->SetValue(g_Config.bForceFiltering); @@ -369,6 +370,7 @@ void GFXConfigDialogOGL::CreateGUIControls() m_UseRealXFB = new wxCheckBox(m_PageGeneral, ID_USEREALXFB, wxT("Use Real XFB"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_AutoScale = new wxCheckBox(m_PageGeneral, ID_AUTOSCALE, wxT("Auto scale (try to remove borders)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_WidescreenHack = new wxCheckBox(m_PageGeneral, ID_WIDESCREENHACK, wxT("Wide screen hack"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_UseNativeMips = new wxCheckBox(m_PageGeneral, ID_USENATIVEMIPS, wxT("Use Native Mips"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); // Enhancements sbEnhancements = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Enhancements")); @@ -405,6 +407,7 @@ void GFXConfigDialogOGL::CreateGUIControls() sBasicAdvanced->Add(m_UseRealXFB, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5); sBasicAdvanced->Add(m_AutoScale, wxGBPosition(4, 0), wxGBSpan(1, 2), wxALL, 5); sBasicAdvanced->Add(m_WidescreenHack, wxGBPosition(5, 0), wxGBSpan(1, 2), wxALL, 5); + sBasicAdvanced->Add(m_UseNativeMips, wxGBPosition(6, 0), wxGBSpan(1, 2), wxALL, 5); sbBasicAdvanced->Add(sBasicAdvanced); sGeneral->Add(sbBasicAdvanced, 0, wxEXPAND|wxALL, 5); @@ -591,6 +594,9 @@ void GFXConfigDialogOGL::GeneralSettingsChanged(wxCommandEvent& event) case ID_USEREALXFB: g_Config.bUseRealXFB = m_UseRealXFB->IsChecked(); break; + case ID_USENATIVEMIPS: + g_Config.bUseNativeMips = m_UseNativeMips->IsChecked(); + break; case ID_AUTOSCALE: g_Config.bAutoScale = m_AutoScale->IsChecked(); break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index 3b71b256f2..29b754150a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -95,6 +95,7 @@ class GFXConfigDialogOGL : public wxDialog wxCheckBox *m_ForceFiltering; wxCheckBox *m_Crop; wxCheckBox *m_UseXFB; + wxCheckBox *m_UseNativeMips; wxCheckBox *m_UseRealXFB; wxCheckBox *m_AutoScale; wxChoice *m_MaxAnisotropyCB; @@ -150,6 +151,7 @@ class GFXConfigDialogOGL : public wxDialog ID_CROP, ID_USEREALXFB, ID_USEXFB, + ID_USENATIVEMIPS, ID_AUTOSCALE, ID_WIDESCREENHACK, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index ea196cbd57..36db5a9feb 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -260,7 +260,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width TexMode0 &tm0 = bpmem.tex[texstage >> 2].texMode0[texstage & 3]; TexMode1 &tm1 = bpmem.tex[texstage >> 2].texMode1[texstage & 3]; - bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8); + bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8) && g_ActiveConfig.bUseNativeMips; int maxlevel = ((tm1.max_lod >> 4)); u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); @@ -395,13 +395,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); int TexLevels = (width > height)?width:height; - TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : 1; + TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2? 0 : 1); if(TexLevels > maxlevel && maxlevel > 0) TexLevels = maxlevel; + bool GenerateMipmaps = TexLevels > 1 || TexLevels == 0; + entry.bHaveMipMaps = GenerateMipmaps; int gl_format = 0; int gl_iformat = 0; - int gl_type = 0; - entry.bHaveMipMaps = UseNativeMips; + int gl_type = 0; if (dfmt != PC_TEX_FMT_DXT1) { switch (dfmt) @@ -447,9 +448,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width } if (expandedWidth != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth); - //generate mipmaps even if we use native mips to suport textures with less levels - bool GenerateMipmaps = isPow2 && UseNativeMips && (maxlevel > 0); - entry.bHaveMipMaps = GenerateMipmaps; + //generate mipmaps even if we use native mips to suport textures with less levels if(skip_texture_create) { glTexSubImage2D(target, 0,0,0,width, height, gl_format, gl_type, temp); @@ -458,7 +457,16 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width { if (GenerateMipmaps) { - gluBuild2DMipmaps(target, gl_iformat, width, height, gl_format, gl_type, temp); + if(UseNativeMips) + { + gluBuild2DMipmaps(target, gl_iformat, width, height, gl_format, gl_type, temp); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); + } } else { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index a6e7745e7c..3230d718a6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -126,9 +126,27 @@ int GetRemainingSize() return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer); } +int GetRemainingVertices(int primitive) +{ + switch (primitive) + { + case GX_DRAW_QUADS: + case GX_DRAW_TRIANGLES: + case GX_DRAW_TRIANGLE_STRIP: + case GX_DRAW_TRIANGLE_FAN: + return (max_Index_size - IndexGenerator::GetTriangleindexLen())/3; + case GX_DRAW_LINE_STRIP: + case GX_DRAW_LINES: + return (max_Index_size - IndexGenerator::GetLineindexLen())/2; + case GX_DRAW_POINTS: + return (max_Index_size - IndexGenerator::GetPointindexLen()); + default: return 0; + } +} + void AddVertices(int primitive, int numvertices) { - if (numvertices < 0) + if (numvertices <= 0) return; switch (primitive) { @@ -136,7 +154,7 @@ void AddVertices(int primitive, int numvertices) case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_FAN: - if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 2 * numvertices) + if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 3 * numvertices) Flush(); break; case GX_DRAW_LINE_STRIP: