CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Windows/GPU/D3D9Context.cpp
Views: 1401
#include "ppsspp_config.h"12#include "Common/CommonWindows.h"3#include <d3d9.h>45#include "Common/GPU/D3D9/D3D9StateCache.h"67#include "Common/System/Display.h"8#include "Common/Data/Encoding/Utf8.h"9#include "Common/Data/Text/I18n.h"10#include "Common/Log.h"11#include "Common/OSVersion.h"1213#include "Core/Config.h"14#include "Core/ConfigValues.h"15#include "Core/System.h"16#include "Common/OSVersion.h"17#include "Windows/GPU/D3D9Context.h"18#include "Windows/W32Util/Misc.h"19#include "Common/GPU/thin3d.h"20#include "Common/GPU/thin3d_create.h"21#include "Common/GPU/D3D9/D3DCompilerLoader.h"2223typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);2425bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {26bool windowed = true;27hWnd_ = wnd;2829// D3D9 has no need for display rotation.30g_display.rotation = DisplayRotation::ROTATE_0;31g_display.rot_matrix.setIdentity();3233DIRECT3DCREATE9EX g_pfnCreate9ex;3435hD3D9_ = LoadLibrary(TEXT("d3d9.dll"));36if (!hD3D9_) {37ERROR_LOG(Log::G3D, "Missing d3d9.dll");38*error_message = "D3D9.dll missing - try reinstalling DirectX.";39return false;40}4142bool result = LoadD3DCompilerDynamic();43if (!result) {44*error_message = "D3DCompiler not found! Try reinstalling DirectX.";45return false;46}4748g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex");49has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher();5051if (has9Ex_) {52HRESULT result = g_pfnCreate9ex(D3D_SDK_VERSION, &d3dEx_);53d3d_ = d3dEx_;54if (FAILED(result)) {55FreeLibrary(hD3D9_);56*error_message = "D3D9Ex available but context creation failed. Try reinstalling DirectX.";57return false;58}59} else {60d3d_ = Direct3DCreate9(D3D_SDK_VERSION);61if (!d3d_) {62FreeLibrary(hD3D9_);63*error_message = "Failed to create D3D9 context. Try reinstalling DirectX.";64return false;65}66}67adapterId_ = D3DADAPTER_DEFAULT;6869D3DCAPS9 d3dCaps;7071D3DDISPLAYMODE d3ddm;72if (FAILED(d3d_->GetAdapterDisplayMode(adapterId_, &d3ddm))) {73*error_message = "GetAdapterDisplayMode failed";74d3d_ = nullptr;75return false;76}7778if (FAILED(d3d_->GetDeviceCaps(adapterId_, D3DDEVTYPE_HAL, &d3dCaps))) {79*error_message = "GetDeviceCaps failed (?)";80d3d_ = nullptr;81return false;82}8384HRESULT hr;85if (FAILED(hr = d3d_->CheckDeviceFormat(adapterId_,86D3DDEVTYPE_HAL,87d3ddm.Format,88D3DUSAGE_DEPTHSTENCIL,89D3DRTYPE_SURFACE,90D3DFMT_D24S8))) {91if (hr == D3DERR_NOTAVAILABLE) {92*error_message = "D24S8 depth/stencil not available";93d3d_ = nullptr;94return false;95}96}9798DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE;99if (d3dCaps.VertexProcessingCaps != 0)100dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;101else102dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;103104int xres, yres;105W32Util::GetWindowRes(hWnd_, &xres, &yres);106107presentParams_ = {};108presentParams_.BackBufferWidth = xres;109presentParams_.BackBufferHeight = yres;110presentParams_.BackBufferFormat = d3ddm.Format;111presentParams_.MultiSampleType = D3DMULTISAMPLE_NONE;112presentParams_.SwapEffect = D3DSWAPEFFECT_DISCARD;113presentParams_.Windowed = windowed;114presentParams_.hDeviceWindow = wnd;115presentParams_.EnableAutoDepthStencil = true;116presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;117presentParams_.PresentationInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;118119if (has9Ex_) {120if (windowed && IsWin7OrHigher()) {121// This "new" flip mode should give higher performance but doesn't.122//pp.BackBufferCount = 2;123//pp.SwapEffect = D3DSWAPEFFECT_FLIPEX;124}125hr = d3dEx_->CreateDeviceEx(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, NULL, &deviceEx_);126device_ = deviceEx_;127} else {128hr = d3d_->CreateDevice(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, &device_);129}130131if (FAILED(hr)) {132*error_message = "Failed to create D3D device";133d3d_ = nullptr;134return false;135}136137device_->BeginScene();138pD3Ddevice9 = device_;139pD3DdeviceEx9 = deviceEx_;140141if (deviceEx_ && IsWin7OrHigher()) {142// TODO: This makes it slower?143//deviceEx->SetMaximumFrameLatency(1);144}145draw_ = Draw::T3DCreateDX9Context(d3d_.Get(), d3dEx_.Get(), adapterId_, device_.Get(), deviceEx_.Get());146SetGPUBackend(GPUBackend::DIRECT3D9);147if (!draw_->CreatePresets()) {148// Shader compiler not installed? Return an error so we can fall back to GL.149device_ = nullptr;150d3d_ = nullptr;151*error_message = "DirectX9 runtime not correctly installed. Please install.";152return false;153}154if (draw_)155draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);156return true;157}158159void D3D9Context::Resize() {160// This should only be called from the emu thread.161int xres, yres;162W32Util::GetWindowRes(hWnd_, &xres, &yres);163uint32_t newInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;164bool w_changed = presentParams_.BackBufferWidth != xres;165bool h_changed = presentParams_.BackBufferHeight != yres;166bool i_changed = presentParams_.PresentationInterval != newInterval;167168if (device_ && (w_changed || h_changed || i_changed)) {169draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);170presentParams_.BackBufferWidth = xres;171presentParams_.BackBufferHeight = yres;172presentParams_.PresentationInterval = newInterval;173HRESULT hr = device_->Reset(&presentParams_);174if (FAILED(hr)) {175// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.176_assert_msg_(false, "Unable to reset D3D9 device");177}178draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);179}180}181182void D3D9Context::Shutdown() {183draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);184delete draw_;185draw_ = nullptr;186device_->EndScene();187device_ = nullptr;188d3d_ = nullptr;189UnloadD3DCompiler();190pD3Ddevice9 = nullptr;191pD3DdeviceEx9 = nullptr;192device_ = nullptr;193hWnd_ = nullptr;194FreeLibrary(hD3D9_);195hD3D9_ = nullptr;196}197198199