Start hooking up D3D

This commit is contained in:
Henrik Rydgard 2014-08-17 16:07:14 +02:00
parent 808f05da89
commit 92c3775d95
14 changed files with 222 additions and 50 deletions

View file

@ -384,6 +384,7 @@ static int DefaultAndroidHwScale() {
}
static ConfigSetting graphicsSettings[] = {
ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0),
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0),
ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode),
ConfigSetting("SoftwareRendering", &g_Config.bSoftwareRendering, false),
@ -815,6 +816,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
}
CleanRecent();
iGPUBackend = 0;
}
void Config::Save() {

View file

@ -39,6 +39,12 @@ enum {
ROTATION_LOCKED_VERTICAL180 = 4,
};
// Software is not among these because it will have one of these perform the blit to display.
enum {
GPU_BACKEND_OPENGL = 0,
GPU_BACKEND_DIRECT3D9 = 1,
};
namespace http {
class Download;
class Downloader;
@ -100,8 +106,8 @@ public:
std::vector<std::string> vPinnedPaths;
std::string sLanguageIni;
// GFX
int iGPUBackend;
bool bSoftwareRendering;
bool bHardwareTransform; // only used in the GLES backend
bool bSoftwareSkinning; // may speed up some games

View file

@ -33,6 +33,7 @@
#ifdef _WIN32
#ifndef _XBOX
#include "Windows/OpenGLBase.h"
#include "Windows/D3D9Base.h"
#endif
#include "Windows/InputDevice.h"
#endif
@ -151,6 +152,19 @@ void UpdateRunLoop() {
}
}
void GPU_SwapBuffers() {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
GL_SwapBuffers();
break;
#ifdef _WIN32
case GPU_BACKEND_DIRECT3D9:
D3D9_SwapBuffers();
break;
#endif
}
}
void Core_RunLoop() {
while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) {
time_update();
@ -165,7 +179,7 @@ void Core_RunLoop() {
if (sleepTime > 0)
Sleep(sleepTime);
if (!windowHidden) {
GL_SwapBuffers();
GPU_SwapBuffers();
}
#else
UpdateRunLoop();
@ -177,7 +191,7 @@ void Core_RunLoop() {
UpdateRunLoop();
#if defined(USING_WIN_UI)
if (!windowHidden && !Core_IsStepping()) {
GL_SwapBuffers();
GPU_SwapBuffers();
}
#endif
}

View file

@ -707,7 +707,14 @@ void EmuScreen::render() {
screenManager()->getUIContext()->RebindTexture();
Thin3DContext *thin3d = screenManager()->getThin3DContext();
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
glstate.viewport.restore();
thin3d->SetBlendState(thin3d->GetBlendStatePreset(BS_STANDARD_ALPHA));

View file

@ -38,6 +38,7 @@
#include "ext/jpge/jpge.h"
#include "Windows/DSoundStream.h"
#include "Windows/WndMainWindow.h"
#include "Windows/D3D9Base.h"
#endif
#include "base/display.h"
@ -48,7 +49,7 @@
#include "file/zip_read.h"
#include "thread/thread.h"
#include "net/http_client.h"
#include "gfx_es2/gl_state.h"
#include "gfx_es2/gl_state.h" // only for screenshot!
#include "gfx_es2/draw_text.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx/gl_lost_manager.h"
@ -112,7 +113,7 @@ static UI::Theme ui_theme;
#include "android/android-ndk-profiler/prof.h"
#endif
Texture *uiTexture;
Thin3DTexture *uiTexture;
ScreenManager *screenManager;
std::string config_filename;
@ -464,9 +465,12 @@ void NativeInit(int argc, const char *argv[],
void NativeInitGraphics() {
FPU_SetFastMode();
thin3d = T3DCreateGLContext();
CheckGLExtensions();
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
thin3d = T3DCreateGLContext();
CheckGLExtensions();
} else {
thin3d = D3D9_CreateThin3DContext();
}
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
@ -489,18 +493,6 @@ void NativeInitGraphics() {
ui_theme.sliderKnob = I_CIRCLE;
ui_theme.dropShadow4Grid = I_DROP_SHADOW;
/*
ui_theme.buttonStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON);
ui_theme.buttonStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonStyle.image = I_BUTTON;
ui_theme.buttonFocusedStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFFe0e0e0);
ui_theme.buttonFocusedStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonDownStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON_SELECTED, 0xFFFFFFFF);
ui_theme.buttonDownStyle.fgColor = 0xFFFFFFFF;
ui_theme.buttonDisabledStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFF404040);
ui_theme.buttonDisabledStyle.fgColor = 0xFF707070;
*/
ui_theme.itemStyle.background = UI::Drawable(0x55000000);
ui_theme.itemStyle.fgColor = 0xFFFFFFFF;
ui_theme.itemFocusedStyle.background = UI::Drawable(0xFFedc24c);
@ -531,16 +523,16 @@ void NativeInitGraphics() {
ui_draw2d.Init(thin3d);
ui_draw2d_front.Init(thin3d);
uiTexture = new Texture();
#ifdef USING_QT_UI
if (!uiTexture->Load("ui_atlas_lowmem.zim")) {
uiTexture = thin3d->CreateTextureFromFile("ui_atlas_lowmem.zim");
if (!uiTexture) {
#else
if (!uiTexture->Load("ui_atlas.zim")) {
uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim");
if (!uiTexture) {
#endif
PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
ELOG("Failed to load ui_atlas.zim");
}
uiTexture->Bind(0);
uiContext = new UIContext();
uiContext->theme = &ui_theme;
@ -571,8 +563,7 @@ void NativeShutdownGraphics() {
g_gameInfoCache.Clear();
delete uiTexture;
uiTexture = NULL;
uiTexture->Release();
delete uiContext;
uiContext = NULL;
@ -584,7 +575,13 @@ void NativeShutdownGraphics() {
}
void TakeScreenshot() {
if (g_Config.iGPUBackend != GPU_BACKEND_OPENGL) {
// Not yet supported
return;
}
g_TakeScreenshot = false;
#if defined(_WIN32) || (defined(USING_QT_UI) && !defined(MOBILE_DEVICE))
mkDir(g_Config.memCardDirectory + "/PSP/SCREENSHOT");
@ -675,15 +672,23 @@ void DrawDownloadsOverlay(UIContext &dc) {
void NativeRender() {
g_GameManager.Update();
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
// Clearing the screen at the start of the frame is an optimization for tiled mobile GPUs, as it then doesn't need to keep it around between frames.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
glstate.depthWrite.set(GL_TRUE);
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glstate.Restore();
}
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
glstate.Restore();
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
thin3d->SetTargetSize(pixel_xres, pixel_yres);
float xres = dp_xres;
float yres = dp_yres;
@ -695,7 +700,6 @@ void NativeRender() {
ui_draw2d.SetDrawMatrix(ortho);
ui_draw2d_front.SetDrawMatrix(ortho);
// glsl_bind(UIShader_Get());
screenManager->render();

109
Windows/D3D9Base.cpp Normal file
View file

@ -0,0 +1,109 @@
#include "Common/CommonWindows.h"
#include <d3d9.h>
#include "base/logging.h"
#include "util/text/utf8.h"
#include "i18n/i18n.h"
#include "Windows/D3D9Base.h"
#include "thin3d/thin3d.h"
static LPDIRECT3D9 d3d;
static LPDIRECT3DDEVICE9 device;
static HDC hDC; // Private GDI Device Context
static HGLRC hRC; // Permanent Rendering Context
static HWND hWnd; // Holds Our Window Handle
static int xres, yres;
// TODO: Make config?
static bool enableGLDebug = true;
void D3D9_SwapBuffers() {
device->EndScene();
device->Present(NULL, NULL, NULL, NULL);
device->BeginScene();
}
Thin3DContext *D3D9_CreateThin3DContext() {
return T3DCreateDX9Context(device);
}
bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d) {
ELOG("Failed to create D3D context");
return false;
}
RECT rc;
GetClientRect(hWnd, &rc);
int xres = rc.right - rc.left;
int yres = rc.bottom - rc.top;
D3DCAPS9 d3dCaps;
D3DDISPLAYMODE d3ddm;
if (FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
d3d->Release();
return false;
}
int adapter = D3DADAPTER_DEFAULT;
if (FAILED(d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &d3dCaps))) {
d3d->Release();
return false;
}
HRESULT hr;
if (FAILED(hr = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
d3ddm.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D16))) {
if (hr == D3DERR_NOTAVAILABLE) {
d3d->Release();
return false;
}
}
DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE;
if (d3dCaps.VertexProcessingCaps != 0)
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS pp;
memset(&pp, 0, sizeof(pp));
pp.BackBufferWidth = xres;
pp.BackBufferHeight = yres;
pp.BackBufferFormat = d3ddm.Format;
pp.MultiSampleType = D3DMULTISAMPLE_NONE;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = windowed;
pp.hDeviceWindow = hWnd;
pp.EnableAutoDepthStencil = true;
pp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device);
if (FAILED(hr)) {
ELOG("Failed to create D3D device");
d3d->Release();
return false;
}
device->BeginScene();
return true;
}
void D3D9_Resize(HWND window) {
}
void D3D9_Shutdown() {
device->EndScene();
device->Release();
d3d->Release();
hWnd = NULL;
}

13
Windows/D3D9Base.h Normal file
View file

@ -0,0 +1,13 @@
// Modelled on OpenD3DBase. Might make a cleaner interface later.
#pragma once
#include "Common/CommonWindows.h"
class Thin3DContext;
bool D3D9_Init(HWND window, bool windowed, std::string *error_message);
void D3D9_Shutdown();
void D3D9_Resize(HWND window);
void D3D9_SwapBuffers();
Thin3DContext *D3D9_CreateThin3DContext();

View file

@ -106,7 +106,7 @@ unsigned int WINAPI TheThread(void *)
std::string error_string;
if (!host->InitGL(&error_string)) {
Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str());
Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), L"OpenGL Error", MB_OK | MB_ICONERROR);
ERROR_LOG(BOOT, full_error.c_str());

View file

@ -1,10 +1,6 @@
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
#include "util/text/utf8.h"
#include "Common/CommonWindows.h"
#include "native/gfx_es2/gl_state.h"
#include "native/gfx/gl_common.h"
#include "util/text/utf8.h"
#include "GL/gl.h"
#include "GL/wglew.h"
#include "util/text/utf8.h"

View file

@ -1,5 +1,3 @@
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
#pragma once
#include "Common/CommonWindows.h"

View file

@ -277,6 +277,7 @@
</ForcedIncludeFiles>
</ClCompile>
<ClCompile Include="ControlMapping.cpp" />
<ClCompile Include="D3D9Base.cpp" />
<ClCompile Include="Debugger\BreakpointWindow.cpp" />
<ClCompile Include="Debugger\CtrlDisAsmView.cpp" />
<ClCompile Include="Debugger\CtrlMemView.cpp" />
@ -330,6 +331,7 @@
<ClInclude Include="..\android\jni\TestRunner.h" />
<ClInclude Include="..\ios\ViewController.h" />
<ClInclude Include="ControlMapping.h" />
<ClInclude Include="D3D9Base.h" />
<ClInclude Include="Debugger\BreakpointWindow.h" />
<ClInclude Include="Debugger\CtrlDisAsmView.h" />
<ClInclude Include="Debugger\CtrlMemView.h" />

View file

@ -67,6 +67,9 @@
<ClCompile Include="DSoundStream.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
<ClCompile Include="D3D9Base.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
<ClCompile Include="OpenGLBase.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
@ -187,6 +190,9 @@
<ClInclude Include="DSoundStream.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="D3D9Base.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="OpenGLBase.h">
<Filter>Windows\System</Filter>
</ClInclude>
@ -326,4 +332,4 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>

View file

@ -42,6 +42,7 @@
#include "WindowsHost.h"
#include "WndMainWindow.h"
#include "OpenGLBase.h"
#include "D3D9Base.h"
#include "Windows/Debugger/DebuggerShared.h"
#include "Windows/Debugger/Debugger_Disasm.h"
@ -88,14 +89,26 @@ WindowsHost::WindowsHost(HWND mainWindow, HWND displayWindow)
SetConsolePosition();
}
bool WindowsHost::InitGL(std::string *error_message)
{
return GL_Init(displayWindow_, error_message);
bool WindowsHost::InitGL(std::string *error_message) {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
return GL_Init(displayWindow_, error_message);
case GPU_BACKEND_DIRECT3D9:
return D3D9_Init(displayWindow_, true, error_message);
default:
return false;
}
}
void WindowsHost::ShutdownGL()
{
GL_Shutdown();
void WindowsHost::ShutdownGL() {
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
GL_Shutdown();
break;
case GPU_BACKEND_DIRECT3D9:
D3D9_Shutdown();
break;
}
PostMessage(mainWindow_, WM_CLOSE, 0, 0);
}

View file

@ -66,7 +66,8 @@ public:
};
struct InputState;
// Temporary hack around annoying linking error.
// Temporary hacks around annoying linking errors.
void D3D9_SwapBuffers() { }
void GL_SwapBuffers() { }
void NativeUpdate(InputState &input_state) { }
void NativeRender() { }