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:
parent
c15b1d3219
commit
8eb21d1bac
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"));
|
||||||
|
@ -348,6 +351,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
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
|
||||||
// If someone wants to control the whole GUI's language, it should be set here too
|
// If someone wants to control the whole GUI's language, it should be set here too
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -178,7 +178,9 @@ private:
|
||||||
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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
|
gluBuild2DMipmaps(target, gl_iformat, width, height, gl_format, gl_type, temp);
|
||||||
entry.bHaveMipMaps = true;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expandedWidth != width) // reset
|
if (expandedWidth != width) // reset
|
||||||
|
@ -486,34 +485,38 @@ 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
|
||||||
|
{
|
||||||
|
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);
|
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;
|
||||||
|
|
Loading…
Reference in New Issue