From 808f05da8978fc2fa2ea046c43a7a1be433f98d4 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 17 Aug 2014 12:19:04 +0200 Subject: [PATCH 01/13] (Partially) slip thin3d underneath DrawBuffer. --- Common/KeyMap.cpp | 2 +- Core/Dialog/SavedataParam.cpp | 1 + Core/MIPS/JitCommon/JitBlockCache.cpp | 2 +- UI/ControlMappingScreen.cpp | 1 - UI/CwCheatScreen.cpp | 1 - UI/EmuScreen.cpp | 10 +-- UI/MiscScreens.cpp | 11 +-- UI/NativeApp.cpp | 25 ++++-- UI/UI.vcxproj | 4 +- UI/UI.vcxproj.filters | 2 - UI/UIShader.cpp | 113 -------------------------- UI/UIShader.h | 31 ------- Windows/OpenGLBase.cpp | 3 +- native | 2 +- 14 files changed, 31 insertions(+), 177 deletions(-) delete mode 100644 UI/UIShader.cpp delete mode 100644 UI/UIShader.h diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 6b3bfc5bad..bf7314a9fd 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -747,7 +747,7 @@ bool KeyFromPspButton(int btn, std::vector *keys) { bool AxisToPspButton(int deviceId, int axisId, int direction, std::vector *pspKeys) { int key = TranslateKeyCodeFromAxis(axisId, direction); - return KeyToPspButton(deviceId, key, pspKeys); + return KeyToPspButton(deviceId, key, pspKeys); } bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) { diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 0abff6aefc..760fa3dd83 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -185,6 +185,7 @@ void SaveFileInfo::DoState(PointerWrap &p) p.Do(hasTexture); if (hasTexture) { if (p.mode == p.MODE_READ) { + delete texture; texture = new PPGeImage(""); } texture->DoState(p); diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index e0e42cbbc4..54fa8016ab 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -316,7 +316,7 @@ MIPSOpcode JitBlockCache::GetEmuHackOpForBlock(int blockNum) const { } int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr, bool realBlocksOnly) { - if (!blocks_) + if (!blocks_ || !Memory::IsValidAddress(addr)) return -1; MIPSOpcode inst = MIPSOpcode(Memory::Read_U32(addr)); diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 9db228d193..ab5bb942c2 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -30,7 +30,6 @@ #include "Core/Config.h" #include "UI/ui_atlas.h" #include "UI/ControlMappingScreen.h" -#include "UI/UIShader.h" #include "UI/GameSettingsScreen.h" class ControlMapper : public UI::LinearLayout { diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 498ed41aa0..b5dc4bd732 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -28,7 +28,6 @@ #include "UI/OnScreenDisplay.h" #include "UI/ui_atlas.h" #include "UI/GamepadEmu.h" -#include "UI/UIShader.h" #include "UI/MainScreen.h" #include "UI/EmuScreen.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index d01cae3a31..0e10380169 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -50,7 +50,6 @@ #include "UI/ui_atlas.h" #include "UI/OnScreenDisplay.h" #include "UI/GamepadEmu.h" -#include "UI/UIShader.h" #include "UI/MainScreen.h" #include "UI/EmuScreen.h" #include "UI/DevScreens.h" @@ -705,14 +704,14 @@ void EmuScreen::render() { if (useBufferedRendering) fbo_unbind(); - UIShader_Prepare(); - - uiTexture->Bind(0); + screenManager()->getUIContext()->RebindTexture(); + Thin3DContext *thin3d = screenManager()->getThin3DContext(); glstate.viewport.set(0, 0, pixel_xres, pixel_yres); glstate.viewport.restore(); - ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); + thin3d->SetBlendState(thin3d->GetBlendStatePreset(BS_STANDARD_ALPHA)); + ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL); if (root_) { UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); @@ -757,7 +756,6 @@ void EmuScreen::render() { ui_draw2d.SetFontScale(1.0f, 1.0f); } - glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index e91c6ea952..24e3903e26 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -18,7 +18,6 @@ #include "base/colorutil.h" #include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" -#include "gfx_es2/gl_state.h" #include "file/vfs.h" #include "math/curves.h" #include "i18n/i18n.h" @@ -85,11 +84,8 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) { last_xres = xres; last_yres = yres; } - - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClearColor(0.1f, 0.2f, 0.43f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + dc.GetThin3DContext()->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xff224477, 0.0, 0); int img = I_BG; #ifdef GOLD img = I_BG_GOLD; @@ -396,15 +392,16 @@ bool LogoScreen::key(const KeyInput &key) { void LogoScreen::render() { UIScreen::render(); - UIContext &dc = *screenManager()->getUIContext(); + int error = glGetError(); const Bounds &bounds = dc.GetBounds(); float xres = dc.GetBounds().w; float yres = dc.GetBounds().h; dc.Begin(); + error = glGetError(); float t = (float)frames_ / 60.0f; float alpha = t; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 45cc19124b..45e42612e3 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -58,6 +58,7 @@ #include "math/fast/fast_math.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" +#include "thin3d/thin3d.h" #include "ui/ui.h" #include "ui/screen.h" #include "ui/ui_context.h" @@ -80,7 +81,6 @@ #include "ui_atlas.h" #include "EmuScreen.h" #include "GameInfoCache.h" -#include "UIShader.h" #include "HostTypes.h" #include "UI/OnScreenDisplay.h" @@ -132,6 +132,7 @@ struct PendingMessage { static recursive_mutex pendingMutex; static std::vector pendingMessages; +static Thin3DContext *thin3d; static UIContext *uiContext; std::thread *graphicsLoadThread; @@ -463,12 +464,13 @@ void NativeInit(int argc, const char *argv[], void NativeInitGraphics() { FPU_SetFastMode(); + thin3d = T3DCreateGLContext(); + CheckGLExtensions(); + ui_draw2d.SetAtlas(&ui_atlas); ui_draw2d_front.SetAtlas(&ui_atlas); - UIShader_Init(); - // memset(&ui_theme, 0, sizeof(ui_theme)); // New style theme #ifdef _WIN32 @@ -526,8 +528,8 @@ void NativeInitGraphics() { ui_theme.popupTitle.fgColor = 0xFF59BEE3; #endif - ui_draw2d.Init(); - ui_draw2d_front.Init(); + ui_draw2d.Init(thin3d); + ui_draw2d_front.Init(thin3d); uiTexture = new Texture(); #ifdef USING_QT_UI @@ -542,11 +544,13 @@ void NativeInitGraphics() { uiContext = new UIContext(); uiContext->theme = &ui_theme; - uiContext->Init(UIShader_Get(), UIShader_GetPlain(), uiTexture, &ui_draw2d, &ui_draw2d_front); + + uiContext->Init(thin3d, thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), thin3d->GetShaderSetPreset(SS_COLOR_2D), uiTexture, &ui_draw2d, &ui_draw2d_front); if (uiContext->Text()) uiContext->Text()->SetFont("Tahoma", 20, 0); screenManager->setUIContext(uiContext); + screenManager->setThin3DContext(thin3d); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -576,7 +580,7 @@ void NativeShutdownGraphics() { ui_draw2d.Shutdown(); ui_draw2d_front.Shutdown(); - UIShader_Shutdown(); + thin3d->Release(); } void TakeScreenshot() { @@ -688,8 +692,11 @@ void NativeRender() { Matrix4x4 ortho; ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); - glsl_bind(UIShader_Get()); - glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); + ui_draw2d.SetDrawMatrix(ortho); + ui_draw2d_front.SetDrawMatrix(ortho); + + + // glsl_bind(UIShader_Get()); screenManager->render(); if (screenManager->getUIContext()->Text()) { diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 938c45c27b..9202890720 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -38,7 +38,6 @@ - @@ -60,7 +59,6 @@ - @@ -192,4 +190,4 @@ - + \ No newline at end of file diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 5cdfefd726..8a3740e483 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -5,7 +5,6 @@ - Screens @@ -53,7 +52,6 @@ - Screens diff --git a/UI/UIShader.cpp b/UI/UIShader.cpp deleted file mode 100644 index c982d983b9..0000000000 --- a/UI/UIShader.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// 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, version 2.0 or later versions. - -// 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 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include "gfx_es2/glsl_program.h" -#include "gfx_es2/gl_state.h" -#include "UIShader.h" - -static GLSLProgram *glslModulate; -static GLSLProgram *glslPlain; - -static const char modulate_fs[] = - "#ifdef GL_ES\n" - "precision lowp float;\n" - "#endif\n" - "uniform sampler2D sampler0;\n" - "varying vec2 v_texcoord0;\n" - "varying vec4 v_color;\n" - "void main() {\n" - " gl_FragColor = texture2D(sampler0, v_texcoord0) * v_color;\n" - "}\n"; - -static const char modulate_vs[] = - "attribute vec4 a_position;\n" - "attribute vec4 a_color;\n" - "attribute vec2 a_texcoord0;\n" - "uniform mat4 u_worldviewproj;\n" - "varying vec2 v_texcoord0;\n" - "varying vec4 v_color;\n" - "void main() {\n" - " v_texcoord0 = a_texcoord0;\n" - " v_color = a_color;\n" - " gl_Position = u_worldviewproj * a_position;\n" - "}\n"; - -static const char plain_fs[] = - "#ifdef GL_ES\n" - "precision lowp float;\n" - "#endif\n" - "varying vec4 v_color;\n" - "void main() {\n" - " gl_FragColor = v_color;\n" - "}\n"; - -static const char plain_vs[] = - "attribute vec4 a_position;\n" - "attribute vec4 a_color;\n" - "uniform mat4 u_worldviewproj;\n" - "varying vec4 v_color;\n" - "void main() {\n" - " v_color = a_color;\n" - " gl_Position = u_worldviewproj * a_position;\n" - "}\n"; - -void UIShader_Init() { - // Compile UI shaders - glslModulate = glsl_create_source(modulate_vs, modulate_fs); - glslPlain = glsl_create_source(plain_vs, plain_fs); -} - -GLSLProgram *UIShader_Get() -{ - return glslModulate; -} - - -GLSLProgram *UIShader_GetPlain() -{ - return glslPlain; -} - -void UIShader_Shutdown() -{ - glsl_destroy(glslModulate); - glsl_destroy(glslPlain); -} - -void UIShader_Prepare() -{ - // Draw 2D overlay stuff - glstate.cullFace.disable(); - glstate.depthTest.disable(); - glstate.scissorTest.disable(); - glstate.stencilTest.disable(); - glstate.stencilMask.set(0xFF); -#if !defined(USING_GLES2) - glstate.colorLogicOp.disable(); -#endif - glstate.dither.enable(); - - glstate.blend.enable(); - glstate.blendFuncSeparate.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_ADD); - - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.Restore(); - - uiTexture->Bind(0); -} diff --git a/UI/UIShader.h b/UI/UIShader.h deleted file mode 100644 index 6edb962c3d..0000000000 --- a/UI/UIShader.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// 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, version 2.0 or later versions. - -// 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 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include "gfx_es2/glsl_program.h" -#include "gfx/texture.h" - -void UIShader_Init(); -GLSLProgram *UIShader_Get(); -GLSLProgram *UIShader_GetPlain(); // Just color -void UIShader_Shutdown(); - -void UIShader_Prepare(); - -// TODO: Remove -extern Texture *uiTexture; \ No newline at end of file diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index a6b5bd66a0..437bac92f3 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -19,7 +19,7 @@ static HWND hWnd; // Holds Our Window Handle static int xres, yres; // TODO: Make config? -static bool enableGLDebug = false; +static bool enableGLDebug = true; void GL_SwapBuffers() { SwapBuffers(hDC); @@ -71,6 +71,7 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, FILE *outFile = (FILE*)userParam; char finalMessage[256]; FormatDebugOutputARB(finalMessage, 256, source, type, id, severity, message); + OutputDebugStringA(finalMessage); ERROR_LOG(G3D, "GL: %s", finalMessage); } diff --git a/native b/native index 2ba8e36b2b..ff5df25135 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 2ba8e36b2bde65021c9a5c0f937a0e3892c2ad62 +Subproject commit ff5df25135423a06357d5e455be19acfec81663f From 92c3775d95d8c10fedac77817c6f00182252d49e Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 17 Aug 2014 16:07:14 +0200 Subject: [PATCH 02/13] Start hooking up D3D --- Core/Config.cpp | 3 + Core/Config.h | 8 ++- Core/Core.cpp | 18 +++++- UI/EmuScreen.cpp | 9 ++- UI/NativeApp.cpp | 66 ++++++++++---------- Windows/D3D9Base.cpp | 109 +++++++++++++++++++++++++++++++++ Windows/D3D9Base.h | 13 ++++ Windows/EmuThread.cpp | 2 +- Windows/OpenGLBase.cpp | 4 -- Windows/OpenGLBase.h | 2 - Windows/PPSSPP.vcxproj | 2 + Windows/PPSSPP.vcxproj.filters | 8 ++- Windows/WindowsHost.cpp | 25 ++++++-- headless/Headless.cpp | 3 +- 14 files changed, 222 insertions(+), 50 deletions(-) create mode 100644 Windows/D3D9Base.cpp create mode 100644 Windows/D3D9Base.h diff --git a/Core/Config.cpp b/Core/Config.cpp index 73135f1a82..ff0f3c40e7 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -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() { diff --git a/Core/Config.h b/Core/Config.h index 9a87a7c952..0994a1d48e 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -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 vPinnedPaths; std::string sLanguageIni; - // GFX + int iGPUBackend; bool bSoftwareRendering; bool bHardwareTransform; // only used in the GLES backend bool bSoftwareSkinning; // may speed up some games diff --git a/Core/Core.cpp b/Core/Core.cpp index d93d02a74a..e2fcf0c536 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -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 } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 0e10380169..ad821d5936 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -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)); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 45e42612e3..5a9b8903c3 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -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(); diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp new file mode 100644 index 0000000000..1b6a61d130 --- /dev/null +++ b/Windows/D3D9Base.cpp @@ -0,0 +1,109 @@ +#include "Common/CommonWindows.h" +#include + +#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; +} diff --git a/Windows/D3D9Base.h b/Windows/D3D9Base.h new file mode 100644 index 0000000000..716402cc14 --- /dev/null +++ b/Windows/D3D9Base.h @@ -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(); \ No newline at end of file diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 29a3294e78..02fb35f110 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -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()); diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index 437bac92f3..f9694b3836 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -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" diff --git a/Windows/OpenGLBase.h b/Windows/OpenGLBase.h index e900b4bed5..e103ece39e 100644 --- a/Windows/OpenGLBase.h +++ b/Windows/OpenGLBase.h @@ -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" diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index e501733af7..833939c1a1 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -277,6 +277,7 @@ + @@ -330,6 +331,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 92331e214d..9d7a6df7c5 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -67,6 +67,9 @@ Windows\System + + Windows\System + Windows\System @@ -187,6 +190,9 @@ Windows\System + + Windows\System + Windows\System @@ -326,4 +332,4 @@ Resource Files - \ No newline at end of file + diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index e023bd69e3..b5f0060b62 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -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); } diff --git a/headless/Headless.cpp b/headless/Headless.cpp index db2b4c6914..4af9a6d855 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -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() { } From e539c7009f6f63385572b30587cb72ea647000de Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 17 Aug 2014 21:29:36 +0200 Subject: [PATCH 03/13] Hook up DX9 backend. Not really working though, it seems. --- Core/Config.cpp | 2 - GPU/Directx9/helper/dx_state.h | 5 +- GPU/Directx9/helper/global.cpp | 51 ++++++++++ GPU/Directx9/helper/global.h | 5 +- UI/BackgroundAudio.cpp | 2 +- UI/EmuScreen.cpp | 17 ++-- UI/GameInfoCache.cpp | 27 +++--- UI/GameInfoCache.h | 14 +-- UI/GameScreen.cpp | 21 +++-- UI/GameScreen.h | 2 +- UI/GameSettingsScreen.cpp | 2 +- UI/MainScreen.cpp | 12 +-- UI/MiscScreens.cpp | 6 +- UI/NativeApp.cpp | 7 +- Windows/D3D9Base.cpp | 166 ++++++++++++++++++--------------- 15 files changed, 205 insertions(+), 134 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index ff0f3c40e7..c493a5cd44 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1062,5 +1062,3 @@ void Config::GetReportingInfo(UrlEncoder &data) { } } } - - diff --git a/GPU/Directx9/helper/dx_state.h b/GPU/Directx9/helper/dx_state.h index 89d3244921..b6be350529 100644 --- a/GPU/Directx9/helper/dx_state.h +++ b/GPU/Directx9/helper/dx_state.h @@ -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 class BoolState { diff --git a/GPU/Directx9/helper/global.cpp b/GPU/Directx9/helper/global.cpp index 0a48fa6bda..425db94fe0 100644 --- a/GPU/Directx9/helper/global.cpp +++ b/GPU/Directx9/helper/global.cpp @@ -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) ) diff --git a/GPU/Directx9/helper/global.h b/GPU/Directx9/helper/global.h index 931b7543c4..9c41d6128c 100644 --- a/GPU/Directx9/helper/global.h +++ b/GPU/Directx9/helper/global.h @@ -9,11 +9,11 @@ #define D3DFMT(x) x #endif -namespace DX9 { - #include #include +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); diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 33abf2d016..8abe4ac9b1 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -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; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ad821d5936..803e4a364a 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -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,11 +138,13 @@ void EmuScreen::bootComplete() { #endif memset(virtKeys, 0, sizeof(virtKeys)); - 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); + 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(); diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 24814f6713..a5c94ed50f 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -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; } } diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 4048e9452d..8719577b36 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -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 info_; diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index c6fc549f10..b4fa85860d 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -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 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); } diff --git a/UI/GameScreen.h b/UI/GameScreen.h index cbca7dc13a..bf210bc52e 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -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_; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index d0ad767b3a..5326583796 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -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; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 292b1a838e..45a93846be 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -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; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 24e3903e26..cf201e740a 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -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; } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 5a9b8903c3..a01fb95b32 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -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); diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index 1b6a61d130..5a042bc019 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -1,46 +1,50 @@ -#include "Common/CommonWindows.h" -#include - -#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; - +#include "Common/CommonWindows.h" +#include + +#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; +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; @@ -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; @@ -73,37 +77,45 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { 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_D24S8; + pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + 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(); + DX9::pD3Ddevice = device; + + LoadD3DX9Dynamic(); - 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; -} + DX9::CompileShaders(); + DX9::fbo_init(); + + return true; +} + +void D3D9_Resize(HWND window) { + +} + +void D3D9_Shutdown() { + device->EndScene(); + device->Release(); + d3d->Release(); + hWnd = NULL; +} From e2ecbb7a4ddab2c83fe9d6ca3552d5944a36e6e9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 22 Aug 2014 20:48:35 +0200 Subject: [PATCH 04/13] Convert more UI code to Thin3D --- Core/Config.cpp | 4 +--- GPU/Directx9/helper/fbo.cpp | 11 +++++++++-- UI/DevScreens.cpp | 18 +++++++++++------- UI/MiscScreens.cpp | 2 ++ Windows/D3D9Base.cpp | 6 +++--- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index c493a5cd44..7a3ef803e6 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -384,8 +384,8 @@ static int DefaultAndroidHwScale() { } static ConfigSetting graphicsSettings[] = { - ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0), ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0), + ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0), ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode), ConfigSetting("SoftwareRendering", &g_Config.bSoftwareRendering, false), ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true), @@ -816,8 +816,6 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { } CleanRecent(); - - iGPUBackend = 0; } void Config::Save() { diff --git a/GPU/Directx9/helper/fbo.cpp b/GPU/Directx9/helper/fbo.cpp index 8b1dad31bf..21608f2e90 100644 --- a/GPU/Directx9/helper/fbo.cpp +++ b/GPU/Directx9/helper/fbo.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "base/logging.h" #include "fbo.h" namespace DX9 { @@ -60,8 +61,14 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F pD3Ddevice->CreateRenderTarget(fbo->width/FB_DIV, fbo->height/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL); } #else - pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL); - pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); + HRESULT rtResult = pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL); + if (FAILED(rtResult)) { + ELOG("Failed to create render target"); + } + HRESULT dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); + if (FAILED(dsResult)) { + ELOG("Failed to create depth buffer"); + } #endif fbo->stencil_buffer = 8; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 4e1dc5db3d..161c100ec6 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -231,16 +231,20 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem("Threads", cores)); #endif deviceSpecs->Add(new ItemHeader("GPU Information")); - deviceSpecs->Add(new InfoItem("Vendor", (char *)glGetString(GL_VENDOR))); - deviceSpecs->Add(new InfoItem("Model", (char *)glGetString(GL_RENDERER))); + + Thin3DContext *thin3d = screenManager()->getThin3DContext(); + + deviceSpecs->Add(new InfoItem("3D API", thin3d->GetInfoString(T3DInfo::APINAME))); + deviceSpecs->Add(new InfoItem("Vendor", thin3d->GetInfoString(T3DInfo::VENDOR))); + deviceSpecs->Add(new InfoItem("Model", thin3d->GetInfoString(T3DInfo::RENDERER))); #ifdef _WIN32 deviceSpecs->Add(new InfoItem("Driver Version", System_GetProperty(SYSPROP_GPUDRIVER_VERSION))); #endif - deviceSpecs->Add(new ItemHeader("OpenGL Version Information")); - std::string openGL = (char *)glGetString(GL_VERSION); - openGL.resize(30); - deviceSpecs->Add(new InfoItem("OpenGL", openGL)); - deviceSpecs->Add(new InfoItem("GLSL", (char *)glGetString(GL_SHADING_LANGUAGE_VERSION))); + deviceSpecs->Add(new ItemHeader("Version Information")); + std::string apiVersion = thin3d->GetInfoString(T3DInfo::APIVERSION); + apiVersion.resize(30); + deviceSpecs->Add(new InfoItem("API Version", apiVersion)); + deviceSpecs->Add(new InfoItem("Shading Language", thin3d->GetInfoString(T3DInfo::SHADELANGVERSION))); #ifdef ANDROID char temp[256]; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index cf201e740a..58b2ebc0ad 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -432,6 +432,8 @@ void LogoScreen::render() { ui_draw2d.DrawTextShadow(UBUNTU24, boot_filename.c_str(), bounds.centerX(), bounds.centerY() + 180, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); } + dc.DrawText(screenManager()->getThin3DContext()->GetInfoString(T3DInfo::APINAME), bounds.centerX(), bounds.y2() - 100, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); + dc.End(); dc.Flush(); } diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index 5a042bc019..49abb30be5 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -102,9 +102,9 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { DX9::pD3Ddevice = device; LoadD3DX9Dynamic(); - - DX9::CompileShaders(); - DX9::fbo_init(); + + DX9::CompileShaders(); + DX9::fbo_init(); return true; } From 00d5793f7dacc22bfd46238ac98f2d86b00e8f8b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 22 Aug 2014 21:27:13 +0200 Subject: [PATCH 05/13] D3D9: Don't crash on bad vertex formats. --- GPU/Directx9/TransformPipelineDX9.cpp | 45 +++++++++++++++------------ native | 2 +- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index 7c2c3c30c0..6ab9416c65 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -154,8 +154,8 @@ static const DeclTypeInfo VComp[] = { {D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_2, {D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_3, {D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_4, - {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_1, - {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_2, + {D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_1, + {D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_2, {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_3, {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_4, #ifdef _XBOX @@ -164,7 +164,7 @@ static const DeclTypeInfo VComp[] = { #else // Not supported in regular DX9 so faking, will cause graphics bugs until worked around {D3DDECLTYPE_UBYTE4 ,"D3DDECLTYPE_BYTE4 "}, // DEC_U8A_2, - {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4 "}, // DEC_U16A_2, + {D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT4 " }, // DEC_U16A_2, #endif }; @@ -219,6 +219,7 @@ static void LogDecFmtForDraw(const DecVtxFormat &decFmt) { //pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); } + static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &decFmt, u32 pspFmt) { auto vertexDeclCached = vertexDeclMap.find(pspFmt); @@ -271,13 +272,15 @@ static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &dec memcpy(VertexElement, &end, sizeof(D3DVERTEXELEMENT9)); // Create declaration - pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl ); + HRESULT hr = pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl ); + if (FAILED(hr)) { + // Log + LogDecFmtForDraw(decFmt); + // DebugBreak(); + } // Add it to map vertexDeclMap[pspFmt] = pHardwareVertexDecl; - - // Log - //LogDecFmtForDraw(decFmt); } else { // Set it from map pHardwareVertexDecl = vertexDeclCached->second; @@ -1135,23 +1138,25 @@ rotateVBO: DEBUG_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount); SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), dec_->VertexType()); - pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl); - if (vb_ == NULL) { - if (useElements) { - pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride); + if (pHardwareVertexDecl) { + pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl); + if (vb_ == NULL) { + if (useElements) { + pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride); + } else { + pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride); + } } else { - pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride); - } - } else { - pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride); + pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride); - if (useElements) { - pD3Ddevice->SetIndices(ib_); + if (useElements) { + pD3Ddevice->SetIndices(ib_); - pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount)); - } else { - pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount)); + pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount)); + } else { + pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount)); + } } } } else { diff --git a/native b/native index ff5df25135..1401de50dc 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit ff5df25135423a06357d5e455be19acfec81663f +Subproject commit 1401de50dca62f9084edbf50ff1b09f6ca06d8d4 From a758917919179b6bf8e0297197d36f759787246e Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 22 Aug 2014 22:16:46 +0200 Subject: [PATCH 06/13] D3d cleanups and improvements --- GPU/Directx9/StateMappingDX9.cpp | 4 +- GPU/Directx9/TextureCacheDX9.cpp | 90 ++----------------------------- GPU/Directx9/VertexDecoderDX9.cpp | 19 ++++--- GPU/Directx9/helper/dx_state.h | 42 +++++++++++++-- 4 files changed, 54 insertions(+), 101 deletions(-) diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 1b9f57c85d..9d1e4ef7f7 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -192,8 +192,8 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { } // At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow. - dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB); - dxstate.blendEquation.set(eqLookup[blendFuncEq]); + dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB, D3DBLEND_ONE, D3DBLEND_ZERO); + dxstate.blendEquation.set(eqLookup[blendFuncEq], D3DBLENDOP_ADD); } // Set Dither diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 12c26edad2..8ba556516d 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -569,9 +569,8 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int const u16_le *src = (const u16_le *)srcBuf; u16_le *dst = (u16_le *)dstBuf; for (int i = 0; i < numPixels; i++) { - // Already good format u16 rgb = src[i]; - dst[i] = (rgb & 0xF) | (rgb & 0xF0)<<8 | ( rgb & 0xF00) | ((rgb & 0xF000)>>8); + dst[i] = rgb; // (rgb & 0xF) | (rgb & 0xF0) << 8 | (rgb & 0xF00) | ((rgb & 0xF000) >> 8); } } break; @@ -721,7 +720,7 @@ void TextureCacheDX9::UpdateCurrentClut() { clutAlphaLinear_ = true; clutAlphaLinearColor_ = clut[15] & 0xFFF0; for (int i = 0; i < 16; ++i) { - if ((clut[i] & 0xf) != i) { + if ((clut[i] >> 12) != i) { clutAlphaLinear_ = false; break; } @@ -745,48 +744,6 @@ inline u32 TextureCacheDX9::GetCurrentClutHash() { return clutHash_; } -// #define DEBUG_TEXTURES - -#ifdef DEBUG_TEXTURES -bool SetDebugTexture() { - static const int highlightFrames = 30; - - static int numTextures = 0; - static int lastFrames = 0; - static int mostTextures = 1; - - if (lastFrames != gpuStats.numFlips) { - mostTextures = std::max(mostTextures, numTextures); - numTextures = 0; - lastFrames = gpuStats.numFlips; - } - - static GLuint solidTexture = 0; - - bool changed = false; - if (((gpuStats.numFlips / highlightFrames) % mostTextures) == numTextures) { - if (gpuStats.numFlips % highlightFrames == 0) { - NOTICE_LOG(G3D, "Highlighting texture # %d / %d", numTextures, mostTextures); - } - static const u32 solidTextureData[] = {0x99AA99FF}; - - if (solidTexture == 0) { - glGenTextures(1, &solidTexture); - glBindTexture(GL_TEXTURE_2D, solidTexture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, solidTextureData); - } else { - glBindTexture(GL_TEXTURE_2D, solidTexture); - } - changed = true; - } - - ++numTextures; - return changed; -} -#endif - void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry) { entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE; @@ -1409,12 +1366,13 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch, int srcfmt, int fmt, void * pSrc, void * pDst) { // Swap color + int y; switch(fmt) { case D3DFMT_R5G6B5: case D3DFMT_A4R4G4B4: case D3DFMT_A1R5G5B5: // Really needed ? - for(int y = 0; y < h; y++) { + for(y = 0; y < h; y++) { const u16 *src = (const u16 *)((u8*)pSrc + (w*2) * y); u16 *dst = (u16*)((u8*)pDst + pitch * y); memcpy(dst, src, w * sizeof(u16)); @@ -1423,23 +1381,13 @@ static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch // 32 bit texture case D3DFMT_A8R8G8B8: - for(int y = 0; y < h; y++) { + for(y = 0; y < h; y++) { const u32 *src = (const u32 *)((u8*)pSrc + (w*4) * y); u32 *dst = (u32*)((u8*)pDst + pitch * y); - - /* - // todo use memcpy - for(int x = 0; x < w; x++) { - unsigned int rgb = src[x]; - dst[x] = rgb; - } - */ memcpy(dst, src, w * sizeof(u32)); } break; - } - } void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages) { @@ -1505,37 +1453,9 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool rep entry.texture->UnlockRect(level); } - -//#ifdef _DEBUG -#if 0 - // Hack save to disk ... - char fname[256]; - int fmt = 0; - static int ipic = 0; - switch(dstFmt) { - case D3DFMT_A4R4G4B4: - fmt = 0x4444; - break; - case D3DFMT_A1R5G5B5: - fmt = 0x5551; - break; - case D3DFMT_R5G6B5: - fmt = 0x5650; - break; - case D3DFMT_A8R8G8B8: - fmt = 0x8888; - break; - default: - fmt = 0xDEAD; - break; - } - sprintf(fname, "game:\\pic\\pic.%02x.%04x.%08x.%08x.png", ipic++, fmt, entry.format, clutformat); - D3DXSaveTextureToFile(fname, D3DXIFF_PNG, entry.texture, NULL); -#endif } } -// Only used by Qt UI? bool TextureCacheDX9::DecodeTexture(u8* output, GPUgstate state) { OutputDebugStringA("TextureCache::DecodeTexture : FixMe\r\n"); diff --git a/GPU/Directx9/VertexDecoderDX9.cpp b/GPU/Directx9/VertexDecoderDX9.cpp index d60f51e506..66f1062b72 100644 --- a/GPU/Directx9/VertexDecoderDX9.cpp +++ b/GPU/Directx9/VertexDecoderDX9.cpp @@ -273,21 +273,20 @@ void VertexDecoderDX9::Step_Color4444() const { u8 *c = decoded_ + decFmt.c0off; u16 cdata = (u16)(*(u16_le*)(ptr_ + coloff)); - c[0] = Convert4To8((cdata >> (12)) & 0xF); - c[1] = Convert4To8((cdata >> (0)) & 0xF); - c[2] = Convert4To8((cdata >> (4)) & 0xF); - c[3] = Convert4To8((cdata >> (8)) & 0xF); + c[0] = Convert4To8((cdata >> (0)) & 0xF); + c[1] = Convert4To8((cdata >> (4)) & 0xF); + c[2] = Convert4To8((cdata >> (8)) & 0xF); + c[3] = Convert4To8((cdata >> (12)) & 0xF); } void VertexDecoderDX9::Step_Color8888() const { - // Directx want ARGB u8 *c = (u8*)(decoded_ + decFmt.c0off); const u8 *cdata = (const u8*)(ptr_ + coloff); - c[0] = cdata[3]; - c[1] = cdata[0]; - c[2] = cdata[1]; - c[3] = cdata[2]; + c[0] = cdata[0]; + c[1] = cdata[1]; + c[2] = cdata[2]; + c[3] = cdata[3]; } void VertexDecoderDX9::Step_Color565Morph() const @@ -864,7 +863,7 @@ void VertexDecoderDX9::SetVertexType(u32 fmt) { // The normal formats match the gl formats perfectly, let's use 'em. switch (nrm) { //case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S8_3; break; - case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break; + case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break; case GE_VTYPE_NRM_16BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S16_3; break; case GE_VTYPE_NRM_FLOAT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break; } diff --git a/GPU/Directx9/helper/dx_state.h b/GPU/Directx9/helper/dx_state.h index b6be350529..33ee5998e3 100644 --- a/GPU/Directx9/helper/dx_state.h +++ b/GPU/Directx9/helper/dx_state.h @@ -103,10 +103,44 @@ private: void restore() { // pD3Ddevice->SetRenderState(_state1, p1); // pD3Ddevice->SetRenderState(_state2, p2); - // pD3Ddevice->SetRenderState(_state3, p2); + // pD3Ddevice->SetRenderState(_state3, p3); } }; - + + template + class DxState4 { + D3DRENDERSTATETYPE _state1; + D3DRENDERSTATETYPE _state2; + D3DRENDERSTATETYPE _state3; + D3DRENDERSTATETYPE _state4; + DWORD p1; + DWORD p2; + DWORD p3; + DWORD p4; + public: + DxState4() : _state1(state1), _state2(state2), _state3(state3), _state4(state4), + p1(p1def), p2(p2def), p3(p3def), p4(p4def) { + // DirectxState::state_count++; + } + + inline void set(DWORD newp1, DWORD newp2, DWORD newp3, DWORD newp4) { + p1 = newp1; + p2 = newp2; + p3 = newp3; + p4 = newp4; + pD3Ddevice->SetRenderState(_state1, p1); + pD3Ddevice->SetRenderState(_state2, p2); + pD3Ddevice->SetRenderState(_state3, p3); + pD3Ddevice->SetRenderState(_state4, p4); + } + void restore() { + // pD3Ddevice->SetRenderState(_state1, p1); + // pD3Ddevice->SetRenderState(_state2, p2); + // pD3Ddevice->SetRenderState(_state3, p3); + // pD3Ddevice->SetRenderState(_state3, p4); + } + }; + class SavedBlendFactor { DWORD c; @@ -250,8 +284,8 @@ public: // When adding a state here, don't forget to add it to DirectxState::Restore() too BoolState blend; - DxState2 blendFunc; - DxState1 blendEquation; + DxState4 blendFunc; + DxState2 blendEquation; SavedBlendFactor blendColor; BoolState scissorTest; From 155623482503ed03065b97a958b92aa07ebfd77b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 01:52:46 +0200 Subject: [PATCH 07/13] Bit more d3d stuff. Can't get depth right, pretty sure it's the projection matrix calc. --- GPU/Directx9/FramebufferDX9.cpp | 16 +--- GPU/Directx9/ShaderManagerDX9.cpp | 22 ++--- GPU/Directx9/ShaderManagerDX9.h | 3 + GPU/Directx9/StateMappingDX9.cpp | 6 +- GPU/Directx9/TextureCacheDX9.cpp | 88 ++++++++------------ GPU/Directx9/TextureCacheDX9.h | 7 -- GPU/Directx9/VertexDecoderDX9.cpp | 4 +- GPU/Directx9/helper/dx_state.cpp | 13 ++- GPU/Directx9/helper/dx_state.h | 51 +++++++----- GPU/Directx9/helper/fbo.cpp | 130 ++++++------------------------ GPU/Directx9/helper/global.h | 7 +- UI/NativeApp.cpp | 10 ++- Windows/D3D9Base.cpp | 3 +- 13 files changed, 132 insertions(+), 228 deletions(-) diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index aa85937bf6..21d214c8bf 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -241,19 +241,6 @@ void FramebufferManagerDX9::DrawPixels(const u8 *framebuf, GEBufferFormat pixelF DrawActiveTexture(x, y, w, h, false, 480.0f / 512.0f); } -// Depth in ogl is between -1;1 we need between 0;1 -static void ConvertMatrices(Matrix4x4 & in) { - /* - in.zz *= 0.5f; - in.wz += 1.f; - */ - Matrix4x4 s; - Matrix4x4 t; - s.setScaling(Vec3(1, 1, 0.5f)); - t.setTranslation(Vec3(0, 0, 0.5f)); - in = in * s; - in = in * t; -} void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h, bool flip, float uscale, float vscale) { float u2 = uscale; @@ -269,9 +256,9 @@ void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h }; Matrix4x4 ortho; - ConvertMatrices(ortho); ortho.setOrtho(0, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0, -1, 1); + ConvertProjMatrixToD3D(ortho); //pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); pD3Ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); @@ -635,6 +622,7 @@ void FramebufferManagerDX9::CopyDisplayToOutput() { dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address); DisableState(); + fbo_bind_color_as_texture(vfb->fbo, 0); // These are in the output display coordinates diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 39e4bce998..f385dc108f 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -268,26 +268,17 @@ void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, void LinkedShaderDX9::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) { float m4x4[16]; ConvertMatrix4x3To4x4(m4x4, m4x3); - - if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4) == D3D_OK); - else - m_fs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4); + m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4); } void LinkedShaderDX9::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) { D3DXMATRIX * pDxMat = (D3DXMATRIX*)pMatrix; - - if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat) == D3D_OK); - else - m_fs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat); + m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat); } // Depth in ogl is between -1;1 we need between 0;1 -static void ConvertMatrices(Matrix4x4 & in) { - /* - in.zz *= 0.5f; - in.wz += 1.f; - */ +// Pretty sure this is wrong, our Z buffer is screwed up anyhow.. +void ConvertProjMatrixToD3D(Matrix4x4 & in) { Matrix4x4 s; Matrix4x4 t; s.setScaling(Vec3(1, 1, 0.5f)); @@ -297,7 +288,6 @@ static void ConvertMatrices(Matrix4x4 & in) { } void LinkedShaderDX9::use() { - updateUniforms(); pD3Ddevice->SetPixelShader(m_fs->shader); @@ -325,7 +315,7 @@ void LinkedShaderDX9::updateUniforms() { flippedMatrix[12] = -flippedMatrix[12]; } // Convert matrices ! - ConvertMatrices(flippedMatrix); + ConvertProjMatrixToD3D(flippedMatrix); SetMatrix(u_proj, flippedMatrix.getReadPtr()); } @@ -335,7 +325,7 @@ void LinkedShaderDX9::updateUniforms() { proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1); // Convert matrices ! - ConvertMatrices(proj_through); + ConvertProjMatrixToD3D(proj_through); SetMatrix(u_proj_through, proj_through.getReadPtr()); } diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index a318048d90..08278bdfd5 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -22,11 +22,14 @@ #include #include "GPU/Directx9/VertexShaderGeneratorDX9.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" +#include "thin3d/d3dx9_loader.h" +#include "math/lin/matrix4x4.h" namespace DX9 { class PSShader; class VSShader; +void ConvertProjMatrixToD3D(Matrix4x4 & in); class LinkedShaderDX9 { diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 9d1e4ef7f7..97633dde68 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -77,6 +77,11 @@ static const D3DCMPFUNC ztests[] = { D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_GREATER, D3DCMP_GREATEREQUAL, }; +static const D3DCMPFUNC ztests_backwards[] = { + D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_EQUAL, D3DCMP_NOTEQUAL, + D3DCMP_GREATER, D3DCMP_GREATEREQUAL, D3DCMP_LESS, D3DCMP_LESSEQUAL, +}; + static const D3DSTENCILOP stencilOps[] = { D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO, @@ -229,7 +234,6 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { } } else { - // Set cull bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); dxstate.cullMode.set(wantCull, gstate.getCullMode()); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 8ba556516d..8234ae32ce 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -25,6 +25,7 @@ #include "GPU/GPUState.h" #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/helper/dx_state.h" #include "GPU/Common/TextureDecoder.h" #include "Core/Config.h" #include "Core/Host.h" @@ -32,6 +33,7 @@ #include "ext/xxhash.h" #include "math/math_util.h" + extern int g_iNumVideos; namespace DX9 { @@ -75,12 +77,14 @@ void TextureCacheDX9::Clear(bool delete_them) { lastBoundTexture = INVALID_TEX; if (delete_them) { for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ++iter) { - DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture); - iter->second.texture->Release(); + DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture); + if (iter->second.texture) + iter->second.texture->Release(); } for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ++iter) { - DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture); - iter->second.texture->Release(); + DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture); + if (iter->second.texture) + iter->second.texture->Release(); } } if (cache.size() + secondCache.size()) { @@ -103,7 +107,8 @@ void TextureCacheDX9::Decimate() { int killAge = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE; for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ) { if (iter->second.lastFrame + killAge < gpuStats.numFlips) { - iter->second.texture->Release(); + if (iter->second.texture) + iter->second.texture->Release(); cache.erase(iter++); } else { ++iter; @@ -114,7 +119,8 @@ void TextureCacheDX9::Decimate() { for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ) { // In low memory mode, we kill them all. if (lowMemoryMode_ || iter->second.lastFrame + TEXTURE_KILL_AGE < gpuStats.numFlips) { - iter->second.texture->Release(); + if (iter->second.texture) + iter->second.texture->Release(); secondCache.erase(iter++); } else { ++iter; @@ -451,7 +457,7 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) { static const u8 texByteAlignMap[] = {2, 2, 2, 4}; -static const u32 MinFilt[8] = { +static const u8 MinFilt[8] = { D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_POINT, @@ -462,7 +468,7 @@ static const u32 MinFilt[8] = { D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, }; -static const u32 MipFilt[8] = { +static const u8 MipFilt[8] = { D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_POINT, @@ -473,13 +479,11 @@ static const u32 MipFilt[8] = { D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, }; -static const u32 MagFilt[2] = { +static const u8 MagFilt[2] = { D3DTEXF_POINT, D3DTEXF_LINEAR }; -// This should not have to be done per texture! OpenGL is silly yo -// TODO: Dirty-check this against the current texture. void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { int minFilt = gstate.texfilter & 0x7; int magFilt = (gstate.texfilter>>8) & 1; @@ -517,23 +521,11 @@ void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { minFilt &= 1; } - if (force || entry.minFilt != minFilt) { - pD3Ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, MinFilt[minFilt]); - pD3Ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, MipFilt[minFilt]); - entry.minFilt = minFilt; - } - if (force || entry.magFilt != magFilt) { - pD3Ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, MagFilt[magFilt]); - entry.magFilt = magFilt; - } - if (force || entry.sClamp != sClamp) { - pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); - entry.sClamp = sClamp; - } - if (force || entry.tClamp != tClamp) { - pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); - entry.tClamp = tClamp; - } + dxstate.texMinFilter.set(MinFilt[minFilt]); + dxstate.texMipFilter.set(MipFilt[minFilt]); + dxstate.texMagFilter.set(MagFilt[magFilt]); + dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); + dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); #ifdef _XBOX pD3Ddevice->SetRenderState(D3DRS_HALFPIXELOFFSET, TRUE ); @@ -570,7 +562,7 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int u16_le *dst = (u16_le *)dstBuf; for (int i = 0; i < numPixels; i++) { u16 rgb = src[i]; - dst[i] = rgb; // (rgb & 0xF) | (rgb & 0xF0) << 8 | (rgb & 0xF00) | ((rgb & 0xF000) >> 8); + dst[i] = ((rgb & 0xF) << 8) | (rgb & 0xF0F0) | ((rgb & 0xF00) >> 8); } } break; @@ -580,7 +572,7 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int u16 *dst = (u16 *)dstBuf; for (int i = 0; i < numPixels; i++) { u16 rgb = src[i]; - dst[i] = ((rgb & 0x1f) << 11) | ( rgb & 0x7e0) | ((rgb & 0xF800) >>11 ); + dst[i] = ((rgb & 0x1f) << 11) | (rgb & 0x7e0) | ((rgb & 0xF800) >> 11); } } break; @@ -725,7 +717,7 @@ void TextureCacheDX9::UpdateCurrentClut() { break; } // Alpha 0 doesn't matter. - if (i != 0 && (clut[i] & 0xFFF0) != clutAlphaLinearColor_) { + if (i != 0 && (clut[i] >> 12) != clutAlphaLinearColor_) { clutAlphaLinear_ = false; break; } @@ -1304,21 +1296,12 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm { const u32 *p = pixelData; for (int i = 0; i < (w * h + 1) / 2; ++i) { -#ifndef BIG_ENDIAN - u32 a = p[i] & 0x000F000F; - hitZeroAlpha |= a ^ 0x000F000F; - if (a != 0x000F000F && a != 0x0000000F && a != 0x000F0000 && a != 0) { - hitSomeAlpha = 1; - break; - } -#else u32 a = p[i] & 0xF000F000; hitZeroAlpha |= a ^ 0xF000F000; if (a != 0xF000F000 && a != 0x0000F000 && a != 0xF0000000 && a != 0) { hitSomeAlpha = 1; break; } -#endif } } break; @@ -1326,13 +1309,8 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm { const u32 *p = pixelData; for (int i = 0; i < (w * h + 1) / 2; ++i) { -#ifndef BIG_ENDIAN - u32 a = p[i] & 0x00010001; - hitZeroAlpha |= a ^ 0x00010001; -#else - u32 a = p[i] & 0x10001000; - hitZeroAlpha |= a ^ 0x10001000; -#endif + u32 a = p[i] & 0x80008000; + hitZeroAlpha |= a ^ 0x80008000; } } break; @@ -1442,16 +1420,20 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool rep } else { // Create texture #ifdef _XBOX - pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL); + HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL); #else - pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL); + HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL); #endif - D3DLOCKED_RECT rect; - entry.texture->LockRect(level, &rect, NULL, 0); + if (FAILED(hr)) { + INFO_LOG(G3D, "Failed to create D3D texture"); + } else { + D3DLOCKED_RECT rect; + entry.texture->LockRect(level, &rect, NULL, 0); - copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits); + copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits); - entry.texture->UnlockRect(level); + entry.texture->UnlockRect(level); + } } } } diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index e336aef9d0..a32d84aae0 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -106,13 +106,6 @@ private: int maxLevel; float lodBias; - // Cache the current filter settings so we can avoid setting it again. - // (OpenGL madness where filter settings are attached to each texture). - u8 magFilt; - u8 minFilt; - bool sClamp; - bool tClamp; - bool Matches(u16 dim2, u8 format2, int maxLevel2); }; diff --git a/GPU/Directx9/VertexDecoderDX9.cpp b/GPU/Directx9/VertexDecoderDX9.cpp index 66f1062b72..bc2227cdf8 100644 --- a/GPU/Directx9/VertexDecoderDX9.cpp +++ b/GPU/Directx9/VertexDecoderDX9.cpp @@ -283,9 +283,9 @@ void VertexDecoderDX9::Step_Color8888() const { u8 *c = (u8*)(decoded_ + decFmt.c0off); const u8 *cdata = (const u8*)(ptr_ + coloff); - c[0] = cdata[0]; + c[0] = cdata[2]; c[1] = cdata[1]; - c[2] = cdata[2]; + c[2] = cdata[0]; c[3] = cdata[3]; } diff --git a/GPU/Directx9/helper/dx_state.cpp b/GPU/Directx9/helper/dx_state.cpp index 115eaa27fa..1f3dc0eaf9 100644 --- a/GPU/Directx9/helper/dx_state.cpp +++ b/GPU/Directx9/helper/dx_state.cpp @@ -19,6 +19,7 @@ void DirectxState::Initialize() { void DirectxState::Restore() { int count = 0; + blend.restore(); count++; blendEquation.restore(); count++; blendFunc.restore(); count++; @@ -37,7 +38,8 @@ void DirectxState::Restore() { depthWrite.restore(); count++; colorMask.restore(); count++; - viewport.restore(); count++; + + // viewport.restore(); count++; stencilTest.restore(); count++; stencilOp.restore(); count++; @@ -45,7 +47,14 @@ void DirectxState::Restore() { dither.restore(); count++; - assert(count == state_count && "DirectxState::Restore is missing some states"); + texMinFilter.restore(); count++; + texMagFilter.restore(); count++; + texMipFilter.restore(); count++; + texAddressU.restore(); count++; + texAddressV.restore(); count++; + + + //assert(count == state_count && "DirectxState::Restore is missing some states"); } void CheckGLExtensions() { diff --git a/GPU/Directx9/helper/dx_state.h b/GPU/Directx9/helper/dx_state.h index 33ee5998e3..bb9b520578 100644 --- a/GPU/Directx9/helper/dx_state.h +++ b/GPU/Directx9/helper/dx_state.h @@ -55,6 +55,24 @@ private: } }; + template + class DxSampler0State1 { + D3DSAMPLERSTATETYPE _state1; + DWORD p1; + public: + DxSampler0State1() : _state1(state1), p1(p1def) { + DirectxState::state_count++; + } + + inline void set(DWORD newp1) { + p1 = newp1; + pD3Ddevice->SetSamplerState(0, _state1, p1); + } + void restore() { + pD3Ddevice->SetSamplerState(0, _state1, p1); + } + }; + template class DxState2 { D3DRENDERSTATETYPE _state1; @@ -101,9 +119,9 @@ private: pD3Ddevice->SetRenderState(_state3, p3); } void restore() { - // pD3Ddevice->SetRenderState(_state1, p1); - // pD3Ddevice->SetRenderState(_state2, p2); - // pD3Ddevice->SetRenderState(_state3, p3); + pD3Ddevice->SetRenderState(_state1, p1); + pD3Ddevice->SetRenderState(_state2, p2); + pD3Ddevice->SetRenderState(_state3, p3); } }; @@ -134,10 +152,10 @@ private: pD3Ddevice->SetRenderState(_state4, p4); } void restore() { - // pD3Ddevice->SetRenderState(_state1, p1); - // pD3Ddevice->SetRenderState(_state2, p2); - // pD3Ddevice->SetRenderState(_state3, p3); - // pD3Ddevice->SetRenderState(_state3, p4); + pD3Ddevice->SetRenderState(_state1, p1); + pD3Ddevice->SetRenderState(_state2, p2); + pD3Ddevice->SetRenderState(_state3, p3); + pD3Ddevice->SetRenderState(_state3, p4); } }; @@ -222,15 +240,6 @@ private: viewport.Y=y; viewport.Width=w; viewport.Height=h; - /* - if (f > n) { - viewport.MinZ=n; - viewport.MaxZ=f; - } else { - viewport.MinZ=f; - viewport.MaxZ=n; - } - */ viewport.MinZ=n; viewport.MaxZ=f; @@ -263,12 +272,10 @@ private: cull = D3DCULL_NONE; } else { // add front face ... - cull = cullmode==0?D3DCULL_CW:D3DCULL_CCW; + cull = cullmode==0 ? D3DCULL_CW:D3DCULL_CCW; } - pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull); } - inline void restore() { pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull); } @@ -309,6 +316,12 @@ public: DxState3 stencilOp; DxState3 stencilFunc; + DxSampler0State1 texMinFilter; + DxSampler0State1 texMagFilter; + DxSampler0State1 texMipFilter; + DxSampler0State1 texAddressU; + DxSampler0State1 texAddressV; + // Only works on Win32, all other platforms are "force-vsync" void SetVSyncInterval(int interval); // one of the above VSYNC, or a higher number for multi-frame waits (could be useful for 30hz games) }; diff --git a/GPU/Directx9/helper/fbo.cpp b/GPU/Directx9/helper/fbo.cpp index 21608f2e90..b4aad950b9 100644 --- a/GPU/Directx9/helper/fbo.cpp +++ b/GPU/Directx9/helper/fbo.cpp @@ -7,8 +7,6 @@ namespace DX9 { -static LPDIRECT3DSURFACE9 currentRtt; -static LPDIRECT3DSURFACE9 workingRtt; static LPDIRECT3DSURFACE9 deviceRTsurf; static LPDIRECT3DSURFACE9 deviceDSsurf; @@ -19,10 +17,6 @@ struct FBO { LPDIRECT3DSURFACE9 surf; LPDIRECT3DSURFACE9 depthstencil; LPDIRECT3DTEXTURE9 tex; - uint32_t color_texture; - uint32_t z_stencil_buffer; // Either this is set, or the two below. - uint32_t z_buffer; - uint32_t stencil_buffer; int width; int height; @@ -32,8 +26,11 @@ struct FBO { void fbo_init() { pD3Ddevice->GetRenderTarget(0, &deviceRTsurf); pD3Ddevice->GetDepthStencilSurface(&deviceDSsurf); +} - //pD3Ddevice->CreateRenderTarget(1280/FB_DIV, 720/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL); +void fbo_shutdown() { + deviceRTsurf->Release(); + deviceDSsurf->Release(); } FBO * current_fbo = NULL; @@ -47,91 +44,49 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F fbo->height = height; fbo->colorDepth = colorDepth; - // only support 32bit surfaces - //pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL); - - /* - // Create depth + stencil target | forced to 24-bit Z, 8-bit stencil - pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); - */ - // Only needed on xbox -#ifdef _XBOX - pD3Ddevice->CreateTexture(fbo->width/FB_DIV, fbo->height/FB_DIV, 1, 0, D3DFMT_A8R8G8B8, 0, &fbo->tex, NULL); - if (workingRtt == NULL) { - pD3Ddevice->CreateRenderTarget(fbo->width/FB_DIV, fbo->height/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL); - } -#else - HRESULT rtResult = pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL); + HRESULT rtResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL); if (FAILED(rtResult)) { ELOG("Failed to create render target"); + delete fbo; + return NULL; } + fbo->tex->GetSurfaceLevel(0, &fbo->surf); + HRESULT dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); if (FAILED(dsResult)) { ELOG("Failed to create depth buffer"); + fbo->surf->Release(); + fbo->tex->Release(); + delete fbo; + return NULL; } -#endif - fbo->stencil_buffer = 8; - fbo->z_buffer = 24; fbo->id = id++; return fbo; } +void fbo_destroy(FBO *fbo) { + fbo->tex->Release(); + fbo->surf->Release(); + fbo->depthstencil->Release(); + delete fbo; +} + void * fbo_get_rtt(FBO *fbo) { return fbo->tex; } void fbo_unbind() { - if (current_fbo != NULL) { - -#ifdef _XBOX - D3DVECTOR4 White = {0.0f, 0.0f, 0.0f, 0.0f}; - pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS|D3DRESOLVE_CLEARRENDERTARGET|D3DRESOLVE_CLEARDEPTHSTENCIL, NULL, - current_fbo->tex, NULL, 0, 0, &White, 0.0f, 0, NULL ); -#else - // TODO? -#endif - /* - pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, - current_fbo->tex, NULL, 0, 0, 0, 0.0f, 0, NULL ); - */ - //pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0); - } - - //pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0); - current_fbo = NULL; - pD3Ddevice->SetRenderTarget(0, deviceRTsurf); - //pD3Ddevice->SetDepthStencilSurface(deviceDSsurf); - - currentRtt = deviceRTsurf; + pD3Ddevice->SetDepthStencilSurface(deviceDSsurf); } void fbo_resolve(FBO *fbo) { - if (fbo && fbo->tex) { -#ifdef _XBOX - pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL ); -#else - // TODO? -#endif - } -#if 0 - // Hack save to disk ... - char fname[256]; - static int f = 0; - sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++); - D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL); - //strcat(fname, "\n"); - OutputDebugString(fname); -#endif } void fbo_bind_as_render_target(FBO *fbo) { - current_fbo = fbo; - pD3Ddevice->SetRenderTarget(0, workingRtt); - currentRtt = workingRtt; - //pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0); - //pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil); + pD3Ddevice->SetRenderTarget(0, fbo->surf); + pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil); } void fbo_bind_for_read(FBO *fbo) { @@ -139,37 +94,7 @@ void fbo_bind_for_read(FBO *fbo) { } void fbo_bind_color_as_texture(FBO *fbo, int color) { - -#if 0 - // Hack save to disk ... - char fname[256]; - static int f = 0; - sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++); - D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL); - //strcat(fname, "\n"); - OutputDebugString(fname); -#endif - //pD3Ddevice->SetRenderTarget(0, workingRtt); - //pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL ); - //pD3Ddevice->SetRenderTarget(0, currentRtt); - - //OutputDebugStringA("fbo_bind_color_as_texture: Fix me\r\n"); pD3Ddevice->SetTexture(0, fbo->tex); - //pD3Ddevice->SetTexture(0, NULL); -} - -void fbo_destroy(FBO *fbo) { - /* - fbo->depthstencil->Release(); - */ - //fbo->surf->Release(); -#ifdef _XBOX - fbo->tex->Release(); -#else - fbo->depthstencil->Release(); - fbo->surf->Release(); -#endif - delete fbo; } void fbo_get_dimensions(FBO *fbo, int *w, int *h) { @@ -177,11 +102,4 @@ void fbo_get_dimensions(FBO *fbo, int *w, int *h) { *h = fbo->height; } -void SwapBuffer() { - pD3Ddevice->Present(0, 0, 0, 0); - - // :s - //pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0 ,0), 0, 0); -} - -}; \ No newline at end of file +} \ No newline at end of file diff --git a/GPU/Directx9/helper/global.h b/GPU/Directx9/helper/global.h index 9c41d6128c..d863dddbfd 100644 --- a/GPU/Directx9/helper/global.h +++ b/GPU/Directx9/helper/global.h @@ -10,7 +10,8 @@ #endif #include -#include + +struct ID3DXConstantTable; namespace DX9 { @@ -23,8 +24,8 @@ 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); +bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, ID3DXConstantTable **pShaderTable); +bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, ID3DXConstantTable **pShaderTable); void DirectxInit(HWND window); #define D3DBLEND_UNK D3DSTENCILOP_FORCE_DWORD diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index a01fb95b32..49842bd860 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -83,7 +83,9 @@ #include "EmuScreen.h" #include "GameInfoCache.h" #include "HostTypes.h" - +#ifdef _WIN32 +#include "GPU/Directx9/helper/dx_state.h" +#endif #include "UI/OnScreenDisplay.h" #include "UI/MiscScreens.h" #include "UI/TiltEventProcessor.h" @@ -686,7 +688,9 @@ void NativeRender() { glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glstate.Restore(); } else { - // DirectxState::Restore(); + DX9::dxstate.depthWrite.set(true); + DX9::dxstate.colorMask.set(true, true, true, true); + DX9::dxstate.Restore(); } thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0); @@ -703,8 +707,6 @@ void NativeRender() { ui_draw2d.SetDrawMatrix(ortho); ui_draw2d_front.SetDrawMatrix(ortho); - // glsl_bind(UIShader_Get()); - screenManager->render(); if (screenManager->getUIContext()->Text()) { screenManager->getUIContext()->Text()->OncePerFrame(); diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index 49abb30be5..cc5ec15b10 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -8,6 +8,7 @@ #include "util/text/utf8.h" #include "i18n/i18n.h" +#include "Core/Config.h" #include "Windows/D3D9Base.h" #include "thin3d/thin3d.h" #include "thin3d/d3dx9_loader.h" @@ -89,7 +90,7 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { pp.hDeviceWindow = hWnd; pp.EnableAutoDepthStencil = true; pp.AutoDepthStencilFormat = D3DFMT_D24S8; - pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; hr = d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device); if (FAILED(hr)) { From 0f973a327604a2b55db4908b9f7354a5576cedf7 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 09:48:08 +0200 Subject: [PATCH 08/13] Get it running on Android again --- CMakeLists.txt | 1 - Core/Core.cpp | 6 ++++-- Core/HLE/sceKernelModule.cpp | 6 +++--- UI/MiscScreens.cpp | 2 -- UI/NativeApp.cpp | 10 +++++++++- android/jni/Android.mk | 1 - native | 2 +- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a9894ade5..8ee6c67856 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -762,7 +762,6 @@ set(NativeAppSource UI/TouchControlLayoutScreen.cpp UI/TouchControlVisibilityScreen.cpp UI/GamepadEmu.cpp - UI/UIShader.cpp UI/OnScreenDisplay.cpp UI/ControlMappingScreen.cpp UI/Store.cpp diff --git a/Core/Core.cpp b/Core/Core.cpp index e2fcf0c536..6520ea211d 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -152,19 +152,21 @@ void UpdateRunLoop() { } } +#if defined(USING_WIN_UI) + void GPU_SwapBuffers() { switch (g_Config.iGPUBackend) { case GPU_BACKEND_OPENGL: GL_SwapBuffers(); break; -#ifdef _WIN32 case GPU_BACKEND_DIRECT3D9: D3D9_SwapBuffers(); break; -#endif } } +#endif + void Core_RunLoop() { while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) { time_update(); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index f014f44495..1ff2515ecf 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1670,15 +1670,15 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) if (optionAddr) { lmoption = (SceKernelLMOption *)Memory::GetPointer(optionAddr); if (lmoption->position < PSP_SMEM_Low || lmoption->position > PSP_SMEM_HighAligned) { - ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position", name, lmoption->position); + ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (%i)", name, (int)lmoption->position); return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE; } if (lmoption->position == PSP_SMEM_LowAligned || lmoption->position == PSP_SMEM_HighAligned) { - ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name, lmoption->position); + ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name); return SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE; } if (lmoption->position == PSP_SMEM_Addr) { - ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name, lmoption->position); + ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name); return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED; } WARN_LOG_REPORT(LOADER, "sceKernelLoadModule: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 58b2ebc0ad..6384d70121 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -394,14 +394,12 @@ void LogoScreen::render() { UIScreen::render(); UIContext &dc = *screenManager()->getUIContext(); - int error = glGetError(); const Bounds &bounds = dc.GetBounds(); float xres = dc.GetBounds().w; float yres = dc.GetBounds().h; dc.Begin(); - error = glGetError(); float t = (float)frames_ / 60.0f; float alpha = t; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 49842bd860..27f80a85ef 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -467,11 +467,18 @@ void NativeInit(int argc, const char *argv[], void NativeInitGraphics() { FPU_SetFastMode(); +#ifndef _WIN32 + // Force backend to GL + g_Config.iGPUBackend = GPU_BACKEND_OPENGL; +#endif + if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) { thin3d = T3DCreateGLContext(); CheckGLExtensions(); } else { +#ifdef _WIN32 thin3d = D3D9_CreateThin3DContext(); +#endif } ui_draw2d.SetAtlas(&ui_atlas); @@ -688,9 +695,11 @@ void NativeRender() { glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glstate.Restore(); } else { +#ifdef _WIN32 DX9::dxstate.depthWrite.set(true); DX9::dxstate.colorMask.set(true, true, true, true); DX9::dxstate.Restore(); +#endif } thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0); @@ -901,7 +910,6 @@ void NativeResized() { #if defined(__APPLE__) && !defined(USING_QT_UI) static int dp_xres_old=dp_xres; if (dp_xres != dp_xres_old) { - UIShader_Init(); uiTexture->Load("ui_atlas.zim"); dp_xres_old = dp_xres; } diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 7a63066d4a..976eb95e05 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -286,7 +286,6 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/MainScreen.cpp \ $(SRC)/UI/MiscScreens.cpp \ $(SRC)/UI/Store.cpp \ - $(SRC)/UI/UIShader.cpp \ $(SRC)/UI/GamepadEmu.cpp \ $(SRC)/UI/GameInfoCache.cpp \ $(SRC)/UI/GameScreen.cpp \ diff --git a/native b/native index 1401de50dc..7708558c2f 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 1401de50dca62f9084edbf50ff1b09f6ca06d8d4 +Subproject commit 7708558c2f247dd4e8d874df9a05c414c3739bc8 From 0bed77ed0da4d9aa1973922f2e75fd7170575c67 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Aug 2014 01:20:26 -0700 Subject: [PATCH 09/13] Buildfix Linux. --- CMakeLists.txt | 3 +++ Qt/Native.pro | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ee6c67856..bacb74ee63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -896,6 +896,9 @@ add_library(native STATIC native/net/url.h native/profiler/profiler.cpp native/profiler/profiler.h + native/thin3d/thin3d.cpp + native/thin3d/thin3d.h + native/thin3d/thin3d_gl.cpp native/thread/prioritizedworkqueue.cpp native/thread/prioritizedworkqueue.h native/thread/threadutil.cpp diff --git a/Qt/Native.pro b/Qt/Native.pro index 6065e834c6..4b4968739d 100644 --- a/Qt/Native.pro +++ b/Qt/Native.pro @@ -94,6 +94,8 @@ SOURCES += $$P/native/audio/*.cpp \ $$P/native/math/fast/*.c \ $$P/native/net/*.cpp \ $$P/native/profiler/profiler.cpp \ + $$P/native/thin3d/thin3d.cpp \ + $$P/native/thin3d/thin3d_gl.cpp \ $$P/native/thread/*.cpp \ $$P/native/ui/*.cpp \ $$P/native/util/bits/*.cpp \ From 7f4758baae87f1b67449a5824fb675a1fe9c58b9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 10:20:57 +0200 Subject: [PATCH 10/13] Provide more info to thin3d d3d init --- Windows/D3D9Base.cpp | 11 ++++++----- native | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index cc5ec15b10..e8af6bef05 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -14,6 +14,7 @@ #include "thin3d/d3dx9_loader.h" static LPDIRECT3D9 d3d; +static int adapterId; static LPDIRECT3DDEVICE9 device; static HDC hDC; // Private GDI Device Context static HGLRC hRC; // Permanent Rendering Context @@ -31,7 +32,7 @@ void D3D9_SwapBuffers() { } Thin3DContext *D3D9_CreateThin3DContext() { - return T3DCreateDX9Context(device); + return T3DCreateDX9Context(d3d, adapterId, device); } bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { @@ -54,8 +55,8 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { return false; } - int adapter = D3DADAPTER_DEFAULT; - if (FAILED(d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &d3dCaps))) { + adapterId = D3DADAPTER_DEFAULT; + if (FAILED(d3d->GetDeviceCaps(adapterId, D3DDEVTYPE_HAL, &d3dCaps))) { d3d->Release(); return false; } @@ -90,9 +91,9 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { pp.hDeviceWindow = hWnd; pp.EnableAutoDepthStencil = true; pp.AutoDepthStencilFormat = D3DFMT_D24S8; - pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - hr = d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device); + hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device); if (FAILED(hr)) { ELOG("Failed to create D3D device"); d3d->Release(); diff --git a/native b/native index 7708558c2f..6f96004381 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 7708558c2f247dd4e8d874df9a05c414c3739bc8 +Subproject commit 6f96004381895365cfe0d748bd8c8805aa472a0a From 4231af2c0f70b21bb346f3430c20b006abc9af47 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 10:47:32 +0200 Subject: [PATCH 11/13] Disable OpenGL debug log output --- Windows/OpenGLBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index f9694b3836..a3c9e5c839 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -15,7 +15,7 @@ static HWND hWnd; // Holds Our Window Handle static int xres, yres; // TODO: Make config? -static bool enableGLDebug = true; +static bool enableGLDebug = false; void GL_SwapBuffers() { SwapBuffers(hDC); From 308b13fdf080329c402cb795a26172d0adaf9706 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 10:49:40 +0200 Subject: [PATCH 12/13] Set the right ortho matrix for the backend (although doesn't seem to matter too much for 2D) --- UI/NativeApp.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 27f80a85ef..e2b9434e92 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -710,8 +710,11 @@ 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.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) { + ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + } else { + ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); + } ui_draw2d.SetDrawMatrix(ortho); ui_draw2d_front.SetDrawMatrix(ortho); From 7ae886afa9e13ae875c8fe2a91937bda347dcc17 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Aug 2014 10:51:47 +0200 Subject: [PATCH 13/13] Update native --- native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native b/native index 6f96004381..467599cf56 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 6f96004381895365cfe0d748bd8c8805aa472a0a +Subproject commit 467599cf5655625aa7fe8c9c409624a131cdd6bd