fixed mipmap loading in both plugins.

add an option to limit fps instead of vps for games with bad synchronization
some minor fixes in d3d gui
enjoy :)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5394 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-04-22 02:51:07 +00:00
parent c15b1d3219
commit 8eb21d1bac
9 changed files with 73 additions and 49 deletions

View File

@ -148,6 +148,7 @@ void SConfig::SaveSettings()
ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer);
ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
ini.Set("Core", "FrameLimit", m_Framelimit); ini.Set("Core", "FrameLimit", m_Framelimit);
ini.Set("Core", "UseFPS", b_UseFPS);
// Plugins // Plugins
ini.Set("Core", "GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin); ini.Set("Core", "GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin);
@ -276,6 +277,7 @@ void SConfig::LoadSettings()
ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false);
ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0);
ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default
ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default
// Plugins // Plugins
ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str());

View File

@ -70,6 +70,7 @@ struct SConfig
INTERFACE_LANGUAGE m_InterfaceLanguage; INTERFACE_LANGUAGE m_InterfaceLanguage;
// framelimit choose // framelimit choose
int m_Framelimit; int m_Framelimit;
bool b_UseFPS;
// other interface settings // other interface settings
bool m_InterfaceToolbar; bool m_InterfaceToolbar;
bool m_InterfaceStatusbar; bool m_InterfaceStatusbar;

View File

