From 3d0d666e09b5a71a41b44b2246bc5fb4bed2e4fb Mon Sep 17 00:00:00 2001 From: Benau Date: Thu, 21 Jul 2022 12:26:06 +0800 Subject: [PATCH] Add texture mapping --- data/shaders/ge_shaders/solid.frag | 7 +- data/shaders/ge_shaders/solid.vert | 11 ++- .../ge_shaders/utils/sample_mesh_texture.h | 87 +++++++++++++++++++ .../include/ge_vulkan_driver.hpp | 4 + .../include/ge_vulkan_scene_manager.hpp | 2 + .../include/ge_vulkan_texture_descriptor.hpp | 13 +-- .../src/ge_vulkan_draw_call.cpp | 75 +++++++++++++--- .../src/ge_vulkan_draw_call.hpp | 19 +++- lib/graphics_engine/src/ge_vulkan_driver.cpp | 10 ++- .../src/ge_vulkan_features.cpp | 42 ++++++--- .../src/ge_vulkan_features.hpp | 2 + .../src/ge_vulkan_scene_manager.cpp | 10 +++ .../src/ge_vulkan_shader_manager.cpp | 13 +++ .../src/ge_vulkan_shader_manager.hpp | 2 + 14 files changed, 264 insertions(+), 33 deletions(-) create mode 100644 data/shaders/ge_shaders/utils/sample_mesh_texture.h diff --git a/data/shaders/ge_shaders/solid.frag b/data/shaders/ge_shaders/solid.frag index ab91840ba..74adeed15 100644 --- a/data/shaders/ge_shaders/solid.frag +++ b/data/shaders/ge_shaders/solid.frag @@ -1,8 +1,13 @@ layout(location = 0) in vec4 f_vertex_color; +layout(location = 1) in vec2 f_uv; +layout(location = 2) flat in int f_material_id; layout(location = 0) out vec4 o_color; +#include "utils/sample_mesh_texture.h" + void main() { - o_color = f_vertex_color; + vec3 mixed_color = sampleMeshTexture0(f_material_id, f_uv).xyz * f_vertex_color.xyz; + o_color = vec4(mixed_color, 1.0); } diff --git a/data/shaders/ge_shaders/solid.vert b/data/shaders/ge_shaders/solid.vert index a79aa9b4a..e280aa2fe 100644 --- a/data/shaders/ge_shaders/solid.vert +++ b/data/shaders/ge_shaders/solid.vert @@ -1,4 +1,4 @@ -layout(std140, set = 0, binding = 0) uniform CameraBuffer +layout(std140, set = 1, binding = 0) uniform CameraBuffer { mat4 m_view_matrix; mat4 m_projection_matrix; @@ -10,9 +10,12 @@ layout(std140, set = 0, binding = 0) uniform CameraBuffer struct ObjectData { mat4 m_model; + int m_skinning_offest; + int m_material_id; + vec2 m_texture_trans; }; -layout(std140, set = 0, binding = 1) readonly buffer ObjectBuffer +layout(std140, set = 1, binding = 1) readonly buffer ObjectBuffer { ObjectData m_objects[]; } u_object_buffer; @@ -27,6 +30,8 @@ layout(location = 6) in ivec4 v_joint; layout(location = 7) in vec4 v_weight; layout(location = 0) out vec4 f_vertex_color; +layout(location = 1) out vec2 f_uv; +layout(location = 2) flat out int f_material_id; void main() { @@ -34,4 +39,6 @@ void main() gl_Position = u_camera.m_projection_view_matrix * model_matrix * vec4(v_position, 1.0); f_vertex_color = v_color.zyxw; + f_uv = v_uv; + f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id; } diff --git a/data/shaders/ge_shaders/utils/sample_mesh_texture.h b/data/shaders/ge_shaders/utils/sample_mesh_texture.h new file mode 100644 index 000000000..d5ba85d1f --- /dev/null +++ b/data/shaders/ge_shaders/utils/sample_mesh_texture.h @@ -0,0 +1,87 @@ +#ifdef BIND_MESH_TEXTURES_AT_ONCE +layout(binding = 0) uniform sampler2D f_mesh_textures[SAMPLER_SIZE * TOTAL_MESH_TEXTURE_LAYER]; + +vec4 sampleMeshTexture0(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 0], uv); +} + +vec4 sampleMeshTexture1(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 1], uv); +} + +vec4 sampleMeshTexture2(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 2], uv); +} + +vec4 sampleMeshTexture3(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 3], uv); +} + +vec4 sampleMeshTexture4(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 4], uv); +} + +vec4 sampleMeshTexture5(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 5], uv); +} + +vec4 sampleMeshTexture6(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 6], uv); +} + +vec4 sampleMeshTexture7(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 7], uv); +} +#else +layout(binding = 0) uniform sampler2D f_mesh_textures[TOTAL_MESH_TEXTURE_LAYER]; + +vec4 sampleMeshTexture0(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[0], uv); +} + +vec4 sampleMeshTexture1(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[1], uv); +} + +#ifdef PBR_ENABLED +vec4 sampleMeshTexture2(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[2], uv); +} + +vec4 sampleMeshTexture3(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[3], uv); +} + +vec4 sampleMeshTexture4(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[4], uv); +} + +vec4 sampleMeshTexture5(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[5], uv); +} + +vec4 sampleMeshTexture6(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[6], uv); +} + +vec4 sampleMeshTexture7(int material_id, vec2 uv) +{ + return texture(f_mesh_textures[7], uv); +} +#endif +#endif diff --git a/lib/graphics_engine/include/ge_vulkan_driver.hpp b/lib/graphics_engine/include/ge_vulkan_driver.hpp index 403f71cff..bd67c9bb0 100644 --- a/lib/graphics_engine/include/ge_vulkan_driver.hpp +++ b/lib/graphics_engine/include/ge_vulkan_driver.hpp @@ -25,6 +25,7 @@ namespace GE { class GEVulkanDepthTexture; class GEVulkanMeshCache; + class GEVulkanTextureDescriptor; enum GEVulkanSampler : unsigned { GVS_MIN = 0, @@ -343,6 +344,8 @@ namespace GE VkFormatFeatureFlags features); VmaAllocator getVmaAllocator() const { return m_vk->allocator; } GEVulkanMeshCache* getVulkanMeshCache() const; + GEVulkanTextureDescriptor* getMeshTextureDescriptor() const + { return m_mesh_texture_descriptor; } private: struct SwapChainSupportDetails { @@ -469,6 +472,7 @@ namespace GE IrrlichtDevice* m_irrlicht_device; GEVulkanDepthTexture* m_depth_texture; + GEVulkanTextureDescriptor* m_mesh_texture_descriptor; void createInstance(SDL_Window* window); void findPhysicalDevice(); diff --git a/lib/graphics_engine/include/ge_vulkan_scene_manager.hpp b/lib/graphics_engine/include/ge_vulkan_scene_manager.hpp index 440cd7a85..6d8bb5db7 100644 --- a/lib/graphics_engine/include/ge_vulkan_scene_manager.hpp +++ b/lib/graphics_engine/include/ge_vulkan_scene_manager.hpp @@ -45,6 +45,8 @@ public: const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f), bool alsoAddIfMeshPointerZero = false); // ------------------------------------------------------------------------ + virtual void clear(); + // ------------------------------------------------------------------------ virtual void drawAll(irr::u32 flags = 0xFFFFFFFF); // ------------------------------------------------------------------------ virtual irr::u32 registerNodeForRendering(irr::scene::ISceneNode* node, diff --git a/lib/graphics_engine/include/ge_vulkan_texture_descriptor.hpp b/lib/graphics_engine/include/ge_vulkan_texture_descriptor.hpp index 3fad1bd32..e31226f63 100644 --- a/lib/graphics_engine/include/ge_vulkan_texture_descriptor.hpp +++ b/lib/graphics_engine/include/ge_vulkan_texture_descriptor.hpp @@ -54,6 +54,13 @@ public: // ------------------------------------------------------------------------ ~GEVulkanTextureDescriptor(); // ------------------------------------------------------------------------ + void clear() + { + m_texture_list.clear(); + m_needs_update_descriptor = true; + m_recreate_next_frame = false; + } + // ------------------------------------------------------------------------ void handleDeletedTextures() { bool has_deleted_image_view = false; @@ -69,11 +76,7 @@ public: } } if (has_deleted_image_view || m_recreate_next_frame) - { - m_texture_list.clear(); - m_needs_update_descriptor = true; - m_recreate_next_frame = false; - } + clear(); } // ------------------------------------------------------------------------ int getTextureID(const irr::video::ITexture** list); diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp index 42124ac24..350bec064 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp @@ -7,12 +7,25 @@ #include "ge_vulkan_camera_scene_node.hpp" #include "ge_vulkan_driver.hpp" #include "ge_vulkan_dynamic_buffer.hpp" +#include "ge_vulkan_features.hpp" #include "ge_vulkan_mesh_cache.hpp" #include "ge_vulkan_mesh_scene_node.hpp" #include "ge_vulkan_shader_manager.hpp" +#include "ge_vulkan_texture_descriptor.hpp" namespace GE { +// ============================================================================ +ObjectData::ObjectData(irr::scene::ISceneNode* node, int material_id) +{ + memcpy(m_mat_1, node->getAbsoluteTransformation().pointer(), + sizeof(irr::core::matrix4)); + m_skinning_offset = -1; + m_material_id = material_id; + m_texture_trans[0] = 0.0f; + m_texture_trans[1] = 0.0f; +} // ObjectData + // ---------------------------------------------------------------------------- GEVulkanDrawCall::GEVulkanDrawCall() { @@ -29,6 +42,7 @@ GEVulkanDrawCall::GEVulkanDrawCall() m_descriptor_pool = VK_NULL_HANDLE; m_graphics_pipeline = VK_NULL_HANDLE; m_pipeline_layout = VK_NULL_HANDLE; + m_texture_descriptor = getVKDriver()->getMeshTextureDescriptor(); } // GEVulkanDrawCall // ---------------------------------------------------------------------------- @@ -86,11 +100,26 @@ void GEVulkanDrawCall::generate() unsigned accumulated_instance = 0; for (auto& p : m_visible_nodes) { + irr::video::SMaterial& m = p.first->getMaterial(); + std::array textures = + {{ + m.TextureLayer[0].Texture, + m.TextureLayer[1].Texture, + m.TextureLayer[2].Texture, + m.TextureLayer[3].Texture, + m.TextureLayer[4].Texture, + m.TextureLayer[5].Texture, + m.TextureLayer[6].Texture, + m.TextureLayer[7].Texture + }}; + const irr::video::ITexture** list = &textures[0]; + const int material_id = m_texture_descriptor->getTextureID(list); + m_materials.push_back(material_id); unsigned visible_count = p.second.size(); if (visible_count != 0) { for (auto* node : p.second) - m_visible_trans.push_back(node->getAbsoluteTransformation()); + m_visible_objects.emplace_back(node, material_id); VkDrawIndexedIndirectCommand cmd; cmd.indexCount = p.first->getIndexCount(); cmd.instanceCount = visible_count; @@ -110,7 +139,8 @@ void GEVulkanDrawCall::prepare(GEVulkanCameraSceneNode* cam) { m_visible_nodes.clear(); m_cmds.clear(); - m_visible_trans.clear(); + m_visible_objects.clear(); + m_materials.clear(); m_culling_tool->init(cam); } // prepare @@ -192,10 +222,16 @@ void GEVulkanDrawCall::createVulkanData() } // m_pipeline_layout + std::array all_layouts = + {{ + *m_texture_descriptor->getDescriptorSetLayout(), + m_data_layout + }}; + VkPipelineLayoutCreateInfo pipeline_layout_info = {}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = 1; - pipeline_layout_info.pSetLayouts = &m_data_layout; + pipeline_layout_info.setLayoutCount = all_layouts.size(); + pipeline_layout_info.pSetLayouts = all_layouts.data(); result = vkCreatePipelineLayout(vk->getDevice(), &pipeline_layout_info, NULL, &m_pipeline_layout); @@ -366,13 +402,13 @@ void GEVulkanDrawCall::createVulkanData() if (result != VK_SUCCESS) throw std::runtime_error("vkCreateGraphicsPipelines failed"); - size_t size = m_visible_trans.size(); - if (m_visible_trans.empty()) + size_t size = m_visible_objects.size(); + if (m_visible_objects.empty()) size = 100; m_dynamic_data = new GEVulkanDynamicBuffer(GVDBT_GPU_RAM, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - (sizeof(irr::core::matrix4) * size) + sizeof(GEVulkanCameraUBO)); + (sizeof(ObjectData) * size) + sizeof(GEVulkanCameraUBO)); } // createVulkanData // ---------------------------------------------------------------------------- @@ -385,7 +421,7 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk, const VkPhysicalDeviceLimits& limit = vk->getPhysicalDeviceProperties().limits; const size_t object_data_size = - sizeof(irr::core::matrix4) * m_visible_trans.size(); + sizeof(ObjectData) * m_visible_objects.size(); size_t ubo_alignment = limit.minUniformBufferOffsetAlignment; size_t ubo_padding = 0; if (ubo_alignment > 0) @@ -393,7 +429,7 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk, m_object_data_padded_size = object_data_size + ubo_padding; std::vector > data; - data.emplace_back((void*)m_visible_trans.data(), object_data_size); + data.emplace_back((void*)m_visible_objects.data(), object_data_size); if (ubo_padding > 0) data.emplace_back((void*)m_object_data_padding, ubo_padding); data.emplace_back(cam->getUBOData(), sizeof(GEVulkanCameraUBO)); @@ -455,11 +491,20 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam) vkUpdateDescriptorSets(vk->getDevice(), data_set.size(), data_set.data(), 0, NULL); + m_texture_descriptor->updateDescriptor(); + vkCmdBindPipeline(vk->getCurrentCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphics_pipeline); + if (GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + { + vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, + m_texture_descriptor->getDescriptorSet(), 0, NULL); + } + vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), - VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1, &m_data_descriptor_sets[cur_frame], 0, NULL); VkDeviceSize offsets[] = {0}; @@ -488,8 +533,16 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam) scissor.extent.height = vp.height; vkCmdSetScissor(vk->getCurrentCommandBuffer(), 0, 1, &scissor); - for (VkDrawIndexedIndirectCommand& cmd : m_cmds) + for (unsigned i = 0; i < m_cmds.size(); i++) { + if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + { + vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, + &m_texture_descriptor->getDescriptorSet()[m_materials[i]], 0, + NULL); + } + const VkDrawIndexedIndirectCommand& cmd = m_cmds[i]; vkCmdDrawIndexed(vk->getCurrentCommandBuffer(), cmd.indexCount, cmd.instanceCount, cmd.firstIndex, cmd.vertexOffset, cmd.firstInstance); diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp index efbf6c7c6..1958582d8 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp @@ -20,6 +20,20 @@ class GESPMBuffer; class GEVulkanCameraSceneNode; class GEVulkanDriver; class GEVulkanDynamicBuffer; +class GEVulkanTextureDescriptor; + +struct ObjectData +{ + float m_mat_1[4]; + float m_mat_2[4]; + float m_mat_3[4]; + float m_mat_4[4]; + int m_skinning_offset; + int m_material_id; + float m_texture_trans[2]; + // ------------------------------------------------------------------------ + ObjectData(irr::scene::ISceneNode* node, int material_id); +}; class GEVulkanDrawCall { @@ -30,7 +44,7 @@ private: std::vector m_cmds; - std::vector m_visible_trans; + std::vector m_visible_objects; GEVulkanDynamicBuffer* m_dynamic_data; @@ -48,6 +62,9 @@ private: VkPipeline m_graphics_pipeline; + std::vector m_materials; + + GEVulkanTextureDescriptor* m_texture_descriptor; // ------------------------------------------------------------------------ void createVulkanData(); public: diff --git a/lib/graphics_engine/src/ge_vulkan_driver.cpp b/lib/graphics_engine/src/ge_vulkan_driver.cpp index 21ac2f3ef..ecbc9dd85 100644 --- a/lib/graphics_engine/src/ge_vulkan_driver.cpp +++ b/lib/graphics_engine/src/ge_vulkan_driver.cpp @@ -11,7 +11,7 @@ #include "ge_vulkan_mesh_cache.hpp" #include "ge_vulkan_scene_manager.hpp" #include "ge_vulkan_shader_manager.hpp" -#include "ge_vulkan_texture.hpp" +#include "ge_vulkan_texture_descriptor.hpp" #include "ISceneManager.h" #include "IrrlichtDevice.h" @@ -490,7 +490,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params, IrrlichtDevice* device) : CNullDriver(io, core::dimension2d(0, 0)), m_params(params), m_irrlicht_device(device), - m_depth_texture(NULL) + m_depth_texture(NULL), m_mesh_texture_descriptor(NULL) { m_vk.reset(new VK()); m_physical_device = VK_NULL_HANDLE; @@ -622,6 +622,10 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params, GE::setVideoDriver(this); createUnicolorTextures(); GEVulkan2dRenderer::init(this); + m_mesh_texture_descriptor = new GEVulkanTextureDescriptor( + GEVulkanShaderManager::getSamplerSize(), + GEVulkanShaderManager::getMeshTextureLayer(), + GEVulkanFeatures::supportsBindMeshTexturesAtOnce()); GEVulkanFeatures::printStats(); } catch (std::exception& e) @@ -666,6 +670,7 @@ void GEVulkanDriver::destroyVulkan() if (m_irrlicht_device->getSceneManager() && m_irrlicht_device->getSceneManager()->getMeshCache()) getVulkanMeshCache()->destroy(); + delete m_mesh_texture_descriptor; GEVulkan2dRenderer::destroy(); GEVulkanShaderManager::destroy(); @@ -2220,6 +2225,7 @@ VkFormat GEVulkanDriver::findSupportedFormat(const std::vector& candid void GEVulkanDriver::handleDeletedTextures() { GEVulkan2dRenderer::handleDeletedTextures(); + m_mesh_texture_descriptor->handleDeletedTextures(); } // handleDeletedTextures } diff --git a/lib/graphics_engine/src/ge_vulkan_features.cpp b/lib/graphics_engine/src/ge_vulkan_features.cpp index 7835334e8..425a3c72f 100644 --- a/lib/graphics_engine/src/ge_vulkan_features.cpp +++ b/lib/graphics_engine/src/ge_vulkan_features.cpp @@ -3,6 +3,7 @@ #include "ge_vulkan_driver.hpp" #include "ge_vulkan_shader_manager.hpp" +#include #include #include #include @@ -21,6 +22,7 @@ bool g_supports_r8_blit = false; bool g_supports_descriptor_indexing = false; bool g_supports_non_uniform_indexing = false; bool g_supports_partially_bound = false; +uint32_t g_max_sampler_supported = 0; } // GEVulkanFeatures // ============================================================================ @@ -34,14 +36,15 @@ void GEVulkanFeatures::init(GEVulkanDriver* vk) // https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxPerStageDescriptorSamplers&platform=all // https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxPerStageDescriptorSampledImages&platform=all // We decide 256 (GEVulkanShaderManager::getSamplerSize()) based on those infos + g_max_sampler_supported = std::min( + { + limit.maxDescriptorSetSamplers, + limit.maxDescriptorSetSampledImages, + limit.maxPerStageDescriptorSamplers, + limit.maxPerStageDescriptorSampledImages + }); const unsigned max_sampler_size = GEVulkanShaderManager::getSamplerSize(); - if (limit.maxDescriptorSetSamplers < max_sampler_size) - g_supports_bind_textures_at_once = false; - if (limit.maxDescriptorSetSampledImages < max_sampler_size) - g_supports_bind_textures_at_once = false; - if (limit.maxPerStageDescriptorSamplers < max_sampler_size) - g_supports_bind_textures_at_once = false; - if (limit.maxPerStageDescriptorSampledImages < max_sampler_size) + if (max_sampler_size > g_max_sampler_supported) g_supports_bind_textures_at_once = false; if (vk->getPhysicalDeviceFeatures().shaderSampledImageArrayDynamicIndexing == VK_FALSE) { @@ -107,11 +110,15 @@ void GEVulkanFeatures::init(GEVulkanDriver* vk) if (props2.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES) { + g_max_sampler_supported = std::min( + { + props2.maxPerStageDescriptorUpdateAfterBindSamplers, + props2.maxPerStageDescriptorUpdateAfterBindSampledImages, + props2.maxDescriptorSetUpdateAfterBindSamplers, + props2.maxDescriptorSetUpdateAfterBindSampledImages + }); g_supports_bind_textures_at_once = - props2.maxPerStageDescriptorUpdateAfterBindSamplers > max_sampler_size && - props2.maxPerStageDescriptorUpdateAfterBindSampledImages > max_sampler_size && - props2.maxDescriptorSetUpdateAfterBindSamplers > max_sampler_size && - props2.maxDescriptorSetUpdateAfterBindSampledImages > max_sampler_size; + g_max_sampler_supported >= max_sampler_size; } } } // init @@ -122,6 +129,9 @@ void GEVulkanFeatures::printStats() os::Printer::log( "Vulkan can bind textures at once in shader", g_supports_bind_textures_at_once ? "true" : "false"); + os::Printer::log( + "Vulkan can bind mesh textures at once in shader", + supportsBindMeshTexturesAtOnce() ? "true" : "false"); os::Printer::log( "Vulkan supports linear blitting for rgba8", g_supports_rgba8_blit ? "true" : "false"); @@ -182,4 +192,14 @@ bool GEVulkanFeatures::supportsPartiallyBound() return g_supports_partially_bound; } // supportsPartiallyBound +// ---------------------------------------------------------------------------- +bool GEVulkanFeatures::supportsBindMeshTexturesAtOnce() +{ + if (!g_supports_bind_textures_at_once) + return false; + const unsigned sampler_count = GEVulkanShaderManager::getSamplerSize() * + GEVulkanShaderManager::getMeshTextureLayer(); + return g_max_sampler_supported >= sampler_count; +} // supportsBindMeshTexturesAtOnce + } diff --git a/lib/graphics_engine/src/ge_vulkan_features.hpp b/lib/graphics_engine/src/ge_vulkan_features.hpp index ea33e296f..5582e917c 100644 --- a/lib/graphics_engine/src/ge_vulkan_features.hpp +++ b/lib/graphics_engine/src/ge_vulkan_features.hpp @@ -26,6 +26,8 @@ bool supportsNonUniformIndexing(); bool supportsDifferentTexturePerDraw(); // ---------------------------------------------------------------------------- bool supportsPartiallyBound(); +// ---------------------------------------------------------------------------- +bool supportsBindMeshTexturesAtOnce(); }; // GEVulkanFeatures } diff --git a/lib/graphics_engine/src/ge_vulkan_scene_manager.cpp b/lib/graphics_engine/src/ge_vulkan_scene_manager.cpp index 95f2bcf9c..9748c8cb7 100644 --- a/lib/graphics_engine/src/ge_vulkan_scene_manager.cpp +++ b/lib/graphics_engine/src/ge_vulkan_scene_manager.cpp @@ -6,8 +6,10 @@ #include "ge_vulkan_animated_mesh_scene_node.hpp" #include "ge_vulkan_camera_scene_node.hpp" #include "ge_vulkan_draw_call.hpp" +#include "ge_vulkan_driver.hpp" #include "ge_vulkan_mesh_cache.hpp" #include "ge_vulkan_mesh_scene_node.hpp" +#include "ge_vulkan_texture_descriptor.hpp" namespace GE { @@ -28,6 +30,14 @@ GEVulkanSceneManager::~GEVulkanSceneManager() { } // ~GEVulkanSceneManager +// ---------------------------------------------------------------------------- +void GEVulkanSceneManager::clear() +{ + irr::scene::CSceneManager::clear(); + static_cast(getVideoDriver()) + ->getMeshTextureDescriptor()->clear(); +} // clear + // ---------------------------------------------------------------------------- irr::scene::ICameraSceneNode* GEVulkanSceneManager::addCameraSceneNode( irr::scene::ISceneNode* parent, diff --git a/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp b/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp index d7e165f8a..9273c6f0a 100644 --- a/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp +++ b/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp @@ -21,6 +21,10 @@ GEVulkanDriver* g_vk = NULL; irr::io::IFileSystem* g_file_system = NULL; std::string g_predefines = ""; + +// More when PBR is used later +uint32_t g_mesh_texture_layer = 2; + uint32_t g_sampler_size = 256; std::map g_shaders; @@ -109,8 +113,11 @@ void GEVulkanShaderManager::init(GEVulkanDriver* vk) std::ostringstream oss; oss << "#version 450\n"; oss << "#define SAMPLER_SIZE " << g_sampler_size << "\n"; + oss << "#define TOTAL_MESH_TEXTURE_LAYER " << g_mesh_texture_layer << "\n"; if (GEVulkanFeatures::supportsBindTexturesAtOnce()) oss << "#define BIND_TEXTURES_AT_ONCE\n"; + if (GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + oss << "#define BIND_MESH_TEXTURES_AT_ONCE\n"; if (GEVulkanFeatures::supportsDifferentTexturePerDraw()) { @@ -222,6 +229,12 @@ unsigned GEVulkanShaderManager::getSamplerSize() return g_sampler_size; } // getSamplerSize +// ---------------------------------------------------------------------------- +unsigned GEVulkanShaderManager::getMeshTextureLayer() +{ + return g_mesh_texture_layer; +} // getMeshTextureLayer + // ---------------------------------------------------------------------------- VkShaderModule GEVulkanShaderManager::getShader(const std::string& filename) { diff --git a/lib/graphics_engine/src/ge_vulkan_shader_manager.hpp b/lib/graphics_engine/src/ge_vulkan_shader_manager.hpp index 67ee1932a..b1e1923ef 100644 --- a/lib/graphics_engine/src/ge_vulkan_shader_manager.hpp +++ b/lib/graphics_engine/src/ge_vulkan_shader_manager.hpp @@ -22,6 +22,8 @@ VkShaderModule getShader(const std::string& filename); VkShaderModule loadShader(shaderc_shader_kind, const std::string&); // ---------------------------------------------------------------------------- unsigned getSamplerSize(); +// ---------------------------------------------------------------------------- +unsigned getMeshTextureLayer(); }; // GEVulkanShaderManager }