1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Refatora SwapChain

This commit is contained in:
Danilo 2024-04-22 11:22:18 -03:00
parent f8c881de09
commit c095ff3407
12 changed files with 141 additions and 118 deletions

View File

@ -9,7 +9,8 @@ namespace xna {
public: public:
virtual ~IRenderTarget2D(){} virtual ~IRenderTarget2D(){}
virtual bool Bind() = 0; virtual bool Initialize(GraphicsDevice& device) = 0;
virtual bool Apply(GraphicsDevice& device) = 0;
}; };
} }

View File

@ -1,17 +1,14 @@
#ifndef XNA_GRAPHICS_SWAPCHAIN_HPP #ifndef XNA_GRAPHICS_SWAPCHAIN_HPP
#define XNA_GRAPHICS_SWAPCHAIN_HPP #define XNA_GRAPHICS_SWAPCHAIN_HPP
#include "../types.hpp" #include "../default.hpp"
#include "../enums.hpp"
#include "../forward.hpp"
#include "../game/window.hpp" #include "../game/window.hpp"
namespace xna { namespace xna {
class ISwapChain { class ISwapChain {
public: public:
virtual ~ISwapChain() {} virtual ~ISwapChain() {}
virtual bool Initialize(GameWindow const& gameWindow) = 0; virtual bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow) = 0;
virtual bool Apply() = 0;
}; };
} }

View File

