1.0 branch: Merge of GSdx changes.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/1.0.0@5249 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2012-05-31 10:49:04 +00:00
parent e31b0755d0
commit 309516bc2b
20 changed files with 1607 additions and 401 deletions

View File

@ -18,7 +18,7 @@ set(CommonFlags
-Wunused-variable
-std=c++0x
-fno-strict-aliasing
-DOGL_DEBUG # FIXME remove me when code is ready
#-DOGL_DEBUG # FIXME remove me when code is ready
# Unload of Geometry shader was fixed in Cat 12.3 (ie OpenGL version string: 4.2.11554)
#-DAMD_DRIVER_WORKAROUND
)
@ -201,7 +201,7 @@ if(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
foreach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/${glsl} DESTINATION ${PLUGIN_DIR})
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/${glsl} DESTINATION ${GLSL_SHADER_DIR})
endforeach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
else(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)

View File

@ -245,10 +245,10 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
#ifdef ENABLE_SDL_DEV
case 2: dev = new GSDeviceSDL(); break;
#endif
case 3: dev = new GSDeviceNull(); break;
#ifdef _LINUX
case 4: dev = new GSDeviceOGL(); break;
#endif
case 3: dev = new GSDeviceNull(); break;
}
if(dev == NULL)

View File

@ -17,11 +17,6 @@
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* Special Notes:
*
* Register definitions and most of the enums originate from sps2dev-0.4.0
* Copyright (C) 2002 Terratron Technologies Inc. All Rights Reserved.
*
*/
#pragma once
@ -45,10 +40,6 @@
#pragma pack(push, 1)
//
// sps2registers.h
//
enum GS_PRIM
{
GS_POINTLIST = 0,
@ -225,10 +216,6 @@ enum GS_AFAIL
AFAIL_RGB_ONLY = 3,
};
//
// sps2regstructs.h
//
#define REG32(name) \
union name \
{ \
@ -507,21 +494,6 @@ REG64_SET(GSReg)
GSRegSMODE2 SMODE2;
REG_SET_END
//
// sps2tags.h
//
#define SET_GIF_REG(gifTag, iRegNo, uiValue) \
{((GIFTag*)&gifTag)->u64[1] |= (((uiValue) & 0xf) << ((iRegNo) << 2));}
#ifdef _M_AMD64
#define GET_GIF_REG(tag, reg) \
(((tag).u64[1] >> ((reg) << 2)) & 0xf)
#else
#define GET_GIF_REG(tag, reg) \
(((tag).u32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf)
#endif
//
// GIFTag

View File

@ -94,6 +94,7 @@ CRC::Game CRC::m_games[] =
{0x0393B6BE, DBZBT2, EU, 0},
{0xE2F289ED, DBZBT2, JP, 0}, // Sparking Neo!
{0xE29C09A3, DBZBT2, KO, 0}, //DragonBall Z Sparking Neo
{0x0BAA4387, DBZBT2, JP, 0},
{0x35AA84D1, DBZBT2, NoRegion, 0},
{0x428113C2, DBZBT3, US, 0},
{0xA422BB13, DBZBT3, EU, 0},
@ -104,16 +105,20 @@ CRC::Game CRC::m_games[] =
{0x72B3802A, SFEX3, US, 0},
{0x71521863, SFEX3, US, 0},
{0x28703748, Bully, US, 0},
{0x019CFA48, Bully, JP, 0},
{0xC78A495D, BullyCC, US, 0},
{0xC19A374E, SoTC, US, 0},
{0x7D8F539A, SoTC, EU, 0},
{0x0F0C4A9C, SoTC, EU, 0},
{0x877F3436, SoTC, JP, 0},
{0xA17D6AAA, SoTC, KO, 0},
{0x877B3D35, SoTC, CH, 0},
{0x3122B508, OnePieceGrandAdventure, US, 0},
{0x8DF14A24, OnePieceGrandAdventure, EU, 0},
{0xE446C9F9, OnePieceGrandAdventure, KO, 0},
{0xCA2073B3, OnePieceGrandBattle, KO, 0},
{0x66953267, OnePieceGrandAdventure, JP, 0},
{0x947B933B, OnePieceGrandAdventure, US, 0},
{0xB049DD5E, OnePieceGrandBattle, US, 0},
{0x5D02CC5B, OnePieceGrandBattle, NoRegion, 0},
{0x6F8545DB, ICO, US, 0},
@ -121,12 +126,18 @@ CRC::Game CRC::m_games[] =
{0x2DF2C1EA, ICO, KO, 0},
{0x5C991F4E, ICO, NoRegion, 0},
{0x7ACF7E03, ICO, NoRegion, 0},
{0x788D8B4F, ICO, EU, 0},
{0x29C28734, ICO, CH, 0},
{0xAEAD1CA3, GT4, JP, 0},
{0x30E41D93, GT4, KO, 0},
{0x44A61C8F, GT4, EU, 0},
{0x0086E35B, GT4, EU, 0},
{0x77E61C8A, GT4, US, 0},
{0x33C6E35E, GT4, US, 0},
{0x7ABDBB5E, GT3, CH, 0}, //GT4中文D9版
{0x3E9D448A, GT3, CH, 0}, //GT4中文D5版
{0xAD66643C, GT3, CH, 0}, //GT4中文D9轉D5版
{0x6810C3BC, GT3, CH, 0}, //GRAN TURISMO Concept 2002 Tokyo-Geneva中文版
{0x85AE91B3, GT3, US, 0},
{0xC220951A, GT3, NoRegion, 0},
{0x60013EBD, GTConcept, EU, 0},
@ -145,7 +156,9 @@ CRC::Game CRC::m_games[] =
{0x5188ABCA, CrashBandicootWoC, US, 0},
{0x3A03D62F, CrashBandicootWoC, EU, 0},
{0x013E349D, ResidentEvil4, US, 0},
{0x6BA2F6B9, ResidentEvil4, NoRegion, 0},
// same CRC as EU {0x6BA2F6B9, ResidentEvil4, NoRegion, 0},
{0xDBB7A559, ResidentEvil4, US, 0},
{0x6BA2F6B9, ResidentEvil4, EU, 0},
{0x60FA8C69, ResidentEvil4, JP, 0},
{0x5F254B7C, ResidentEvil4, KO, 0},
{0x72E1E60E, Spartan, NoRegion, 0},
@ -155,6 +168,7 @@ CRC::Game CRC::m_games[] =
{0x1B9B7563, AceCombat4, NoRegion, 0},
{0xEC432B24, Drakengard2, EU, 0},
{0x1648E3C9, Drakengard2, US, 0},
{0xB7ADB13A, Drakengard2, CH, 0}, //復仇龍騎士2
{0xFC46EA61, Tekken5, JP, 0},
{0x1F88EE37, Tekken5, EU, 0},
{0x1F88BECD, Tekken5, EU, 0}, //language selector...
@ -171,7 +185,9 @@ CRC::Game CRC::m_games[] =
{0xA61A4C6D, GodOfWar, NoRegion, 0},
{0xE23D532B, GodOfWar, NoRegion, 0},
{0xDF1AF973, GodOfWar, NoRegion, 0},
{0xD6385328, GodOfWar, NoRegion, 0},
// same CRC as US {0xD6385328, GodOfWar, NoRegion, 0},
{0x1A85E924, GodOfWar, NoRegion, 0}, //天幻1+2不能同時使用
{0x608ACBD3, GodOfWar, CH, 0}, //完美漢化修改版
{0x2F123FD8, GodOfWar2, RU, 0},
{0x2F123FD8, GodOfWar2, US, 0},
{0x44A8A22A, GodOfWar2, EU, 0},
@ -180,17 +196,22 @@ CRC::Game CRC::m_games[] =
{0xF8CD3DF6, GodOfWar2, NoRegion, 0},
{0x0B82BFF7, GodOfWar2, NoRegion, 0},
{0x5990866F, GodOfWar2, NoRegion, 0},
{0xC4C4FD5F, GodOfWar2, CH, 0},
{0xDCD9A9F7, GodOfWar2, NoRegion, 0},
{0xFA0DF523, GodOfWar2, CH, 0}, //完美漢化修改版D5
{0x9FEE3466, GodOfWar2, CH, 0}, //完美漢化修改版D9
{0x5D482F18, JackieChanAdv, NoRegion, 0},
{0xF0A6D880, HarvestMoon, US, 0},
{0x75C01A04, NamcoXCapcom, US, 0},
{0xBF6F101F, GiTS, US, 0},
//Same CRC also reported as EU, and we have another US crc... {0xBF6F101F, GiTS, US, 0},
{0x95CC86EF, GiTS, US, 0},
{0xA5768F53, GiTS, JP, 0},
{0xA3643EB1, GiTS, KO, 0},
{0xBF6F101F, GiTS, EU, 0},
{0x6BF11378, Onimusha3, US, 0},
{0x71320CA8, Onimusha3, JP, 0},
{0xDAFFFB0D, Onimusha3, KO, 0},
// apparently on google most results for this crc is Onimusha4 (shinOnimusha) {0x812C5A96, Onimusha3, EU, 0},
{0xF442260C, MajokkoALaMode2, JP, 0},
{0x14FE77F7, TalesOfAbyss, US, 0},
{0x045D77E9, TalesOfAbyss, JPUNDUB, 0},
@ -207,6 +228,8 @@ CRC::Game CRC::m_games[] =
{0xFADEBC45, Genji, EU, 0},
{0xB4776FC1, Genji, JP, 0},
{0x56242EC9, Genji, KO, 0},
{0xCDAF243D, Genji, CH, 0},
{0x2A5E0B61, Genji, CH, 0},
{0x7D4EA48F, Genji, NoRegion, 0},
{0xE04EA200, StarOcean3, EU, 0},
{0x23A97857, StarOcean3, US, 0},
@ -272,6 +295,7 @@ CRC::Game CRC::m_games[] =
{0x9ABF90FB, LordOfTheRingsTwoTowers, ES, 0},
{0xC0E909E9, LordOfTheRingsTwoTowers, JP, 0},
{0x6898435D, LordOfTheRingsTwoTowers, KO, 0},
{0xDC2F9B98, LordOfTheRingsTwoTowers, CH, 0}, //魔戒二部曲
{0xEB198738, LordOfTheRingsThirdAge, US, 0},
{0x614F4CF4, LordOfTheRingsThirdAge, EU, 0},
{0x37CD4279, LordOfTheRingsThirdAge, KO, 0},
@ -293,14 +317,53 @@ CRC::Game CRC::m_games[] =
{0x3A446111, CastlevaniaCoD, US, 0},
{0xF321BC38, CastlevaniaCoD, EU, 0},
{0x950876FA, CastlevaniaCoD, KO, 0},
{0x237B84D3, CastlevaniaCoD, CH, 0},
{0x28270F7D, CastlevaniaLoI, US, 0},
{0x306CDADA, CastlevaniaLoI, EU, 0},
{0xA36CFF6C, CastlevaniaLoI, JP, 0},
{0x9A93FE5D, CastlevaniaLoI, KO, 0},
{0xA79B0491, NanoBreaker, JP, 0},
{0x7985D894, FinalFightStreetwise, US, 0},
{0xED4BF0D3, FinalFightStreetwise, US, 0}, //紅星
{0x73C560BA, FinalFightStreetwise, EU, 0},
{0xCBB87BF9, EvangelionJo, JP, 0}, //新世紀福音戰士:序
{0x278A91FD, CaptainTsubasa, JP, 0}, //足球小將翼
{0xC5B75C7C, Oneechanbara2Special, JP, 0}, //性感女劍士2特別編
{0xC0659AD1, NarutimateAccel, JP, 0}, //火影忍者疾風傳
{0xF3D9DFBE, NarutimateAccel, JP, 0},
{0x59739DDE, Naruto, JP, 0}, //木葉英雄3
{0xF7786EE4, EternalPoison, JP, 0}, //粉紅劇毒
{0x2BE55519, EternalPoison, US, 0},
{0xE01F57EC, LegoBatman, US, 0}, //樂高蝙蝠俠
{0xE01F57ED, LegoBatman, EU, 0},
{0xE0347841, XE3, JP, 0}, //異域傳說3
{0xA4E88698, XE3, CH, 0},
{0x2088950A, XE3, US, 0},
// DMC(1)? {0x79B8A95F, DevilMayCry3, US, 0},
{0x7F3D692D, DevilMayCry3, CH, 0},
{0x1A85E924, DevilMayCry3, CH, 0}, //惡魔獵人3三合一中文特別版
{0x0a8ef911, ArctheLad, US, 0}, //亞克傳承-精靈之黃昏
{0x2C5E7DEA, ArctheLad, CH, 0},
{0xE69E7F58, ArctheLad, US, 0}, //亞克傳承-黑暗之終結
{0xB1995E29, ShadowofRome, EU, 0}, //羅馬之影
{0x958DCA28, ShadowofRome, EU, 0},
{0x57818AF6, ShadowofRome, US, 0},
{0xF21EE6E0, CrashNburn, US, 0},
{0x694A998E, TombRaiderUnderworld, JP, 0}, //8代地城奪寶
{0x8E214549, TombRaiderUnderworld, EU, 0},
{0xB639EB17, TombRaiderAnniversary, US, 0},
{0xB05805B6, TombRaiderAnniversary, JP, 0}, //十週年紀念版 重返禁地
{0xA629A376, TombRaiderAnniversary, EU, 0},
{0xBC8B3F50, TombRaiderLegend, US, 0}, //7代傳奇
{0x05177ECE, TombRaiderLegend, EU, 0},
{0x08FFF00D, SSX3, JP, 0}, //極限滑雪3
{0xCE942B2A, SSX3, EU, 0},
{0x5C891FF1, Black, US, 0},
{0xCAA04879, Black, EU, 0},
{0xADDFF505, Black, EU, 0}, //?
{0xB3A9F9ED, Black, JP, 0},
{0x7838882F, VF4, JP, 0},
{0xEA131B57, VF4, US, 0},
{0x4F755D39, TyTasmanianTiger, US, 0},
{0xD59D3252, TyTasmanianTiger, EU, 0},
{0x5A1BB2A1, TyTasmanianTiger2, US, 0},
@ -352,17 +415,92 @@ CRC::Game CRC::m_games[] =
{0x9B89F425, NanoBreaker, EU, 0},
{0x519E816B, Kunoichi, US, 0}, //Nightshade
{0x3FB419FD, Kunoichi, JP, 0},
{0x086D198E, Kunoichi, CH, 0},
{0x3B470BBD, Kunoichi, EU, 0},
{0x6BA65DD8, Kunoichi, KO, 0},
{0XD3F182A3, Yakuza, EU, 0},
{0x6F9F99F8, Yakuza, EU, 0},
{0x388F687B, Yakuza, US, 0},
{0xB7B3800A, Yakuza, JP, 0},
{0xA60C2E65, Yakuza2, EU, 0},
{0x800E3E5A, Yakuza2, EU, 0},
{0x97E9C87E, Yakuza2, US, 0},
{0xC6B95C48, Yakuza2, JP, 0},
{0x9000252A, SkyGunner, JP, 0},
{0x93092623, SkyGunner, JP, 0},
{0xA9461CB2, SkyGunner, US, 0},
{0xB799A60C, SkyGunner, NoRegion, 0},
{0x6848699B, JamesBondEverythingOrNothing, US, 0},
{0x5FFFDE40, JamesBondEverythingOrNothing, EU, 0},
{0xF7FB054C, Siren, CH, 0}, //死魂曲
{0x47C2C34A, Siren, KO, 0},
{0xB083CCC2, Siren, EU, 0}, // Spanish
{0x90F4B057, ZettaiZetsumeiToshi2, CH, 0},
{0xC988ECBB, ZettaiZetsumeiToshi2, JP, 0},
{0x81CA29BE, VF4EVO, EU, 0},
{0xC9DEF513, VF4EVO, US, 0},
{0x7B402694, VF4EVO, KO, 0},
{0xAB01411F, VF4EVO, JP, 0},
{0xE11DFA28, Dororo, CH, 0},
{0x89954774, Dororo, US, 0},
{0xFDA2F2DF, Dororo, KO, 0},
{0xBD17248E, ShinOnimusha, JP, 0},
{0xBE17248E, ShinOnimusha, JP, 0},
{0xB817248E, ShinOnimusha, JP, 0},
{0x812C5A96, ShinOnimusha, EU, 0},
{0xFE44479E, ShinOnimusha, US, 0},
{0xFFDE85E9, ShinOnimusha, US, 0},
{0xE21404E2, GetaWay, US, 0},
{0xE78971DF, GetaWayBlackMonday, US, 0},
{0x1130BF23, SakuraTaisen, CH, 0}, //櫻花大戰熾熱之血
{0x4FAE8B83, SakuraTaisen, KO, 0},
{0xEF06DBD6, SakuraWarsSoLongMyLove, JP, 0}, //櫻花大戰5
{0xDD41054D, SakuraWarsSoLongMyLove, US, 0}, //櫻花大戰5
{0xC2E3A7A4, SakuraWarsSoLongMyLove, KO, 0},
{0x4A4B623A, FightingBeautyWulong, JP,0}, //格鬥美神武龍
{0x5AC7E79C, TouristTrophy, CH, 0}, //摩拖車浪漫旅
{0xFF9C0E93, TouristTrophy, US, 0},
{0xCA9AA903, TouristTrophy, EU, 0}, //crc hack not fully working on PAL, still needs brightness =0
{0xA1B3F232, GTASanAndreas, EU, 0}, //俠盜獵車手聖安地列斯
{0x399A49CA, GTASanAndreas, US, 0},
{0x60FE139C, GTASanAndreas, JP, 0},
{0x2615F542, FrontMission5, JP, 0},
{0xF60255AC, FrontMission5, JP, 0},
{0xCB783836, FrontMission5, JP, 0},
{0xAEDAEE99, GodHand, JP, 0},
{0x6FB69282, GodHand, US, 0},
{0x924C4AA6, GodHand, KO, 0},
{0x9637D496, KnightsOfTheTemple2, JP, 0}, //聖堂騎士團2
{0x4E811100, UltramanFightingEvolution, JP, 0}, //超能力霸王戰鬥進化重生
{0x0643F90C, RogueGalaxy, US, 0}, //俠盜銀河
{0xCDEE4B19, RogueGalaxy, JP, 0},
{0xCBB4B383, RogueGalaxy, EU, 0},
{0xF7F181C3, DeathByDegreesTekkenNinaWilliams, CH, 0}, //鐵拳妮娜
{0xF088FA5B, DeathByDegreesTekkenNinaWilliams, KO, 0},
{0x59683BB0, DeathByDegreesTekkenNinaWilliams, EU, 0},
{0x771C3B47, AlpineRacer3, JP, 0}, //阿爾卑斯山滑雪大賽3
{0x7367D841, AlpineRacer3, EU, 0},
{0x449E1F6B, HummerBadlands, US, 0},
{0xAEA1B3AD, SengokuBasara, JP, 0},
{0x5B659BED, Grandia3, JP, 0},
{0x5B657DAD, Grandia3, US, 0},
{0x830B6FB1, TalesofSymphonia, JP, 0},
{0x8409FD51, TalesofDestiny, JP, 0}, //導演剪輯版
{0xA90CD846, TalesofDestiny, JP, 0},
{0xC4D0FACC, SDGundamGGeneration, JP, 0}, //世紀戰役
{0xBBDE6926, SDGundamGGeneration, JP, 0}, //戰魂
{0x49D60A00, SDGundamGGeneration, JP, 0}, //NEO
{0x83AFB38A, SoulCalibur2, KO, 0},
{0xE1B01308, SoulCalibur2, US, 0},
{0xFB8554A0, SoulCalibur3, JP, 0},
{0x027C604C, SoulCalibur3, US, 0},
{0x24090A12, SoulCalibur3, EU, 0},
{0x37B99B14, SoulCalibur3, KO, 0},
{0xBC5480A3, SoulCalibur3, EU, 0},
{0xFC0F8A5B, Simple2000Vol114, JP, 0},
{0x0098F740, SeintoSeiya, NoRegion, 0}, //聖鬥士星矢-黃道十二宮
{0xBDD9BAAD, UrbanReign, US, 0}, //街頭爭霸
{0xAE4BEBD3, UrbanReign, EU, 0},
};
hash_map<uint32, CRC::Game*> CRC::m_map;
@ -392,13 +530,23 @@ CRC::Game CRC::Lookup(uint32 crc)
if (exclusions.length() != 0)
printf( "GSdx: CrcHacksExclusions: %s\n", exclusions.c_str() );
int crcDups = 0;
for(int i = 0; i < countof(m_games); i++)
{
if( !IsCrcExcluded( exclusions, m_games[i].crc ) )
m_map[m_games[i].crc] = &m_games[i];
if( !IsCrcExcluded( exclusions, m_games[i].crc ) ){
if(m_map[m_games[i].crc]){
printf("[FIXME] GSdx: Duplicate CRC: 0x%x: (game-id/region-id) %d/%d overrides %d/%d\n"
, m_games[i].crc, m_games[i].title, m_games[i].region, m_map[m_games[i].crc]->title, m_map[m_games[i].crc]->region);
crcDups++;
}
m_map[m_games[i].crc] = &m_games[i];
}
//else
// printf( "GSdx: excluding CRC hack for 0x%08x\n", m_games[i].crc );
}
if(crcDups)
printf("[FIXME] GSdx: Duplicate CRC: Overall: %d\n", crcDups);
}
#ifndef DISABLE_CRC_HACKS
hash_map<uint32, Game*>::iterator i = m_map.find(crc);

