summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/xe_descriptors.cpp22
-rw-r--r--engine/xe_descriptors.hpp4
-rw-r--r--engine/xe_render_system.cpp29
-rw-r--r--engine/xe_render_system.hpp11
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;