@ -608,13 +608,13 @@ void ScreenShot()
void VideoThrottle() void VideoThrottle()
{ {
u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ? u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ?
SConfig::GetInstance().m_Framelimit * 10 : VideoInterface::TargetRefreshRate; SConfig::GetInstance().m_Framelimit * 5 : VideoInterface::TargetRefreshRate;
// When frame limit is NOT off // When frame limit is NOT off
if (SConfig::GetInstance().m_Framelimit) if (SConfig::GetInstance().m_Framelimit)
{ {
// Make the limiter a bit loose // Make the limiter a bit loose
u32 frametime = DrawnVideo * 1000 / ++TargetVPS; u32 frametime = ((SConfig::GetInstance().b_UseFPS)? Common::AtomicLoad(DrawnFrame) : DrawnVideo) * 1000 / ++TargetVPS;
while ((u32)Timer.GetTimeDifference() < frametime) while ((u32)Timer.GetTimeDifference() < frametime)
Common::YieldCPU(); Common::YieldCPU();
//Common::SleepCurrentThread(1); //Common::SleepCurrentThread(1);
@ -692,7 +692,7 @@ void VideoThrottle()
// depending on the framelimit set // depending on the framelimit set
bool report_slow(int skipped) bool report_slow(int skipped)
{ {
u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 10 u32 TargetFPS = (SConfig::GetInstance().m_Framelimit > 1) ? SConfig::GetInstance().m_Framelimit * 5
: VideoInterface::TargetRefreshRate; : VideoInterface::TargetRefreshRate;
u32 frames = Common::AtomicLoad(DrawnFrame); u32 frames = Common::AtomicLoad(DrawnFrame);
bool fps_slow = (Timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS) ? false : true; bool fps_slow = (Timer.GetTimeDifference() < (frames + skipped) * 1000 / TargetFPS) ? false : true;

View File

@ -52,6 +52,7 @@ EVT_BUTTON(wxID_CLOSE, CConfigMain::CloseClick)
EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_FRAMELIMIT_USEFPSFORLIMITING, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_DISPLAY_HIDECURSOR, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_DISPLAY_HIDECURSOR, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_DISPLAY_FULLSCREEN, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_DISPLAY_FULLSCREEN, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_DISPLAY_RENDERTOMAIN, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_DISPLAY_RENDERTOMAIN, CConfigMain::CoreSettingsChanged)
@ -185,7 +186,7 @@ void CConfigMain::InitializeGUILists()
// Framelimit // Framelimit
arrayStringFor_Framelimit.Add(wxT("Off")); arrayStringFor_Framelimit.Add(wxT("Off"));
arrayStringFor_Framelimit.Add(wxT("Auto")); arrayStringFor_Framelimit.Add(wxT("Auto"));
for (int i = 20; i <= 120; i += 10) // from 20 to 120 for (int i = 10; i <= 120; i += 5) // from 10 to 120
arrayStringFor_Framelimit.Add(wxString::Format(wxT("%i"), i)); arrayStringFor_Framelimit.Add(wxString::Format(wxT("%i"), i));
// Themes // Themes
@ -210,6 +211,7 @@ void CConfigMain::InitializeGUIValues()
SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle); SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle);
EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats); EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats);
Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit); Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit);
UseFPSForLimiting->SetValue(SConfig::GetInstance().b_UseFPS);
// General - Advanced // General - Advanced
AlwaysHLE_BS2->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLE_BS2); AlwaysHLE_BS2->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLE_BS2);
@ -334,6 +336,7 @@ void CConfigMain::CreateGUIControls()
// Framelimit // Framelimit
wxStaticText *FramelimitText = new wxStaticText(GeneralPage, ID_FRAMELIMIT_TEXT, wxT("Framelimit :"), wxDefaultPosition, wxDefaultSize); wxStaticText *FramelimitText = new wxStaticText(GeneralPage, ID_FRAMELIMIT_TEXT, wxT("Framelimit :"), wxDefaultPosition, wxDefaultSize);
Framelimit = new wxChoice(GeneralPage, ID_FRAMELIMIT, wxDefaultPosition, wxDefaultSize, arrayStringFor_Framelimit, 0, wxDefaultValidator); Framelimit = new wxChoice(GeneralPage, ID_FRAMELIMIT, wxDefaultPosition, wxDefaultSize, arrayStringFor_Framelimit, 0, wxDefaultValidator);
UseFPSForLimiting = new wxCheckBox(GeneralPage, ID_FRAMELIMIT_USEFPSFORLIMITING, wxT("Use FPS For Limiting"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Core Settings - Advanced // Core Settings - Advanced
wxStaticBoxSizer* sizerCoreType = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("CPU Emulator Engine")); wxStaticBoxSizer* sizerCoreType = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("CPU Emulator Engine"));
@ -347,6 +350,7 @@ void CConfigMain::CreateGUIControls()
// Interface settings // Interface settings
ConfirmStop = new wxCheckBox(GeneralPage, ID_INTERFACE_CONFIRMSTOP, wxT("Confirm On Stop"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); ConfirmStop = new wxCheckBox(GeneralPage, ID_INTERFACE_CONFIRMSTOP, wxT("Confirm On Stop"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
UsePanicHandlers = new wxCheckBox(GeneralPage, ID_INTERFACE_USEPANICHANDLERS, wxT("Use Panic Handlers"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); UsePanicHandlers = new wxCheckBox(GeneralPage, ID_INTERFACE_USEPANICHANDLERS, wxT("Use Panic Handlers"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Interface Language // Interface Language
// At the moment this only changes the language displayed in m_gamelistctrl // At the moment this only changes the language displayed in m_gamelistctrl
@ -373,6 +377,7 @@ void CConfigMain::CreateGUIControls()
wxBoxSizer *sFramelimit = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sFramelimit = new wxBoxSizer(wxHORIZONTAL);
sFramelimit->Add(FramelimitText, 0, wxALL | wxALIGN_CENTER, 1); sFramelimit->Add(FramelimitText, 0, wxALL | wxALIGN_CENTER, 1);
sFramelimit->Add(Framelimit, 0, wxALL | wxEXPAND, 5); sFramelimit->Add(Framelimit, 0, wxALL | wxEXPAND, 5);
sFramelimit->Add(UseFPSForLimiting, 0, wxALL | wxEXPAND, 5);
sbBasic->Add(sFramelimit, 0, wxALL | wxEXPAND, 5); sbBasic->Add(sFramelimit, 0, wxALL | wxEXPAND, 5);
sbAdvanced->Add(AlwaysHLE_BS2, 0, wxALL, 5); sbAdvanced->Add(AlwaysHLE_BS2, 0, wxALL, 5);
@ -702,6 +707,9 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
{ {
switch (event.GetId()) switch (event.GetId())
{ {
case ID_FRAMELIMIT_USEFPSFORLIMITING:
SConfig::GetInstance().b_UseFPS = UseFPSForLimiting->IsChecked();
break;
case ID_INTERFACE_CONFIRMSTOP: // Interface case ID_INTERFACE_CONFIRMSTOP: // Interface
SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop = ConfirmStop->IsChecked(); SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop = ConfirmStop->IsChecked();
break; break;

View File

@ -48,7 +48,7 @@ private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
wxBoxSizer* sGeneralPage; // General Settings wxBoxSizer* sGeneralPage; // General Settings
wxCheckBox* ConfirmStop, *UsePanicHandlers; wxCheckBox* ConfirmStop, *UsePanicHandlers, *UseFPSForLimiting;
wxCheckBox* HideCursor; wxCheckBox* HideCursor;
wxChoice* InterfaceLang; wxChoice* InterfaceLang;
wxChoice* Framelimit; wxChoice* Framelimit;
@ -171,14 +171,16 @@ private:
ID_ENABLECHEATS, ID_ENABLECHEATS,
ID_INTERFACE_CONFIRMSTOP, // Interface settings ID_INTERFACE_CONFIRMSTOP, // Interface settings
ID_INTERFACE_USEPANICHANDLERS, ID_INTERFACE_USEPANICHANDLERS,
ID_DISPLAY_FULLSCREEN, ID_DISPLAY_FULLSCREEN,
ID_DISPLAY_HIDECURSOR, ID_DISPLAY_HIDECURSOR,
ID_DISPLAY_RENDERTOMAIN, ID_DISPLAY_RENDERTOMAIN,
ID_HOTKEY_CONFIG, ID_HOTKEY_CONFIG,
ID_INTERFACE_LANG_TEXT, ID_INTERFACE_LANG, ID_INTERFACE_LANG_TEXT, ID_INTERFACE_LANG,
ID_INTERFACE_THEME, ID_INTERFACE_THEME,
ID_FRAMELIMIT_TEXT, ID_FRAMELIMIT, ID_FRAMELIMIT_TEXT,
ID_FRAMELIMIT,
ID_FRAMELIMIT_USEFPSFORLIMITING,
ID_GC_SRAM_LNG_TEXT, ID_GC_SRAM_LNG_TEXT,
ID_GC_SRAM_LNG, ID_GC_SRAM_LNG,

View File

@ -211,6 +211,13 @@ struct TabAdvanced : public W32Util::Tab
g_Config.bUseXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEXFB)) ? true : false; g_Config.bUseXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEXFB)) ? true : false;
} }
break; break;
case IDC_ENABLEREALXFB:
{
g_Config.bUseXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEREALXFB)) ? true : (Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEXFB)) ? true : false);
g_Config.bUseRealXFB = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEREALXFB)) ? true : false;
Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEREALXFB)) ? Button_Enable(GetDlgItem(hDlg,IDC_ENABLEXFB), false) : Button_Enable(GetDlgItem(hDlg,IDC_ENABLEXFB), true);
}
break;
case IDC_ENABLEEFBCOPY: case IDC_ENABLEEFBCOPY:
{ {
Button_GetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY)) ? Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), true) : Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), false); Button_GetCheck(GetDlgItem(hDlg,IDC_ENABLEEFBCOPY)) ? Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), true) : Button_Enable(GetDlgItem(hDlg,IDC_EFBTORAM), false);