View File

@ -83,11 +83,21 @@ public:
SMTDDS1,
SMTDDS2,
RozenMaidenGebetGarden,
EvangelionJo,
SuikodenTactics,
CaptainTsubasa,
Oneechanbara2Special,
NarutimateAccel,
Naruto,
EternalPoison,
LegoBatman,
XE3,
TenchuWoH,
TenchuFS,
Sly3,
Sly2,
ShadowofRome,
ArctheLad,
DemonStone,
BigMuthaTruckers,
TimeSplitters2,
@ -102,7 +112,14 @@ public:
BleachBladeBattlers,
CastlevaniaCoD,
CastlevaniaLoI,
FinalFightStreetwise,
CrashNburn,
TombRaiderUnderworld,
TombRaiderAnniversary,
TombRaiderLegend,
SSX3,
Black,
VF4,
TyTasmanianTiger,
TyTasmanianTiger2,
FFVIIDoC,
@ -127,6 +144,36 @@ public:
Yakuza2,
SkyGunner,
JamesBondEverythingOrNothing,
Siren,
ZettaiZetsumeiToshi2,
VF4EVO,
Dororo,
ShinOnimusha,
GetaWay,
GetaWayBlackMonday,
SakuraTaisen,
SakuraWarsSoLongMyLove,
FightingBeautyWulong,
TouristTrophy,
GTASanAndreas,
FrontMission5,
GodHand,
KnightsOfTheTemple2,
UltramanFightingEvolution,
RogueGalaxy,
DeathByDegreesTekkenNinaWilliams,
AlpineRacer3,
HummerBadlands,
SengokuBasara,
Grandia3,
TalesofSymphonia,
TalesofDestiny,
SDGundamGGeneration,
SoulCalibur2,
SoulCalibur3,
Simple2000Vol114,
SeintoSeiya,
UrbanReign,
TitleCount,
};
@ -142,6 +189,7 @@ public:
DE,
IT,
ES,
CH,
ASIA,
KO,
RegionCount,

