Merge pull request #17890 from hrydgard/d3d-present-refactor

D3D presentation refactoring
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2023-08-11 10:41:55 +02:00
commit fabcaf6e04
31 files changed
+47 -88

No files matched your search

+11 -11
View File
@@ -62,7 +62,7 @@ public:
class D3D11DrawContext : public DrawContext {
public:
D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Device1 *device1, ID3D11DeviceContext1 *deviceContext1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> deviceList, int maxInflightFrames);
D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Device1 *device1, ID3D11DeviceContext1 *deviceContext1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> deviceList, int maxInflightFrames);
~D3D11DrawContext();
const DeviceCaps &GetDeviceCaps() const override {
@@ -139,7 +139,7 @@ public:
void BeginFrame(DebugFlags debugFlags) override;
void EndFrame() override;
void Present() override;
void Present(int vblanks) override;
int GetFrameCount() override { return frameCount_; }
@@ -185,6 +185,7 @@ private:
ID3D11Device1 *device1_;
ID3D11DeviceContext *context_;
ID3D11DeviceContext1 *context1_;
IDXGISwapChain *swapChain_;
ID3D11Texture2D *bbRenderTargetTex_ = nullptr; // NOT OWNED
ID3D11RenderTargetView *bbRenderTargetView_ = nullptr;
@@ -245,13 +246,14 @@ private:
std::vector<std::string> deviceList_;
};
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Device1 *device1, ID3D11DeviceContext1 *deviceContext1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> deviceList, int maxInflightFrames)
D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Device1 *device1, ID3D11DeviceContext1 *deviceContext1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> deviceList, int maxInflightFrames)
: hWnd_(hWnd),
device_(device),
context_(deviceContext1),
device1_(device1),
context1_(deviceContext1),
featureLevel_(featureLevel),
swapChain_(swapChain),
deviceList_(deviceList) {
// We no longer support Windows Phone.
@@ -424,11 +426,6 @@ void D3D11DrawContext::HandleEvent(Event ev, int width, int height, void *param1
curRTHeight_ = height;
break;
}
case Event::PRESENTED:
// Make sure that we don't eliminate the next time the render target is set.
curRenderTargetView_ = nullptr;
curDepthStencilView_ = nullptr;
break;
}
}
@@ -436,7 +433,10 @@ void D3D11DrawContext::EndFrame() {
curPipeline_ = nullptr;
}
void D3D11DrawContext::Present() {
void D3D11DrawContext::Present(int vblanks) {
swapChain_->Present(1, 0);
curRenderTargetView_ = nullptr;
curDepthStencilView_ = nullptr;
frameCount_++;
}
@@ -1869,8 +1869,8 @@ void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h
}
}
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> adapterNames, int maxInflightFrames) {
return new D3D11DrawContext(device, context, device1, context1, featureLevel, hWnd, adapterNames, maxInflightFrames);
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> adapterNames, int maxInflightFrames) {
return new D3D11DrawContext(device, context, device1, context1, swapChain, featureLevel, hWnd, adapterNames, maxInflightFrames);
}
} // namespace Draw
+11 -2
View File
@@ -580,7 +580,7 @@ public:
}
void EndFrame() override;
void Present() override;
void Present(int vblanks) override;
int GetFrameCount() override { return frameCount_; }
@@ -970,7 +970,16 @@ void D3D9Context::EndFrame() {
curPipeline_ = nullptr;
}
void D3D9Context::Present() {
void D3D9Context::Present(int vblanks) {
if (deviceEx_) {
deviceEx_->EndScene();
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
deviceEx_->BeginScene();
} else {
device_->EndScene();
device_->Present(NULL, NULL, NULL, NULL);
device_->BeginScene();
}
frameCount_++;
}
+2 -2
View File
@@ -366,7 +366,7 @@ public:
void BeginFrame(DebugFlags debugFlags) override;
void EndFrame() override;
void Present() override;
void Present(int vblanks) override;
int GetFrameCount() override {
return frameCount_;
@@ -802,7 +802,7 @@ void OpenGLContext::EndFrame() {
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
}
void OpenGLContext::Present() {
void OpenGLContext::Present(int vblanks) {
renderManager_.Present();
frameCount_++;
}
+3 -2
View File
@@ -480,7 +480,7 @@ public:
void BeginFrame(DebugFlags debugFlags) override;
void EndFrame() override;
void Present() override;
void Present(int vblanks) override;
void WipeQueue() override;
@@ -1121,7 +1121,8 @@ void VKContext::EndFrame() {
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
}
void VKContext::Present() {
void VKContext::Present(int vblanks) {
_dbg_assert_(vblanks == 0 || vblanks == 1);
renderManager_.Present();
frameCount_++;
}
+1 -1
View File
@@ -815,7 +815,7 @@ public:
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
virtual void BeginFrame(DebugFlags debugFlags) {}
virtual void EndFrame() = 0;
virtual void Present() = 0;
virtual void Present(int vblanks) = 0; // NOTE: Not all backends support vblanks > 1.
virtual void WipeQueue() {}
+2 -2
View File
@@ -17,7 +17,7 @@ struct ID3D11Device;
struct ID3D11DeviceContext;
struct ID3D11Device1;
struct ID3D11DeviceContext1;
struct IDXGISwapChain;
#endif
class VulkanContext;
@@ -28,7 +28,7 @@ DrawContext *T3DCreateGLContext();
#ifdef _WIN32
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> adapterNames, int maxInflightFrames);
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> adapterNames, int maxInflightFrames);
#endif
DrawContext *T3DCreateVulkanContext(VulkanContext *context, bool useRenderThread);
-2
View File
@@ -16,8 +16,6 @@ public:
virtual void Shutdown() = 0;
virtual void SwapInterval(int interval) = 0;
virtual void SwapBuffers() = 0;
// Used during window resize. Must be called from the window thread,
// not the rendering thread or CPU thread.
virtual void Pause() {}
-4
View File
@@ -227,10 +227,6 @@ void Core_RunLoop(GraphicsContext *ctx) {
if (sleepTime > 0)
sleep_ms(sleepTime);
}
if ((!windowHidden && !Core_IsStepping()) || menuThrottle) {
ctx->SwapBuffers();
}
}
void Core_DoSingleStep() {
-1
View File
@@ -70,7 +70,6 @@ public:
// See TODO in constructor.
// renderManager_->SwapInterval(interval);
}
void SwapBuffers() override {}
void Resize() override {}
Draw::DrawContext *GetDrawContext() override {
-4
View File
@@ -19,10 +19,6 @@ public:
void Shutdown() override;
void ShutdownFromRenderThread() override;
void SwapBuffers() override {
// Do nothing, the render thread takes care of this.
}
// Gets forwarded to the render thread.
void SwapInterval(int interval) override;
-2
View File
@@ -1452,8 +1452,6 @@ int main(int argc, char *argv[]) {
break;
}
graphicsContext->SwapBuffers();
{
std::lock_guard<std::mutex> guard(g_mutexWindow);
if (g_windowState.update) {
-4
View File
@@ -26,10 +26,6 @@ public:
void Shutdown() override;
void SwapBuffers() override {
// We don't do it this way.
}
void Resize() override;
void Poll() override;
+1 -1
View File
@@ -1157,7 +1157,7 @@ void NativeFrame(GraphicsContext *graphicsContext) {
ClearFailedGPUBackends();
}
g_draw->Present();
g_draw->Present(1);
if (resized) {
INFO_LOG(G3D, "Resized flag set - recalculating bounds");
+2 -3
View File
@@ -198,9 +198,8 @@ void App::Run() {
while (!m_windowClosed) {
if (m_windowVisible) {
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
if (m_main->Render()) {
m_deviceResources->Present();
}
m_main->Render();
// TODO: Adopt some practices from m_deviceResources->Present();
} else {
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
+1 -7
View File
@@ -164,8 +164,6 @@ void PPSSPP_UWPMain::CreateWindowSizeDependentResources() {
// Renders the current frame according to the current application state.
// Returns true if the frame was rendered and is ready to be displayed.
bool PPSSPP_UWPMain::Render() {
ctx_->GetDrawContext()->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
static bool hasSetThreadName = false;
if (!hasSetThreadName) {
SetCurrentThreadName("UWPRenderThread");
@@ -316,7 +314,7 @@ UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> reso
std::vector<std::string> adapterNames;
draw_ = Draw::T3DCreateD3D11Context(
resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0, adapterNames, g_Config.iInflightFrames);
resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetSwapChain(), resources->GetDeviceFeatureLevel(), 0, adapterNames, g_Config.iInflightFrames);
bool success = draw_->CreatePresets();
_assert_(success);
}
@@ -325,10 +323,6 @@ void UWPGraphicsContext::Shutdown() {
delete draw_;
}
void UWPGraphicsContext::SwapInterval(int interval) {
}
std::string System_GetProperty(SystemProperty prop) {
static bool hasCheckedGPUDriverVersion = false;
switch (prop) {
+3 -4
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <mutex>
@@ -19,8 +19,7 @@ public:
UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources);
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override {}
void SwapInterval(int interval) override {}
void Resize() override {}
Draw::DrawContext * GetDrawContext() override {
return draw_;
@@ -70,4 +69,4 @@ private:
std::unique_ptr<UWPGraphicsContext> ctx_;
};
}
}
+5 -9
View File
@@ -33,11 +33,6 @@
#error This file should not be compiled for UWP.
#endif
void D3D11Context::SwapBuffers() {
swapChain_->Present(swapInterval_, 0);
draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
}
void D3D11Context::SwapInterval(int interval) {
swapInterval_ = interval;
}
@@ -158,10 +153,6 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
}
#endif
draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames, g_Config.iInflightFrames);
SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName);
bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think.
_assert_msg_(success, "Failed to compile preset shaders");
int width;
int height;
@@ -202,6 +193,11 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
dxgiFactory->Release();
draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, swapChain_, featureLevel_, hWnd_, adapterNames, g_Config.iInflightFrames);
SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName);
bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think.
_assert_msg_(success, "Failed to compile preset shaders");
GotBackbuffer();
return true;
}
-1
View File
@@ -31,7 +31,6 @@ public:
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override;
void Resize() override;
-12
View File
@@ -21,18 +21,6 @@
#include "Common/GPU/thin3d_create.h"
#include "Common/GPU/D3D9/D3DCompilerLoader.h"
void D3D9Context::SwapBuffers() {
if (has9Ex_) {
deviceEx_->EndScene();
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
deviceEx_->BeginScene();
} else {
device_->EndScene();
device_->Present(NULL, NULL, NULL, NULL);
device_->BeginScene();
}
}
typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
void D3D9Context::SwapInterval(int interval) {
-1
View File
@@ -35,7 +35,6 @@ public:
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override;
void Resize() override;
+1 -1
View File
@@ -39,7 +39,7 @@
// Currently, just compile time for debugging. May be NVIDIA only.
static const int simulateGLES = false;
void WindowsGLContext::SwapBuffers() {
void WindowsGLContext::Poll() {
// We no longer call RenderManager::Swap here, it's handled by the render thread, which
// we're not on here.
+2 -1
View File
@@ -18,7 +18,8 @@ public:
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override;
void Poll() override;
// Used during window resize. Must be called from the window thread,
// not the rendering thread or CPU thread.
-1
View File
@@ -7,4 +7,3 @@ class WindowsGraphicsContext : public GraphicsContext {
public:
virtual bool Init(HINSTANCE hInst, HWND window, std::string *error_message) = 0;
};
-1
View File
@@ -30,7 +30,6 @@ public:
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
void Shutdown() override;
void SwapInterval(int interval) override {}
void SwapBuffers() override {}
void Resize() override;
void Poll() override;
-1
View File
@@ -15,7 +15,6 @@ public:
void ShutdownFromRenderThread() override;
void Shutdown() override {}
void SwapBuffers() override {}
void SwapInterval(int interval) override {}
void Resize() override {}
-1
View File
@@ -16,7 +16,6 @@ public:
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override {}
void Resize() override;
void *GetAPIContext() override { return g_Vulkan; }
-3
View File
@@ -96,7 +96,6 @@ public:
void Shutdown() override {}
void Resize() override {}
void SwapInterval(int interval) override {}
void SwapBuffers() override {}
private:
Draw::DrawContext *draw_ = nullptr;
@@ -193,7 +192,6 @@ bool SDLHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext *
if (!gfx_->ThreadFrame()) {
break;
}
gfx_->SwapBuffers();
}
threadState_ = RenderThreadState::STOPPING;
@@ -221,7 +219,6 @@ void SDLHeadlessHost::ShutdownGraphics() {
}
void SDLHeadlessHost::SwapBuffers() {
gfx_->SwapBuffers();
}
#endif
-2
View File
@@ -132,7 +132,6 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte
if (!gfx_->ThreadFrame()) {
break;
}
gfx_->SwapBuffers();
}
threadState_ = RenderThreadState::STOPPING;
@@ -173,5 +172,4 @@ void WindowsHeadlessHost::SwapBuffers() {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
gfx_->SwapBuffers();
}
-1
View File
@@ -64,7 +64,6 @@ public:
}
void SwapInterval(int interval) override {}
void SwapBuffers() override {}
void Resize() override {}
void Shutdown() override {}
+1
View File
@@ -22,6 +22,7 @@ public:
DestroyDrawContext();
}
void SwapInterval(int interval) override {}
virtual void SwapBuffers() = 0;
void Resize() override {}
virtual void GotBackbuffer();
+1 -1
View File
@@ -1174,7 +1174,7 @@ namespace Libretro
if (ctx->GetDrawContext()) {
ctx->GetDrawContext()->EndFrame();
ctx->GetDrawContext()->Present();
ctx->GetDrawContext()->Present(1);
}
}