diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/xe_descriptors.cpp | 22 | ||||
-rw-r--r-- | engine/xe_descriptors.hpp | 4 | ||||
-rw-r--r-- | engine/xe_render_system.cpp | 29 | ||||
-rw-r--r-- | engine/xe_render_system.hpp | 11 |
4 files changed, 59 insertions, 7 deletions
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<VkDescriptorImageInfo> *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<DescriptorSetLayout> 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<VkDescriptorImageInfo> *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<uint32_t, uint32_t> uniformBindings, std::map<uint32_t, Image*> imageBindings, + std::map<uint32_t, std::vector<Image*>> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> 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<VkDescriptorImageInfo> 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<Image*>& 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*>& image) { + imageArrayBindings[binding] = image; + return *this; + } + Builder& setCulling(bool enabled) { cullingEnabled = enabled; return *this; } std::unique_ptr<RenderSystem> build() { - return std::make_unique<RenderSystem>(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<RenderSystem>(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<uint32_t, uint32_t> uniformBindings{}; std::map<uint32_t, Image*> imageBindings{}; + std::map<uint32_t, std::vector<Image*>> imageArrayBindings{}; uint32_t pushCunstantDataSize{0}; std::vector<VkVertexInputAttributeDescription> attributeDescptions{}; @@ -86,6 +92,7 @@ class RenderSystem { std::string frag, std::map<uint32_t, uint32_t> uniformBindings, std::map<uint32_t, Image*> imageBindings, + std::map<uint32_t, std::vector<Image*>> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> 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<Image*> &images); void render(GameObject &gameObject); void stop(); @@ -123,6 +131,7 @@ class RenderSystem { std::map<uint32_t, std::vector<std::unique_ptr<Buffer>>> uboBuffers{}; std::map<uint32_t, uint32_t> uniformBindings; std::map<uint32_t, Image*> imageBindings; + std::map<uint32_t, std::vector<Image*>> imageArrayBindings{}; std::vector<VkDescriptorSet> descriptorSets; uint32_t pushCunstantDataSize; |