View File

@ -29,9 +29,6 @@
//#define PRINT_FRAME_NUMBER
//#define ONLY_LINES
// It seems dual blending does not work on AMD !!!
//#define DISABLE_DUAL_BLEND
static uint32 g_draw_count = 0;
static uint32 g_frame_count = 1;
@ -42,6 +39,7 @@ GSDeviceOGL::GSDeviceOGL()
, m_pipeline(0)
, m_fbo(0)
, m_fbo_read(0)
, m_enable_shader_AMD_hack(false)
, m_vb_sr(NULL)
, m_srv_changed(false)
, m_ss_changed(false)
@ -55,8 +53,10 @@ GSDeviceOGL::GSDeviceOGL()
memset(&m_state, 0, sizeof(m_state));
// Reset the debug file
#ifdef OGL_DEBUG
FILE* f = fopen("Debug.txt","w");
fclose(f);
#endif
}
GSDeviceOGL::~GSDeviceOGL()
@ -168,6 +168,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
const GLubyte* s;
s = glGetString(GL_VERSION);
if (s == NULL) return false;
fprintf(stderr, "Supported Opengl version: %s\n", s);
GLuint dot = 0;
while (s[dot] != '\0' && s[dot] != '.') dot++;
@ -225,7 +226,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs);
CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs);
for(int i = 0; i < countof(m_convert.ps); i++)
for(uint i = 0; i < countof(m_convert.ps); i++)
CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i]);
// Note the following object are initialized to 0 so disabled.
@ -253,7 +254,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameteri(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX);
glSamplerParameterf(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@ -269,7 +270,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameteri(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX);
glSamplerParameterf(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@ -285,7 +286,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
m_merge_obj.cb = new GSUniformBufferOGL(1, sizeof(MergeConstantBuffer));
for(int i = 0; i < countof(m_merge_obj.ps); i++)
for(uint i = 0; i < countof(m_merge_obj.ps); i++)
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i]);
m_merge_obj.bs = new GSBlendStateOGL();
@ -297,7 +298,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
m_interlace.cb = new GSUniformBufferOGL(2, sizeof(InterlaceConstantBuffer));
for(int i = 0; i < countof(m_interlace.ps); i++)
for(uint i = 0; i < countof(m_interlace.ps); i++)
CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i]);
// ****************************************************************
// Shade boost
@ -378,6 +379,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
// HW renderer shader
// ****************************************************************
m_enable_shader_AMD_hack = true; // ....
CreateTextureFX();
// ****************************************************************
@ -500,7 +502,9 @@ bool GSDeviceOGL::Reset(int w, int h)
void GSDeviceOGL::Flip()
{
// FIXME: disable it when code is working
#ifdef OGL_DEBUG
CheckDebugLog();
#endif
m_wnd->Flip();
@ -1166,8 +1170,6 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer)
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
{
uint ref = sref;
if(m_state.dss != dss) {
m_state.dss = dss;
m_state.sref = sref;
@ -1236,6 +1238,40 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
}
}
// AMD drivers fail to support correctly the setting of index in fragment shader (layout statement in glsl)...
// So instead to use directly glCreateShaderProgramv, you need to emulate the function and manually set
// the index in the fragment shader.
GLuint GSDeviceOGL::glCreateShaderProgramv_AMD_BUG_WORKAROUND(GLenum type, GLsizei count, const char ** strings)
{
const GLuint shader = glCreateShader(type);
if (shader) {
glShaderSource(shader, count, strings, NULL);
glCompileShader(shader);
const GLuint program = glCreateProgram();
if (program) {
GLint compiled = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
if (compiled) {
glAttachShader(program, shader);
// HACK TO SET CORRECTLY THE INDEX
if (type == GL_FRAGMENT_SHADER && m_enable_shader_AMD_hack) {
glBindFragDataLocationIndexed(program, 0, 0, "SV_Target0");
glBindFragDataLocationIndexed(program, 0, 1, "SV_Target1");
}
// END OF HACK
glLinkProgram(program);
glDetachShader(program, shader);
}
/* append-shader-info-log-to-program-info-log */
}
glDeleteShader(shader);
return program;
} else {
return 0;
}
}
void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const std::string& macro_sel)
{
// *****************************************************
@ -1264,9 +1300,6 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
std::string entry_main = format("#define %s main\n", entry.c_str());
std::string header = version + shader_type + entry_main + macro_sel;
#ifdef DISABLE_DUAL_BLEND
header += "#define DISABLE_DUAL_BLEND 1\n";
#endif
// *****************************************************
// Read the source file
@ -1275,10 +1308,10 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
std::string line;
// Each linux distributions have his rules for path so we give them the possibility to
// change it with compilation flags. -- Gregory
#ifdef PLUGIN_DIR_COMPILATION
#define xPLUGIN_DIR_str(s) PLUGIN_DIR_str(s)
#define PLUGIN_DIR_str(s) #s
const std::string shader_file = string(xPLUGIN_DIR_str(PLUGIN_DIR_COMPILATION)) + '/' + glsl_file;
#ifdef GLSL_SHADER_DIR_COMPILATION
#define xGLSL_SHADER_DIR_str(s) GLSL_SHADER_DIR_str(s)
#define GLSL_SHADER_DIR_str(s) #s
const std::string shader_file = string(xGLSL_SHADER_DIR_str(GLSL_SHADER_DIR_COMPILATION)) + '/' + glsl_file;
#else
const std::string shader_file = string("plugins/") + glsl_file;
#endif
@ -1309,7 +1342,22 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
header.copy(header_str, header.size(), 0);
header_str[header.size()] = '\0';
*program = glCreateShaderProgramv(type, 2, sources_array);
// ... See below to test that index is correctly set by driver
//*program = glCreateShaderProgramv(type, 2, sources_array);
*program = glCreateShaderProgramv_AMD_BUG_WORKAROUND(type, 2, sources_array);
// DEBUG AMD failure...
// GLint index = -1;
// index = glGetFragDataIndex(*program, "SV_Target0");
// fprintf(stderr, "Frag0 index %d\n", index);
// assert(index == 0);
// index = glGetFragDataIndex(*program, "SV_Target1");
// fprintf(stderr, "Frag1 index %d\n", index);
// assert(index == 1);
// END DEBUG AMD
free(source_str);
free(header_str);
free(sources_array);
@ -1430,13 +1478,8 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
#define D3DBLEND_BLENDFACTOR GL_CONSTANT_COLOR
#define D3DBLEND_INVBLENDFACTOR GL_ONE_MINUS_CONSTANT_COLOR
#ifdef DISABLE_DUAL_BLEND
#define D3DBLEND_SRCALPHA GL_SRC_ALPHA
#define D3DBLEND_INVSRCALPHA GL_ONE_MINUS_SRC_ALPHA
#else
#define D3DBLEND_SRCALPHA GL_SRC1_ALPHA
#define D3DBLEND_INVSRCALPHA GL_ONE_MINUS_SRC1_ALPHA
#endif
#define D3DBLEND_SRCALPHA GL_SRC1_ALPHA
#define D3DBLEND_INVSRCALPHA GL_ONE_MINUS_SRC1_ALPHA
const GSDeviceOGL::D3D9Blend GSDeviceOGL::m_blendMapD3D9[3*3*3*3] =
{

View File

@ -25,6 +25,8 @@
#include "GSDevice.h"
#include "GSTextureOGL.h"
#include "GSdx.h"
#include "GSVertexArrayOGL.h"
#include "GSUniformBufferOGL.h"
class GSBlendStateOGL {
// Note: You can also select the index of the draw buffer for which to set the blend setting
@ -228,281 +230,6 @@ public:
}
};
class GSUniformBufferOGL {
GLuint buffer; // data object
GLuint index; // GLSL slot
uint size; // size of the data
const GLenum target;
public:
GSUniformBufferOGL(GLuint index, uint size) : index(index)
, size(size)
,target(GL_UNIFORM_BUFFER)
{
glGenBuffers(1, &buffer);
bind();
allocate();
attach();
}
void bind()
{
glBindBuffer(target, buffer);
}
void allocate()
{
glBufferData(target, size, NULL, GL_STREAM_DRAW);
}
void attach()
{
glBindBufferBase(target, index, buffer);
}
void upload(const void* src)
{
uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags);
memcpy(dst, src, size);
glUnmapBuffer(target);
}
~GSUniformBufferOGL() {
glDeleteBuffers(1, &buffer);
}
};
struct GSInputLayoutOGL {
GLuint index;
GLint size;
GLenum type;
GLboolean normalize;
GLsizei stride;
const GLvoid* offset;
};
class GSVertexBufferStateOGL {
class GSBufferOGL {
size_t m_stride;
size_t m_start;
size_t m_count;
size_t m_limit;
GLenum m_target;
GLuint m_buffer;
size_t m_default_size;
public:
GSBufferOGL(GLenum target, size_t stride) :
m_stride(stride)
, m_start(0)
, m_count(0)
, m_limit(0)
, m_target(target)
{
glGenBuffers(1, &m_buffer);
// Opengl works best with 1-4MB buffer.
m_default_size = 2 * 1024 * 1024 / m_stride;
}
~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); }
void allocate() { allocate(m_default_size); }
void allocate(size_t new_limit)
{
m_start = 0;
m_limit = new_limit;
glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW);
}
void bind()
{
glBindBuffer(m_target, m_buffer);
}
void upload(const void* src, uint32 count)
{
// Upload the data to the buffer
void* dst;
if (Map(&dst, count)) {
// FIXME which one to use
// GSVector4i::storent(dst, src, m_count * m_stride);
memcpy(dst, src, m_stride*m_count);
Unmap();
}
}
bool Map(void** pointer, uint32 count ) {
#ifdef OGL_DEBUG
GLint b_size = -1;
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
if (b_size <= 0) return false;
#endif
m_count = count;
// Note: For an explanation of the map flag
// see http://www.opengl.org/wiki/Buffer_Object_Streaming
uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
// Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) {
allocate(std::max<int>(m_count * 3 / 2, m_default_size));
} else if (m_count > (m_limit - m_start) ) {
// Not enough left free room. Just go back at the beginning
m_start = 0;
// Tell the driver that it can orphan previous buffer and restart from a scratch buffer.
// Technically the buffer will not be accessible by the application anymore but the
// GL will effectively remove it when draws call are finised.
map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT;
} else {
// Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map
map_flags |= GL_MAP_INVALIDATE_RANGE_BIT;
}
// Upload the data to the buffer
*pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
//fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count);
#ifdef OGL_DEBUG
if (*pointer == NULL) {
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
return false;
}
#endif
return true;
}
void Unmap() { glUnmapBuffer(m_target); }
void EndScene()
{
m_start += m_count;
m_count = 0;
}
void Draw(GLenum mode)
{
glDrawArrays(mode, m_start, m_count);
}
void Draw(GLenum mode, GLint basevertex)
{
glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex);
}
void Draw(GLenum mode, GLint basevertex, int offset, int count)
{
glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex);
}
size_t GetStart() { return m_start; }
void debug()
{
fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count);
}
} *m_vb, *m_ib;
GLuint m_va;
GLenum m_topology;
public:
GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr)
{
glGenVertexArrays(1, &m_va);
m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride);
m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32));
bind();
// Note: index array are part of the VA state so it need to be bind only once.
m_ib->bind();
m_vb->allocate();
m_ib->allocate();
set_internal_format(layout, layout_nbr);
}
void bind()
{
glBindVertexArray(m_va);
m_vb->bind();
}
void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr)
{
for (int i = 0; i < layout_nbr; i++) {
// Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer
glEnableVertexAttribArray(layout[i].index);
switch (layout[i].type) {
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
// Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I)
glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
break;
default:
glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
break;
}
}
}
void EndScene()
{
m_vb->EndScene();
m_ib->EndScene();
}
void DrawPrimitive() { m_vb->Draw(m_topology); }
void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); }
void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); }
void SetTopology(GLenum topology) { m_topology = topology; }
void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); }
void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); }
bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); }
void UnmapVB() { m_vb->Unmap(); }
~GSVertexBufferStateOGL()
{
glDeleteVertexArrays(1, &m_va);
}
void debug()
{
string topo;
switch (m_topology) {
case GL_POINTS:
topo = "point";
break;
case GL_LINES:
topo = "line";
break;
case GL_TRIANGLES:
topo = "triangle";
break;
case GL_TRIANGLE_STRIP:
topo = "triangle strip";
break;
}
m_vb->debug();
m_ib->debug();
fprintf(stderr, "primitives of %s\n", topo.c_str());
}
};
class GSDeviceOGL : public GSDevice
{
public:
@ -754,6 +481,8 @@ class GSDeviceOGL : public GSDevice
GSVertexBufferStateOGL* m_vb; // vb_state for HW renderer
GSVertexBufferStateOGL* m_vb_sr; // vb_state for StretchRect
bool m_enable_shader_AMD_hack;
struct {
GLuint ps[2]; // program object
GSUniformBufferOGL* cb; // uniform buffer object
@ -919,4 +648,6 @@ class GSDeviceOGL : public GSDevice
void SetupGS(GSSelector sel);
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
GLuint glCreateShaderProgramv_AMD_BUG_WORKAROUND(GLenum type, GLsizei count, const char ** strings);
};

View File

@ -67,11 +67,15 @@ GtkWidget* CreateRenderComboBox()
switch (i) {
// better use opengl instead of SDL
case 6:
case 7:
#ifdef ENABLE_SDL_DEV
label += " (deprecated)";
#else
label += " (removed)";
#endif
break;
// (dev only) for any NULL stuff
case 7:
case 8:
case 9:
label += " (debug only)";
@ -90,12 +94,17 @@ GtkWidget* CreateRenderComboBox()
switch (theApp.GetConfig("renderer", 0)) {
// Note the value are based on m_gs_renderers vector on GSdx.cpp
#ifdef ENABLE_SDL_DEV
case 7 : renderer_box_position = 0; break;
case 8 : renderer_box_position = 1; break;
#endif
case 10: renderer_box_position = 2; break;
case 11: renderer_box_position = 3; break;
case 12: renderer_box_position = 4; break;
case 13: renderer_box_position = 5; break;
// Fallback to openGL SW
default: renderer_box_position = 5; break;
}
gtk_combo_box_set_active(GTK_COMBO_BOX(render_combo_box), renderer_box_position);
return render_combo_box;
@ -157,7 +166,7 @@ void toggle_widget_states( GtkWidget *widget, gpointer callback_data )
bool hardware_render = false, software_render = false, sdl_render = false, null_render = false;
render_type = gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box));
hardware_render = (render_type == 1 || render_type == 4 || render_type == 7 || render_type == 13);
hardware_render = ((render_type % 3) == 1);
if (hardware_render)
{
@ -432,16 +441,19 @@ bool RunLinuxDialog()
// Get all the settings from the dialog box.
if (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box)) != -1) {
// FIXME test current opengl version supported through glxinfo (OpenGL version string:)
// Warn the user if 4.2 is not supported and switch back to basic SDL renderer
// Note the value are based on m_gs_renderers vector on GSdx.cpp
switch (gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box))) {
// Note the value are based on m_gs_renderers vector on GSdx.cpp
#ifdef ENABLE_SDL_DEV
case 0: theApp.SetConfig("renderer", 7); break;
case 1: theApp.SetConfig("renderer", 8); break;
#endif
case 2: theApp.SetConfig("renderer", 10); break;
case 3: theApp.SetConfig("renderer", 11); break;
case 4: theApp.SetConfig("renderer", 12); break;
case 5: theApp.SetConfig("renderer", 13); break;
// Fallback to SW opengl
default: theApp.SetConfig("renderer", 13); break;
}
}

