diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 8c6bb70c44..6f9814691b 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -129,7 +129,17 @@ namespace DX9 { // by themselves. ClearBuffer(); // TODO: Check / use D3DCAPS2_DYNAMICTEXTURES? - pD3Ddevice->CreateTexture(512, 272, 1, 0, D3DFMT(D3DFMT_A8R8G8B8), D3DPOOL_MANAGED, &drawPixelsTex_, NULL); + int usage = 0; + D3DPOOL pool = D3DPOOL_MANAGED; + if (pD3DdeviceEx) { + pool = D3DPOOL_DEFAULT; + usage = D3DUSAGE_DYNAMIC; + } + HRESULT hr = pD3Ddevice->CreateTexture(512, 272, 1, usage, D3DFMT(D3DFMT_A8R8G8B8), pool, &drawPixelsTex_, NULL); + if (!hr) { + drawPixelsTex_ = nullptr; + ERROR_LOG(G3D, "Failed to create drawpixels texture"); + } useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; } @@ -158,6 +168,10 @@ namespace DX9 { u8 * convBuf = NULL; D3DLOCKED_RECT rect; + if (!drawPixelsTex_) { + return; + } + drawPixelsTex_->LockRect(0, &rect, NULL, 0); convBuf = (u8*)rect.pBits; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 6ca63c6ae8..a6e39c575d 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -1632,7 +1632,13 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool rep pD3Ddevice->SetTexture(0, entry.texture); } else { // Create texture - HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL); + D3DPOOL pool = D3DPOOL_MANAGED; + int usage = 0; + if (pD3DdeviceEx) { + pool = D3DPOOL_DEFAULT; + usage = D3DUSAGE_DYNAMIC; // TODO: Switch to using a staging texture? + } + HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, usage, (D3DFORMAT)D3DFMT(dstFmt), pool, &entry.texture, NULL); if (FAILED(hr)) { INFO_LOG(G3D, "Failed to create D3D texture"); } else { diff --git a/GPU/Directx9/VertexDecoderDX9.cpp b/GPU/Directx9/VertexDecoderDX9.cpp index 44e3f04eb5..5cd7a9aa19 100644 --- a/GPU/Directx9/VertexDecoderDX9.cpp +++ b/GPU/Directx9/VertexDecoderDX9.cpp @@ -107,7 +107,7 @@ void VertexDecoderDX9::Step_WeightsU16() const wt[j] *= (1.0f/65535.f); } while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0; + wt[j++] = 0.0f; #else u16 *wt = (u16 *)(decoded_ + decFmt.w0off); const u16_le *wdata = (const u16_le*)(ptr_); @@ -124,26 +124,14 @@ void VertexDecoderDX9::Step_WeightsU16() const // (PSP uses 0.0-2.0 fixed point numbers for weights) void VertexDecoderDX9::Step_WeightsFloat() const { -#if 0 - float *wt = (float *)(decoded_ + decFmt.w0off); - const float_le *wdata = (const float_le*)(ptr_); - int j; - for (j = 0; j < nweights; j++) { - wt[j] = wdata[j]; - } - while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0.0f; -#else - float *wt = (float *)(decoded_ + decFmt.w0off); - u32 *st = (u32 *)wt; + u32 *st = (u32 *)(decoded_ + decFmt.w0off); const u32_le *wdata = (const u32_le*)(ptr_); int j; for (j = 0; j < nweights; j++) { st[j] = wdata[j]; } while (j & 3) // Zero additional weights rounding up to 4. - wt[j++] = 0.0f; -#endif + st[j++] = 0; } void VertexDecoderDX9::Step_TcU8() const diff --git a/GPU/Directx9/helper/global.cpp b/GPU/Directx9/helper/global.cpp index e8fa5fa70e..97d42647d5 100644 --- a/GPU/Directx9/helper/global.cpp +++ b/GPU/Directx9/helper/global.cpp @@ -5,6 +5,7 @@ namespace DX9 { LPDIRECT3DDEVICE9 pD3Ddevice = NULL; +LPDIRECT3DDEVICE9EX pD3DdeviceEx = NULL; LPDIRECT3D9 pD3D = NULL; static const char * vscode = diff --git a/GPU/Directx9/helper/global.h b/GPU/Directx9/helper/global.h index abb52aa4bc..cc0a37f1b1 100644 --- a/GPU/Directx9/helper/global.h +++ b/GPU/Directx9/helper/global.h @@ -17,6 +17,7 @@ struct ID3DXConstantTable; namespace DX9 { extern LPDIRECT3DDEVICE9 pD3Ddevice; +extern LPDIRECT3DDEVICE9EX pD3DdeviceEx; extern LPDIRECT3DVERTEXSHADER9 pFramebufferVertexShader; // Vertex Shader extern LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader; // Pixel Shader diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 46955b31dc..4113e0dad1 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -360,34 +360,34 @@ public: yAxis_(yAxis), yDevice_(yDevice), curX_(0.0f), curY_(0.0f), maxCount_(500) {} - void Draw(UIContext &dc) override; - void Update(const InputState &input_state) override; - void Axis(const AxisInput &input) { - if (input.axisId == xAxis_) { - curX_ = input.value; - } else if (input.axisId == yAxis_) { - curY_ = input.value; - } - } - -private: - struct Location { - Location() : x(0.0f), y(0.0f) {} - Location(float xx, float yy) : x(xx), y(yy) {} - float x; - float y; - }; - - int xAxis_; - int yAxis_; - int xDevice_; - int yDevice_; - - float curX_; - float curY_; - - std::deque locations_; - int maxCount_; + void Draw(UIContext &dc) override; + void Update(const InputState &input_state) override; + void Axis(const AxisInput &input) { + if (input.axisId == xAxis_) { + curX_ = input.value; + } else if (input.axisId == yAxis_) { + curY_ = input.value; + } + } + +private: + struct Location { + Location() : x(0.0f), y(0.0f) {} + Location(float xx, float yy) : x(xx), y(yy) {} + float x; + float y; + }; + + int xAxis_; + int yAxis_; + int xDevice_; + int yDevice_; + + float curX_; + float curY_; + + std::deque locations_; + int maxCount_; }; void JoystickHistoryView::Draw(UIContext &dc) { diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index 4823a1ebaf..04c62eb5ae 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -13,9 +13,12 @@ #include "thin3d/thin3d.h" #include "thin3d/d3dx9_loader.h" +static bool has9Ex = false; static LPDIRECT3D9 d3d; +static LPDIRECT3D9EX d3dEx; static int adapterId; static LPDIRECT3DDEVICE9 device; +static LPDIRECT3DDEVICE9EX deviceEx; static HDC hDC; // Private GDI Device Context static HGLRC hRC; // Permanent Rendering Context static HWND hWnd; // Holds Our Window Handle @@ -26,27 +29,57 @@ static int xres, yres; static bool enableGLDebug = true; void D3D9_SwapBuffers() { - device->EndScene(); - device->Present(NULL, NULL, NULL, NULL); - device->BeginScene(); + if (has9Ex) { + deviceEx->EndScene(); + deviceEx->PresentEx(NULL, NULL, NULL, NULL, 0); + deviceEx->BeginScene(); + } else { + device->EndScene(); + device->Present(NULL, NULL, NULL, NULL); + device->BeginScene(); + } } Thin3DContext *D3D9_CreateThin3DContext() { - return T3DCreateDX9Context(d3d, adapterId, device); + return T3DCreateDX9Context(d3d, d3dEx, adapterId, device, deviceEx); +} + +typedef HRESULT (*DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**); + +bool IsWin7OrLater() { + DWORD version = GetVersion(); + DWORD major = (DWORD)(LOBYTE(LOWORD(version))); + DWORD minor = (DWORD)(HIBYTE(LOWORD(version))); + + return (major > 6) || ((major == 6) && (minor >= 1)); } 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; + DIRECT3DCREATE9EX g_pfnCreate9ex; + + HMODULE hD3D9 = LoadLibrary(TEXT("d3d9.dll")); + g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9, "Direct3DCreate9Ex"); + has9Ex = (g_pfnCreate9ex != NULL); + FreeLibrary(hD3D9); + + // For some reason, can't quite get Ex to work right.. + // has9Ex = false; + + if (has9Ex) { + HRESULT result = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3dEx); + d3d = d3dEx; + if (FAILED(result)) { + ELOG("Failed to create D3D9Ex context"); + return false; + } + } else { + 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; @@ -80,6 +113,11 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { else dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; + RECT rc; + GetClientRect(hWnd, &rc); + int xres = rc.right - rc.left; + int yres = rc.bottom - rc.top; + D3DPRESENT_PARAMETERS pp; memset(&pp, 0, sizeof(pp)); pp.BackBufferWidth = xres; @@ -93,21 +131,41 @@ bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) { pp.AutoDepthStencilFormat = D3DFMT_D24S8; pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device); + if (has9Ex) { + if (windowed && IsWin7OrLater()) { + // This new flip mode gives higher performance. + pp.BackBufferCount = 2; + pp.SwapEffect = D3DSWAPEFFECT_FLIPEX; + } + hr = d3dEx->CreateDeviceEx(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, NULL, &deviceEx); + device = deviceEx; + } else { + hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device); + } + if (FAILED(hr)) { ELOG("Failed to create D3D device"); - d3d->Release(); + if (has9Ex) { + d3dEx->Release(); + } else { + d3d->Release(); + } return false; } device->BeginScene(); DX9::pD3Ddevice = device; + DX9::pD3DdeviceEx = deviceEx; LoadD3DX9Dynamic(); DX9::CompileShaders(); DX9::fbo_init(); + if (deviceEx && IsWin7OrLater()) { + deviceEx->SetMaximumFrameLatency(1); + } + return true; } diff --git a/native b/native index 3c0d666e90..33d496d76f 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 3c0d666e90e528a91d76d0d07b312ae76b4d1c63 +Subproject commit 33d496d76f529a6b921c4c8fef70e6c5fd2caef7