@ -152,9 +152,9 @@ namespace xna {
return static_cast<Uint>(desc.VendorId); return static_cast<Uint>(desc.VendorId);
} }
static UINT getDisplayModesCount(IDXGIAdapter* adapter) { static size_t getDisplayModesCount(IDXGIAdapter* adapter) {
IDXGIOutput* pOutput = nullptr; IDXGIOutput* pOutput = nullptr;
UINT numModes = 0; size_t numModes = 0;
if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
@ -177,11 +177,14 @@ namespace xna {
UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const { UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const {
if (!_adapter) return nullptr; if (!_adapter) return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT numModes = 0;
UINT totalModes = 0;
const auto totalDisplay = getDisplayModesCount(_adapter); const auto totalDisplay = getDisplayModesCount(_adapter);
if (totalDisplay == 0)
return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
std::vector<DXGI_MODE_DESC> buffer(totalDisplay); std::vector<DXGI_MODE_DESC> buffer(totalDisplay);
if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
@ -189,14 +192,15 @@ namespace xna {
const auto currentSurface = static_cast<SurfaceFormat>(f); const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface);
UINT numModes = 0;
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr); pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
if (numModes == 0) if (numModes == 0)
continue; continue;
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes); pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + bufferOffset);
totalModes += numModes; bufferOffset += numModes;
} }
} }
@ -211,7 +215,7 @@ namespace xna {
std::vector<PDisplayMode> displayList; std::vector<PDisplayMode> displayList;
PDisplayMode pDisplay = nullptr; PDisplayMode pDisplay = nullptr;
for (size_t i = 0; i < totalModes; ++i) { for (size_t i = 0; i < totalDisplay; ++i) {
auto& modedesc = buffer[i]; auto& modedesc = buffer[i];
DisplayModeDescription description; DisplayModeDescription description;

View File

@ -63,23 +63,22 @@ namespace xna {
_backgroundColor[3] = 1.0f; _backgroundColor[3] = 1.0f;
if (!_swapChain) if (!_swapChain)
_swapChain = New<xna::SwapChain>(this); _swapChain = New<xna::SwapChain>();
_swapChain->Initialize(gameWindow); _swapChain->Initialize(*this, gameWindow);
if (!_swapChain->Apply())
return false;
if FAILED(_factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) if FAILED(_factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER))
return false; return false;
if (!_renderTarget2D) { if (!_renderTarget2D) {
_renderTarget2D = New<RenderTarget2D>(this); _renderTarget2D = New<RenderTarget2D>();
} }
if (!_renderTarget2D->Bind()) if (!_renderTarget2D->Initialize(*this))
return false; return false;
_renderTarget2D->Apply(*this);
D3D11_VIEWPORT view{}; D3D11_VIEWPORT view{};
view.TopLeftX = _viewport.X; view.TopLeftX = _viewport.X;
view.TopLeftY = _viewport.Y; view.TopLeftY = _viewport.Y;

View File

@ -74,6 +74,7 @@ namespace xna {
ID3D11Device* _device{ nullptr }; ID3D11Device* _device{ nullptr };
ID3D11DeviceContext* _context{ nullptr }; ID3D11DeviceContext* _context{ nullptr };
IDXGIFactory1* _factory = nullptr; IDXGIFactory1* _factory = nullptr;
PSwapChain _swapChain{ nullptr };
private: private:
unsigned int _createDeviceFlags{ 0 }; unsigned int _createDeviceFlags{ 0 };
@ -81,7 +82,6 @@ namespace xna {
float _backgroundColor[4] = { 0, 0, 0, 0 }; float _backgroundColor[4] = { 0, 0, 0, 0 };
xna::PresentationParameters _presentParameters; xna::PresentationParameters _presentParameters;
PGraphicsAdapter _adapter{ nullptr }; PGraphicsAdapter _adapter{ nullptr };
PSwapChain _swapChain{ nullptr };
PRenderTarget2D _renderTarget2D{ nullptr }; PRenderTarget2D _renderTarget2D{ nullptr };
xna::Viewport _viewport{}; xna::Viewport _viewport{};
PBlendState _blendState{ nullptr }; PBlendState _blendState{ nullptr };

View File

@ -1 +1,41 @@
#include "displaymode-dx.hpp" #include "displaymode-dx.hpp"
namespace xna {
std::vector<PDisplayMode> DisplayModeCollection::At(SurfaceFormat format) const
{
std::vector<PDisplayMode> modes;
At(format, modes);
return modes;
}
void DisplayModeCollection::At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const
{
size_t counter = 0;
for (size_t i = 0; i < _displayModes.size(); ++i) {
const auto& displayMode = _displayModes[i];
if (displayMode->Format() == format)
{
modes.push_back(displayMode);
++counter;
}
}
if (!modes.empty())
modes.resize(counter);
}
size_t DisplayModeCollection::SurfaceCount(SurfaceFormat format) const
{
size_t counter = 0;
for (size_t i = 0; i < _displayModes.size(); ++i) {
if (_displayModes[i]->Format() == format) {
++counter;
}
}
return counter;
}
}

View File

@ -88,40 +88,11 @@ namespace xna {
DisplayModeCollection(std::vector<PDisplayMode> const& displayModes) : DisplayModeCollection(std::vector<PDisplayMode> const& displayModes) :
_displayModes(displayModes) {} _displayModes(displayModes) {}
std::vector<PDisplayMode> At(SurfaceFormat format) const { virtual std::vector<PDisplayMode> At(SurfaceFormat format) const override;
std::vector<PDisplayMode> modes;
At(format, modes);
return modes;
}
void At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const { virtual void At(SurfaceFormat format, std::vector<PDisplayMode>& modes) const override;
size_t counter = 0;
for (size_t i = 0; i < _displayModes.size(); ++i) { virtual size_t SurfaceCount(SurfaceFormat format) const override;
const auto& displayMode = _displayModes[i];
if (displayMode->Format() == format)
{
modes.push_back(displayMode);
++counter;
}
}
if (!modes.empty())
modes.resize(counter);
}
size_t SurfaceCount(SurfaceFormat format) const {
size_t counter = 0;
for (size_t i = 0; i < _displayModes.size(); ++i) {
if (_displayModes[i]->Format() == format) {
++counter;
}
}
return counter;
}
std::vector<PDisplayMode> operator[](SurfaceFormat format) const { std::vector<PDisplayMode> operator[](SurfaceFormat format) const {
return At(format); return At(format);

View File

@ -4,27 +4,31 @@
#include "device-dx.hpp" #include "device-dx.hpp"
namespace xna { namespace xna {
RenderTarget2D::RenderTarget2D(GraphicsDevice* device) { bool RenderTarget2D::Initialize(GraphicsDevice& device) {
_device = device; if (!device._device)
} return false;
bool RenderTarget2D::Bind() {
if (_texture2D) { if (_texture2D) {
_texture2D->Release(); _texture2D->Release();
_texture2D = nullptr; _texture2D = nullptr;
} }
if (!_device->GetSwapChainBackBuffer(_texture2D)) if (!device._swapChain->GetBackBuffer(_texture2D))
return false; return false;
auto& device = _device->_device; auto& dxdevice = device._device;
if FAILED(device->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView)) const auto hr = dxdevice->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView);
return false;
auto& context = _device->_context; if (FAILED(hr))
context->OMSetRenderTargets(1, &_renderTargetView, nullptr); return false;
return true; return true;
} }
bool RenderTarget2D::Apply(GraphicsDevice& device) {
auto& context = device._context;
context->OMSetRenderTargets(1, &_renderTargetView, nullptr);
return true;
}
} }

View File

@ -9,8 +9,6 @@
namespace xna { namespace xna {
class RenderTarget2D : public IRenderTarget2D, public Texture2D { class RenderTarget2D : public IRenderTarget2D, public Texture2D {
public: public:
RenderTarget2D(GraphicsDevice* device);
virtual ~RenderTarget2D() override { virtual ~RenderTarget2D() override {
if (_renderTargetView) { if (_renderTargetView) {
_renderTargetView->Release(); _renderTargetView->Release();
@ -18,12 +16,12 @@ namespace xna {
} }
} }
virtual bool Bind() override; virtual bool Initialize(GraphicsDevice& device) override;
virtual bool Apply(GraphicsDevice& device) override;
public: public:
ID3D11RenderTargetView* _renderTargetView = nullptr; ID3D11RenderTargetView* _renderTargetView = nullptr;
D3D11_RENDER_TARGET_VIEW_DESC _renderTargetDesc{}; D3D11_RENDER_TARGET_VIEW_DESC _renderTargetDesc{};
GraphicsDevice* _device{ nullptr };
}; };
} }

View File

@ -1,53 +1,66 @@
#include "swapchain-dx.hpp" #include "swapchain-dx.hpp"
#include "../graphics/device.hpp"
#include "adapter-dx.hpp" #include "adapter-dx.hpp"
#include "device-dx.hpp" #include "device-dx.hpp"
namespace xna { namespace xna {
SwapChain::SwapChain(GraphicsDevice* device){ static bool internalInit(GraphicsDevice& device, GameWindow const& gameWindow, IDXGISwapChain1*& swapChain, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fdesc) {
_device = device; if (!device._device || !gameWindow.WindowHandle())
} return false;
if (swapChain) {
swapChain->Release();
swapChain = nullptr;
}
bool SwapChain::Initialize(GameWindow const& gameWindow) { auto adapter = device.Adapter();
const auto bounds = gameWindow.ClientBounds(); auto dxAdapter = adapter->_adapter;
IDXGIFactory1* dxFactory1 = nullptr;
auto hr = dxAdapter->GetParent(IID_IDXGIFactory1, (void**)&dxFactory1);
if (FAILED(hr)) return false;
IDXGIFactory2* dxFactory2 = nullptr;
hr = dxFactory1->QueryInterface(IID_IDXGIFactory2, (void**)&dxFactory2);
if (FAILED(hr)) return false;
dxFactory2->CreateSwapChainForHwnd(
device._device,
gameWindow.WindowHandle(),
&desc,
&fdesc,
nullptr,
&swapChain);
_swapDescription.BufferDesc.Width = static_cast<UINT>(bounds.Width);
_swapDescription.BufferDesc.Height = static_cast<UINT>(bounds.Height);
_swapDescription.BufferDesc.RefreshRate.Numerator = 60;
_swapDescription.BufferDesc.RefreshRate.Denominator = 1;
_swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
_swapDescription.SampleDesc.Count = 1;
_swapDescription.SampleDesc.Quality = 0;
_swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
_swapDescription.BufferCount = 2;
_swapDescription.OutputWindow = gameWindow.WindowHandle();
_swapDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen;
_swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
_swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
return true; return true;
} }
bool SwapChain::Apply() { bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow) {
auto adapter = _device->Adapter(); const auto bounds = gameWindow.ClientBounds();
auto dxAdapter = adapter->_adapter;
IDXGIFactory* dxFactory = nullptr; _description.Width = static_cast<UINT>(bounds.Width);
if FAILED(dxAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxFactory)) _description.Height = static_cast<UINT>(bounds.Height);
return false; _description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
_description.SampleDesc.Count = 1;
_description.SampleDesc.Quality = 0;
_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
_description.BufferCount = 2;
_description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
_description.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
_description.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED;
_fullScreenDescription.RefreshRate.Numerator = 60;
_fullScreenDescription.RefreshRate.Denominator = 1;
_fullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
_fullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
_fullScreenDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen;
auto dxdevice = _device->_device; return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription);
}
if FAILED(dxFactory->CreateSwapChain(dxdevice, &_swapDescription, &_swapChain)) bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc)
{ {
dxFactory->Release(); return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription);
dxFactory = nullptr; }
return false;
}
dxFactory->Release();
dxFactory = nullptr;
return true;
}
} }

View File

@ -3,14 +3,11 @@
#include "../graphics/swapchain.hpp" #include "../graphics/swapchain.hpp"
#include "window-dx.hpp" #include "window-dx.hpp"
#include "dxgi.h" #include "dxheaders.hpp"
#include "d3d11.h"
namespace xna { namespace xna {
class SwapChain : public ISwapChain{ class SwapChain : public ISwapChain{
public: public:
SwapChain(GraphicsDevice* device);
virtual ~SwapChain() override { virtual ~SwapChain() override {
if (_swapChain) { if (_swapChain) {
_swapChain->Release(); _swapChain->Release();
@ -18,8 +15,8 @@ namespace xna {
} }
} }
virtual bool Initialize(GameWindow const& gameWindow) override; virtual bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow) override;
virtual bool Apply() override; bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc);
bool GetBackBuffer(ID3D11Texture2D*& texture2D) { bool GetBackBuffer(ID3D11Texture2D*& texture2D) {
if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D))) if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D)))
@ -29,9 +26,9 @@ namespace xna {
} }
public: public:
IDXGISwapChain* _swapChain{ nullptr }; IDXGISwapChain1* _swapChain{ nullptr };
DXGI_SWAP_CHAIN_DESC _swapDescription{}; DXGI_SWAP_CHAIN_DESC1 _description{};
GraphicsDevice* _device{ nullptr }; DXGI_SWAP_CHAIN_FULLSCREEN_DESC _fullScreenDescription{};
}; };
} }

View File

@ -21,7 +21,6 @@ public:
void Initialize() override { void Initialize() override {
graphics->Initialize(); graphics->Initialize();
const auto modes= _graphicsDevice->Adapter()->SupportedDisplayModes();
Game::Initialize(); Game::Initialize();
} }