View File

@ -422,6 +422,7 @@ void GSHacksDlg::OnInit()
CheckDlgButton(m_hWnd, IDC_OFFSETHACK, theApp.GetConfig("UserHacks_HalfPixelOffset", 0));
CheckDlgButton(m_hWnd, IDC_SPRITEHACK, theApp.GetConfig("UserHacks_SpriteHack", 0));
CheckDlgButton(m_hWnd, IDC_WILDHACK, theApp.GetConfig("UserHacks_WildHack", 0));
CheckDlgButton(m_hWnd, IDC_AGGRESSIVECRC, theApp.GetConfig("UserHacks_AggressiveCRC", 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_SETRANGE, 0, MAKELPARAM(1000, 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("UserHacks_SkipDraw", 0), 0));
@ -483,6 +484,11 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
helpstr = "Multisample Anti-Aliasing\n\nEnables hardware Anti-Aliasing. Needs lots of memory."
" The Z-24 modes might need to have LogarithmicZ to compensate for the bits lost (only in DX9 mode).";
break;
case IDC_AGGRESSIVECRC:
helpstr = "Use more aggressive CRC hacks on some games\n\n"
"Only affects few games, removing some effects which might make the image sharper/clearer.\n"
"Affected games: FFX, FFX2, GOW2, SoTC, SSX3.";
break;
default:
helpstr = "Hover over an item to get a description.";
break;
@ -506,6 +512,7 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
theApp.SetConfig("UserHacks_SpriteHack", (int)IsDlgButtonChecked(m_hWnd, IDC_SPRITEHACK));
theApp.SetConfig("UserHacks_SkipDraw", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_GETPOS, 0, 0));
theApp.SetConfig("UserHacks_WildHack", (int)IsDlgButtonChecked(m_hWnd, IDC_WILDHACK));
theApp.SetConfig("UserHacks_AggressiveCRC", (int)IsDlgButtonChecked(m_hWnd, IDC_AGGRESSIVECRC));
EndDialog(m_hWnd, id);
} break;
}

