From 27b5770ea93929663c8c086bd6cdba7ea163d747 Mon Sep 17 00:00:00 2001 From: Benau Date: Sun, 10 Jul 2022 14:48:07 +0800 Subject: [PATCH] Add GEVulkanDepthTexture --- lib/graphics_engine/CMakeLists.txt | 1 + .../include/ge_vulkan_driver.hpp | 6 ++ .../src/ge_vulkan_depth_texture.cpp | 39 ++++++++++ .../src/ge_vulkan_depth_texture.hpp | 53 ++++++++++++++ lib/graphics_engine/src/ge_vulkan_driver.cpp | 71 +++++++++++++++++-- lib/graphics_engine/src/ge_vulkan_texture.cpp | 62 ++++++++-------- lib/graphics_engine/src/ge_vulkan_texture.hpp | 17 +++-- 7 files changed, 208 insertions(+), 41 deletions(-) create mode 100644 lib/graphics_engine/src/ge_vulkan_depth_texture.cpp create mode 100644 lib/graphics_engine/src/ge_vulkan_depth_texture.hpp diff --git a/lib/graphics_engine/CMakeLists.txt b/lib/graphics_engine/CMakeLists.txt index 614103e0a..0edce74ec 100644 --- a/lib/graphics_engine/CMakeLists.txt +++ b/lib/graphics_engine/CMakeLists.txt @@ -29,6 +29,7 @@ set(GE_SOURCES src/ge_vulkan_2d_renderer.cpp src/ge_vulkan_camera_scene_node.cpp src/ge_vulkan_command_loader.cpp + src/ge_vulkan_depth_texture.cpp src/ge_vulkan_driver.cpp src/ge_vulkan_dynamic_buffer.cpp src/ge_vulkan_features.cpp diff --git a/lib/graphics_engine/include/ge_vulkan_driver.hpp b/lib/graphics_engine/include/ge_vulkan_driver.hpp index ca35ab97e..b586d0959 100644 --- a/lib/graphics_engine/include/ge_vulkan_driver.hpp +++ b/lib/graphics_engine/include/ge_vulkan_driver.hpp @@ -22,6 +22,7 @@ using namespace video; namespace GE { + class GEVulkanDepthTexture; class GEVulkanMeshCache; enum GEVulkanSampler : unsigned { @@ -335,6 +336,10 @@ namespace GE void waitIdle(); void setDisableWaitIdle(bool val) { m_disable_wait_idle = val; } IrrlichtDevice* getIrrlichtDevice() const { return m_irrlicht_device; } + GEVulkanDepthTexture* getDepthTexture() const { return m_depth_texture; } + VkFormat findSupportedFormat(const std::vector& candidates, + VkImageTiling tiling, + VkFormatFeatureFlags features); private: struct SwapChainSupportDetails { @@ -452,6 +457,7 @@ namespace GE bool m_disable_wait_idle; IrrlichtDevice* m_irrlicht_device; + GEVulkanDepthTexture* m_depth_texture; void createInstance(SDL_Window* window); void findPhysicalDevice(); diff --git a/lib/graphics_engine/src/ge_vulkan_depth_texture.cpp b/lib/graphics_engine/src/ge_vulkan_depth_texture.cpp new file mode 100644 index 000000000..de240fe4e --- /dev/null +++ b/lib/graphics_engine/src/ge_vulkan_depth_texture.cpp @@ -0,0 +1,39 @@ +#include "ge_vulkan_depth_texture.hpp" + +#include "ge_main.hpp" +#include "ge_vulkan_driver.hpp" + +namespace GE +{ +GEVulkanDepthTexture::GEVulkanDepthTexture(GEVulkanDriver* vk, + const core::dimension2d& size) + : GEVulkanTexture() +{ + m_vk = vk; + m_vulkan_device = m_vk->getDevice(); + m_image = VK_NULL_HANDLE; + m_image_memory = VK_NULL_HANDLE; + m_image_view = VK_NULL_HANDLE; + m_has_mipmaps = false; + m_locked_data = NULL; + m_size = m_orig_size = m_max_size = size; + m_texture_size = m_size.Width * m_size.Height * 4; + + std::vector preferred = + { + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT + }; + m_internal_format = m_vk->findSupportedFormat(preferred, + VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + if (!createImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) + throw std::runtime_error("createImage failed for depth texture"); + + if (!createImageView(VK_IMAGE_ASPECT_DEPTH_BIT)) + throw std::runtime_error("createImageView failed for depth texture"); +} // GEVulkanDepthTexture + +} diff --git a/lib/graphics_engine/src/ge_vulkan_depth_texture.hpp b/lib/graphics_engine/src/ge_vulkan_depth_texture.hpp new file mode 100644 index 000000000..4799a6fcf --- /dev/null +++ b/lib/graphics_engine/src/ge_vulkan_depth_texture.hpp @@ -0,0 +1,53 @@ +#ifndef HEADER_GE_VULKAN_DEPTH_TEXTURE_HPP +#define HEADER_GE_VULKAN_DEPTH_TEXTURE_HPP + +#include "ge_vulkan_texture.hpp" + +namespace GE +{ +class GEVulkanDriver; +class GEVulkanDepthTexture : public GEVulkanTexture +{ +public: + // ------------------------------------------------------------------------ + GEVulkanDepthTexture(GEVulkanDriver* vk, + const core::dimension2d& size); + // ------------------------------------------------------------------------ + virtual ~GEVulkanDepthTexture() {} + // ------------------------------------------------------------------------ + virtual void* lock(video::E_TEXTURE_LOCK_MODE mode = + video::ETLM_READ_WRITE, u32 mipmap_level = 0) + { return NULL; } + // ------------------------------------------------------------------------ + virtual void unlock() {} + // ------------------------------------------------------------------------ + virtual const core::dimension2d& getOriginalSize() const + { return m_orig_size; } + // ------------------------------------------------------------------------ + virtual const core::dimension2d& getSize() const { return m_size; } + // ------------------------------------------------------------------------ + virtual video::E_DRIVER_TYPE getDriverType() const + { return video::EDT_VULKAN; } + // ------------------------------------------------------------------------ + virtual video::ECOLOR_FORMAT getColorFormat() const + { return video::ECF_A8R8G8B8; } + // ------------------------------------------------------------------------ + virtual u32 getPitch() const { return 0; } + // ------------------------------------------------------------------------ + virtual bool hasMipMaps() const { return false; } + // ------------------------------------------------------------------------ + virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {} + // ------------------------------------------------------------------------ + virtual u64 getTextureHandler() const { return (u64)m_image_view; } + // ------------------------------------------------------------------------ + virtual unsigned int getTextureSize() const { return m_texture_size; } + // ------------------------------------------------------------------------ + virtual void reload() {} + // ------------------------------------------------------------------------ + virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format, + u32 w, u32 h, u32 x, u32 y) {} +}; // GEVulkanDepthTexture + +} + +#endif diff --git a/lib/graphics_engine/src/ge_vulkan_driver.cpp b/lib/graphics_engine/src/ge_vulkan_driver.cpp index 832cce56f..0968f53b9 100644 --- a/lib/graphics_engine/src/ge_vulkan_driver.cpp +++ b/lib/graphics_engine/src/ge_vulkan_driver.cpp @@ -5,6 +5,7 @@ #include "ge_vulkan_2d_renderer.hpp" #include "ge_vulkan_camera_scene_node.hpp" #include "ge_vulkan_command_loader.hpp" +#include "ge_vulkan_depth_texture.hpp" #include "ge_vulkan_features.hpp" #include "ge_vulkan_mesh_cache.hpp" #include "ge_vulkan_shader_manager.hpp" @@ -459,7 +460,8 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, SDL_Window* window, IrrlichtDevice* device) : CNullDriver(io, core::dimension2d(0, 0)), - m_params(params), m_irrlicht_device(device) + m_params(params), m_irrlicht_device(device), + m_depth_texture(NULL) { m_vk.reset(new VK()); m_physical_device = VK_NULL_HANDLE; @@ -577,6 +579,11 @@ GEVulkanDriver::~GEVulkanDriver() // ---------------------------------------------------------------------------- void GEVulkanDriver::destroyVulkan() { + if (m_depth_texture) + { + m_depth_texture->drop(); + m_depth_texture = NULL; + } if (m_white_texture) { m_white_texture->drop(); @@ -1158,6 +1165,10 @@ found_mode: throw std::runtime_error("vkCreateImageView failed"); m_vk->swap_chain_image_views.push_back(swap_chain_image_view); } + + m_depth_texture = new GEVulkanDepthTexture(this, + core::dimension2du(m_swap_chain_extent.width, + m_swap_chain_extent.height)); } // createSwapChain // ---------------------------------------------------------------------------- @@ -1283,21 +1294,43 @@ void GEVulkanDriver::createRenderPass() color_attachment_ref.attachment = 0; color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentDescription depth_attachment = {}; + depth_attachment.format = m_depth_texture->getInternalFormat(); + depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentReference depth_attachment_ref = {}; + depth_attachment_ref.attachment = 1; + depth_attachment_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &color_attachment_ref; + subpass.pDepthStencilAttachment = &depth_attachment_ref; VkSubpassDependency dependency = {}; dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.srcAccessMask = 0; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - std::array attachments = { color_attachment }; + std::array attachments = + { + color_attachment, + depth_attachment + }; VkRenderPassCreateInfo render_pass_info = {}; render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; render_pass_info.attachmentCount = (uint32_t)(attachments.size()); @@ -1320,9 +1353,9 @@ void GEVulkanDriver::createFramebuffers() const std::vector& image_views = m_vk->swap_chain_image_views; for (unsigned int i = 0; i < image_views.size(); i++) { - std::array attachments = + std::array attachments = { - image_views[i] + image_views[i], (VkImageView)m_depth_texture->getTextureHandler() }; VkFramebufferCreateInfo framebuffer_info = {}; @@ -1999,6 +2032,11 @@ void GEVulkanDriver::unpauseRendering() void GEVulkanDriver::destroySwapChainRelated(bool handle_surface) { waitIdle(); + if (m_depth_texture) + { + m_depth_texture->drop(); + m_depth_texture = NULL; + } for (VkFramebuffer& framebuffer : m_vk->swap_chain_framebuffers) vkDestroyFramebuffer(m_vk->device, framebuffer, NULL); m_vk->swap_chain_framebuffers.clear(); @@ -2106,6 +2144,25 @@ void GEVulkanDriver::buildCommandBuffers() vkEndCommandBuffer(getCurrentCommandBuffer()); } // buildCommandBuffers +// ---------------------------------------------------------------------------- +VkFormat GEVulkanDriver::findSupportedFormat(const std::vector& candidates, + VkImageTiling tiling, + VkFormatFeatureFlags features) +{ + for (VkFormat format : candidates) + { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(m_physical_device, format, &props); + if (tiling == VK_IMAGE_TILING_LINEAR && + (props.linearTilingFeatures & features) == features) + return format; + else if (tiling == VK_IMAGE_TILING_OPTIMAL && + (props.optimalTilingFeatures & features) == features) + return format; + } + throw std::runtime_error("failed to find supported format!"); +} + } namespace irr diff --git a/lib/graphics_engine/src/ge_vulkan_texture.cpp b/lib/graphics_engine/src/ge_vulkan_texture.cpp index 135313a48..618ebf85f 100644 --- a/lib/graphics_engine/src/ge_vulkan_texture.cpp +++ b/lib/graphics_engine/src/ge_vulkan_texture.cpp @@ -25,8 +25,9 @@ GEVulkanTexture::GEVulkanTexture(const std::string& path, m_vulkan_device(getVKDriver()->getDevice()), m_image(VK_NULL_HANDLE), m_image_memory(VK_NULL_HANDLE), m_image_view(VK_NULL_HANDLE), m_texture_size(0), - m_disable_reload(false), m_single_channel(false), - m_has_mipmaps(true) + m_disable_reload(false), m_has_mipmaps(true), + m_internal_format(VK_FORMAT_R8G8B8A8_UNORM), + m_vk(getVKDriver()) { m_max_size = getDriver()->getDriverAttributes() .getAttributeAsDimension2d("MAX_TEXTURE_SIZE"); @@ -50,8 +51,9 @@ GEVulkanTexture::GEVulkanTexture(video::IImage* img, const std::string& name) m_vulkan_device(getVKDriver()->getDevice()), m_image(VK_NULL_HANDLE), m_image_memory(VK_NULL_HANDLE), m_image_view(VK_NULL_HANDLE), m_texture_size(0), - m_disable_reload(true), m_single_channel(false), - m_has_mipmaps(true) + m_disable_reload(true), m_has_mipmaps(true), + m_internal_format(VK_FORMAT_R8G8B8A8_UNORM), + m_vk(getVKDriver()) { if (!img) { @@ -75,12 +77,14 @@ GEVulkanTexture::GEVulkanTexture(const std::string& name, unsigned int size, m_locked_data(NULL), m_vulkan_device(getVKDriver()->getDevice()), m_image(VK_NULL_HANDLE), m_image_memory(VK_NULL_HANDLE), m_image_view(VK_NULL_HANDLE), m_texture_size(0), - m_disable_reload(true), m_single_channel(single_channel), - m_has_mipmaps(true) + m_disable_reload(true), m_has_mipmaps(true), + m_internal_format(single_channel ? + VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8B8A8_UNORM), + m_vk(getVKDriver()) { - if (m_single_channel && !GEVulkanFeatures::supportsR8Blit()) + if (isSingleChannel() && !GEVulkanFeatures::supportsR8Blit()) m_has_mipmaps = false; - else if (!m_single_channel && !GEVulkanFeatures::supportsRGBA8Blit()) + else if (!isSingleChannel() && !GEVulkanFeatures::supportsRGBA8Blit()) m_has_mipmaps = false; m_orig_size.Width = size; @@ -88,7 +92,7 @@ GEVulkanTexture::GEVulkanTexture(const std::string& name, unsigned int size, m_size = m_orig_size; std::vector data; - data.resize(size * size * (m_single_channel ? 1 : 4), 0); + data.resize(size * size * (isSingleChannel() ? 1 : 4), 0); upload(data.data()); } // GEVulkanTexture @@ -100,7 +104,7 @@ GEVulkanTexture::~GEVulkanTexture() if (m_image_view != VK_NULL_HANDLE || m_image != VK_NULL_HANDLE || m_image_memory != VK_NULL_HANDLE) - getVKDriver()->waitIdle(); + m_vk->waitIdle(); clearVulkanData(); } // ~GEVulkanTexture @@ -114,7 +118,7 @@ bool GEVulkanTexture::createTextureImage(uint8_t* texture_data, getMipmapSizes(); VkDeviceSize mipmap_data_size = 0; - unsigned channels = (m_single_channel ? 1 : 4); + unsigned channels = (isSingleChannel() ? 1 : 4); VkDeviceSize image_size = m_size.Width * m_size.Height * channels; if (generate_hq_mipmap) { @@ -131,7 +135,7 @@ bool GEVulkanTexture::createTextureImage(uint8_t* texture_data, VkBuffer staging_buffer; VkDeviceMemory staging_buffer_memory; - bool success = getVKDriver()->createBuffer(image_total_size, + bool success = m_vk->createBuffer(image_total_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, staging_buffer, @@ -205,8 +209,7 @@ bool GEVulkanTexture::createImage(VkImageUsageFlags usage) image_info.extent.depth = 1; image_info.mipLevels = getMipmapLevels(); image_info.arrayLayers = 1; - image_info.format = - (m_single_channel ? VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8B8A8_UNORM); + image_info.format = m_internal_format; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.usage = usage; @@ -223,7 +226,7 @@ bool GEVulkanTexture::createImage(VkImageUsageFlags usage) vkGetImageMemoryRequirements(m_vulkan_device, m_image, &mem_requirements); VkPhysicalDeviceMemoryProperties mem_properties; - vkGetPhysicalDeviceMemoryProperties(getVKDriver()->getPhysicalDevice(), + vkGetPhysicalDeviceMemoryProperties(m_vk->getPhysicalDevice(), &mem_properties); uint32_t memory_type_index = std::numeric_limits::max(); @@ -378,14 +381,13 @@ bool GEVulkanTexture::createImageView(VkImageAspectFlags aspect_flags) view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view_info.image = m_image; view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - view_info.format = - (m_single_channel ? VK_FORMAT_R8_UNORM : VK_FORMAT_R8G8B8A8_UNORM); + view_info.format = m_internal_format; view_info.subresourceRange.aspectMask = aspect_flags; view_info.subresourceRange.baseMipLevel = 0; view_info.subresourceRange.levelCount = getMipmapLevels(); view_info.subresourceRange.baseArrayLayer = 0; view_info.subresourceRange.layerCount = 1; - if (m_single_channel) + if (isSingleChannel()) { view_info.components.r = VK_COMPONENT_SWIZZLE_ONE; view_info.components.g = VK_COMPONENT_SWIZZLE_ONE; @@ -453,14 +455,14 @@ void GEVulkanTexture::upload(uint8_t* data, bool generate_hq_mipmap) return; if (!createImageView(VK_IMAGE_ASPECT_COLOR_BIT)) return; - m_texture_size = m_size.Width * m_size.Height * (m_single_channel ? 1 : 4); + m_texture_size = m_size.Width * m_size.Height * (isSingleChannel() ? 1 : 4); } // upload // ---------------------------------------------------------------------------- void* GEVulkanTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level) { uint8_t* texture_data = getTextureData(); - if (m_single_channel) + if (isSingleChannel()) { m_locked_data = new uint8_t[m_size.Width * m_size.Height * 4](); for (unsigned int i = 0; i < m_size.Width * m_size.Height; i++) @@ -488,8 +490,8 @@ uint8_t* GEVulkanTexture::getTextureData() VkBuffer buffer; VkDeviceMemory buffer_memory; VkDeviceSize image_size = - m_size.Width * m_size.Height * (m_single_channel ? 1 : 4); - if (!getVKDriver()->createBuffer(image_size, + m_size.Width * m_size.Height * (isSingleChannel() ? 1 : 4); + if (!m_vk->createBuffer(image_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, buffer, buffer_memory)) @@ -548,12 +550,12 @@ void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format, VkBuffer staging_buffer; VkDeviceMemory staging_buffer_memory; - if (m_single_channel) + if (isSingleChannel()) { if (format == video::ECF_R8) { unsigned image_size = w * h; - if (!getVKDriver()->createBuffer(image_size, + if (!m_vk->createBuffer(image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, staging_buffer, @@ -572,7 +574,7 @@ void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format, if (format == video::ECF_R8) { unsigned image_size = w * h * 4; - if (!getVKDriver()->createBuffer(w * h * 4, + if (!m_vk->createBuffer(w * h * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, staging_buffer, @@ -593,7 +595,7 @@ void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format, else if (format == video::ECF_A8R8G8B8) { unsigned image_size = w * h * 4; - if (!getVKDriver()->createBuffer(w * h * 4, + if (!m_vk->createBuffer(w * h * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, staging_buffer, @@ -622,9 +624,9 @@ void GEVulkanTexture::updateTexture(void* data, video::ECOLOR_FORMAT format, copyBufferToImage(command_buffer, staging_buffer, w, h, x, y, 0, 0); bool blit_mipmap = true; - if (m_single_channel && !GEVulkanFeatures::supportsR8Blit()) + if (isSingleChannel() && !GEVulkanFeatures::supportsR8Blit()) blit_mipmap = false; - else if (!m_single_channel && !GEVulkanFeatures::supportsRGBA8Blit()) + else if (!isSingleChannel() && !GEVulkanFeatures::supportsRGBA8Blit()) blit_mipmap = false; if (blit_mipmap) { @@ -720,7 +722,7 @@ void GEVulkanTexture::reload() if (m_image_view != VK_NULL_HANDLE || m_image != VK_NULL_HANDLE || m_image_memory != VK_NULL_HANDLE) - getVKDriver()->waitIdle(); + m_vk->waitIdle(); if (!m_disable_reload) { @@ -745,7 +747,7 @@ void GEVulkanTexture::generateHQMipmap(void* in, 2/*hopcount*/, 2.0f/*alpha*/, 1.0f/*amplifynormal*/, 0.0f/*normalsustainfactor*/); - unsigned channels = (m_single_channel ? 1 : 4); + unsigned channels = (isSingleChannel() ? 1 : 4); #ifdef DEBUG int ret = imBuildMipmapCascade(&cascade, in, mms[0].first.Width, mms[0].first.Height, 1/*layercount*/, channels, diff --git a/lib/graphics_engine/src/ge_vulkan_texture.hpp b/lib/graphics_engine/src/ge_vulkan_texture.hpp index ac1d50811..ac9db95ba 100644 --- a/lib/graphics_engine/src/ge_vulkan_texture.hpp +++ b/lib/graphics_engine/src/ge_vulkan_texture.hpp @@ -16,9 +16,10 @@ using namespace irr; namespace GE { +class GEVulkanDriver; class GEVulkanTexture : public video::ITexture { -private: +protected: core::dimension2d m_size, m_orig_size, m_max_size; std::function m_image_mani; @@ -37,8 +38,6 @@ private: const bool m_disable_reload; - const bool m_single_channel; - bool m_has_mipmaps; GESpinLock m_size_lock; @@ -47,6 +46,10 @@ private: io::path m_full_path; + VkFormat m_internal_format; + + GEVulkanDriver* m_vk; + // ------------------------------------------------------------------------ bool createTextureImage(uint8_t* texture_data, bool generate_hq_mipmap); // ------------------------------------------------------------------------ @@ -98,11 +101,15 @@ private: // ------------------------------------------------------------------------ unsigned getMipmapLevels() const { - if (!hasMipMaps()) + if (!m_has_mipmaps) return 1; return std::floor(std::log2(std::max(m_size.Width, m_size.Height))) + 1; } // ------------------------------------------------------------------------ + bool isSingleChannel() const + { return m_internal_format == VK_FORMAT_R8_UNORM; } + // ------------------------------------------------------------------------ + GEVulkanTexture() : video::ITexture(""), m_disable_reload(true) {} public: // ------------------------------------------------------------------------ GEVulkanTexture(const std::string& path, @@ -171,6 +178,8 @@ public: // ------------------------------------------------------------------------ virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format, u32 w, u32 h, u32 x, u32 y); + // ------------------------------------------------------------------------ + VkFormat getInternalFormat() const { return m_internal_format; } }; // GEVulkanTexture }