diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 06f78162d6..9121e630b4 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -114,8 +114,8 @@ bool WindowsHost::InitGraphics(std::string *error_message, GraphicsContext **ctx graphicsContext = new D3D9Context(); break; case GPU_BACKEND_VULKAN: - graphicsContext = new WindowsVulkanContext(); - break; + graphicsContext = new WindowsVulkanContext(); + break; default: return false; } diff --git a/headless/Headless.cpp b/headless/Headless.cpp index eba3ffca29..630c1bd39b 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -25,9 +25,7 @@ #include "Compare.h" #include "StubHost.h" #ifdef _WIN32 -#include "Windows/GPU/WindowsGLContext.h" #include "WindowsHeadlessHost.h" -#include "WindowsHeadlessHostDx9.h" #endif // https://github.com/richq/android-ndk-profiler @@ -120,10 +118,6 @@ static HeadlessHost *getHost(GPUCore gpuCore) { switch (gpuCore) { case GPU_NULL: return new HeadlessHost(); -#ifdef _WIN32 - case GPU_DIRECTX9: - return new WindowsHeadlessHostDx9(); -#endif #ifdef HEADLESSHOST_CLASS default: return new HEADLESSHOST_CLASS(); @@ -258,6 +252,8 @@ int main(int argc, const char* argv[]) gpuCore = GPU_SOFTWARE; else if (!strcasecmp(gpuName, "directx9")) gpuCore = GPU_DIRECTX9; + else if (!strcasecmp(gpuName, "vulkan")) + gpuCore = GPU_VULKAN; else if (!strcasecmp(gpuName, "null")) gpuCore = GPU_NULL; else @@ -295,10 +291,10 @@ int main(int argc, const char* argv[]) return printUsage(argv[0], argc <= 1 ? NULL : "No executables specified"); HeadlessHost *headlessHost = getHost(gpuCore); + headlessHost->SetGraphicsCore(gpuCore); host = headlessHost; std::string error_string; - GraphicsContext *graphicsContext; bool glWorking = host->InitGraphics(&error_string, &graphicsContext); diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index cdf062c374..c1ae2d41fa 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -225,6 +225,10 @@ + + + + NotUsing @@ -233,7 +237,6 @@ NotUsing - @@ -267,9 +270,8 @@ - - + \ No newline at end of file diff --git a/headless/Headless.vcxproj.filters b/headless/Headless.vcxproj.filters index fd3ee83d54..d699015802 100644 --- a/headless/Headless.vcxproj.filters +++ b/headless/Headless.vcxproj.filters @@ -2,11 +2,24 @@ - - + + Windows + + + Windows + + + Windows + + + Windows + + + Windows + @@ -14,9 +27,15 @@ - - + + Windows + + + + + {28215e85-3e11-4a8a-8b4d-3e355b85a542} + \ No newline at end of file diff --git a/headless/StubHost.h b/headless/StubHost.h index d12ca57099..78e9b1a15f 100644 --- a/headless/StubHost.h +++ b/headless/StubHost.h @@ -17,6 +17,7 @@ #pragma once +#include "Core/CoreParameter.h" #include "Core/Host.h" #include "Core/Debugger/SymbolMap.h" @@ -30,6 +31,7 @@ public: void SetDebugMode(bool mode) { } + void SetGraphicsCore(GPUCore core) { gpuCore_ = core; } bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override {return false;} void ShutdownGraphics() override {} @@ -70,4 +72,5 @@ public: protected: std::string debugOutputBuffer_; + GPUCore gpuCore_; }; \ No newline at end of file diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index e2e776f21c..55a9b39de5 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -28,6 +28,8 @@ #include "GPU/Common/GPUDebugInterface.h" #include "GPU/GPUState.h" #include "Windows/GPU/WindowsGLContext.h" +#include "Windows/GPU/D3D9Context.h" +#include "Windows/GPU/WindowsVulkanContext.h" #include "base/logging.h" #include "gfx/gl_common.h" @@ -141,79 +143,68 @@ void WindowsHeadlessHost::SetComparisonScreenshot(const std::string &filename) comparisonScreenshot = filename; } -bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **graphicsContext) -{ +bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **ctx) { hWnd = CreateHiddenWindow(); - if (WINDOW_VISIBLE) - { + if (WINDOW_VISIBLE) { ShowWindow(hWnd, TRUE); SetFocus(hWnd); } - int pixelFormat; + WindowsGraphicsContext *graphicsContext = nullptr; + switch (gpuCore_) { + case GPU_NULL: + case GPU_GLES: + case GPU_SOFTWARE: + graphicsContext = new WindowsGLContext(); + break; - static PIXELFORMATDESCRIPTOR pfd = {0}; - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 32; - pfd.cDepthBits = 16; - pfd.iLayerType = PFD_MAIN_PLANE; + case GPU_DIRECTX9: + graphicsContext = new D3D9Context(); + break; -#define ENFORCE(x, msg) { if (!(x)) { fprintf(stderr, msg); *error_message = msg; return false; } } + case GPU_DIRECTX11: + return false; - ENFORCE(hDC = GetDC(hWnd), "Unable to create DC."); - ENFORCE(pixelFormat = ChoosePixelFormat(hDC, &pfd), "Unable to match pixel format."); - ENFORCE(SetPixelFormat(hDC, pixelFormat, &pfd), "Unable to set pixel format."); - ENFORCE(hRC = wglCreateContext(hDC), "Unable to create GL context."); - ENFORCE(wglMakeCurrent(hDC, hRC), "Unable to activate GL context."); + case GPU_VULKAN: + graphicsContext = new WindowsVulkanContext(); + break; + } - // GL_SwapInterval(0); + if (graphicsContext->Init(NULL, hWnd, error_message)) { + *ctx = graphicsContext; + gfx_ = graphicsContext; + } else { + delete graphicsContext; + *ctx = nullptr; + gfx_ = nullptr; + return false; + } - glewInit(); - CheckGLExtensions(); + if (gpuCore_ == GPU_GLES) { + // TODO: Do we need to do this here? + CheckGLExtensions(); + } LoadNativeAssets(); - *graphicsContext = new DummyGraphicsContext(); - return ResizeGL(); + return true; } -void WindowsHeadlessHost::ShutdownGraphics() -{ - if (hRC) { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hRC); - hRC = NULL; - } - - if (hDC) - ReleaseDC(hWnd, hDC); - hDC = NULL; +void WindowsHeadlessHost::ShutdownGraphics() { + gfx_->Shutdown(); + delete gfx_; + gfx_ = nullptr; DestroyWindow(hWnd); hWnd = NULL; } -bool WindowsHeadlessHost::ResizeGL() -{ - if (!hWnd) - return false; - - RECT rc; - GetWindowRect(hWnd, &rc); - - glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 0.0f, -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - return true; -} - -void WindowsHeadlessHost::SwapBuffers() -{ - ::SwapBuffers(hDC); +void WindowsHeadlessHost::SwapBuffers() { + if (gpuCore_ == GPU_DIRECTX9) { + MSG msg; + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + TranslateMessage(&msg); + DispatchMessage(&msg); + } + gfx_->SwapBuffers(); } diff --git a/headless/WindowsHeadlessHost.h b/headless/WindowsHeadlessHost.h index 7e968fb9fb..088e7935da 100644 --- a/headless/WindowsHeadlessHost.h +++ b/headless/WindowsHeadlessHost.h @@ -38,12 +38,12 @@ public: virtual void SetComparisonScreenshot(const std::string &filename) override; protected: - virtual bool ResizeGL(); void LoadNativeAssets(); void SendOrCollectDebugOutput(const std::string &output); HWND hWnd; HDC hDC; HGLRC hRC; + GraphicsContext *gfx_; std::string comparisonScreenshot; }; \ No newline at end of file diff --git a/headless/WindowsHeadlessHostDx9.cpp b/headless/WindowsHeadlessHostDx9.cpp deleted file mode 100644 index b110d69a7a..0000000000 --- a/headless/WindowsHeadlessHostDx9.cpp +++ /dev/null @@ -1,101 +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 "WindowsHeadlessHostDx9.h" -#include "Compare.h" - -#include -#include "Common/CommonWindows.h" -#include - -#include "base/logging.h" -#include "thin3d/d3dx9_loader.h" -#include "GPU/Directx9/helper/global.h" -#include "GPU/Directx9/helper/dx_fbo.h" -#include "file/vfs.h" -#include "file/zip_read.h" - -const bool WINDOW_VISIBLE = false; -const int WINDOW_WIDTH = 480; -const int WINDOW_HEIGHT = 272; - -HWND DxCreateWindow() { - static WNDCLASSEX wndClass = { - sizeof(WNDCLASSEX), - CS_HREDRAW | CS_VREDRAW | CS_OWNDC, - DefWindowProc, - 0, - 0, - NULL, - NULL, - LoadCursor(NULL, IDC_ARROW), - (HBRUSH) GetStockObject(BLACK_BRUSH), - NULL, - _T("PPSSPPHeadless"), - NULL, - }; - RegisterClassEx(&wndClass); - - RECT wr = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; // set the size, but not the position - AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); // adjust the size - - DWORD style = WS_OVERLAPPEDWINDOW | (WINDOW_VISIBLE ? WS_VISIBLE : 0); - return CreateWindowEx(0, _T("PPSSPPHeadless"), _T("PPSSPPHeadless"), style, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, NULL, NULL); -} - -bool WindowsHeadlessHostDx9::InitGraphics(std::string *error_message, GraphicsContext **graphicsContext) { - *graphicsContext = nullptr; - LoadD3DX9Dynamic(); - hWnd = DxCreateWindow(); - - if (WINDOW_VISIBLE) { - ShowWindow(hWnd, TRUE); - SetFocus(hWnd); - } - - DX9::DirectxInit(hWnd); - - LoadNativeAssets(); - - DX9::pD3Ddevice->BeginScene(); - - return true; -} - -void WindowsHeadlessHostDx9::ShutdownGraphics() { - DX9::DestroyShaders(); - DX9::fbo_shutdown(); - DX9::pD3Ddevice->EndScene(); - DX9::pD3Ddevice->Release(); - DX9::pD3Ddevice = NULL; - hWnd = NULL; -} - -bool WindowsHeadlessHostDx9::ResizeGL() { - return true; -} - -void WindowsHeadlessHostDx9::SwapBuffers() { - MSG msg; - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - TranslateMessage(&msg); - DispatchMessage(&msg); - - DX9::pD3Ddevice->EndScene(); - DX9::pD3Ddevice->Present(0, 0, 0, 0); - DX9::pD3Ddevice->BeginScene(); -} diff --git a/headless/WindowsHeadlessHostDx9.h b/headless/WindowsHeadlessHostDx9.h deleted file mode 100644 index 29966ec756..0000000000 --- a/headless/WindowsHeadlessHostDx9.h +++ /dev/null @@ -1,39 +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 "StubHost.h" -#include "WindowsHeadlessHost.h" - -#undef HEADLESSHOST_CLASS -#define HEADLESSHOST_CLASS WindowsHeadlessHost - -#include "Common/CommonWindows.h" - -// TODO: Get rid of this junk -class WindowsHeadlessHostDx9 : public WindowsHeadlessHost -{ -public: - bool InitGraphics(std::string *error_message, GraphicsContext **graphicsContext) override; - void ShutdownGraphics() override; - - void SwapBuffers() override; - -private: - bool ResizeGL() override; -}; \ No newline at end of file