Skip to content

Commit

Permalink
variable array bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNumbat committed Mar 17, 2024
1 parent f4ab6b4 commit 10533e0
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 54 deletions.
49 changes: 45 additions & 4 deletions rvk/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ template<typename B>
concept Binding = requires(B bind, Vec<VkWriteDescriptorSet, Mregion<0>>& writes) {
Same<VkDescriptorType, decltype(B::type)>;
Same<VkShaderStageFlags, decltype(B::stages)>;
Same<VkDescriptorBindingFlags, decltype(B::flags)>;
{ bind.template write<0>(writes) } -> Same<void>;
};

Expand All @@ -32,6 +33,7 @@ template<VkShaderStageFlags stages_>
struct Sampler {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_SAMPLER;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Sampler() {
info.sampler = null;
Expand All @@ -57,6 +59,7 @@ template<VkShaderStageFlags stages_>
struct Image_And_Sampler {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Image_And_Sampler() {
info.sampler = null;
Expand Down Expand Up @@ -86,6 +89,7 @@ template<VkShaderStageFlags stages_>
struct Image_Sampled {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Image_Sampled() {
info.imageView = null;
Expand All @@ -109,10 +113,36 @@ struct Image_Sampled {
}
};

template<VkShaderStageFlags stages_>
struct Image_Sampled_Array {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags =
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;

explicit Image_Sampled_Array() = default;
explicit Image_Sampled_Array(Slice<Image_Sampled<stages_>> images) {
info = images;
}

Slice<Image_Sampled<stages_>> info;

template<Region R>
void write(Vec<VkWriteDescriptorSet, Mregion<R>>& writes) const {
VkWriteDescriptorSet write = {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.descriptorType = type;
write.descriptorCount = static_cast<u32>(info.length());
write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo*>(info.data());
writes.push(write);
}
};

template<VkShaderStageFlags stages_>
struct Image_Storage {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Image_Storage() {
info.imageView = null;
Expand Down Expand Up @@ -140,6 +170,7 @@ template<VkShaderStageFlags stages_>
struct Buffer_Uniform {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Buffer_Uniform() {
info.buffer = null;
Expand Down Expand Up @@ -169,6 +200,7 @@ template<VkShaderStageFlags stages_>
struct Buffer_Storage {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit Buffer_Storage() {
info.buffer = null;
Expand Down Expand Up @@ -198,6 +230,7 @@ template<VkShaderStageFlags stages_>
struct TLAS {
static constexpr VkDescriptorType type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
static constexpr VkShaderStageFlags stages = stages_;
static constexpr VkDescriptorBindingFlags flags = 0;

explicit TLAS() {
info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
Expand Down Expand Up @@ -233,10 +266,17 @@ template<Region R>
struct Make {
template<Binding B>
void apply() {
bindings.push(VkDescriptorSetLayoutBinding{static_cast<u32>(bindings.length()), B::type, 1,
B::stages, null});
bindings.push(VkDescriptorSetLayoutBinding{
.binding = static_cast<u32>(bindings.length()),
.descriptorType = B::type,
.descriptorCount = 1,
.stageFlags = B::stages,
.pImmutableSamplers = null,
});
flags.push(B::flags);
}
Vec<VkDescriptorSetLayoutBinding, Mregion<R>>& bindings;
Vec<VkDescriptorBindingFlags, Mregion<R>>& flags;
};

template<Region R, Binding... Binds>
Expand All @@ -256,8 +296,9 @@ struct Binder {
static Descriptor_Set_Layout make(Arc<rvk::impl::Device, Alloc> device) {
Region(R) {
Vec<VkDescriptorSetLayoutBinding, Mregion<R>> bindings(Reflect::List_Length<L>);
Reflect::Iter<Make<R>, L>::apply(Make<R>{bindings});
return Descriptor_Set_Layout{move(device), bindings.slice()};
Vec<VkDescriptorBindingFlags, Mregion<R>> flags(Reflect::List_Length<L>);
Reflect::Iter<Make<R>, L>::apply(Make<R>{bindings, flags});
return Descriptor_Set_Layout{move(device), bindings.slice(), flags.slice()};
}
}

Expand Down
52 changes: 39 additions & 13 deletions rvk/descriptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ void Descriptor_Pool::release(Descriptor_Set& set) {
vkFreeDescriptorSets(*device, pool, static_cast<u32>(set.sets.length()), set.sets.data());
}

Descriptor_Set Descriptor_Pool::make(Descriptor_Set_Layout& layout, u64 frames_in_flight) {
Descriptor_Set Descriptor_Pool::make(Descriptor_Set_Layout& layout, u64 frames_in_flight,
Slice<u32> counts) {
assert(counts.length() == 0 || counts.length() == layout.flag_count);

Vec<VkDescriptorSet, Alloc> sets;

Expand All @@ -69,11 +71,19 @@ Descriptor_Set Descriptor_Pool::make(Descriptor_Set_Layout& layout, u64 frames_i

sets.resize(frames_in_flight);

VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = pool;
alloc_info.descriptorSetCount = static_cast<u32>(frames_in_flight);
alloc_info.pSetLayouts = layouts.data();
VkDescriptorSetVariableDescriptorCountAllocateInfo variable_count_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.descriptorSetCount = static_cast<u32>(frames_in_flight),
.pDescriptorCounts = counts.data(),
};

VkDescriptorSetAllocateInfo alloc_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = counts.length() ? &variable_count_info : null,
.descriptorPool = pool,
.descriptorSetCount = static_cast<u32>(frames_in_flight),
.pSetLayouts = layouts.data(),
};

{
Thread::Lock lock(mutex);
Expand All @@ -100,6 +110,7 @@ void Descriptor_Set::write(u64 frame_index, Slice<VkWriteDescriptorSet> writes)
Region(R) {
Vec<VkWriteDescriptorSet, Mregion<R>> vk_writes;
for(auto& write : writes) {
if(write.descriptorCount == 0) continue;
vk_writes.push(write).dstSet = sets[frame_index];
}
vkUpdateDescriptorSets(*pool->device, static_cast<u32>(vk_writes.length()),
Expand All @@ -108,13 +119,26 @@ void Descriptor_Set::write(u64 frame_index, Slice<VkWriteDescriptorSet> writes)
}

Descriptor_Set_Layout::Descriptor_Set_Layout(Arc<Device, Alloc> D,
Slice<VkDescriptorSetLayoutBinding> bindings)
: device(move(D)) {

VkDescriptorSetLayoutCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
info.bindingCount = static_cast<u32>(bindings.length());
info.pBindings = bindings.data();
Slice<VkDescriptorSetLayoutBinding> bindings,
Slice<VkDescriptorBindingFlags> flags)
: device(move(D)), flag_count(flags.length()) {

assert(bindings.length() == flags.length() || flags.length() == 0);

VkDescriptorSetLayoutBindingFlagsCreateInfo flags_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = null,
.bindingCount = static_cast<u32>(flags.length()),
.pBindingFlags = flags.data(),
};

VkDescriptorSetLayoutCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = flags.length() ? &flags_info : null,
.flags = 0,
.bindingCount = static_cast<u32>(bindings.length()),
.pBindings = bindings.data(),
};

RVK_CHECK(vkCreateDescriptorSetLayout(*device, &info, null, &layout));
}
Expand All @@ -134,6 +158,8 @@ Descriptor_Set_Layout& Descriptor_Set_Layout::operator=(Descriptor_Set_Layout&&
device = move(src.device);
layout = src.layout;
src.layout = null;
flag_count = src.flag_count;
src.flag_count = 0;
return *this;
}

Expand Down
7 changes: 5 additions & 2 deletions rvk/descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ struct Descriptor_Set_Layout {

private:
explicit Descriptor_Set_Layout(Arc<Device, Alloc> device,
Slice<VkDescriptorSetLayoutBinding> bindings);
Slice<VkDescriptorSetLayoutBinding> bindings,
Slice<VkDescriptorBindingFlags> flags);
friend struct Vk;

Arc<Device, Alloc> device;
VkDescriptorSetLayout layout = null;
u64 flag_count = 0;

friend struct Compositor;
friend struct Binder;
friend struct Descriptor_Pool;
};

struct Descriptor_Set {
Expand Down Expand Up @@ -75,7 +78,7 @@ struct Descriptor_Pool {
return pool;
}

Descriptor_Set make(Descriptor_Set_Layout& layout, u64 frames_in_flight);
Descriptor_Set make(Descriptor_Set_Layout& layout, u64 frames_in_flight, Slice<u32> counts);

private:
explicit Descriptor_Pool(Arc<Device, Alloc> device, u32 bindings_per_type, bool ray_tracing);
Expand Down
100 changes: 72 additions & 28 deletions rvk/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,34 +72,40 @@ Opt<Image> Device_Memory::make(VkExtent3D extent, VkFormat format, VkImageUsageF

VkImage image = null;

VkImageCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
info.imageType = VK_IMAGE_TYPE_2D;
info.extent = extent;
info.mipLevels = 1;
info.arrayLayers = 1;
info.format = format;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.samples = VK_SAMPLE_COUNT_1_BIT;
info.usage = usage;
info.sharingMode = VK_SHARING_MODE_CONCURRENT;

Array<u32, 3> indices{device->queue_index(Queue_Family::graphics),
device->queue_index(Queue_Family::compute),
device->queue_index(Queue_Family::transfer)};

info.pQueueFamilyIndices = indices.data();
info.queueFamilyIndexCount = static_cast<u32>(indices.length());
VkImageCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = null,
.flags = 0,
.imageType = VK_IMAGE_TYPE_2D,
.format = format,
.extent = extent,
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = usage,
.sharingMode = VK_SHARING_MODE_CONCURRENT,
.queueFamilyIndexCount = static_cast<u32>(indices.length()),
.pQueueFamilyIndices = indices.data(),
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};

RVK_CHECK(vkCreateImage(*device, &info, null, &image));

VkImageMemoryRequirementsInfo2 image_requirements = {};
image_requirements.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
image_requirements.image = image;
VkImageMemoryRequirementsInfo2 image_requirements = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
.pNext = null,
.image = image,
};

VkMemoryRequirements2 memory_requirements = {};
memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
VkMemoryRequirements2 memory_requirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = null,
};

vkGetImageMemoryRequirements2(*device, &image_requirements, &memory_requirements);

Expand All @@ -112,15 +118,17 @@ Opt<Image> Device_Memory::make(VkExtent3D extent, VkFormat format, VkImageUsageF
return {};
}

VkBindImageMemoryInfo bind = {};
bind.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
bind.memory = device_memory;
bind.image = image;
bind.memoryOffset = (*address)->offset;
VkBindImageMemoryInfo bind = {
.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
.pNext = null,
.image = image,
.memory = device_memory,
.memoryOffset = (*address)->offset,
};

RVK_CHECK(vkBindImageMemory2(*device, 1, &bind));

return Opt{Image{Arc<Device_Memory, Alloc>::from_this(this), *address, image, format}};
return Opt{Image{Arc<Device_Memory, Alloc>::from_this(this), *address, image, format, extent}};
}

Opt<Buffer> Device_Memory::make(u64 size, VkBufferUsageFlags usage) {
Expand Down Expand Up @@ -165,8 +173,8 @@ Opt<Buffer> Device_Memory::make(u64 size, VkBufferUsageFlags usage) {
}

Image::Image(Arc<Device_Memory, Alloc> memory, Heap_Allocator::Range address, VkImage image,
VkFormat format)
: memory(move(memory)), image(image), format_(format), address(address){};
VkFormat format, VkExtent3D extent)
: memory(move(memory)), image(image), format_(format), extent_(extent), address(address){};

Image::~Image() {
if(image) {
Expand All @@ -191,6 +199,8 @@ Image& Image::operator=(Image&& src) {
src.format_ = VK_FORMAT_UNDEFINED;
address = src.address;
src.address = null;
extent_ = src.extent_;
src.extent_ = {};
return *this;
}

Expand All @@ -205,6 +215,40 @@ void Image::setup(Commands& commands, VkImageLayout layout) {
VK_ACCESS_2_NONE, VK_ACCESS_2_NONE);
}

void Image::from_buffer(Commands& commands, Buffer buffer) {

VkBufferImageCopy2 copy = {
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = null,
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.imageOffset = {0, 0, 0},
.imageExtent = extent_,
};

VkCopyBufferToImageInfo2 copy_info = {
.sType = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2,
.pNext = null,
.srcBuffer = buffer,
.dstImage = image,
.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.regionCount = 1,
.pRegions = &copy,
};

vkCmdCopyBufferToImage2(commands, &copy_info);

commands.attach(move(buffer));
}

void Image::transition(Commands& commands, VkImageAspectFlags aspect, VkImageLayout src_layout,
VkImageLayout dst_layout, VkPipelineStageFlags2 src_stage,
VkPipelineStageFlags2 dst_stage, VkAccessFlags2 src_access,
Expand Down
Loading

0 comments on commit 10533e0

Please sign in to comment.