VulkanRenderer: Add RenderWindow wrapper
Former-commit-id: 8046b7ecb5a71ba64bb5d51faaa2d2946318e6f1 [formerly adbc30c0ed533b63c445125f013384412f9272bd] [formerly eaa0c2a91e13440ee9b869d5fd2faad08d682879 [formerly 67381c6dbe3b960b1ab23bbe18c0a6193286f330]] Former-commit-id: f4716a44444383d107f44265b5720490e141e4d0 [formerly 49d667d30dda623e6192853573efe05aa589035c] Former-commit-id: fd3718fac5bb6d896d7cfd350807bbc1c0af309f
This commit is contained in:
@@ -1,138 +1,21 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
/*
|
||||
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderWindow::RenderWindow(VideoMode mode, const String& title, UInt32 style, const ContextParameters& parameters) :
|
||||
RenderTarget(), Window()
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowException, true);
|
||||
Create(mode, title, style, parameters);
|
||||
}
|
||||
|
||||
RenderWindow::RenderWindow(WindowHandle handle, const ContextParameters& parameters) :
|
||||
RenderTarget(), Window()
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowException, true);
|
||||
Create(handle, parameters);
|
||||
}
|
||||
|
||||
RenderWindow::~RenderWindow()
|
||||
{
|
||||
// Nécessaire si Window::Destroy est appelé par son destructeur
|
||||
OnWindowDestroy();
|
||||
}
|
||||
|
||||
bool RenderWindow::CopyToImage(AbstractImage* image, const Vector3ui& dstPos) const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CopyToImage(image, Rectui(Vector2ui(0U), GetSize()), dstPos);
|
||||
}
|
||||
|
||||
bool RenderWindow::CopyToImage(AbstractImage* image, const Rectui& rect, const Vector3ui& dstPos) const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
Vector2ui windowSize = GetSize();
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!image)
|
||||
{
|
||||
NazaraError("Image must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (image->GetFormat() != PixelFormatType_RGBA8)
|
||||
{
|
||||
// Pour plus de facilité, évidemment on peut faire sauter cette règle avec un peu de gestion
|
||||
NazaraError("Image must be RGBA8-formatted");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rect.x + rect.width > windowSize.x || rect.y + rect.height > windowSize.y)
|
||||
{
|
||||
NazaraError("Rectangle dimensions are out of window's bounds");
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3ui imageSize = image->GetSize();
|
||||
if (dstPos.x + rect.width > imageSize.x || dstPos.y + rect.height > imageSize.y || dstPos.z > imageSize.z)
|
||||
{
|
||||
NazaraError("Cube dimensions are out of image's bounds");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Context* currentContext = Context::GetCurrent();
|
||||
if (m_context != currentContext)
|
||||
{
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///TODO: Fast-path pour les images en cas de copie du buffer entier
|
||||
|
||||
m_buffer.resize(rect.width*rect.height*4);
|
||||
glReadPixels(rect.x, windowSize.y - rect.height - rect.y, rect.width, rect.height, GL_RGBA, GL_UNSIGNED_BYTE, m_buffer.data());
|
||||
|
||||
// Les pixels sont retournés, nous devons envoyer les pixels par rangée
|
||||
for (unsigned int i = 0; i < rect.height; ++i)
|
||||
image->Update(&m_buffer[rect.width*4*i], Boxui(dstPos.x, rect.height - i - 1, dstPos.z, rect.width, 1, 1), rect.width);
|
||||
|
||||
if (m_context != currentContext)
|
||||
{
|
||||
if (currentContext)
|
||||
{
|
||||
if (!currentContext->SetActive(true))
|
||||
NazaraWarning("Failed to reset old context");
|
||||
}
|
||||
else
|
||||
m_context->SetActive(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(VideoMode mode, const String& title, UInt32 style, const ContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return Window::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(WindowHandle handle, const ContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return Window::Create(handle);
|
||||
}
|
||||
|
||||
void RenderWindow::Display()
|
||||
{
|
||||
if (m_framerateLimit > 0)
|
||||
@@ -143,129 +26,23 @@ namespace Nz
|
||||
|
||||
m_clock.Restart();
|
||||
}
|
||||
|
||||
if (m_context && m_parameters.doubleBuffered)
|
||||
m_context->SwapBuffers();
|
||||
}
|
||||
|
||||
void RenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
m_context->EnableVerticalSync(enabled);
|
||||
}
|
||||
else
|
||||
NazaraError("No context");
|
||||
}
|
||||
|
||||
unsigned int RenderWindow::GetHeight() const
|
||||
{
|
||||
return Window::GetHeight();
|
||||
}
|
||||
|
||||
RenderTargetParameters RenderWindow::GetParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
const ContextParameters& parameters = m_context->GetParameters();
|
||||
return RenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return RenderTargetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int RenderWindow::GetWidth() const
|
||||
{
|
||||
return Window::GetWidth();
|
||||
}
|
||||
|
||||
bool RenderWindow::IsRenderable() const
|
||||
{
|
||||
return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi
|
||||
}
|
||||
|
||||
bool RenderWindow::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void RenderWindow::SetFramerateLimit(unsigned int limit)
|
||||
{
|
||||
m_framerateLimit = limit;
|
||||
}
|
||||
|
||||
ContextParameters RenderWindow::GetContextParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
return m_context->GetParameters();
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return ContextParameters();
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderWindow::HasContext() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderWindow::Activate() const
|
||||
{
|
||||
if (m_context->SetActive(true))
|
||||
{
|
||||
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Failed to activate window's context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWindow::EnsureTargetUpdated() const
|
||||
{
|
||||
// Rien à faire
|
||||
///TODO
|
||||
}
|
||||
|
||||
bool RenderWindow::OnWindowCreated()
|
||||
{
|
||||
m_parameters.doubleBuffered = true;
|
||||
m_parameters.window = GetHandle();
|
||||
|
||||
std::unique_ptr<Context> context(new Context);
|
||||
if (!context->Create(m_parameters))
|
||||
auto impl = Renderer::GetRendererImpl()->CreateRenderWindowImpl();
|
||||
if (!impl->Create(GetHandle(), Vector2ui(GetWidth(), GetHeight()), m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
NazaraError("Failed to create render window implementation: " + Error::GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_context = context.release();
|
||||
|
||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||
NazaraWarning("Failed to activate window");
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
Vector2ui size = GetSize();
|
||||
|
||||
// Le scissorBox/viewport (à la création) est de la taille de la fenêtre
|
||||
// https://www.opengl.org/sdk/docs/man/xhtml/glGet.xml
|
||||
OpenGL::SetScissorBox(Recti(0, 0, size.x, size.y));
|
||||
OpenGL::SetViewport(Recti(0, 0, size.x, size.y));
|
||||
|
||||
OnRenderTargetParametersChange(this);
|
||||
OnRenderTargetSizeChange(this);
|
||||
m_impl = std::move(impl);
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
@@ -274,19 +51,10 @@ namespace Nz
|
||||
|
||||
void RenderWindow::OnWindowDestroy()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
if (IsActive())
|
||||
Renderer::SetTarget(nullptr);
|
||||
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
m_impl.reset();
|
||||
}
|
||||
|
||||
void RenderWindow::OnWindowResized()
|
||||
{
|
||||
OnRenderTargetSizeChange(this);
|
||||
}
|
||||
}
|
||||
*/
|
||||
11
src/Nazara/Renderer/RendererWindowImpl.cpp
Normal file
11
src/Nazara/Renderer/RendererWindowImpl.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderWindowImpl::~RenderWindowImpl() = default;
|
||||
}
|
||||
@@ -2,12 +2,12 @@
|
||||
// This file is part of the "Nazara Engine - Vulkan Renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/RenderTarget.hpp>
|
||||
#include <Nazara/VulkanRenderer/VkRenderTarget.hpp>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderTarget::~RenderTarget()
|
||||
VkRenderTarget::~VkRenderTarget()
|
||||
{
|
||||
OnRenderTargetRelease(this);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/RenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VkRenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
@@ -13,35 +13,24 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderWindow::RenderWindow() :
|
||||
RenderTarget(), Window(),
|
||||
VkRenderWindow::VkRenderWindow() :
|
||||
m_surface(Nz::Vulkan::GetInstance()),
|
||||
m_forcedPhysicalDevice(nullptr),
|
||||
m_physicalDevice(nullptr),
|
||||
m_depthStencilFormat(VK_FORMAT_MAX_ENUM)
|
||||
{
|
||||
}
|
||||
|
||||
RenderWindow::RenderWindow(VideoMode mode, const String& title, UInt32 style) :
|
||||
RenderWindow()
|
||||
VkRenderWindow::~VkRenderWindow()
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowException, true);
|
||||
Create(mode, title, style);
|
||||
m_device->WaitForIdle();
|
||||
m_frameBuffers.clear();
|
||||
m_renderPass.Destroy();
|
||||
|
||||
m_swapchain.Destroy();
|
||||
m_surface.Destroy();
|
||||
}
|
||||
|
||||
RenderWindow::RenderWindow(WindowHandle handle) :
|
||||
RenderWindow()
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowException, true);
|
||||
Create(handle);
|
||||
}
|
||||
|
||||
RenderWindow::~RenderWindow()
|
||||
{
|
||||
// Nécessaire si Window::Destroy est appelé par son destructeur
|
||||
OnWindowDestroy();
|
||||
}
|
||||
|
||||
bool RenderWindow::Acquire(UInt32* imageIndex) const
|
||||
bool VkRenderWindow::Acquire(UInt32* imageIndex) const
|
||||
{
|
||||
if (!m_swapchain.AcquireNextImage(std::numeric_limits<UInt64>::max(), m_imageReadySemaphore, VK_NULL_HANDLE, imageIndex))
|
||||
{
|
||||
@@ -52,7 +41,7 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderWindow::BuildPreRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
|
||||
void VkRenderWindow::BuildPreRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
|
||||
{
|
||||
//commandBuffer.SetImageLayout(m_swapchain.GetBuffer(imageIndex).image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
@@ -71,83 +60,19 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWindow::BuildPostRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
|
||||
void VkRenderWindow::BuildPostRenderCommands(UInt32 imageIndex, Vk::CommandBuffer& commandBuffer)
|
||||
{
|
||||
//commandBuffer.SetImageLayout(m_swapchain.GetBuffer(imageIndex).image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
}
|
||||
|
||||
const Vk::Framebuffer& RenderWindow::GetFrameBuffer(UInt32 imageIndex) const
|
||||
bool VkRenderWindow::Create(WindowHandle handle, const Vector2ui& size, const RenderWindowParameters& parameters)
|
||||
{
|
||||
return m_frameBuffers[imageIndex];
|
||||
}
|
||||
|
||||
UInt32 RenderWindow::GetFramebufferCount() const
|
||||
{
|
||||
return static_cast<UInt32>(m_frameBuffers.size());
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(VideoMode mode, const String& title, UInt32 style)
|
||||
{
|
||||
return Window::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(WindowHandle handle)
|
||||
{
|
||||
return Window::Create(handle);
|
||||
}
|
||||
|
||||
const Vk::DeviceHandle& RenderWindow::GetDevice() const
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
|
||||
UInt32 RenderWindow::GetPresentableFamilyQueue() const
|
||||
{
|
||||
return m_presentableFamilyQueue;
|
||||
}
|
||||
|
||||
const Vk::Surface& RenderWindow::GetSurface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
const Vk::Swapchain& RenderWindow::GetSwapchain() const
|
||||
{
|
||||
return m_swapchain;
|
||||
}
|
||||
|
||||
void RenderWindow::Present(UInt32 imageIndex)
|
||||
{
|
||||
NazaraAssert(imageIndex < m_frameBuffers.size(), "Invalid image index");
|
||||
|
||||
m_presentQueue.Present(m_swapchain, imageIndex);
|
||||
}
|
||||
|
||||
bool RenderWindow::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void RenderWindow::SetDepthStencilFormats(std::vector<PixelFormatType> pixelFormat)
|
||||
{
|
||||
m_wantedDepthStencilFormats = std::move(pixelFormat);
|
||||
}
|
||||
|
||||
void RenderWindow::SetPhysicalDevice(VkPhysicalDevice device)
|
||||
{
|
||||
m_forcedPhysicalDevice = device;
|
||||
}
|
||||
|
||||
bool RenderWindow::OnWindowCreated()
|
||||
{
|
||||
OnRenderTargetSizeChange(this);
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
HWND handle = reinterpret_cast<HWND>(GetHandle());
|
||||
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(handle, GWLP_HINSTANCE));
|
||||
bool success = m_surface.Create(instance, handle);
|
||||
HWND winHandle = reinterpret_cast<HWND>(handle);
|
||||
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(winHandle, GWLP_HINSTANCE));
|
||||
bool success = m_surface.Create(instance, winHandle);
|
||||
#else
|
||||
#error This OS is not supported by Vulkan
|
||||
#error This OS is not supported by Vulkan
|
||||
#endif
|
||||
|
||||
if (!success)
|
||||
@@ -156,7 +81,9 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
m_device = Vulkan::SelectDevice(m_forcedPhysicalDevice, m_surface, &m_presentableFamilyQueue);
|
||||
m_physicalDevice = Vulkan::GetPhysicalDevices()[0].device;
|
||||
|
||||
m_device = Vulkan::SelectDevice(m_physicalDevice, m_surface, &m_presentableFamilyQueue);
|
||||
if (!m_device)
|
||||
{
|
||||
NazaraError("Failed to get compatible Vulkan device");
|
||||
@@ -166,7 +93,7 @@ namespace Nz
|
||||
m_presentQueue = m_device->GetQueue(m_presentableFamilyQueue, 0);
|
||||
|
||||
std::vector<VkSurfaceFormatKHR> surfaceFormats;
|
||||
if (!m_surface.GetFormats(m_forcedPhysicalDevice, &surfaceFormats))
|
||||
if (!m_surface.GetFormats(m_physicalDevice, &surfaceFormats))
|
||||
{
|
||||
NazaraError("Failed to query supported surface formats");
|
||||
return false;
|
||||
@@ -179,11 +106,11 @@ namespace Nz
|
||||
|
||||
m_colorSpace = surfaceFormats[0].colorSpace;
|
||||
|
||||
if (!m_wantedDepthStencilFormats.empty())
|
||||
if (!parameters.depthFormats.empty())
|
||||
{
|
||||
const Vk::PhysicalDevice& deviceInfo = Vulkan::GetPhysicalDeviceInfo(m_forcedPhysicalDevice);
|
||||
const Vk::PhysicalDevice& deviceInfo = Vulkan::GetPhysicalDeviceInfo(m_physicalDevice);
|
||||
|
||||
for (PixelFormatType format : m_wantedDepthStencilFormats)
|
||||
for (PixelFormatType format : parameters.depthFormats)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
@@ -223,7 +150,7 @@ namespace Nz
|
||||
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM)
|
||||
{
|
||||
VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(m_forcedPhysicalDevice, m_depthStencilFormat);
|
||||
VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(m_physicalDevice, m_depthStencilFormat);
|
||||
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
break; //< Found it
|
||||
|
||||
@@ -232,19 +159,19 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetupSwapchain())
|
||||
if (!SetupSwapchain(size))
|
||||
{
|
||||
NazaraError("Failed to create swapchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM && !SetupDepthBuffer())
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM && !SetupDepthBuffer(size))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetupRenderPass())
|
||||
if (!SetupRenderPass(size))
|
||||
{
|
||||
NazaraError("Failed to create render pass");
|
||||
return false;
|
||||
@@ -265,8 +192,8 @@ namespace Nz
|
||||
m_renderPass, // VkRenderPass renderPass;
|
||||
(attachments[1] != VK_NULL_HANDLE) ? 2U : 1U, // uint32_t attachmentCount;
|
||||
attachments.data(), // const VkImageView* pAttachments;
|
||||
GetWidth(), // uint32_t width;
|
||||
GetHeight(), // uint32_t height;
|
||||
size.x, // uint32_t width;
|
||||
size.y, // uint32_t height;
|
||||
1U // uint32_t layers;
|
||||
};
|
||||
|
||||
@@ -284,22 +211,7 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderWindow::OnWindowDestroy()
|
||||
{
|
||||
m_device->WaitForIdle();
|
||||
m_frameBuffers.clear();
|
||||
m_renderPass.Destroy();
|
||||
|
||||
m_swapchain.Destroy();
|
||||
m_surface.Destroy();
|
||||
}
|
||||
|
||||
void RenderWindow::OnWindowResized()
|
||||
{
|
||||
OnRenderTargetSizeChange(this);
|
||||
}
|
||||
|
||||
bool RenderWindow::SetupDepthBuffer()
|
||||
bool VkRenderWindow::SetupDepthBuffer(const Vector2ui& size)
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
|
||||
@@ -307,7 +219,7 @@ namespace Nz
|
||||
0U, // VkImageCreateFlags flags;
|
||||
VK_IMAGE_TYPE_2D, // VkImageType imageType;
|
||||
m_depthStencilFormat, // VkFormat format;
|
||||
{GetWidth(), GetHeight(), 1U}, // VkExtent3D extent;
|
||||
{size.x, size.y, 1U}, // VkExtent3D extent;
|
||||
1U, // uint32_t mipLevels;
|
||||
1U, // uint32_t arrayLayers;
|
||||
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
|
||||
@@ -369,7 +281,7 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderWindow::SetupRenderPass()
|
||||
bool VkRenderWindow::SetupRenderPass(const Vector2ui& size)
|
||||
{
|
||||
std::array<VkAttachmentDescription, 2> attachments = {
|
||||
{
|
||||
@@ -424,8 +336,8 @@ namespace Nz
|
||||
std::array<VkSubpassDependency, 2> dependencies;
|
||||
// First dependency at the start of the renderpass
|
||||
// Does the transition from final to initial layout
|
||||
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; // Producer of the dependency
|
||||
dependencies[0].dstSubpass = 0; // Consumer is our single subpass that will wait for the execution depdendency
|
||||
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; // Producer of the dependency
|
||||
dependencies[0].dstSubpass = 0; // Consumer is our single subpass that will wait for the execution depdendency
|
||||
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
@@ -434,8 +346,8 @@ namespace Nz
|
||||
|
||||
// Second dependency at the end the renderpass
|
||||
// Does the transition from the initial to the final layout
|
||||
dependencies[1].srcSubpass = 0; // Producer of the dependency is our single subpass
|
||||
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; // Consumer are all commands outside of the renderpass
|
||||
dependencies[1].srcSubpass = 0; // Producer of the dependency is our single subpass
|
||||
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; // Consumer are all commands outside of the renderpass
|
||||
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
@@ -450,17 +362,17 @@ namespace Nz
|
||||
attachments.data(), // const VkAttachmentDescription* pAttachments;
|
||||
1U, // uint32_t subpassCount;
|
||||
&subpass, // const VkSubpassDescription* pSubpasses;
|
||||
dependencies.size(), // uint32_t dependencyCount;
|
||||
dependencies.data() // const VkSubpassDependency* pDependencies;
|
||||
UInt32(dependencies.size()), // uint32_t dependencyCount;
|
||||
dependencies.data() // const VkSubpassDependency* pDependencies;
|
||||
};
|
||||
|
||||
return m_renderPass.Create(m_device, createInfo);
|
||||
}
|
||||
|
||||
bool RenderWindow::SetupSwapchain()
|
||||
bool VkRenderWindow::SetupSwapchain(const Vector2ui& size)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
if (!m_surface.GetCapabilities(m_forcedPhysicalDevice, &surfaceCapabilities))
|
||||
if (!m_surface.GetCapabilities(m_physicalDevice, &surfaceCapabilities))
|
||||
{
|
||||
NazaraError("Failed to query surface capabilities");
|
||||
return false;
|
||||
@@ -473,14 +385,14 @@ namespace Nz
|
||||
VkExtent2D extent;
|
||||
if (surfaceCapabilities.currentExtent.width == -1)
|
||||
{
|
||||
extent.width = Nz::Clamp<Nz::UInt32>(GetWidth(), surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
|
||||
extent.height = Nz::Clamp<Nz::UInt32>(GetHeight(), surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
|
||||
extent.width = Nz::Clamp<Nz::UInt32>(size.x, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
|
||||
extent.height = Nz::Clamp<Nz::UInt32>(size.y, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
|
||||
}
|
||||
else
|
||||
extent = surfaceCapabilities.currentExtent;
|
||||
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
if (!m_surface.GetPresentModes(m_forcedPhysicalDevice, &presentModes))
|
||||
if (!m_surface.GetPresentModes(m_physicalDevice, &presentModes))
|
||||
{
|
||||
NazaraError("Failed to query supported present modes");
|
||||
return false;
|
||||
@@ -4,10 +4,16 @@
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VkLoader.hpp>
|
||||
#include <Nazara/VulkanRenderer/VkRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
std::unique_ptr<RenderWindowImpl> VulkanRenderer::CreateRenderWindowImpl()
|
||||
{
|
||||
return std::make_unique<VkRenderWindow>();
|
||||
}
|
||||
|
||||
bool VulkanRenderer::IsBetterThan(const RendererImpl* other) const
|
||||
{
|
||||
if (other->QueryAPI() == RenderAPI_Vulkan && QueryAPIVersion() < other->QueryAPIVersion())
|
||||
|
||||
Reference in New Issue
Block a user