View File

@ -219,7 +219,7 @@ static const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
D3DTEXF_NONE, D3DTEXF_NONE,
D3DTEXF_POINT, D3DTEXF_POINT,
D3DTEXF_LINEAR, D3DTEXF_LINEAR,
D3DTEXF_LINEAR, //reserved D3DTEXF_NONE, //reserved
}; };
static const D3DTEXTUREADDRESS d3dClamps[4] = static const D3DTEXTUREADDRESS d3dClamps[4] =
@ -1402,6 +1402,7 @@ void Renderer::SetSamplerState(int stage, int texindex)
min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mip = (tm0.min_filter == 8)?D3DTEXF_NONE:d3dMipFilters[tm0.min_filter & 3]; mip = (tm0.min_filter == 8)?D3DTEXF_NONE:d3dMipFilters[tm0.min_filter & 3];
if((tm0.min_filter & 3) && (tm0.min_filter != 8) && ((tm1.max_lod >> 4) == 0)) mip = D3DTEXF_NONE;
} }
if (texindex) if (texindex)
stage += 4; stage += 4;

View File

@ -278,12 +278,12 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
} }
entry.addr = address; entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format); entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
entry.isRenderTarget = false; entry.isRenderTarget = false;
bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
entry.isNonPow2 = false; entry.isNonPow2 = false;
int TexLevels = (width > height)?width:height; int TexLevels = (width > height)?width:height;
TexLevels = (isPow2 && UseNativeMips && tex_format != GX_TF_CMPR) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2?0:1); TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : ((isPow2 && g_ActiveConfig.bForceFiltering)? 0 : 1);
if(TexLevels > maxlevel && maxlevel > 0) if(TexLevels > maxlevel && maxlevel > 0)
TexLevels = maxlevel; TexLevels = maxlevel;
if (!skip_texture_create) if (!skip_texture_create)
@ -292,7 +292,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
} }
else else
{ {
D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b); D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b, 0);
} }
if(TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE) if(TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE)
{ {

View File

@ -127,11 +127,12 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST); (newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
if (bHaveMipMaps) { if (bHaveMipMaps)
int filt = newmode.min_filter; {
if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4) if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4)
newmode.min_filter += 4; // take equivalent forced linear mode.min_filter += 4; // take equivalent forced linear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt]); int filt = newmode.min_filter;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & (((newmode1.max_lod >> 4) > 0)?7:4)]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias/2.0f)); //glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias/2.0f));
@ -256,11 +257,11 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
if (address == 0) if (address == 0)
return NULL; return NULL;
TexMode0 &tm0 = bpmem.tex[texstage > 3].texMode0[texstage & 3]; TexMode0 &tm0 = bpmem.tex[texstage >> 2].texMode0[texstage & 3];
TexMode1 &tm1 = bpmem.tex[texstage > 3].texMode1[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);
int maxlevel = (tm1.max_lod >> 4); int maxlevel = ((tm1.max_lod >> 4));
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1;
@ -379,7 +380,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
} }
entry.addr = address; entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format); entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
entry.isRenderTarget = false; entry.isRenderTarget = false;
// For static textures, we use NPOT. // For static textures, we use NPOT.
@ -394,7 +395,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
int TexLevels = (width > height)?width:height; int TexLevels = (width > height)?width:height;
TexLevels = (isPow2 && UseNativeMips && tex_format != GX_TF_CMPR) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2?0:1); TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : 1;
if(TexLevels > maxlevel && maxlevel > 0) if(TexLevels > maxlevel && maxlevel > 0)
TexLevels = maxlevel; TexLevels = maxlevel;
int gl_format = 0; int gl_format = 0;
@ -403,9 +404,6 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
entry.bHaveMipMaps = UseNativeMips; entry.bHaveMipMaps = UseNativeMips;
if (dfmt != PC_TEX_FMT_DXT1) if (dfmt != PC_TEX_FMT_DXT1)
{ {
if (expandedWidth != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
switch (dfmt) switch (dfmt)
{ {
default: default:
@ -447,24 +445,25 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
gl_type = GL_UNSIGNED_SHORT_5_6_5; gl_type = GL_UNSIGNED_SHORT_5_6_5;
break; break;
} }
if (expandedWidth != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
//generate mipmaps even if we use native mips to suport textures with less levels //generate mipmaps even if we use native mips to suport textures with less levels
bool GenerateMipmaps = !entry.isRectangle && ((tm0.min_filter & 3) == 1 || (tm0.min_filter & 3) == 2); bool GenerateMipmaps = isPow2 && UseNativeMips && (maxlevel > 0);
if (GenerateMipmaps) entry.bHaveMipMaps = GenerateMipmaps;
{
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
}
if(skip_texture_create) if(skip_texture_create)
{ {
glTexSubImage2D(target, 0,0,0,width, height, gl_format, gl_type, temp); glTexSubImage2D(target, 0,0,0,width, height, gl_format, gl_type, temp);
} }
else else
{ {
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp); if (GenerateMipmaps)
} {
if (GenerateMipmaps) gluBuild2DMipmaps(target, gl_iformat, width, height, gl_format, gl_type, temp);
{ }
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); else
entry.bHaveMipMaps = true; {
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
}
} }
if (expandedWidth != width) // reset if (expandedWidth != width) // reset
@ -486,41 +485,45 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
if(TexLevels > 1 && dfmt != PC_TEX_FMT_NONE) if(TexLevels > 1 && dfmt != PC_TEX_FMT_NONE)
{ {
int level = 1; int level = 1;
int mipWidth = (width + 1) >> 1; int mipWidth = width >> 1;
int mipHeight = (height + 1) >> 1; int mipHeight = height >> 1;
ptr += entry.size_in_bytes; ptr += entry.size_in_bytes;
while((mipHeight || mipWidth)) while((mipHeight || mipWidth) && (level < TexLevels))
{ {
u32 currentWidth = (mipWidth > 0)? mipWidth : 1; u32 currentWidth = (mipWidth > 0)? mipWidth : 1;
u32 currentHeight = (mipHeight > 0)? mipHeight : 1; u32 currentHeight = (mipHeight > 0)? mipHeight : 1;
expandedWidth = (currentWidth + bsw) & (~bsw); expandedWidth = (currentWidth + bsw) & (~bsw);
expandedHeight = (currentHeight + bsh) & (~bsh); expandedHeight = (currentHeight + bsh) & (~bsh);
if(level < TexLevels) TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
{
TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
}
//ugly hack but it seems to work
//complete the level not defined in hardware with pixels of the top levels
//this is not a problem as the level are filtered by lod min and max value
if (dfmt != PC_TEX_FMT_DXT1) if (dfmt != PC_TEX_FMT_DXT1)
{ {
if (expandedWidth != (int)currentWidth) if (expandedWidth != (int)currentWidth)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth); glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
glTexImage2D(target, level, gl_iformat, currentWidth, currentHeight, 0, gl_format, gl_type, temp);
if (expandedWidth != (int)currentWidth) // reset glTexSubImage2D(target, level,0,0,currentWidth, currentHeight, gl_format, gl_type, temp);
if (expandedWidth != (int)currentWidth)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} }
else else
{ {
glCompressedTexImage2D(target, level, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, currentWidth, currentHeight, 0, expandedWidth*expandedHeight/2, temp); if(skip_texture_create)
{
glCompressedTexSubImage2D(target, level,0,0,currentWidth, currentHeight, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,expandedWidth*expandedHeight/2, temp);
}
else
{
glCompressedTexImage2D(target, level, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, currentWidth, currentHeight, 0, expandedWidth*expandedHeight/2, temp);
}
} }
GL_REPORT_ERRORD();
u32 size = (max(mipWidth, bsw) * max(mipHeight, bsh) * bsdepth) >> 1; u32 size = (max(mipWidth, bsw) * max(mipHeight, bsh) * bsdepth) >> 1;
ptr += size; ptr += size;
mipWidth >>= 1; mipWidth >>= 1;
mipHeight >>= 1; mipHeight >>= 1;
level++; level++;
} }
} }
entry.frameCount = frameCount; entry.frameCount = frameCount;
entry.w = width; entry.w = width;
entry.h = height; entry.h = height;