Hi!
I’m trying to use a Sampler2D array to display my textures, but, this is not working… without the texture the quad is drawn but with the texture nothing is drawn.
Here is when I set up the descriptors :
void createDescriptorPool(VkDescriptorPool& descriptorPool, Device& vkDevice) {
std::array<VkDescriptorPoolSize, 4> poolSizes{};
poolSizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
poolSizes[0].descriptorCount = 1;
poolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
poolSizes[1].descriptorCount = 1;
poolSizes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
poolSizes[2].descriptorCount = 1;
poolSizes[3].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
std::vector<Texture*> allTextures = Texture::getAllTextures();
poolSizes[3].descriptorCount = static_cast<uint32_t>(1 * allTextures.size());
/*poolSizes[4].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
poolSizes[4].descriptorCount = 1;
poolSizes[5].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
poolSizes[5].descriptorCount = 1;*/
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
poolInfo.pPoolSizes = poolSizes.data();
poolInfo.maxSets = 1;
if (vkCreateDescriptorPool(vkDevice.getDevice(), &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
throw std::runtime_error("echec de la creation de la pool de descripteurs!");
}
}
void createDescriptorSetLayout(VkDescriptorSetLayout& descriptorSetLayout, Device& vkDevice) {
VkDescriptorSetLayoutBinding counterLayoutBinding;
counterLayoutBinding.binding = 0;
counterLayoutBinding.descriptorCount = 1;
counterLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
counterLayoutBinding.pImmutableSamplers = nullptr;
counterLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutBinding headPtrImageLayoutBinding;
headPtrImageLayoutBinding.binding = 1;
headPtrImageLayoutBinding.descriptorCount = 1;
headPtrImageLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
headPtrImageLayoutBinding.pImmutableSamplers = nullptr;
headPtrImageLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutBinding linkedListLayoutBinding{};
linkedListLayoutBinding.binding = 2;
linkedListLayoutBinding.descriptorCount = 1;
linkedListLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
linkedListLayoutBinding.pImmutableSamplers = nullptr;
linkedListLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::vector<Texture*> allTextures = Texture::getAllTextures();
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
samplerLayoutBinding.binding = 3;
samplerLayoutBinding.descriptorCount = allTextures.size();
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
/*VkDescriptorSetLayoutBinding modelDataLayoutBinding{};
modelDataLayoutBinding.binding = 4;
modelDataLayoutBinding.descriptorCount = 1;
modelDataLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
modelDataLayoutBinding.pImmutableSamplers = nullptr;
modelDataLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
VkDescriptorSetLayoutBinding materialDataLayoutBinding{};
materialDataLayoutBinding.binding = 5;
materialDataLayoutBinding.descriptorCount = 1;
materialDataLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
materialDataLayoutBinding.pImmutableSamplers = nullptr;
materialDataLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;*/
std::array<VkDescriptorSetLayoutBinding, 4> bindings = {counterLayoutBinding, headPtrImageLayoutBinding, linkedListLayoutBinding, samplerLayoutBinding/*, modelDataLayoutBinding, materialDataLayoutBinding*/};
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());;
layoutInfo.pBindings = bindings.data();
if (vkCreateDescriptorSetLayout(vkDevice.getDevice(), &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
void createDescriptorSets(VkBuffer& modelDataShaderStorageBuffer, VkBuffer& materialDataShaderStorageBuffer, VkBuffer& counterShaderStorageBuffer, VkBuffer& linkedListShaderStorageBuffer, VkImageView& headPtrTextureImageView, VkSampler& headPtrTextureSampler, VkDescriptorPool descriptorPool, VkDescriptorSetLayout descriptorSetLayout, std::vector<VkDescriptorSet>& descriptorSets, Device& vkDevice) {
std::vector<VkDescriptorSetLayout> layouts(1, descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = layouts.data();
descriptorSets.resize(1);
if (vkAllocateDescriptorSets(vkDevice.getDevice(), &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
throw std::runtime_error("echec de l'allocation d'un set de descripteurs!");
}
for (size_t i = 0; i < 1; i++) {
std::array<VkWriteDescriptorSet, 4> descriptorWrites{};
VkDescriptorBufferInfo counterStorageBufferInfoLastFrame{};
counterStorageBufferInfoLastFrame.buffer = counterShaderStorageBuffer;
counterStorageBufferInfoLastFrame.offset = 0;
counterStorageBufferInfoLastFrame.range = sizeof(counterShaderStorageBuffer);
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = descriptorSets[i];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pBufferInfo = &counterStorageBufferInfoLastFrame;
VkDescriptorImageInfo headPtrDescriptorImageInfo;
headPtrDescriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
headPtrDescriptorImageInfo.imageView = headPtrTextureImageView;
headPtrDescriptorImageInfo.sampler = headPtrTextureSampler;
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = descriptorSets[i];
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pImageInfo = &headPtrDescriptorImageInfo;
VkDescriptorBufferInfo linkedListStorageBufferInfoLastFrame{};
linkedListStorageBufferInfoLastFrame.buffer = linkedListShaderStorageBuffer;
linkedListStorageBufferInfoLastFrame.offset = 0;
unsigned int nodeSize = 5 * sizeof(float) + sizeof(unsigned int);
linkedListStorageBufferInfoLastFrame.range = maxNodes * nodeSize;
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = descriptorSets[i];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[2].descriptorCount = 1;
descriptorWrites[2].pBufferInfo = &linkedListStorageBufferInfoLastFrame;
std::vector<VkDescriptorImageInfo> descriptorImageInfos;
std::vector<Texture*> allTextures = Texture::getAllTextures();
descriptorImageInfos.resize(allTextures.size());
for (unsigned int j = 0; j < allTextures.size(); j++) {
descriptorImageInfos[j].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
descriptorImageInfos[j].imageView = allTextures[j]->getImageView();
descriptorImageInfos[j].sampler = allTextures[j]->getSampler();
}
descriptorWrites[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[3].dstSet = descriptorSets[i];
descriptorWrites[3].dstBinding = 3;
descriptorWrites[3].dstArrayElement = 0;
descriptorWrites[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[3].descriptorCount = allTextures.size();
descriptorWrites[3].pImageInfo = descriptorImageInfos.data();
/*VkDescriptorBufferInfo modelDataStorageBufferInfoLastFrame{};
modelDataStorageBufferInfoLastFrame.buffer = modelDataShaderStorageBuffer;
modelDataStorageBufferInfoLastFrame.offset = 0;
modelDataStorageBufferInfoLastFrame.range = sizeof(ModelData) * modelDatas.size();
descriptorWrites[4].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[4].dstSet = descriptorSets[i];
descriptorWrites[4].dstBinding = 4;
descriptorWrites[4].dstArrayElement = 0;
descriptorWrites[4].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[4].descriptorCount = 1;
descriptorWrites[4].pBufferInfo = &modelDataStorageBufferInfoLastFrame;
VkDescriptorBufferInfo materialDataStorageBufferInfoLastFrame{};
materialDataStorageBufferInfoLastFrame.buffer = materialDataShaderStorageBuffer;
materialDataStorageBufferInfoLastFrame.offset = 0;
materialDataStorageBufferInfoLastFrame.range = sizeof(MaterialData) * materialDatas.size();
descriptorWrites[5].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[5].dstSet = descriptorSets[i];
descriptorWrites[5].dstBinding = 5;
descriptorWrites[5].dstArrayElement = 0;
descriptorWrites[5].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptorWrites[5].descriptorCount = 1;
descriptorWrites[5].pBufferInfo = &materialDataStorageBufferInfoLastFrame;*/
vkUpdateDescriptorSets(vkDevice.getDevice(), static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
}
}
In my fragment shader I do this :
const std::string fragmentShader = R"(
#version 460
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_nonuniform_qualifier : enable
struct NodeType {
vec4 color;
float depth;
uint next;
};
layout(set = 0, binding = 0) buffer CounterSSBO {
uint count;
uint maxNodes;
};
layout(set = 0, binding = 1, r32ui) uniform coherent uimage2D headPointers;
layout(set = 0, binding = 2) buffer LinkedLists {
NodeType nodes[];
};
layout(set = 0, binding = 3) uniform sampler2D textures[];
layout(location = 0) in vec4 frontColor;
layout(location = 1) in vec2 fTexCoords;
layout(location = 2) in flat uint texIndex;
layout(location = 0) out vec4 outColor;
void main () {
uint nodeIdx = atomicAdd(count, 1);
vec4 color = (texIndex != 0) ? frontColor * textureLod(textures[texIndex-1], fTexCoords.xy, 0) : frontColor;
if (nodeIdx < maxNodes) {
uint prevHead = imageAtomicExchange(headPointers, ivec2(gl_FragCoord.xy), nodeIdx);
nodes[nodeIdx].color = color;
nodes[nodeIdx].depth = gl_FragCoord.z;
nodes[nodeIdx].next = prevHead;
}
})";
Thanks.