From 873ca38c0dc8966cd54a18dd74d40c709d83eb32 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Mon, 26 Sep 2022 18:03:07 -0400 Subject: texture arrays --- engine/xe_descriptors.cpp | 22 ++++++++++++++++++++-- engine/xe_descriptors.hpp | 4 +++- engine/xe_render_system.cpp | 29 ++++++++++++++++++++++++++--- engine/xe_render_system.hpp | 11 ++++++++++- 4 files changed, 59 insertions(+), 7 deletions(-) (limited to 'engine') diff --git a/engine/xe_descriptors.cpp b/engine/xe_descriptors.cpp index 367b26e..00e627a 100644 --- a/engine/xe_descriptors.cpp +++ b/engine/xe_descriptors.cpp @@ -10,9 +10,9 @@ DescriptorSetLayout::Builder &DescriptorSetLayout::Builder::addBinding( uint32_t binding, VkDescriptorType descriptorType, VkShaderStageFlags stageFlags, - VkSampler *sampler) { + VkSampler *sampler, + uint32_t count) { assert(bindings.count(binding) == 0 && "Binding already in use"); - uint32_t count = 1; VkDescriptorSetLayoutBinding layoutBinding{}; layoutBinding.binding = binding; layoutBinding.descriptorType = descriptorType; @@ -167,6 +167,24 @@ DescriptorWriter &DescriptorWriter::writeImage( return *this; } +DescriptorWriter &DescriptorWriter::writeImageArray( + uint32_t binding, std::vector *imageInfos) { + assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding"); + + auto &bindingDescription = setLayout.bindings[binding]; + + VkWriteDescriptorSet write{}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.descriptorType = bindingDescription.descriptorType; + write.dstBinding = binding; + write.dstArrayElement = 0; + write.pImageInfo = imageInfos->data(); + write.descriptorCount = imageInfos->size(); + + writes.push_back(write); + return *this; +} + bool DescriptorWriter::build(VkDescriptorSet &set) { bool success = pool.allocateDescriptor(setLayout.getDescriptorSetLayout(), set); if (!success) { diff --git a/engine/xe_descriptors.hpp b/engine/xe_descriptors.hpp index ea635c5..7f5c159 100644 --- a/engine/xe_descriptors.hpp +++ b/engine/xe_descriptors.hpp @@ -19,7 +19,8 @@ class DescriptorSetLayout { uint32_t binding, VkDescriptorType descriptorType, VkShaderStageFlags stageFlags, - VkSampler *sampler); + VkSampler *sampler, + uint32_t count); std::unique_ptr build() const; private: @@ -90,6 +91,7 @@ class DescriptorWriter { DescriptorWriter &writeBuffer(uint32_t binding, VkDescriptorBufferInfo *bufferInfo); DescriptorWriter &writeImage(uint32_t binding, VkDescriptorImageInfo *imageInfo); + DescriptorWriter &writeImageArray(uint32_t binding, std::vector *imageInfos); bool build(VkDescriptorSet &set); void overwrite(VkDescriptorSet &set); diff --git a/engine/xe_render_system.cpp b/engine/xe_render_system.cpp index cdfe3cb..f2f0e43 100644 --- a/engine/xe_render_system.cpp +++ b/engine/xe_render_system.cpp @@ -8,6 +8,7 @@ RenderSystem::RenderSystem( std::string frag, std::map uniformBindings, std::map imageBindings, + std::map> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, std::vector attributeDescptions, @@ -17,7 +18,8 @@ RenderSystem::RenderSystem( xeDescriptorPool{xeEngine.xeDescriptorPool}, pushCunstantDataSize{pushCunstantDataSize}, uniformBindings{uniformBindings}, - imageBindings{imageBindings} { + imageBindings{imageBindings}, + imageArrayBindings{imageArrayBindings} { createDescriptorSetLayout(); createUniformBuffers(); createDescriptorSets(); @@ -33,11 +35,15 @@ void RenderSystem::createDescriptorSetLayout() { DescriptorSetLayout::Builder builder{xeDevice}; for ( const auto &[binding, size]: uniformBindings) { - builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr); + builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr, 1); } for ( const auto &[binding, image]: imageBindings) { - builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &(image->textureSampler)); + builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &(image->textureSampler), 1); + } + + for ( const auto &[binding, images]: imageArrayBindings) { + builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0, images.size()); } xeDescriptorSetLayout = builder.build(); @@ -88,6 +94,18 @@ void RenderSystem::updateDescriptorSet(int frameIndex, bool allocate) { writer.writeImage(binding, &imageInfo); } + std::vector imageInfos{}; + for ( const auto &[binding, images]: imageArrayBindings) { + for( const auto &image: images) { + VkDescriptorImageInfo imageInfo{}; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageInfo.imageView = image->textureImageView; + imageInfo.sampler = image->textureSampler; + imageInfos.push_back(imageInfo); + } + writer.writeImageArray(binding, &imageInfos); + } + if (allocate) { writer.build(descriptorSets[frameIndex]); } else { @@ -183,6 +201,11 @@ void RenderSystem::loadTexture(uint32_t binding, Image *image) { updateDescriptorSet(xeRenderer.getFrameIndex(), false); } +void RenderSystem::loadTextureArray(uint32_t binding, std::vector& images) { + imageArrayBindings[binding] = images; + updateDescriptorSet(xeRenderer.getFrameIndex(), false); +} + void RenderSystem::render(GameObject &gameObject) { gameObject.model->bind(xeRenderer.getCurrentCommandBuffer()); diff --git a/engine/xe_render_system.hpp b/engine/xe_render_system.hpp index 045f6db..b82d6e7 100644 --- a/engine/xe_render_system.hpp +++ b/engine/xe_render_system.hpp @@ -54,19 +54,25 @@ class RenderSystem { return *this; } + Builder& addTextureArrayBinding(uint32_t binding, std::vector& image) { + imageArrayBindings[binding] = image; + return *this; + } + Builder& setCulling(bool enabled) { cullingEnabled = enabled; return *this; } std::unique_ptr build() { - return std::make_unique(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize)); + return std::make_unique(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(imageArrayBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize)); } private: std::map uniformBindings{}; std::map imageBindings{}; + std::map> imageArrayBindings{}; uint32_t pushCunstantDataSize{0}; std::vector attributeDescptions{}; @@ -86,6 +92,7 @@ class RenderSystem { std::string frag, std::map uniformBindings, std::map imageBindings, + std::map> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, std::vector attributeDescptions, @@ -101,6 +108,7 @@ class RenderSystem { void loadPushConstant(void *pushConstantData); void loadUniformObject(uint32_t binding, void *uniformBufferData); void loadTexture(uint32_t binding, Image *image); + void loadTextureArray(uint32_t binding, std::vector &images); void render(GameObject &gameObject); void stop(); @@ -123,6 +131,7 @@ class RenderSystem { std::map>> uboBuffers{}; std::map uniformBindings; std::map imageBindings; + std::map> imageArrayBindings{}; std::vector descriptorSets; uint32_t pushCunstantDataSize; -- cgit v1.2.3-freya