Merge pull request #19974 from hrydgard/d3d11flipmodel

Nukem9's D3D11 flipmodel, rebased
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-02-13 09:52:44 -06:00
commit b484d4b1bf
3 files changed
+52 -24

No files matched your search

+20 -5
View File
@@ -18,6 +18,7 @@
#include <cfloat>
#include <D3Dcommon.h>
#include <dxgi1_5.h>
#include <d3d11.h>
#include <d3d11_1.h>
#include <D3Dcompiler.h>
@@ -215,6 +216,7 @@ private:
ID3D11DeviceContext *context_;
ID3D11DeviceContext1 *context1_;
IDXGISwapChain *swapChain_;
bool swapChainTearingSupported_ = false;
ID3D11Texture2D *bbRenderTargetTex_ = nullptr; // NOT OWNED
ID3D11RenderTargetView *bbRenderTargetView_ = nullptr;
@@ -367,6 +369,15 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
caps_.supportsD3D9 = false;
}
if (swapChain_) {
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChain_->GetDesc(&swapChainDesc);
if (swapChainDesc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) {
swapChainTearingSupported_ = true;
}
}
// Temp texture for read-back of small images. Custom textures are created on demand for larger ones.
// TODO: Should really benchmark if this extra complexity has any benefit.
D3D11_TEXTURE2D_DESC packDesc{};
@@ -394,6 +405,7 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
if (SUCCEEDED(hr)) {
caps_.setMaxFrameLatencySupported = true;
dxgiDevice1->SetMaximumFrameLatency(maxInflightFrames);
dxgiDevice1->Release();
}
}
@@ -478,14 +490,17 @@ void D3D11DrawContext::EndFrame() {
void D3D11DrawContext::Present(PresentMode presentMode, int vblanks) {
frameTimeHistory_[frameCount_].queuePresent = time_now_d();
int interval = vblanks;
if (presentMode != PresentMode::FIFO) {
interval = 0;
}
// Safety for libretro
if (swapChain_) {
swapChain_->Present(interval, 0);
uint32_t interval = vblanks;
uint32_t flags = 0;
if (presentMode != PresentMode::FIFO) {
interval = 0;
flags |= swapChainTearingSupported_ ? DXGI_PRESENT_ALLOW_TEARING : 0; // Assume "vsync off" also means "allow tearing"
}
swapChain_->Present(interval, flags);
}
curRenderTargetView_ = nullptr;
curDepthStencilView_ = nullptr;
frameCount_++;
+31 -19
View File
@@ -1,6 +1,7 @@
#include "ppsspp_config.h"
#include "Common/CommonWindows.h"
#include <dxgi1_5.h>
#include <d3d11.h>
#include <WinError.h>
@@ -152,35 +153,46 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
IDXGIFactory1 *dxgiFactory = nullptr;
IDXGIDevice *dxgiDevice = nullptr;
IDXGIAdapter *adapter = nullptr;
hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
if (SUCCEEDED(hr)) {
IDXGIAdapter *adapter = nullptr;
hr = dxgiDevice->GetAdapter(&adapter);
if (SUCCEEDED(hr)) {
hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
adapter->Release();
}
dxgiDevice->Release();
}
// DirectX 11.0 systems
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd_;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
// Create the swap chain. Modern features (flip model, tearing) require Windows 10 (DXGI 1.5) or newer.
swapChainDesc_.BufferCount = 1;
swapChainDesc_.BufferDesc.Width = width;
swapChainDesc_.BufferDesc.Height = height;
swapChainDesc_.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc_.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc_.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc_.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc_.OutputWindow = hWnd_;
swapChainDesc_.SampleDesc.Count = 1;
swapChainDesc_.SampleDesc.Quality = 0;
swapChainDesc_.Windowed = TRUE;
swapChainDesc_.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_);
IDXGIFactory5 *dxgiFactory5 = nullptr;
hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&dxgiFactory5);
if (SUCCEEDED(hr)) {
swapChainDesc_.BufferCount = 2;
swapChainDesc_.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
BOOL allowTearing = FALSE;
hr = dxgiFactory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing));
if (SUCCEEDED(hr) && allowTearing) {
swapChainDesc_.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
}
dxgiFactory5->Release();
}
hr = dxgiFactory->CreateSwapChain(device_, &swapChainDesc_, &swapChain_);
dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER);
dxgiFactory->Release();
@@ -224,7 +236,7 @@ void D3D11Context::Resize() {
int width;
int height;
W32Util::GetWindowRes(hWnd_, &width, &height);
swapChain_->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
swapChain_->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, swapChainDesc_.Flags);
GotBackbuffer();
}
+1
View File
@@ -43,6 +43,7 @@ private:
Draw::DrawContext *draw_ = nullptr;
IDXGISwapChain *swapChain_ = nullptr;
DXGI_SWAP_CHAIN_DESC swapChainDesc_ = {};
ID3D11Device *device_ = nullptr;
ID3D11Device1 *device1_ = nullptr;
ID3D11DeviceContext *context_ = nullptr;