Hook up DX9 backend. Not really working though, it seems.

This commit is contained in:
Henrik Rydgard 2014-08-17 21:29:36 +02:00
parent 92c3775d95
commit e539c7009f
15 changed files with 205 additions and 134 deletions

View File

@ -1062,5 +1062,3 @@ void Config::GetReportingInfo(UrlEncoder &data) {
}
}
}

View File

@ -6,10 +6,7 @@
namespace DX9 {
// OpenGL state cache. Should convert all code to use this instead of directly calling glEnable etc,
// as GL state changes can be expensive on some hardware.
class DirectxState
{
class DirectxState {
private:
template<D3DRENDERSTATETYPE cap, bool init>
class BoolState {

View File

@ -1,5 +1,6 @@
#include "global.h"
#include "fbo.h"
#include "thin3d/d3dx9_loader.h"
namespace DX9 {
@ -91,6 +92,19 @@ bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD
&pShaderCode,
&pErrorMsg,
pShaderTable );
#else
// Compile pixel shader.
hr = dyn_D3DXCompileShader(code,
(UINT)strlen(code),
NULL,
NULL,
"main",
"ps_3_0",
0,
&pShaderCode,
&pErrorMsg,
pShaderTable);
#endif
if( FAILED(hr) )
{
@ -128,6 +142,17 @@ bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, L
&pShaderCode,
&pErrorMsg,
pShaderTable );
#else
hr = dyn_D3DXCompileShader(code,
(UINT)strlen(code),
NULL,
NULL,
"main",
"vs_3_0",
0,
&pShaderCode,
&pErrorMsg,
pShaderTable);
#endif
if( FAILED(hr) )
{
@ -163,6 +188,19 @@ void CompileShaders() {
&pShaderCode,
&pErrorMsg,
NULL );
#else
// Compile vertex shader.
hr = dyn_D3DXCompileShader(vscode,
(UINT)strlen(vscode),
NULL,
NULL,
"main",
"vs_2_0",
0,
&pShaderCode,
&pErrorMsg,
NULL);
#endif
if( FAILED(hr) )
@ -189,6 +227,19 @@ void CompileShaders() {
&pShaderCode,
&pErrorMsg,
NULL );
#else
// Compile pixel shader.
hr = dyn_D3DXCompileShader(pscode,
(UINT)strlen(pscode),
NULL,
NULL,
"main",
"ps_2_0",
0,
&pShaderCode,
&pErrorMsg,
NULL);
#endif
if( FAILED(hr) )

View File

@ -9,11 +9,11 @@
#define D3DFMT(x) x
#endif
namespace DX9 {
#include <d3d9.h>
#include <d3dx9.h>
namespace DX9 {
extern LPDIRECT3DDEVICE9 pD3Ddevice;
extern LPDIRECT3DVERTEXSHADER9 pFramebufferVertexShader; // Vertex Shader
@ -22,6 +22,7 @@ extern LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader; // Pixel Shader
extern IDirect3DVertexDeclaration9* pFramebufferVertexDecl;
extern IDirect3DVertexDeclaration9* pSoftVertexDecl;
void CompileShaders();
bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
void DirectxInit(HWND window);

View File

@ -191,7 +191,7 @@ int MixBackgroundAudio(short *buffer, int size) {
// last changed... (to prevent crazy amount of reads when skipping through a list)
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
// Grab some audio from the current game and play it.
GameInfo *gameInfo = g_gameInfoCache.GetInfo(bgGamePath, GAMEINFO_WANTSND);
GameInfo *gameInfo = g_gameInfoCache.GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
if (!gameInfo)
return 0;

View File

@ -86,6 +86,9 @@ void EmuScreen::bootGame(const std::string &filename) {
CoreParameter coreParam;
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES;
if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
coreParam.gpuCore = GPU_DIRECTX9;
}
coreParam.enableSound = g_Config.bEnableSound;
coreParam.fileToStart = filename;
coreParam.mountIso = "";
@ -135,12 +138,14 @@ void EmuScreen::bootComplete() {
#endif
memset(virtKeys, 0, sizeof(virtKeys));
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
const char *renderer = (const char*)glGetString(GL_RENDERER);
if (strstr(renderer, "Chainfire3D") != 0) {
osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
} else if (strstr(renderer, "GLTools") != 0) {
osm.Show(s->T("GLToolsWarning", "WARNING: GLTools detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
}
}
System_SendMessage("event", "startgame");
}
@ -701,7 +706,7 @@ void EmuScreen::render() {
return;
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (useBufferedRendering)
if (useBufferedRendering && g_Config.iGPUBackend == GPU_BACKEND_OPENGL)
fbo_unbind();
screenManager()->getUIContext()->RebindTexture();

View File

@ -24,6 +24,7 @@
#include "base/stringutil.h"
#include "file/file_util.h"
#include "file/zip_read.h"
#include "thin3d/thin3d.h"
#include "thread/prioritizedworkqueue.h"
#include "Common/FileUtil.h"
#include "Common/StringUtils.h"
@ -561,10 +562,8 @@ void GameInfoCache::FlushBGs() {
}
}
// This may run off-main-thread and we thus can't use the global
// pspFileSystem (well, we could with synchronization but there might not
// even be a game running).
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
GameInfo *info = 0;
auto iter = info_.find(gamePath);
@ -574,16 +573,16 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
// Need to start over. We'll just add a new work item.
goto again;
}
if (info->iconDataLoaded) {
SetupTexture(info, info->iconTextureData, info->iconTexture, info->timeIconWasLoaded);
if (thin3d && info->iconDataLoaded) {
SetupTexture(info, info->iconTextureData, thin3d, info->iconTexture, info->timeIconWasLoaded);
info->iconDataLoaded = false;
}
if (info->pic0DataLoaded) {
SetupTexture(info, info->pic0TextureData, info->pic0Texture, info->timePic0WasLoaded);
if (thin3d && info->pic0DataLoaded) {
SetupTexture(info, info->pic0TextureData, thin3d, info->pic0Texture, info->timePic0WasLoaded);
info->pic0DataLoaded = false;
}
if (info->pic1DataLoaded) {
SetupTexture(info, info->pic1TextureData, info->pic1Texture, info->timePic1WasLoaded);
if (thin3d && info->pic1DataLoaded) {
SetupTexture(info, info->pic1TextureData, thin3d, info->pic1Texture, info->timePic1WasLoaded);
info->pic1DataLoaded = false;
}
iter->second->lastAccessedTime = time_now_d();
@ -607,14 +606,14 @@ again:
return info;
}
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime) {
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime) {
if (textureData.size()) {
if (!tex) {
tex = new Texture();
if (tex->LoadPNG((const u8 *)textureData.data(), textureData.size(), false)) {
tex = thin3d->CreateTextureFromFileData(textureData.data(), textureData.size(), T3DFileType::PNG);
if (tex) {
loadTime = time_now_d();
} else {
delete tex;
tex->Release();
tex = 0;
}
}

View File

@ -23,10 +23,12 @@
#include "base/mutex.h"
#include "file/file_util.h"
#include "thread/prioritizedworkqueue.h"
#include "gfx/texture.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/Loaders.h"
class Thin3DContext;
class Thin3DTexture;
// A GameInfo holds information about a game, and also lets you do things that the VSH
// does on the PSP, namely checking for and deleting savedata, and similar things.
// Only cares about games that are installed on the current device.
@ -128,11 +130,11 @@ public:
// Pre read the data, create a texture the next time (GL thread..)
std::string iconTextureData;
Texture *iconTexture;
Thin3DTexture *iconTexture;
std::string pic0TextureData;
Texture *pic0Texture;
Thin3DTexture *pic0Texture;
std::string pic1TextureData;
Texture *pic1Texture;
Thin3DTexture *pic1Texture;
std::string sndFileData;
@ -170,7 +172,7 @@ public:
// but filled in later asynchronously in the background. So keep calling this,
// redrawing the UI often. Only set flags to GAMEINFO_WANTBG or WANTSND if you really want them
// because they're big. bgTextures and sound may be discarded over time as well.
GameInfo *GetInfo(const std::string &gamePath, int wantFlags);
GameInfo *GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags);
void Decimate(); // Deletes old info.
void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.
@ -179,7 +181,7 @@ public:
void Load();
private:
void SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime);
void SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime);
// Maps ISO path to info.
std::map<std::string, GameInfo *> info_;

View File

@ -45,7 +45,7 @@ GameScreen::~GameScreen() {
}
void GameScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
@ -64,7 +64,7 @@ void GameScreen::CreateViews() {
leftColumn->Add(new Choice(d->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack);
if (info) {
texvGameIcon_ = leftColumn->Add(new TextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
texvGameIcon_ = leftColumn->Add(new Thin3DTextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
tvTitle_ = leftColumn->Add(new TextView(info->title, ALIGN_LEFT, false, new AnchorLayoutParams(10, 200, NONE, NONE)));
// This one doesn't need to be updated.
leftColumn->Add(new TextView(gamePath_, ALIGN_LEFT, true, new AnchorLayoutParams(10, 250, NONE, NONE)));
@ -105,7 +105,10 @@ void GameScreen::update(InputState &input) {
UIScreen::update(input);
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
Thin3DContext *thin3d = screenManager()->getThin3DContext();
GameInfo *info = g_gameInfoCache.GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (tvTitle_)
tvTitle_->SetText(info->title + " (" + info->id + ")");
@ -166,7 +169,7 @@ UI::EventReturn GameScreen::OnPlay(UI::EventParams &e) {
}
UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info && info->paramSFOLoaded) {
std::string discID = info->paramSFO.GetValueString("DISC_ID");
screenManager()->push(new GameSettingsScreen(gamePath_, discID));
@ -177,7 +180,7 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
// Check that there's any savedata to delete
std::vector<std::string> saveDirs = info->GetSaveDataDirectories();
@ -193,7 +196,7 @@ UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteSaveData(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (yes) {
info->DeleteAllSaveData();
info->saveDataSize = 0;
@ -204,7 +207,7 @@ void GameScreen::CallbackDeleteSaveData(bool yes) {
UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
screenManager()->push(
new PromptScreen(d->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."), ga->T("ConfirmDelete"), d->T("Cancel"),
@ -215,7 +218,7 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteGame(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (yes) {
info->DeleteGame();
g_gameInfoCache.Clear();
@ -224,7 +227,7 @@ void GameScreen::CallbackDeleteGame(bool yes) {
}
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (info) {
host->CreateDesktopShortcut(gamePath_, info->title);
}

View File

@ -52,7 +52,7 @@ private:
UI::EventReturn OnShowInFolder(UI::EventParams &e);
// As we load metadata in the background, we need to be able to update these after the fact.
UI::TextureView *texvGameIcon_;
UI::Thin3DTextureView *texvGameIcon_;
UI::TextView *tvTitle_;
UI::TextView *tvGameSize_;
UI::TextView *tvSaveDataSize_;

View File

@ -63,7 +63,7 @@ bool GameSettingsScreen::UseVerticalLayout() const {
}
void GameSettingsScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60;

View File

@ -174,8 +174,8 @@ private:
};
void GameButton::Draw(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, 0);
Texture *texture = 0;
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath_, 0);
Thin3DTexture *texture = 0;
u32 color = 0, shadowColor = 0;
if (ginfo->iconTexture) {
@ -249,7 +249,7 @@ void GameButton::Draw(UIContext &dc) {
if (texture) {
dc.Draw()->Flush();
texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, texture);
if (holdFrameCount_ > 60) {
// Blink before launching by holding
if (((holdFrameCount_ >> 3) & 1) == 0)
@ -959,7 +959,7 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
GameInfo *ginfo = 0;
if (!gamePath.empty()) {
ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
// Loading texture data may bind a texture.
dc.RebindTexture();
@ -972,9 +972,9 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
}
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
}
uint32_t color = whiteAlpha(ease(progress)) & 0xFFc0c0c0;

View File

@ -102,18 +102,18 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
}
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
dc.Flush();
if (ginfo) {
bool hasPic = false;
double loadTime;
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
loadTime = ginfo->timePic1WasLoaded;
hasPic = true;
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
loadTime = ginfo->timePic0WasLoaded;
hasPic = true;
}

View File

@ -527,7 +527,7 @@ void NativeInitGraphics() {
uiTexture = thin3d->CreateTextureFromFile("ui_atlas_lowmem.zim");
if (!uiTexture) {
#else
uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim");
uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim", T3DFileType::ZIM);
if (!uiTexture) {
#endif
PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
@ -685,6 +685,8 @@ void NativeRender() {
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glstate.Restore();
} else {
// DirectxState::Restore();
}
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
@ -695,7 +697,8 @@ void NativeRender() {
// Apply the UIContext bounds as a 2D transformation matrix.
Matrix4x4 ortho;
ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
// ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
ui_draw2d.SetDrawMatrix(ortho);
ui_draw2d_front.SetDrawMatrix(ortho);

View File

@ -1,12 +1,16 @@
#include "Common/CommonWindows.h"
#include <d3d9.h>
#include "GPU/Directx9/helper/global.h"
#include "GPU/Directx9/helper/fbo.h"
#include "base/logging.h"
#include "util/text/utf8.h"
#include "i18n/i18n.h"
#include "Windows/D3D9Base.h"
#include "thin3d/thin3d.h"
#include "thin3d/d3dx9_loader.h"
static LPDIRECT3D9 d3d;
static LPDIRECT3DDEVICE9 device;
@ -61,7 +65,7 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
d3ddm.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D16))) {
D3DFMT_D24S8))) {
if (hr == D3DERR_NOTAVAILABLE) {
d3d->Release();
return false;
@ -84,7 +88,8 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
pp.Windowed = windowed;
pp.hDeviceWindow = hWnd;
pp.EnableAutoDepthStencil = true;
pp.AutoDepthStencilFormat = D3DFMT_D16;
pp.AutoDepthStencilFormat = D3DFMT_D24S8;
pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
hr = d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device);
if (FAILED(hr)) {
@ -94,6 +99,13 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
}
device->BeginScene();
DX9::pD3Ddevice = device;
LoadD3DX9Dynamic();
DX9::CompileShaders();
DX9::fbo_init();
return true;
}