File diff suppressed because it is too large Load Diff

View File

@ -138,6 +138,7 @@ class GSState : public GSAlignedClass<32>
protected:
bool IsBadFrame(int& skip, int UserHacks_SkipDraw);
int userHacks_AggressiveCRC;
GSVertex m_v;
float m_q;

View File

@ -38,7 +38,7 @@ void GSDeviceOGL::CreateTextureFX()
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@ -225,7 +225,7 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2011-2011 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
class GSUniformBufferOGL {
GLuint buffer; // data object
GLuint index; // GLSL slot
uint size; // size of the data
const GLenum target;
public:
GSUniformBufferOGL(GLuint index, uint size) : index(index)
, size(size)
,target(GL_UNIFORM_BUFFER)
{
glGenBuffers(1, &buffer);
bind();
allocate();
attach();
}
void bind()
{
glBindBuffer(target, buffer);
}
void allocate()
{
glBufferData(target, size, NULL, GL_STREAM_DRAW);
}
void attach()
{
glBindBufferBase(target, index, buffer);
}
void upload(const void* src)
{
uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags);
memcpy(dst, src, size);
glUnmapBuffer(target);
}
~GSUniformBufferOGL() {
glDeleteBuffers(1, &buffer);
}
};

View File

@ -0,0 +1,257 @@
/*
* Copyright (C) 2011-2011 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
struct GSInputLayoutOGL {
GLuint index;
GLint size;
GLenum type;
GLboolean normalize;
GLsizei stride;
const GLvoid* offset;
};
class GSBufferOGL {
size_t m_stride;
size_t m_start;
size_t m_count;
size_t m_limit;
GLenum m_target;
GLuint m_buffer;
size_t m_default_size;
public:
GSBufferOGL(GLenum target, size_t stride) :
m_stride(stride)
, m_start(0)
, m_count(0)
, m_limit(0)
, m_target(target)
{
glGenBuffers(1, &m_buffer);
// Opengl works best with 1-4MB buffer.
m_default_size = 2 * 1024 * 1024 / m_stride;
}
~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); }
void allocate() { allocate(m_default_size); }
void allocate(size_t new_limit)
{
m_start = 0;
m_limit = new_limit;
glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW);
}
void bind()
{
glBindBuffer(m_target, m_buffer);
}
void upload(const void* src, uint32 count)
{
// Upload the data to the buffer
void* dst;
if (Map(&dst, count)) {
// FIXME which one to use
// GSVector4i::storent(dst, src, m_count * m_stride);
memcpy(dst, src, m_stride*m_count);
Unmap();
}
}
bool Map(void** pointer, uint32 count ) {
#ifdef OGL_DEBUG
GLint b_size = -1;
glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size);
if (b_size <= 0) return false;
#endif
m_count = count;
// Note: For an explanation of the map flag
// see http://www.opengl.org/wiki/Buffer_Object_Streaming
uint32 map_flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
// Current GPU buffer is really too small need to allocate a new one
if (m_count > m_limit) {
allocate(std::max<int>(m_count * 3 / 2, m_default_size));
} else if (m_count > (m_limit - m_start) ) {
// Not enough left free room. Just go back at the beginning
m_start = 0;
// Tell the driver that it can orphan previous buffer and restart from a scratch buffer.
// Technically the buffer will not be accessible by the application anymore but the
// GL will effectively remove it when draws call are finised.
map_flags |= GL_MAP_INVALIDATE_BUFFER_BIT;
} else {
// Tell the driver that it doesn't need to contain any valid buffer data, and that you promise to write the entire range you map
map_flags |= GL_MAP_INVALIDATE_RANGE_BIT;
}
// Upload the data to the buffer
*pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags);
//fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count);
#ifdef OGL_DEBUG
if (*pointer == NULL) {
fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n");
return false;
}
#endif
return true;
}
void Unmap() { glUnmapBuffer(m_target); }
void EndScene()
{
m_start += m_count;
m_count = 0;
}
void Draw(GLenum mode)
{
glDrawArrays(mode, m_start, m_count);
}
void Draw(GLenum mode, GLint basevertex)
{
glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex);
}
void Draw(GLenum mode, GLint basevertex, int offset, int count)
{
glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex);
}
size_t GetStart() { return m_start; }
void debug()
{
fprintf(stderr, "data buffer: start %d, count %d\n", m_start, m_count);
}
};
class GSVertexBufferStateOGL {
GSBufferOGL *m_vb;
GSBufferOGL *m_ib;
GLuint m_va;
GLenum m_topology;
public:
GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr)
{
glGenVertexArrays(1, &m_va);
m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride);
m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32));
bind();
// Note: index array are part of the VA state so it need to be bind only once.
m_ib->bind();
m_vb->allocate();
m_ib->allocate();
set_internal_format(layout, layout_nbr);
}
void bind()
{
glBindVertexArray(m_va);
m_vb->bind();
}
void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr)
{
for (uint i = 0; i < layout_nbr; i++) {
// Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer
glEnableVertexAttribArray(layout[i].index);
switch (layout[i].type) {
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
// Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I)
glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset);
break;
default:
glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset);
break;
}
}
}
void EndScene()
{
m_vb->EndScene();
m_ib->EndScene();
}
void DrawPrimitive() { m_vb->Draw(m_topology); }
void DrawIndexedPrimitive() { m_ib->Draw(m_topology, m_vb->GetStart() ); }
void DrawIndexedPrimitive(int offset, int count) { m_ib->Draw(m_topology, m_vb->GetStart(), offset, count ); }
void SetTopology(GLenum topology) { m_topology = topology; }
void UploadVB(const void* vertices, size_t count) { m_vb->upload(vertices, count); }
void UploadIB(const void* index, size_t count) { m_ib->upload(index, count); }
bool MapVB(void **pointer, size_t count) { return m_vb->Map(pointer, count); }
void UnmapVB() { m_vb->Unmap(); }
~GSVertexBufferStateOGL()
{
glDeleteVertexArrays(1, &m_va);
delete m_vb;
delete m_ib;
}
void debug()
{
string topo;
switch (m_topology) {
case GL_POINTS:
topo = "point";
break;
case GL_LINES:
topo = "line";
break;
case GL_TRIANGLES:
topo = "triangle";
break;
case GL_TRIANGLE_STRIP:
topo = "triangle strip";
break;
}
m_vb->debug();
m_ib->debug();
fprintf(stderr, "primitives of %s\n", topo.c_str());
}
};

View File

@ -93,6 +93,7 @@ BEGIN
COMBOBOX IDC_MSAACB,35,18,44,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "WildArmsOffset",IDC_WILDHACK,"Button",BS_AUTO3STATE | WS_TABSTOP,14,105,64,10
LTEXT "TEXT_GOES_HERE",IDC_HACK_DESCRIPTION,92,20,209,145
CONTROL "Aggressive-CRC",IDC_AGGRESSIVECRC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,122,66,10
END
IDD_SHADEBOOST DIALOGEX 0, 0, 316, 129

View File

@ -26,6 +26,7 @@
#define ENABLE_JIT_RASTERIZER
//#define ENABLE_DYNAMIC_CRC_HACK
#define DYNA_DLL_PATH "c:/dev/pcsx2/trunk/tools/dynacrchack/DynaCrcHack.dll"
#define ENABLE_UPSCALE_HACKS // Hacks intended to fix upscaling / rendering glitches in HW renderers

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 20011-2012 Hainaut gregory
* Copyright (C) 2011-2012 Hainaut gregory
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -109,7 +109,7 @@ void ps_main1()
c.a *= 256.0f / 127.0f; // hm, 0.5 won't give us 1.0 if we just multiply with 2
highp uvec4 i = uvec4(c * vec4(0x001f, 0x03e0, 0x7c00, 0x8000));
highp uvec4 i = uvec4(c * vec4(uint(0x001f), uint(0x03e0), uint(0x7c00), uint(0x8000)));
SV_Target1 = (i.x & uint(0x001f)) | (i.y & uint(0x03e0)) | (i.z & uint(0x7c00)) | (i.w & uint(0x8000));
}

View File

@ -86,6 +86,10 @@ void vs_main()
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
// Greg TEST
//float logz = log2(1+float(z))/32 * 0.999f;
//vec4 p = vec4(i_p, logz, 0) - vec4(0.05f, 0.05f, 0, 0);
vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0);
vec4 final_p = p * VertexScale - VertexOffset;
@ -261,12 +265,8 @@ void gs_main()
layout(location = 0) in vertex PSin;
// Same buffer but 2 colors for dual source blending
#ifndef DISABLE_DUAL_BLEND
layout(location = 0, index = 1) out vec4 SV_Target0;
layout(location = 0, index = 0) out vec4 SV_Target1;
#else
layout(location = 0) out vec4 SV_Target1;
#endif
layout(location = 0, index = 0) out vec4 SV_Target0;
layout(location = 0, index = 1) out vec4 SV_Target1;
layout(binding = 0) uniform sampler2D TextureSampler;
layout(binding = 1) uniform sampler2D PaletteSampler;
@ -650,9 +650,7 @@ void ps_main()
if(c.a < 0.5) c.a += 0.5;
}
SV_Target1 = c;
#ifndef DISABLE_DUAL_BLEND
SV_Target0 = vec4(alpha, alpha, alpha, alpha);
#endif
SV_Target0 = c;
SV_Target1 = vec4(alpha, alpha, alpha, alpha);
}
#endif

View File

@ -92,6 +92,7 @@
#define IDC_HACK_DESCRIPTION 2073
#define IDC_STATIC_MSAA 2074
#define IDC_STATIC_SKIPDRAW 2075
#define IDC_AGGRESSIVECRC 2076
#define IDC_COLORSPACE 3000
#define IDR_CONVERT_FX 10000
#define IDR_TFX_FX 10001
@ -110,7 +111,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 10012
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 2076
#define _APS_NEXT_CONTROL_VALUE 2077
#define _APS_NEXT_SYMED_VALUE 5000
#endif
#endif