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