Add render scale support in vulkan
This commit is contained in:
parent
97e5064535
commit
d31281cb6f
@ -17,6 +17,7 @@ bool m_disable_npot_texture;
|
|||||||
bool m_convert_irrlicht_mesh;
|
bool m_convert_irrlicht_mesh;
|
||||||
bool m_texture_compression;
|
bool m_texture_compression;
|
||||||
std::unordered_set<std::string> m_ondemand_load_texture_paths;
|
std::unordered_set<std::string> m_ondemand_load_texture_paths;
|
||||||
|
float m_render_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setVideoDriver(irr::video::IVideoDriver* driver);
|
void setVideoDriver(irr::video::IVideoDriver* driver);
|
||||||
|
@ -324,7 +324,7 @@ namespace GE
|
|||||||
video::ITexture* getTransparentTexture() const
|
video::ITexture* getTransparentTexture() const
|
||||||
{ return m_transparent_texture; }
|
{ return m_transparent_texture; }
|
||||||
void getRotatedRect2D(VkRect2D* rect);
|
void getRotatedRect2D(VkRect2D* rect);
|
||||||
void getRotatedViewport(VkViewport* vp);
|
void getRotatedViewport(VkViewport* vp, bool handle_rtt);
|
||||||
const core::matrix4& getPreRotationMatrix()
|
const core::matrix4& getPreRotationMatrix()
|
||||||
{ return m_pre_rotation_matrix; }
|
{ return m_pre_rotation_matrix; }
|
||||||
virtual void pauseRendering();
|
virtual void pauseRendering();
|
||||||
@ -353,6 +353,8 @@ namespace GE
|
|||||||
GEVulkanTextureDescriptor* getMeshTextureDescriptor() const
|
GEVulkanTextureDescriptor* getMeshTextureDescriptor() const
|
||||||
{ return m_mesh_texture_descriptor; }
|
{ return m_mesh_texture_descriptor; }
|
||||||
GEVulkanFBOTexture* getRTTTexture() const { return m_rtt_texture; }
|
GEVulkanFBOTexture* getRTTTexture() const { return m_rtt_texture; }
|
||||||
|
GEVulkanFBOTexture* getSeparateRTTTexture() const
|
||||||
|
{ return m_separate_rtt_texture; }
|
||||||
void handleDeletedTextures();
|
void handleDeletedTextures();
|
||||||
void addRTTPolyCount(unsigned count) { m_rtt_polycount += count; }
|
void addRTTPolyCount(unsigned count) { m_rtt_polycount += count; }
|
||||||
private:
|
private:
|
||||||
@ -493,6 +495,8 @@ namespace GE
|
|||||||
GEVulkanDepthTexture* m_depth_texture;
|
GEVulkanDepthTexture* m_depth_texture;
|
||||||
GEVulkanTextureDescriptor* m_mesh_texture_descriptor;
|
GEVulkanTextureDescriptor* m_mesh_texture_descriptor;
|
||||||
GEVulkanFBOTexture* m_rtt_texture;
|
GEVulkanFBOTexture* m_rtt_texture;
|
||||||
|
GEVulkanFBOTexture* m_prev_rtt_texture;
|
||||||
|
GEVulkanFBOTexture* m_separate_rtt_texture;
|
||||||
u32 m_rtt_polycount;
|
u32 m_rtt_polycount;
|
||||||
|
|
||||||
void createInstance(SDL_Window* window);
|
void createInstance(SDL_Window* window);
|
||||||
|
@ -6,7 +6,14 @@
|
|||||||
namespace GE
|
namespace GE
|
||||||
{
|
{
|
||||||
irr::video::IVideoDriver* g_driver = NULL;
|
irr::video::IVideoDriver* g_driver = NULL;
|
||||||
GEConfig g_config = {};
|
GEConfig g_config =
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
{},
|
||||||
|
1.0f
|
||||||
|
};
|
||||||
std::string g_shader_folder = "";
|
std::string g_shader_folder = "";
|
||||||
std::chrono::steady_clock::time_point g_mono_start =
|
std::chrono::steady_clock::time_point g_mono_start =
|
||||||
std::chrono::steady_clock::now();
|
std::chrono::steady_clock::now();
|
||||||
|
@ -309,7 +309,7 @@ void GEVulkan2dRenderer::render()
|
|||||||
vp.height = g_vk->getViewPort().getHeight();
|
vp.height = g_vk->getViewPort().getHeight();
|
||||||
vp.minDepth = 0;
|
vp.minDepth = 0;
|
||||||
vp.maxDepth = 1.0f;
|
vp.maxDepth = 1.0f;
|
||||||
g_vk->getRotatedViewport(&vp);
|
g_vk->getRotatedViewport(&vp, false/*handle_rtt*/);
|
||||||
vkCmdSetViewport(g_vk->getCurrentCommandBuffer(), 0, 1, &vp);
|
vkCmdSetViewport(g_vk->getCurrentCommandBuffer(), 0, 1, &vp);
|
||||||
|
|
||||||
if (GEVulkanFeatures::supportsBindTexturesAtOnce())
|
if (GEVulkanFeatures::supportsBindTexturesAtOnce())
|
||||||
|
@ -959,13 +959,16 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkViewport vp;
|
VkViewport vp;
|
||||||
vp.x = cam->getViewPort().UpperLeftCorner.X;
|
float scale = getGEConfig()->m_render_scale;
|
||||||
vp.y = cam->getViewPort().UpperLeftCorner.Y;
|
if (vk->getSeparateRTTTexture())
|
||||||
vp.width = cam->getViewPort().getWidth();
|
scale = 1.0f;
|
||||||
vp.height = cam->getViewPort().getHeight();
|
vp.x = cam->getViewPort().UpperLeftCorner.X * scale;
|
||||||
|
vp.y = cam->getViewPort().UpperLeftCorner.Y * scale;
|
||||||
|
vp.width = cam->getViewPort().getWidth() * scale;
|
||||||
|
vp.height = cam->getViewPort().getHeight() * scale;
|
||||||
vp.minDepth = 0;
|
vp.minDepth = 0;
|
||||||
vp.maxDepth = 1.0f;
|
vp.maxDepth = 1.0f;
|
||||||
vk->getRotatedViewport(&vp);
|
vk->getRotatedViewport(&vp, true/*handle_rtt*/);
|
||||||
vkCmdSetViewport(cmd, 0, 1, &vp);
|
vkCmdSetViewport(cmd, 0, 1, &vp);
|
||||||
|
|
||||||
VkRect2D scissor;
|
VkRect2D scissor;
|
||||||
|
@ -498,7 +498,8 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
|||||||
: CNullDriver(io, core::dimension2d<u32>(0, 0)),
|
: CNullDriver(io, core::dimension2d<u32>(0, 0)),
|
||||||
m_params(params), m_irrlicht_device(device),
|
m_params(params), m_irrlicht_device(device),
|
||||||
m_depth_texture(NULL), m_mesh_texture_descriptor(NULL),
|
m_depth_texture(NULL), m_mesh_texture_descriptor(NULL),
|
||||||
m_rtt_texture(NULL), m_rtt_polycount(0)
|
m_rtt_texture(NULL), m_prev_rtt_texture(NULL),
|
||||||
|
m_separate_rtt_texture(NULL), m_rtt_polycount(0)
|
||||||
{
|
{
|
||||||
m_vk.reset(new VK());
|
m_vk.reset(new VK());
|
||||||
m_physical_device = VK_NULL_HANDLE;
|
m_physical_device = VK_NULL_HANDLE;
|
||||||
@ -663,6 +664,11 @@ void GEVulkanDriver::destroyVulkan()
|
|||||||
m_depth_texture->drop();
|
m_depth_texture->drop();
|
||||||
m_depth_texture = NULL;
|
m_depth_texture = NULL;
|
||||||
}
|
}
|
||||||
|
if (m_rtt_texture)
|
||||||
|
{
|
||||||
|
m_rtt_texture->drop();
|
||||||
|
m_rtt_texture = NULL;
|
||||||
|
}
|
||||||
if (m_white_texture)
|
if (m_white_texture)
|
||||||
{
|
{
|
||||||
m_white_texture->drop();
|
m_white_texture->drop();
|
||||||
@ -1260,6 +1266,16 @@ found_mode:
|
|||||||
m_depth_texture = new GEVulkanDepthTexture(this,
|
m_depth_texture = new GEVulkanDepthTexture(this,
|
||||||
core::dimension2du(m_swap_chain_extent.width,
|
core::dimension2du(m_swap_chain_extent.width,
|
||||||
m_swap_chain_extent.height));
|
m_swap_chain_extent.height));
|
||||||
|
const float scale = getGEConfig()->m_render_scale;
|
||||||
|
if (scale != 1.0f)
|
||||||
|
{
|
||||||
|
core::dimension2du screen_size = ScreenSize;
|
||||||
|
screen_size.Width *= scale;
|
||||||
|
screen_size.Height *= scale;
|
||||||
|
m_rtt_texture = new GEVulkanFBOTexture(this, screen_size,
|
||||||
|
true/*create_depth*/);
|
||||||
|
m_rtt_texture->createRTT();
|
||||||
|
}
|
||||||
} // createSwapChain
|
} // createSwapChain
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -1595,6 +1611,14 @@ bool GEVulkanDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
|
|||||||
m_clear_color = color;
|
m_clear_color = color;
|
||||||
PrimitivesDrawn = m_rtt_polycount;
|
PrimitivesDrawn = m_rtt_polycount;
|
||||||
m_rtt_polycount = 0;
|
m_rtt_polycount = 0;
|
||||||
|
|
||||||
|
if (m_rtt_texture)
|
||||||
|
{
|
||||||
|
draw2DImage(m_rtt_texture,core::recti(0, 0,
|
||||||
|
ScreenSize.Width, ScreenSize.Height),
|
||||||
|
core::recti(0, 0,
|
||||||
|
m_rtt_texture->getSize().Width, m_rtt_texture->getSize().Height));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} // beginScene
|
} // beginScene
|
||||||
|
|
||||||
@ -2107,9 +2131,9 @@ void GEVulkanDriver::getRotatedRect2D(VkRect2D* rect)
|
|||||||
} // getRotatedRect2D
|
} // getRotatedRect2D
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GEVulkanDriver::getRotatedViewport(VkViewport* vp)
|
void GEVulkanDriver::getRotatedViewport(VkViewport* vp, bool handle_rtt)
|
||||||
{
|
{
|
||||||
if (m_rtt_texture)
|
if (handle_rtt && m_rtt_texture)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VkRect2D rect;
|
VkRect2D rect;
|
||||||
@ -2165,6 +2189,11 @@ void GEVulkanDriver::destroySwapChainRelated(bool handle_surface)
|
|||||||
m_depth_texture->drop();
|
m_depth_texture->drop();
|
||||||
m_depth_texture = NULL;
|
m_depth_texture = NULL;
|
||||||
}
|
}
|
||||||
|
if (m_rtt_texture)
|
||||||
|
{
|
||||||
|
m_rtt_texture->drop();
|
||||||
|
m_rtt_texture = NULL;
|
||||||
|
}
|
||||||
for (VkFramebuffer& framebuffer : m_vk->swap_chain_framebuffers)
|
for (VkFramebuffer& framebuffer : m_vk->swap_chain_framebuffers)
|
||||||
vkDestroyFramebuffer(m_vk->device, framebuffer, NULL);
|
vkDestroyFramebuffer(m_vk->device, framebuffer, NULL);
|
||||||
m_vk->swap_chain_framebuffers.clear();
|
m_vk->swap_chain_framebuffers.clear();
|
||||||
@ -2247,13 +2276,24 @@ void GEVulkanDriver::buildCommandBuffers()
|
|||||||
|
|
||||||
VkRenderPassBeginInfo render_pass_info = {};
|
VkRenderPassBeginInfo render_pass_info = {};
|
||||||
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
render_pass_info.renderPass = getRenderPass();
|
|
||||||
render_pass_info.framebuffer =
|
|
||||||
getSwapChainFramebuffers()[getCurrentImageIndex()];
|
|
||||||
render_pass_info.renderArea.offset = {0, 0};
|
|
||||||
render_pass_info.renderArea.extent = getSwapChainExtent();
|
|
||||||
render_pass_info.clearValueCount = (uint32_t)(clear_values.size());
|
render_pass_info.clearValueCount = (uint32_t)(clear_values.size());
|
||||||
render_pass_info.pClearValues = &clear_values[0];
|
render_pass_info.pClearValues = &clear_values[0];
|
||||||
|
render_pass_info.renderArea.offset = {0, 0};
|
||||||
|
|
||||||
|
if (m_rtt_texture)
|
||||||
|
{
|
||||||
|
render_pass_info.renderPass = m_rtt_texture->getRTTRenderPass();
|
||||||
|
render_pass_info.framebuffer = m_rtt_texture->getRTTFramebuffer();
|
||||||
|
render_pass_info.renderArea.extent = { m_rtt_texture->getSize().Width,
|
||||||
|
m_rtt_texture->getSize().Height };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
render_pass_info.renderPass = getRenderPass();
|
||||||
|
render_pass_info.framebuffer =
|
||||||
|
getSwapChainFramebuffers()[getCurrentImageIndex()];
|
||||||
|
render_pass_info.renderArea.extent = getSwapChainExtent();
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBufferBeginInfo begin_info = {};
|
VkCommandBufferBeginInfo begin_info = {};
|
||||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
@ -2280,6 +2320,18 @@ void GEVulkanDriver::buildCommandBuffers()
|
|||||||
p.second->render(this, p.first);
|
p.second->render(this, p.first);
|
||||||
PrimitivesDrawn += p.second->getPolyCount();
|
PrimitivesDrawn += p.second->getPolyCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_rtt_texture)
|
||||||
|
{
|
||||||
|
vkCmdEndRenderPass(getCurrentCommandBuffer());
|
||||||
|
render_pass_info.renderPass = getRenderPass();
|
||||||
|
render_pass_info.framebuffer =
|
||||||
|
getSwapChainFramebuffers()[getCurrentImageIndex()];
|
||||||
|
render_pass_info.renderArea.extent = getSwapChainExtent();
|
||||||
|
vkCmdBeginRenderPass(getCurrentCommandBuffer(), &render_pass_info,
|
||||||
|
VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
}
|
||||||
|
|
||||||
GEVulkan2dRenderer::render();
|
GEVulkan2dRenderer::render();
|
||||||
|
|
||||||
vkCmdEndRenderPass(getCurrentCommandBuffer());
|
vkCmdEndRenderPass(getCurrentCommandBuffer());
|
||||||
@ -2319,7 +2371,8 @@ ITexture* GEVulkanDriver::addRenderTargetTexture(const core::dimension2d<u32>& s
|
|||||||
const io::path& name, const ECOLOR_FORMAT format,
|
const io::path& name, const ECOLOR_FORMAT format,
|
||||||
const bool useStencil)
|
const bool useStencil)
|
||||||
{
|
{
|
||||||
GEVulkanFBOTexture* rtt = new GEVulkanFBOTexture(size, true/*create_depth*/);
|
GEVulkanFBOTexture* rtt = new GEVulkanFBOTexture(this, size,
|
||||||
|
true/*create_depth*/);
|
||||||
rtt->createRTT();
|
rtt->createRTT();
|
||||||
return rtt;
|
return rtt;
|
||||||
} // addRenderTargetTexture
|
} // addRenderTargetTexture
|
||||||
@ -2329,9 +2382,21 @@ bool GEVulkanDriver::setRenderTarget(video::ITexture* texture,
|
|||||||
bool clearBackBuffer, bool clearZBuffer,
|
bool clearBackBuffer, bool clearZBuffer,
|
||||||
SColor color)
|
SColor color)
|
||||||
{
|
{
|
||||||
m_rtt_texture = dynamic_cast<GEVulkanFBOTexture*>(texture);
|
GEVulkanFBOTexture* new_rtt = dynamic_cast<GEVulkanFBOTexture*>(texture);
|
||||||
if (m_rtt_texture)
|
if (m_separate_rtt_texture == new_rtt)
|
||||||
|
return true;
|
||||||
|
m_separate_rtt_texture = new_rtt;
|
||||||
|
if (m_separate_rtt_texture)
|
||||||
|
{
|
||||||
m_rtt_clear_color = color;
|
m_rtt_clear_color = color;
|
||||||
|
m_prev_rtt_texture = m_rtt_texture;
|
||||||
|
m_rtt_texture = m_separate_rtt_texture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_rtt_texture = m_prev_rtt_texture;
|
||||||
|
m_prev_rtt_texture = NULL;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} // setRenderTarget
|
} // setRenderTarget
|
||||||
|
|
||||||
|
@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
namespace GE
|
namespace GE
|
||||||
{
|
{
|
||||||
GEVulkanFBOTexture::GEVulkanFBOTexture(const core::dimension2d<u32>& size,
|
GEVulkanFBOTexture::GEVulkanFBOTexture(GEVulkanDriver* vk,
|
||||||
|
const core::dimension2d<u32>& size,
|
||||||
bool create_depth)
|
bool create_depth)
|
||||||
: GEVulkanTexture()
|
: GEVulkanTexture()
|
||||||
{
|
{
|
||||||
m_vk = getVKDriver();
|
m_vk = vk;
|
||||||
m_vulkan_device = m_vk->getDevice();
|
m_vulkan_device = m_vk->getDevice();
|
||||||
m_image = VK_NULL_HANDLE;
|
m_image = VK_NULL_HANDLE;
|
||||||
m_vma_allocation = VK_NULL_HANDLE;
|
m_vma_allocation = VK_NULL_HANDLE;
|
||||||
|
@ -16,7 +16,8 @@ private:
|
|||||||
VkFramebuffer m_rtt_frame_buffer;
|
VkFramebuffer m_rtt_frame_buffer;
|
||||||
public:
|
public:
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
GEVulkanFBOTexture(const core::dimension2d<u32>& size, bool create_depth);
|
GEVulkanFBOTexture(GEVulkanDriver* vk, const core::dimension2d<u32>& size,
|
||||||
|
bool create_depth);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual ~GEVulkanFBOTexture();
|
virtual ~GEVulkanFBOTexture();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -214,7 +214,7 @@ void GEVulkanSceneManager::drawAll(irr::u32 flags)
|
|||||||
{
|
{
|
||||||
drawAllInternal();
|
drawAllInternal();
|
||||||
GEVulkanDriver* vk = static_cast<GEVulkanDriver*>(getVideoDriver());
|
GEVulkanDriver* vk = static_cast<GEVulkanDriver*>(getVideoDriver());
|
||||||
GEVulkanFBOTexture* rtt = vk->getRTTTexture();
|
GEVulkanFBOTexture* rtt = vk->getSeparateRTTTexture();
|
||||||
if (!rtt)
|
if (!rtt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user