2024-05-09 11:37:56 -03:00
|
|
|
#include "platform-dx/device-dx.hpp"
|
2024-05-20 10:41:40 -03:00
|
|
|
#include "platform-dx/dxhelpers.hpp"
|
2024-05-19 17:52:27 -03:00
|
|
|
#include "graphics/adapter.hpp"
|
2024-05-22 20:05:52 -03:00
|
|
|
#include "graphics/swapchain.hpp"
|
2024-05-19 17:52:27 -03:00
|
|
|
#include "platform-dx/implementations.hpp"
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
namespace xna {
|
2024-05-22 20:05:52 -03:00
|
|
|
SwapChain::SwapChain() : GraphicsResource(nullptr) {
|
|
|
|
impl = unew<PlatformImplementation>();
|
|
|
|
}
|
|
|
|
|
|
|
|
SwapChain::SwapChain(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
|
|
|
|
impl = unew<PlatformImplementation>();
|
|
|
|
}
|
|
|
|
|
|
|
|
SwapChain::~SwapChain() {
|
|
|
|
impl = nullptr;
|
|
|
|
}
|
|
|
|
|
2024-04-26 10:13:00 -03:00
|
|
|
static bool internalInit(GraphicsDevice& device, HWND windowHandle, IDXGISwapChain1*& swapChain, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fdesc) {
|
|
|
|
if (!device._device || !windowHandle)
|
2024-04-22 11:22:18 -03:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (swapChain) {
|
|
|
|
swapChain->Release();
|
|
|
|
swapChain = nullptr;
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
auto adapter = device.Adapter();
|
2024-05-19 17:52:27 -03:00
|
|
|
auto dxAdapter = adapter->impl->dxadapter;
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
IDXGIFactory1* dxFactory1 = nullptr;
|
|
|
|
auto hr = dxAdapter->GetParent(IID_IDXGIFactory1, (void**)&dxFactory1);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
if (FAILED(hr)) return false;
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
IDXGIFactory2* dxFactory2 = nullptr;
|
|
|
|
hr = dxFactory1->QueryInterface(IID_IDXGIFactory2, (void**)&dxFactory2);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
if (FAILED(hr)) return false;
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-04-22 11:22:18 -03:00
|
|
|
dxFactory2->CreateSwapChainForHwnd(
|
|
|
|
device._device,
|
2024-04-26 10:13:00 -03:00
|
|
|
windowHandle,
|
2024-04-22 11:22:18 -03:00
|
|
|
&desc,
|
|
|
|
&fdesc,
|
|
|
|
nullptr,
|
|
|
|
&swapChain);
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
|
|
|
|
return true;
|
2024-04-22 11:22:18 -03:00
|
|
|
}
|
|
|
|
|
2024-04-26 10:13:00 -03:00
|
|
|
bool SwapChain::Initialize(xna_error_ptr_arg) {
|
2024-05-22 20:05:52 -03:00
|
|
|
if (!impl || !m_device || !m_device->_device) {
|
2024-04-25 14:51:33 -03:00
|
|
|
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
|
|
|
return false;
|
|
|
|
}
|
2024-04-26 10:13:00 -03:00
|
|
|
|
|
|
|
const auto parameters = m_device->_presentationParameters;
|
2024-04-25 14:51:33 -03:00
|
|
|
|
2024-05-22 20:05:52 -03:00
|
|
|
impl->dxDescription.Width = static_cast<UINT>(parameters.BackBufferWidth);
|
|
|
|
impl->dxDescription.Height = static_cast<UINT>(parameters.BackBufferHeight);
|
|
|
|
impl->dxDescription.Format = DxHelpers::ConvertSurfaceToDXGIFORMAT(parameters.BackBufferFormat);
|
|
|
|
impl->dxDescription.SampleDesc.Count = 1;
|
|
|
|
impl->dxDescription.SampleDesc.Quality = 0;
|
|
|
|
impl->dxDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
|
|
impl->dxDescription.BufferCount = 2;
|
|
|
|
impl->dxDescription.SwapEffect = static_cast<DXGI_SWAP_EFFECT>(parameters.PresentationSwapEffect);
|
|
|
|
impl->dxDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
|
|
|
impl->dxDescription.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED;
|
|
|
|
impl->dxFullScreenDescription.RefreshRate.Numerator = 60;
|
|
|
|
impl->dxFullScreenDescription.RefreshRate.Denominator = 1;
|
|
|
|
impl->dxFullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
|
|
|
impl->dxFullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
|
|
|
impl->dxFullScreenDescription.Windowed = !parameters.Fullscreen;
|
2024-04-23 16:11:17 -03:00
|
|
|
|
2024-05-22 09:55:25 -03:00
|
|
|
HWND hwnd = reinterpret_cast<HWND>(parameters.DeviceWindowHandle);
|
2024-05-22 20:05:52 -03:00
|
|
|
return internalInit(*m_device, hwnd, impl->dxSwapChain, impl->dxDescription, impl->dxFullScreenDescription);
|
|
|
|
}
|
2024-04-23 16:11:17 -03:00
|
|
|
|
2024-05-22 20:05:52 -03:00
|
|
|
bool SwapChain::GetBackBuffer(Texture2D& texture2D) {
|
|
|
|
if (!impl || !impl->dxSwapChain)
|
2024-04-23 16:11:17 -03:00
|
|
|
return false;
|
|
|
|
|
2024-05-22 20:05:52 -03:00
|
|
|
const auto hr = impl->dxSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)(&texture2D.dxTexture2D));
|
2024-04-23 16:11:17 -03:00
|
|
|
|
|
|
|
return !FAILED(hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SwapChain::Present(bool vsync) {
|
2024-05-22 20:05:52 -03:00
|
|
|
if (!impl || !impl->dxSwapChain)
|
2024-04-23 16:11:17 -03:00
|
|
|
return false;
|
|
|
|
|
2024-05-22 20:05:52 -03:00
|
|
|
const auto hr = impl->dxSwapChain->Present(vsync, NULL);
|
2024-04-23 16:11:17 -03:00
|
|
|
return !FAILED(hr);
|
2024-04-22 11:22:18 -03:00
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
}
|