aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2023-02-03 00:15:19 +0100
committerladevieq <ladevie.quentin@gmail.com>2023-02-03 00:15:19 +0100
commit75acd0104448d7c5f43f99700decff39b8a034b2 (patch)
tree1b22b1ce10f24c8ef41b3ab1110a30c545e3cc66
parentddff2fa5d0cbae17cb819c91bad0a79105ba0ea7 (diff)
Graphics pipeline and rendering implementation
-rw-r--r--api-test/CMakeLists.txt1
-rw-r--r--api-test/command-buffer.cpp20
-rw-r--r--api-test/main.cpp221
-rw-r--r--api-test/vk-bindless.cpp123
-rw-r--r--api-test/vk-device.cpp653
-rw-r--r--include/api-test/command-buffer.hpp8
-rw-r--r--include/api-test/handle.hpp2
-rw-r--r--include/api-test/vk-bindless.hpp9
-rw-r--r--include/api-test/vk-device-types.hpp2
-rw-r--r--include/api-test/vk-device.hpp19
-rw-r--r--include/vulkan-loader.hpp1
-rw-r--r--shaders/api-test-ui.frag20
-rw-r--r--shaders/api-test-ui.vert25
-rw-r--r--shaders/test.comp2
14 files changed, 722 insertions, 384 deletions
diff --git a/api-test/CMakeLists.txt b/api-test/CMakeLists.txt
index 93eceee..3fcad92 100644
--- a/api-test/CMakeLists.txt
+++ b/api-test/CMakeLists.txt
@@ -16,3 +16,4 @@ target_include_directories(api-test SYSTEM PUBLIC ${Vulkan_INCLUDE_DIRS})
target_include_directories(api-test SYSTEM PUBLIC ${CMAKE_SOURCE_DIR}/thirdparty)
target_include_directories(api-test PUBLIC ${CMAKE_SOURCE_DIR}/include)
target_include_directories(api-test PUBLIC ${CMAKE_SOURCE_DIR}/include/api-test)
+target_link_libraries(api-test PRIVATE imgui::imgui)
diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp
index b130d3d..78b1505 100644
--- a/api-test/command-buffer.cpp
+++ b/api-test/command-buffer.cpp
@@ -12,7 +12,7 @@ void command_buffer::start() const {
VkCommandBufferBeginInfo begin_info{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
- .flags = 0U,
+ .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
.pInheritanceInfo = nullptr
};
@@ -112,7 +112,8 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t
void graphics_command_buffer::dispatch(const dispatch_params& params) const {
const auto& pipeline = vkdevice::get_render_device()->get_pipeline(params.pipeline);
const auto& bindless = vkdevice::get_render_device()->get_bindingmodel();
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::UNIFORMS), 1U, &bindless.sets[BindlessSetType::UNIFORMS], 1U, &params.uniforms_offset);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::INSTANCES_UNIFORMS), 1U, &bindless.sets[BindlessSetType::INSTANCES_UNIFORMS], 1U, &params.uniforms_offset);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::DRAWS_UNIFORMS), 1U, &bindless.sets[BindlessSetType::DRAWS_UNIFORMS], 1U, &params.uniforms_offset);
vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline);
@@ -179,10 +180,21 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params)
}
void graphics_command_buffer::render(const draw_params& params) const {
- const auto& pipeline = vkdevice::get_render_device()->get_pipeline(params.pipeline);
+ auto* device = vkdevice::get_render_device();
+ const auto& pipeline = device->get_pipeline(params.pipeline);
+
+ const auto& bindless = device->get_bindingmodel();
+ vkCmdBindDescriptorSets(vk_command_buffer, pipeline.bind_point, bindless.layout, static_cast<uint32_t>(BindlessSetType::DRAWS_UNIFORMS), 1U, &bindless.sets[BindlessSetType::DRAWS_UNIFORMS], 1U, &params.uniforms_offset);
vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline);
- vkCmdDraw(vk_command_buffer, params.vertex_count, params.instance_count, 0U, 0U);
+
+ if (params.index_buffer.is_valid()) {
+ const auto& index_buffer = device->get_buffer(params.index_buffer);
+ vkCmdBindIndexBuffer(vk_command_buffer, index_buffer.vk_buffer, 0U, VK_INDEX_TYPE_UINT16);
+ vkCmdDrawIndexed(vk_command_buffer, params.vertex_count, params.instance_count, params.index_offset, static_cast<int32_t>(params.vertex_offset), 0U);
+ } else {
+ vkCmdDraw(vk_command_buffer, params.vertex_count, params.instance_count, params.vertex_offset, 0U);
+ }
}
void graphics_command_buffer::end_renderpass() const {
diff --git a/api-test/main.cpp b/api-test/main.cpp
index d6a4b3b..2f973ff 100644
--- a/api-test/main.cpp
+++ b/api-test/main.cpp
@@ -7,6 +7,8 @@
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
+#include "imgui.h"
+
#include "window.hpp"
#include "vk-device.hpp"
#include "utils.hpp"
@@ -18,9 +20,20 @@ struct device_texture;
#ifdef ENABLE_RENDERDOC
#include <renderdoc.h>
+#define RD_START_CAPTURE if(rdoc_api != nullptr) rdoc_api->StartFrameCapture(nullptr, nullptr)
+#define RD_END_CAPTURE if(rdoc_api != nullptr) rdoc_api->EndFrameCapture(nullptr, nullptr)
+
RENDERDOC_API_1_4_1 *rdoc_api = nullptr;
#endif
+void ui() {
+ ImGui::NewFrame();
+ bool open = true;
+ ImGui::ShowDemoWindow(&open);
+ ImGui::EndFrame();
+ ImGui::Render();
+}
+
int main() {
#ifdef ENABLE_RENDERDOC
@@ -37,9 +50,10 @@ int main() {
constexpr size_t window_height = 360U;
window wnd { window_width, window_height };
-#ifdef ENABLE_RENDERDOC
- if(rdoc_api != nullptr) rdoc_api->StartFrameCapture(nullptr, nullptr);
-#endif
+ ImGui::CreateContext();
+ ImGuiIO &io = ImGui::GetIO();
+ io.DisplaySize.x = 1024.f;
+ io.DisplaySize.y = 1024.f;
auto* device = vkdevice::init_device(wnd);
@@ -90,40 +104,71 @@ int main() {
.type = VK_IMAGE_TYPE_2D,
});
- // auto gpu_buffer = vkdevice::get_buffer(device.create_buffer({
- // .size = 1024U * sizeof(uint32_t),
- // .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
- // .memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- // .memory_usage = VMA_MEMORY_USAGE_GPU_ONLY,
- // }));
+ uint8_t *pixels = nullptr;
+ int atlas_width;
+ int atlas_height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
+ const auto ui_texture_handle = device->create_texture({
+ .width = static_cast<uint32_t>(atlas_width),
+ .height = static_cast<uint32_t>(atlas_height),
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+ });
+ const auto& ui_texture = device->get_texture(ui_texture_handle);
+ io.Fonts->SetTexID(*(void **)&ui_texture_handle.id);
+
+ off_t ui_offset = 2L * offset;
+ size = static_cast<size_t>(atlas_width) * atlas_height * 4U;
+ addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + ui_offset);
+ memcpy(addr, pixels, size);
+
+ auto vertex_buffer = device->get_buffer(device->create_buffer({
+ .size = 1024U * 1024U * sizeof(uint32_t),
+ .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ }));
+
+ auto index_buffer_handle = device->create_buffer({
+ .size = 1024U * 1024U * sizeof(uint32_t),
+ .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ });
+ auto index_buffer = device->get_buffer(index_buffer_handle);
auto code = read_file("shaders/test.comp.spv");
auto compute = device->create_pipeline({
- .cs_code = std::span(code),
+ .cs_code = code,
});
std::array<VkFormat, 1U> formats { VK_FORMAT_R8G8B8A8_UNORM };
auto vertex_code = read_file("shaders/api-test-ui.vert.spv");
auto fragment_code = read_file("shaders/api-test-ui.frag.spv");
auto graphics = device->create_pipeline({
- .vs_code = std::span(vertex_code),
- .fs_code = std::span(fragment_code),
+ .vs_code = vertex_code,
+ .fs_code = fragment_code,
.color_attachments_format = formats
});
+ auto semaphore = device->create_semaphore();
+ std::array<graphics_command_buffer, 2U> command_buffers;
+ device->allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS);
- graphics_command_buffer command_buffer;
- device->allocate_command_buffers(&command_buffer, 1, QueueType::GRAPHICS);
+ RD_START_CAPTURE;
- command_buffer.start();
+ command_buffers[0].start();
- command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- command_buffer.barrier(second_texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- command_buffer.copy(staging_buffer_handle, gpu_texture_handle);
- command_buffer.copy(staging_buffer_handle, second_texture, static_cast<VkDeviceSize>(offset));
+ command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ command_buffers[0].barrier(ui_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ command_buffers[0].copy(staging_buffer_handle, gpu_texture_handle);
+ command_buffers[0].copy(staging_buffer_handle, second_texture, static_cast<VkDeviceSize>(offset));
+ command_buffers[0].copy(staging_buffer_handle, ui_texture_handle, static_cast<VkDeviceSize>(ui_offset));
- command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
- command_buffer.barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
+ command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
+ command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
struct compute_params {
uint32_t input1;
@@ -138,42 +183,128 @@ int main() {
};
memcpy(uniform_buffer.mapped_ptr, &params, sizeof(params));
- command_buffer.dispatch({
+ command_buffers[0].dispatch({
.pipeline = compute,
.group_size = { image_size, image_size, 1U },
.local_group_size = { 8U, 8U, 1U },
.uniforms_offset = 0U,
});
+ command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+ command_buffers[0].stop();
+ std::array<struct command_buffer, 1U> compute_command_buffers = {command_buffers[0]};
+ device->submit(compute_command_buffers, nullptr, &semaphore);
+
+ RD_END_CAPTURE;
+
+ std::array<struct command_buffer, 1U> ui_command_buffers = {command_buffers[1]};
std::array<handle<device_texture>, 1U> color_attachment {gpu_texture_handle};
+ while(wnd.isOpen) {
+ wnd.poll_events();
- command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- command_buffer.begin_renderpass({
- .render_area = {
- .x = 0,
- .y = 0,
- .width = window_width,
- .height = window_height,
- },
- .color_attachments = color_attachment,
- });
- command_buffer.render({
- .pipeline = graphics,
- .vertex_count = 3U,
- .instance_count = 1U,
- });
- command_buffer.end_renderpass();
+ ui();
- command_buffer.stop();
+ auto* draw_data = ImGui::GetDrawData();
+ struct vertex {
+ ImVec2 pos;
+ ImVec2 uv;
+ uint32_t color;
+ uint32_t padding;
+ };
- device->submit(&command_buffer, 1);
+ off_t vertex_offset = 0;
+ off_t index_offset = 0;
+ for (auto index {0U} ; index < draw_data->CmdListsCount; index++) {
+ auto* cmd_list = draw_data->CmdLists[index];
-#ifdef ENABLE_RENDERDOC
- if(rdoc_api != nullptr) rdoc_api->EndFrameCapture(nullptr, nullptr);
-#endif
+ size_t vertex_bytes_size = sizeof(ImDrawVert) * cmd_list->VtxBuffer.size();
+ auto* vtx_ptr = static_cast<vertex*>(vertex_buffer.mapped_ptr) + vertex_offset;
+ for (auto vtx_index{0}; vtx_index < cmd_list->VtxBuffer.size(); vtx_index++, vtx_ptr++) {
+ auto& vtx = cmd_list->VtxBuffer[vtx_index];
+ vtx_ptr->pos = vtx.pos;
+ vtx_ptr->uv = vtx.uv;
+ vtx_ptr->color = vtx.col;
+ }
+ // memcpy(static_cast<uint8_t*>(vertex_buffer.mapped_ptr) + vertex_offset, cmd_list->VtxBuffer.Data, vertex_bytes_size);
+ vertex_offset += static_cast<off_t>(vertex_bytes_size);
- while(wnd.isOpen) {
- wnd.poll_events();
+ size_t index_bytes_size = sizeof(ImDrawIdx) * cmd_list->IdxBuffer.size();
+ memcpy(static_cast<uint8_t*>(index_buffer.mapped_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size);
+ index_offset += static_cast<off_t>(index_bytes_size);
+ }
+
+ device->wait(semaphore);
+
+ RD_START_CAPTURE;
+ command_buffers[1].start(),
+
+ command_buffers[1].begin_renderpass({
+ .render_area = {
+ .x = static_cast<int32_t>(draw_data->DisplayPos.x),
+ .y = static_cast<int32_t>(draw_data->DisplayPos.y),
+ .width = static_cast<uint32_t>(draw_data->DisplaySize.x),
+ .height = static_cast<uint32_t>(draw_data->DisplaySize.y),
+ },
+ .color_attachments = color_attachment,
+ });
+
+ struct draw_params {
+ uintptr_t vertex_buffer;
+ float scale[2U];
+ float translate[2U];
+ uint32_t texture_index;
+ };
+
+ printf("%llu\n", sizeof(ImDrawVert));
+
+ uint32_t draw_index = 0U;
+ uint32_t vtx_offset = 0U;
+ uint32_t idx_offset = 0U;
+ std::array<draw_params, 100U> draws;
+ for (auto index {0U} ; index < draw_data->CmdListsCount; index++) {
+ auto* cmd_list = draw_data->CmdLists[index];
+
+ for (auto& draw_command : cmd_list->CmdBuffer) {
+ draws[draw_index] = draw_params{
+ .vertex_buffer = vertex_buffer.device_address,
+ .scale {
+ 2.f / draw_data->DisplaySize.x,
+ 2.f / draw_data->DisplaySize.y,
+ },
+ .translate {
+ -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x),
+ -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y),
+ },
+ .texture_index = ui_texture.sampled_index,
+ };
+
+ command_buffers[1].render({
+ .pipeline = graphics,
+ .index_buffer = index_buffer_handle,
+ .vertex_count = draw_command.ElemCount,
+ .vertex_offset = draw_command.VtxOffset,
+ .index_offset = draw_command.IdxOffset,
+ .instance_count = 1U,
+ .uniforms_offset = 0U,
+ });
+
+ draw_index++;
+ // vtx_offset += draw_command.
+ }
+ }
+
+ memcpy(uniform_buffer.mapped_ptr, draws.data(), sizeof(draw_params) * draw_index);
+
+ command_buffers[1].end_renderpass();
+
+ command_buffers[1].stop();
+
+ device->submit(ui_command_buffers, nullptr, &semaphore);
+ RD_END_CAPTURE;
+
+ // std::system("PAUSE");
+ break;
}
return 0;
diff --git a/api-test/vk-bindless.cpp b/api-test/vk-bindless.cpp
index c07db8e..654ce0c 100644
--- a/api-test/vk-bindless.cpp
+++ b/api-test/vk-bindless.cpp
@@ -8,7 +8,7 @@
const device_buffer& bindless_model::get_uniform_buffer() const {
auto* render_device = vkdevice::get_render_device();
- return render_device->get_buffer(uniform_buffer);
+ return render_device->get_buffer(draws_uniform_buffer_handle);
}
bindless_model bindless_model::create_bindless_model() {
@@ -20,34 +20,68 @@ bindless_model bindless_model::create_bindless_model() {
bindless.create_layout(device);
bindless.create_descriptor_pool(device);
bindless.allocate_sets(device);
- bindless.uniform_buffer = render_device->create_buffer({
- .size = 64U * 1024U,
- .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
- .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
- .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
- });
- const auto& buffer = render_device->get_buffer(bindless.uniform_buffer);
- VkDescriptorBufferInfo buffer_info {
- .buffer = buffer.vk_buffer,
- .offset = 0U,
- .range = VK_WHOLE_SIZE,
- };
+ VkWriteDescriptorSet writes_descriptor_set[2U];
- VkWriteDescriptorSet write_descriptor_set {
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = bindless.sets[BindlessSetType::UNIFORMS],
- .dstBinding = 0U,
- .dstArrayElement = 0U,
- .descriptorCount = 1U,
- .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
- .pImageInfo = nullptr,
- .pBufferInfo = &buffer_info,
- .pTexelBufferView = nullptr,
- };
+ {
+ bindless.instances_uniform_buffer_handle = render_device->create_buffer({
+ .size = instances_uniform_buffer_size,
+ .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ });
+
+ const auto& buffer = render_device->get_buffer(bindless.instances_uniform_buffer_handle);
+ VkDescriptorBufferInfo buffer_info {
+ .buffer = buffer.vk_buffer,
+ .offset = 0U,
+ .range = VK_WHOLE_SIZE,
+ };
+
+ writes_descriptor_set[0U] = {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .pNext = nullptr,
+ .dstSet = bindless.sets[BindlessSetType::INSTANCES_UNIFORMS],
+ .dstBinding = 0U,
+ .dstArrayElement = 0U,
+ .descriptorCount = 1U,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .pImageInfo = nullptr,
+ .pBufferInfo = &buffer_info,
+ .pTexelBufferView = nullptr,
+ };
+ }
+
+ {
+ bindless.draws_uniform_buffer_handle = render_device->create_buffer({
+ .size = draws_uniform_buffer_size,
+ .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ });
- vkUpdateDescriptorSets(device, 1U, &write_descriptor_set, 0U, nullptr);
+ const auto& buffer = render_device->get_buffer(bindless.draws_uniform_buffer_handle);
+ VkDescriptorBufferInfo buffer_info {
+ .buffer = buffer.vk_buffer,
+ .offset = 0U,
+ .range = VK_WHOLE_SIZE,
+ };
+
+ writes_descriptor_set[1U] = {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .pNext = nullptr,
+ .dstSet = bindless.sets[BindlessSetType::DRAWS_UNIFORMS],
+ .dstBinding = 0U,
+ .dstArrayElement = 0U,
+ .descriptorCount = 1U,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .pImageInfo = nullptr,
+ .pBufferInfo = &buffer_info,
+ .pTexelBufferView = nullptr,
+ };
+ }
+
+ vkUpdateDescriptorSets(device, sizeof(writes_descriptor_set) / sizeof(VkWriteDescriptorSet), writes_descriptor_set, 0U, nullptr);
#else
VkBufferCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -150,8 +184,8 @@ void bindless_model::create_layout(VkDevice device) {
VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::GLOBAL]));
}
- // Set 1 uniforms
- // Binding 0 Uniforms
+ // Set 1 per instance uniforms
+ // Binding 0 Dynamic Uniform Buffer
{
VkDescriptorSetLayoutBinding set_layout_bindings[]{
{
@@ -171,7 +205,31 @@ void bindless_model::create_layout(VkDevice device) {
.pBindings = set_layout_bindings,
};
- VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::UNIFORMS]));
+ VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::INSTANCES_UNIFORMS]));
+ }
+
+ // Set 2 per draw uniforms
+ // Binding 0 Dynamic Uniform Buffer
+ {
+ VkDescriptorSetLayoutBinding set_layout_bindings[]{
+ {
+ .binding = 0U,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
+ .pImmutableSamplers = nullptr,
+ },
+ };
+
+ VkDescriptorSetLayoutCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .bindingCount = sizeof(set_layout_bindings) / sizeof(VkDescriptorSetLayoutBinding),
+ .pBindings = set_layout_bindings,
+ };
+
+ VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::DRAWS_UNIFORMS]));
}
VkPipelineLayoutCreateInfo create_info{
@@ -229,8 +287,11 @@ void bindless_model::allocate_sets(VkDevice device) {
};
VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::GLOBAL]));
- allocate_info.pSetLayouts = &sets_layout[BindlessSetType::UNIFORMS],
- VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::UNIFORMS]));
+ allocate_info.pSetLayouts = &sets_layout[BindlessSetType::INSTANCES_UNIFORMS],
+ VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::INSTANCES_UNIFORMS]));
+
+ allocate_info.pSetLayouts = &sets_layout[BindlessSetType::DRAWS_UNIFORMS],
+ VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::DRAWS_UNIFORMS]));
}
void bindless_model::create_immutable_samplers(VkDevice device) {
diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp
index 6967e41..296d76c 100644
--- a/api-test/vk-device.cpp
+++ b/api-test/vk-device.cpp
@@ -6,26 +6,26 @@
#define VMA_IMPLEMENTATION
#include <vk_mem_alloc.h>
+#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
#include "window.hpp"
-#include "vk-utils.hpp"
vkdevice* vkdevice::render_device = nullptr;
vkdevice::vkdevice(const window& window)
: queues{
- {
- .usages = VK_QUEUE_GRAPHICS_BIT |
- VK_QUEUE_COMPUTE_BIT |
- VK_QUEUE_TRANSFER_BIT,
- },
- {
- .usages = VK_QUEUE_COMPUTE_BIT,
- },
- {
- .usages = VK_QUEUE_TRANSFER_BIT,
- },
- } {
+ {
+ .usages = VK_QUEUE_GRAPHICS_BIT |
+ VK_QUEUE_COMPUTE_BIT |
+ VK_QUEUE_TRANSFER_BIT,
+ },
+ {
+ .usages = VK_QUEUE_COMPUTE_BIT,
+ },
+ {
+ .usages = VK_QUEUE_TRANSFER_BIT,
+ },
+ } {
load_vulkan();
create_instance();
@@ -96,23 +96,22 @@ vkdevice::~vkdevice() {
}
handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
- device_texture device_texture {
+ device_texture device_texture{
.desc = desc,
};
assert(desc.mips <= texture_desc::max_mips);
- VkImageCreateInfo create_info {
- .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .imageType = desc.type,
- .format = desc.format,
- .extent = {
- .width = desc.width,
- .height = desc.height,
- .depth = desc.depth
- },
+ VkImageCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .imageType = desc.type,
+ .format = desc.format,
+ .extent = {
+ .width = desc.width,
+ .height = desc.height,
+ .depth = desc.depth },
.mipLevels = desc.mips,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
@@ -124,14 +123,14 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
- VmaAllocationCreateInfo alloc_create_info {
- .flags = 0U,
- .usage = VMA_MEMORY_USAGE_GPU_ONLY,
- .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- .preferredFlags = 0U,
- .memoryTypeBits = 0U,
- .pool = nullptr,
- .pUserData = nullptr,
+ VmaAllocationCreateInfo alloc_create_info{
+ .flags = 0U,
+ .usage = VMA_MEMORY_USAGE_GPU_ONLY,
+ .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ .preferredFlags = 0U,
+ .memoryTypeBits = 0U,
+ .pool = nullptr,
+ .pUserData = nullptr,
};
VKCHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &device_texture.vk_image, &device_texture.alloc, nullptr));
@@ -139,27 +138,28 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
create_views(device_texture);
// TODO: Handle mips views
- std::vector<VkDescriptorImageInfo> images_info;
- images_info.push_back({
- .sampler = nullptr,
- .imageView = device_texture.whole_view,
- .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- });
+ VkDescriptorImageInfo images_info[]{
+ {
+ nullptr,
+ device_texture.whole_view,
+ VK_IMAGE_LAYOUT_GENERAL,
+ },
+ };
std::vector<VkWriteDescriptorSet> write_descriptor_sets;
if ((desc.usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0) {
device_texture.storage_index = storage_indices.add(&device_texture);
write_descriptor_sets.push_back({
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = bindless.sets[BindlessSetType::GLOBAL],
- .dstBinding = 2U,
- .dstArrayElement = device_texture.storage_index,
- .descriptorCount = static_cast<uint32_t>(images_info.size()),
- .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
- .pImageInfo = images_info.data(),
- .pBufferInfo = nullptr,
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .pNext = nullptr,
+ .dstSet = bindless.sets[BindlessSetType::GLOBAL],
+ .dstBinding = 2U,
+ .dstArrayElement = device_texture.storage_index,
+ .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo),
+ .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+ .pImageInfo = images_info,
+ .pBufferInfo = nullptr,
.pTexelBufferView = nullptr,
});
}
@@ -167,15 +167,15 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
device_texture.sampled_index = sampled_indices.add(&device_texture);
write_descriptor_sets.push_back({
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = bindless.sets[BindlessSetType::GLOBAL],
- .dstBinding = 1U,
- .dstArrayElement = device_texture.sampled_index,
- .descriptorCount = static_cast<uint32_t>(images_info.size()),
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- .pImageInfo = images_info.data(),
- .pBufferInfo = nullptr,
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .pNext = nullptr,
+ .dstSet = bindless.sets[BindlessSetType::GLOBAL],
+ .dstBinding = 1U,
+ .dstArrayElement = device_texture.sampled_index,
+ .descriptorCount = sizeof(images_info) / sizeof(VkDescriptorImageInfo),
+ .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+ .pImageInfo = images_info,
+ .pBufferInfo = nullptr,
.pTexelBufferView = nullptr,
});
}
@@ -186,11 +186,11 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
}
handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
- device_buffer device_buffer {
+ device_buffer device_buffer{
.desc = desc,
};
- VkBufferCreateInfo create_info {
+ VkBufferCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0U,
@@ -201,11 +201,10 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
.pQueueFamilyIndices = nullptr,
};
- VmaAllocatorCreateFlags alloc_create_flags =
- desc.memory_usage != VMA_MEMORY_USAGE_GPU_ONLY ?
- VMA_ALLOCATION_CREATE_MAPPED_BIT : 0U;
+ VmaAllocatorCreateFlags alloc_create_flags =
+ desc.memory_usage != VMA_MEMORY_USAGE_GPU_ONLY ? VMA_ALLOCATION_CREATE_MAPPED_BIT : 0U;
- VmaAllocationCreateInfo alloc_create_info {
+ VmaAllocationCreateInfo alloc_create_info{
.flags = alloc_create_flags,
.usage = static_cast<VmaMemoryUsage>(desc.memory_usage),
.requiredFlags = desc.memory_properties,
@@ -215,53 +214,62 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
.pUserData = nullptr,
};
- VmaAllocationInfo alloc_info {};
+ VmaAllocationInfo alloc_info{};
VKCHECK(vmaCreateBuffer(gpu_allocator, &create_info, &alloc_create_info, &device_buffer.vk_buffer, &device_buffer.alloc, &alloc_info));
+ if ((desc.usages & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) != 0U) {
+ VkBufferDeviceAddressInfo address_info {
+ .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+ .pNext = nullptr,
+ .buffer = device_buffer.vk_buffer,
+ };
+ device_buffer.device_address = vkGetBufferDeviceAddress(device, &address_info);
+ }
+
device_buffer.mapped_ptr = alloc_info.pMappedData;
return { buffers.add(device_buffer) };
}
handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
- device_pipeline device_pipeline {
- .desc = desc,
+ device_pipeline device_pipeline{
+ .desc = desc,
.bindless = &bindless,
};
if (!desc.cs_code.empty()) {
VkShaderModule shader_module;
{
- const auto& code = desc.cs_code;
- VkShaderModuleCreateInfo create_info {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
+ const auto& code = desc.cs_code;
+ VkShaderModuleCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
.codeSize = code.size(),
- .pCode = (uint32_t*)code.data(),
+ .pCode = (uint32_t*)code.data(),
};
VKCHECK(vkCreateShaderModule(device, &create_info, nullptr, &shader_module));
}
- VkPipelineShaderStageCreateInfo stage_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .stage = VK_SHADER_STAGE_COMPUTE_BIT,
- .module = shader_module,
- .pName = "main",
+ VkPipelineShaderStageCreateInfo stage_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_COMPUTE_BIT,
+ .module = shader_module,
+ .pName = "main",
.pSpecializationInfo = nullptr,
};
- VkComputePipelineCreateInfo create_info {
- .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .stage = stage_create_info,
- .layout = bindless.layout,
+ VkComputePipelineCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = stage_create_info,
+ .layout = bindless.layout,
.basePipelineHandle = nullptr,
- .basePipelineIndex = 0,
+ .basePipelineIndex = 0,
};
device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
@@ -269,158 +277,157 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
vkDestroyShaderModule(device, shader_module, nullptr);
} else {
- VkPipelineShaderStageCreateInfo shader_stages_create_info[2U] {
+ VkPipelineShaderStageCreateInfo shader_stages_create_info[2U]{
{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .stage = VK_SHADER_STAGE_VERTEX_BIT,
- .pName = "main",
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_VERTEX_BIT,
+ .pName = "main",
.pSpecializationInfo = nullptr,
},
{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
- .pName = "main",
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+ .pName = "main",
.pSpecializationInfo = nullptr,
},
};
{
- const auto& code = desc.vs_code;
- VkShaderModuleCreateInfo module_create_info {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
+ const auto& code = desc.vs_code;
+ VkShaderModuleCreateInfo module_create_info{
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
.codeSize = code.size(),
- .pCode = (uint32_t*)code.data(),
+ .pCode = (uint32_t*)code.data(),
};
VKCHECK(vkCreateShaderModule(device, &module_create_info, nullptr, &shader_stages_create_info[0U].module));
-
}
{
- const auto& code = desc.fs_code;
- VkShaderModuleCreateInfo module_create_info {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
+ const auto& code = desc.fs_code;
+ VkShaderModuleCreateInfo module_create_info{
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
.codeSize = code.size(),
- .pCode = (uint32_t*)code.data(),
+ .pCode = (uint32_t*)code.data(),
};
VKCHECK(vkCreateShaderModule(device, &module_create_info, nullptr, &shader_stages_create_info[1U].module));
}
- VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info {
+ VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
};
- VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
.primitiveRestartEnable = VK_FALSE,
};
- VkPipelineViewportStateCreateInfo viewport_state_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
+ VkPipelineViewportStateCreateInfo viewport_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
.viewportCount = 1U,
- .pViewports = nullptr,
- .scissorCount = 1U,
- .pScissors = nullptr,
+ .pViewports = nullptr,
+ .scissorCount = 1U,
+ .pScissors = nullptr,
};
- VkPipelineRasterizationStateCreateInfo rasterization_state_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .depthClampEnable = VK_FALSE,
+ VkPipelineRasterizationStateCreateInfo rasterization_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .depthClampEnable = VK_FALSE,
.rasterizerDiscardEnable = VK_FALSE,
- .polygonMode = VK_POLYGON_MODE_FILL,
- .cullMode = VK_CULL_MODE_NONE,
- .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
- .depthBiasEnable = VK_FALSE,
- .lineWidth = 1.f,
+ .polygonMode = VK_POLYGON_MODE_FILL,
+ .cullMode = VK_CULL_MODE_NONE,
+ .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
+ .depthBiasEnable = VK_FALSE,
+ .lineWidth = 1.f,
};
- VkPipelineMultisampleStateCreateInfo multisample_state_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
+ VkPipelineMultisampleStateCreateInfo multisample_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
- .sampleShadingEnable = VK_FALSE,
- .minSampleShading = 1.f,
+ .sampleShadingEnable = VK_FALSE,
+ .minSampleShading = 1.f,
};
- VkPipelineColorBlendAttachmentState color_attachment_state {
- .blendEnable = VK_TRUE,
+ VkPipelineColorBlendAttachmentState color_attachment_state{
+ .blendEnable = VK_TRUE,
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
- .colorBlendOp = VK_BLEND_OP_ADD,
+ .colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
- .alphaBlendOp = VK_BLEND_OP_ADD,
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
+ .alphaBlendOp = VK_BLEND_OP_ADD,
+ .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
};
- VkPipelineColorBlendStateCreateInfo color_blend_state_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .logicOpEnable = VK_FALSE,
+ VkPipelineColorBlendStateCreateInfo color_blend_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .logicOpEnable = VK_FALSE,
.attachmentCount = 1,
- .pAttachments = &color_attachment_state,
+ .pAttachments = &color_attachment_state,
};
- VkDynamicState dynamic_states[] {
+ VkDynamicState dynamic_states[]{
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
};
- VkPipelineDynamicStateCreateInfo dynamic_state_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
+ VkPipelineDynamicStateCreateInfo dynamic_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
.dynamicStateCount = sizeof(dynamic_states) / sizeof(VkDynamicState),
- .pDynamicStates = dynamic_states,
+ .pDynamicStates = dynamic_states,
};
- VkPipelineRenderingCreateInfo pipeline_rendering_create_info {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
- .pNext = nullptr,
- .viewMask = 0U,
- .colorAttachmentCount = static_cast<uint32_t>(desc.color_attachments_format.size()),
+ VkPipelineRenderingCreateInfo pipeline_rendering_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
+ .pNext = nullptr,
+ .viewMask = 0U,
+ .colorAttachmentCount = static_cast<uint32_t>(desc.color_attachments_format.size()),
.pColorAttachmentFormats = desc.color_attachments_format.data(),
- .depthAttachmentFormat = VK_FORMAT_UNDEFINED,
+ .depthAttachmentFormat = VK_FORMAT_UNDEFINED,
.stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
};
- VkGraphicsPipelineCreateInfo create_info {
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = &pipeline_rendering_create_info,
- .flags = 0U,
- .stageCount = sizeof(shader_stages_create_info) / sizeof(VkPipelineShaderStageCreateInfo),
- .pStages = shader_stages_create_info,
- .pVertexInputState = &vertex_input_state_create_info,
+ VkGraphicsPipelineCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .pNext = &pipeline_rendering_create_info,
+ .flags = 0U,
+ .stageCount = sizeof(shader_stages_create_info) / sizeof(VkPipelineShaderStageCreateInfo),
+ .pStages = shader_stages_create_info,
+ .pVertexInputState = &vertex_input_state_create_info,
.pInputAssemblyState = &input_assembly_create_info,
- .pTessellationState = nullptr,
- .pViewportState = &viewport_state_create_info,
+ .pTessellationState = nullptr,
+ .pViewportState = &viewport_state_create_info,
.pRasterizationState = &rasterization_state_create_info,
- .pMultisampleState = &multisample_state_create_info,
- .pDepthStencilState = nullptr,
- .pColorBlendState = &color_blend_state_create_info,
- .pDynamicState = &dynamic_state_create_info,
- .layout = bindless.layout,
- .renderPass = nullptr,
- .subpass = 0U,
- .basePipelineHandle = nullptr,
- .basePipelineIndex = 0,
+ .pMultisampleState = &multisample_state_create_info,
+ .pDepthStencilState = nullptr,
+ .pColorBlendState = &color_blend_state_create_info,
+ .pDynamicState = &dynamic_state_create_info,
+ .layout = bindless.layout,
+ .renderPass = nullptr,
+ .subpass = 0U,
+ .basePipelineHandle = nullptr,
+ .basePipelineIndex = 0,
};
device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
@@ -430,6 +437,28 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
return { pipelines.add(device_pipeline) };
}
+vksemaphore vkdevice::create_semaphore() {
+ vksemaphore semaphore{
+ .value = 0,
+ };
+ VkSemaphoreTypeCreateInfo semaphore_type_create_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+ .pNext = nullptr,
+ .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
+ .initialValue = 0U,
+ };
+
+ VkSemaphoreCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = &semaphore_type_create_info,
+ .flags = 0U,
+ };
+
+ VKCHECK(vkCreateSemaphore(device, &create_info, nullptr, &semaphore.vk_semaphore));
+
+ return semaphore;
+}
+
void vkdevice::destroy_texture(const device_texture& texture) {
destroy_texture({ .id = textures.find(texture) });
}
@@ -467,17 +496,31 @@ void vkdevice::destroy_pipeline(handle<device_pipeline> handle) {
vkDestroyPipeline(device, pipeline.vk_pipeline, nullptr);
}
-void vkdevice::submit(command_buffer* buffers, size_t count) {
- assert((max_submitable_command_buffers - count) >= 0);
+void vkdevice::wait(vksemaphore& semaphore) {
+ VkSemaphoreWaitInfo wait_info {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .semaphoreCount = 1U,
+ .pSemaphores = &semaphore.vk_semaphore,
+ .pValues = &semaphore.value,
+ };
+ VKCHECK(vkWaitSemaphores(device, &wait_info, -1));
+}
+
+void vkdevice::submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal) {
+#define USE_SUBMIT2
+ assert((max_submitable_command_buffers - buffers.size()) >= 0);
const auto queue_type = buffers[0].queue_type;
+#ifndef USE_SUBMIT2
VkCommandBuffer to_submit[max_submitable_command_buffers];
- for (auto index { 0U }; index < count; index++) {
+ for (auto index{ 0U }; index < count; index++) {
assert(queue_type == buffers[index].queue_type);
to_submit[index] = buffers[index].vk_command_buffer;
}
- VkSubmitInfo submit_info {
+ VkSubmitInfo submit_info{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr,
.waitSemaphoreCount = 0U,
@@ -490,25 +533,85 @@ void vkdevice::submit(command_buffer* buffers, size_t count) {
};
VKCHECK(vkQueueSubmit(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
+#else
+ VkCommandBufferSubmitInfo command_buffers_info[buffers.size()];
+
+ for (auto index{ 0U }; index < buffers.size(); index++) {
+ assert(queue_type == buffers[index].queue_type);
+
+ auto& command_buffer_info = command_buffers_info[index];
+ command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
+ command_buffer_info.pNext = nullptr;
+ command_buffer_info.commandBuffer = buffers[index].vk_command_buffer;
+ command_buffer_info.deviceMask = 0U;
+ }
+
+ VkSemaphoreSubmitInfo wait_semaphore_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
+ .deviceIndex = 0U,
+ };
+
+ VkSemaphoreSubmitInfo signal_semaphore_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .stageMask = VK_PIPELINE_STAGE_2_NONE,
+ .deviceIndex = 0U,
+ };
+
+ VkSubmitInfo2 submit_info{
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
+ .pNext = nullptr,
+ .flags = 0U,
+ .commandBufferInfoCount = static_cast<uint32_t>(buffers.size()),
+ .pCommandBufferInfos = command_buffers_info,
+ };
+
+ if (wait != nullptr) {
+ wait_semaphore_info.semaphore = wait->vk_semaphore;
+ wait_semaphore_info.value = wait->value;
+ submit_info.waitSemaphoreInfoCount = 1U;
+ submit_info.pWaitSemaphoreInfos = &wait_semaphore_info;
+ }
+
+ if (signal != nullptr) {
+ signal_semaphore_info.semaphore = signal->vk_semaphore;
+ signal_semaphore_info.value = ++signal->value;
+
+ submit_info.signalSemaphoreInfoCount = 1U;
+ submit_info.pSignalSemaphoreInfos = &signal_semaphore_info;
+ }
+
+ VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
+#endif
}
-void vkdevice::present() {
- VkPresentInfoKHR present_info {
+void vkdevice::present(vksurface& surface, const vksemaphore& semaphore) {
+ VkResult result;
+ VkPresentInfoKHR present_info{
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr,
+ .waitSemaphoreCount = 1U,
+ .pWaitSemaphores = &semaphore.vk_semaphore,
+ .swapchainCount = 1U,
+ .pSwapchains = &surface.vk_swapchain,
+ .pImageIndices = &surface.image_index,
+ .pResults = &result,
};
- // VKCHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info));
-}
+ VKCHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info));
+ VKCHECK(result);
+}
// private
void vkdevice::allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type) {
assert((max_allocable_command_buffers - count) >= 0);
- const auto& queue = queues[static_cast<uint32_t>(type)];
- VkCommandBuffer command_buffers[max_allocable_command_buffers];
+ const auto& queue = queues[static_cast<uint32_t>(type)];
+ VkCommandBuffer command_buffers[max_allocable_command_buffers];
- VkCommandBufferAllocateInfo allocate_info {
+ VkCommandBufferAllocateInfo allocate_info{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
.commandPool = queue.command_pool,
@@ -518,28 +621,28 @@ void vkdevice::allocate_command_buffers(command_buffer* buffers, size_t count, Q
VKCHECK(vkAllocateCommandBuffers(device, &allocate_info, command_buffers));
- for (auto index { 0U }; index < count; index++) {
+ for (auto index{ 0U }; index < count; index++) {
buffers[index].vk_command_buffer = command_buffers[index];
- buffers[index].queue_type = type;
+ buffers[index].queue_type = type;
}
}
void vkdevice::create_views(device_texture& texture) {
- VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U)
- ? VK_IMAGE_ASPECT_DEPTH_BIT
- : VK_IMAGE_ASPECT_COLOR_BIT;
- VkImageViewCreateInfo create_info {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .image = texture.vk_image,
- .viewType = VK_IMAGE_VIEW_TYPE_2D,
- .format = texture.desc.format,
- .components = {
- .r = VK_COMPONENT_SWIZZLE_R,
- .g = VK_COMPONENT_SWIZZLE_G,
- .b = VK_COMPONENT_SWIZZLE_B,
- .a = VK_COMPONENT_SWIZZLE_A,
+ VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U)
+ ? VK_IMAGE_ASPECT_DEPTH_BIT
+ : VK_IMAGE_ASPECT_COLOR_BIT;
+ VkImageViewCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .image = texture.vk_image,
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
+ .format = texture.desc.format,
+ .components = {
+ .r = VK_COMPONENT_SWIZZLE_R,
+ .g = VK_COMPONENT_SWIZZLE_G,
+ .b = VK_COMPONENT_SWIZZLE_B,
+ .a = VK_COMPONENT_SWIZZLE_A,
},
.subresourceRange = {
.aspectMask = aspect_mask,
@@ -562,12 +665,12 @@ void vkdevice::create_views(device_texture& texture) {
// Presentation stuff
void vkdevice::create_surface(const window& window) {
- VkWin32SurfaceCreateInfoKHR create_info {
- .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
- .pNext = nullptr,
- .flags = 0U,
- .hinstance = GetModuleHandle(nullptr),
- .hwnd = window.handle,
+ VkWin32SurfaceCreateInfoKHR create_info{
+ .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0U,
+ .hinstance = GetModuleHandle(nullptr),
+ .hwnd = window.handle,
};
VKCHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &surface));
@@ -575,7 +678,7 @@ void vkdevice::create_surface(const window& window) {
void vkdevice::create_swapchain() {
VkBool32 supported = VK_FALSE;
- auto& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)];
+ auto& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)];
VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, surface, &supported));
assert(supported);
@@ -611,43 +714,43 @@ void vkdevice::create_swapchain() {
VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &supported_present_modes_count, supported_present_modes.data()));
- auto min_image_count = (surface_capabilities.minImageCount <= virtual_frames_count) ? virtual_frames_count : surface_capabilities.minImageCount;
+ auto min_image_count = (surface_capabilities.minImageCount <= virtual_frames_count) ? virtual_frames_count : surface_capabilities.minImageCount;
- VkSwapchainCreateInfoKHR create_info = {
- .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
- .pNext = nullptr,
- .flags = 0U,
- .surface = surface,
- .minImageCount = min_image_count,
- .imageFormat = supported_formats[0].format,
- .imageColorSpace = supported_formats[0].colorSpace,
- .imageExtent = extent,
- .imageArrayLayers = 1U,
- .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
- .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
- .queueFamilyIndexCount = 0U,
- .pQueueFamilyIndices = nullptr,
- .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
- .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
- .presentMode = supported_present_modes[0],
- .clipped = VK_TRUE,
- .oldSwapchain = nullptr,
+ VkSwapchainCreateInfoKHR create_info = {
+ .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0U,
+ .surface = surface,
+ .minImageCount = min_image_count,
+ .imageFormat = supported_formats[0].format,
+ .imageColorSpace = supported_formats[0].colorSpace,
+ .imageExtent = extent,
+ .imageArrayLayers = 1U,
+ .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
+ .queueFamilyIndexCount = 0U,
+ .pQueueFamilyIndices = nullptr,
+ .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
+ .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+ .presentMode = supported_present_modes[0],
+ .clipped = VK_TRUE,
+ .oldSwapchain = nullptr,
};
VKCHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &swapchain));
}
void vkdevice::create_virtual_frames() {
- for (auto index { 0U }; index < virtual_frames_count; index++) {
+ for (auto index{ 0U }; index < virtual_frames_count; index++) {
{
- VkSemaphoreTypeCreateInfo semaphore_type_create_info {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
- .pNext = nullptr,
- .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
- .initialValue = 0U,
+ VkSemaphoreTypeCreateInfo semaphore_type_create_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+ .pNext = nullptr,
+ .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
+ .initialValue = 0U,
};
- VkSemaphoreCreateInfo create_info {
+ VkSemaphoreCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = &semaphore_type_create_info,
.flags = 0U,
@@ -661,7 +764,7 @@ void vkdevice::create_virtual_frames() {
// ----------------- vkadapter -----------------
void vkdevice::create_instance() {
- VkApplicationInfo app_info {
+ VkApplicationInfo app_info{
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "path-tracer",
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
@@ -670,17 +773,17 @@ void vkdevice::create_instance() {
.apiVersion = VK_API_VERSION_1_3,
};
- constexpr const char* instance_layers[] {
+ constexpr const char* instance_layers[]{
"VK_LAYER_KHRONOS_validation",
};
- constexpr const char* instance_extensions[] {
+ constexpr const char* instance_extensions[]{
VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
"VK_KHR_surface",
"VK_KHR_win32_surface"
};
- VkInstanceCreateInfo create_info {
+ VkInstanceCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.flags = 0U,
@@ -703,28 +806,28 @@ void vkdevice::create_device() {
VkDeviceQueueCreateInfo queue_create_infos[static_cast<uint32_t>(QueueType::MAX)];
for (auto& queue_create_info : queue_create_infos) {
- queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_create_info.pNext = nullptr;
- queue_create_info.flags = 0U;
- queue_create_info.queueCount = 1;
- queue_create_info.pQueuePriorities = &queue_priority;
+ queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queue_create_info.pNext = nullptr;
+ queue_create_info.flags = 0U;
+ queue_create_info.queueCount = 1;
+ queue_create_info.pQueuePriorities = &queue_priority;
}
auto queue_properties_count = 0U;
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_properties_count, nullptr);
- std::vector<VkQueueFamilyProperties> queue_properties { queue_properties_count };
+ std::vector<VkQueueFamilyProperties> queue_properties{ queue_properties_count };
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_properties_count, queue_properties.data());
for (auto index{ 0U }; index < static_cast<uint32_t>(QueueType::MAX); index++) {
- auto& queue = queues[index];
+ auto& queue = queues[index];
- for (auto properties_index { 0U }; properties_index < queue_properties_count; properties_index++) {
+ for (auto properties_index{ 0U }; properties_index < queue_properties_count; properties_index++) {
auto& queue_property = queue_properties[properties_index];
if ((queue_property.queueFlags & queue.usages) == queue.usages) {
queue_create_infos[index].queueFamilyIndex = queue.index = properties_index;
- queue_property.queueFlags = 0U;
+ queue_property.queueFlags = 0U;
}
}
}
@@ -734,7 +837,7 @@ void vkdevice::create_device() {
// VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME
};
- VkPhysicalDeviceVulkan12Features physical_device_12_features {
+ VkPhysicalDeviceVulkan12Features physical_device_12_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = nullptr,
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
@@ -746,14 +849,14 @@ void vkdevice::create_device() {
.bufferDeviceAddress = VK_TRUE,
};
- VkPhysicalDeviceVulkan13Features physical_device_13_features {
+ VkPhysicalDeviceVulkan13Features physical_device_13_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
.pNext = &physical_device_12_features,
.synchronization2 = VK_TRUE,
.dynamicRendering = VK_TRUE,
};
- VkDeviceCreateInfo create_info {
+ VkDeviceCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &physical_device_13_features,
.flags = 0U,
@@ -778,22 +881,22 @@ void vkdevice::create_device() {
}
void vkdevice::create_memory_allocator() {
- VmaAllocatorCreateInfo create_info {
- .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
- .physicalDevice = physical_device,
- .device = device,
- .instance = instance,
- .vulkanApiVersion = VK_API_VERSION_1_2,
+ VmaAllocatorCreateInfo create_info{
+ .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
+ .physicalDevice = physical_device,
+ .device = device,
+ .instance = instance,
+ .vulkanApiVersion = VK_API_VERSION_1_2,
};
VKCHECK(vmaCreateAllocator(&create_info, &gpu_allocator));
}
void vkdevice::create_command_pools() {
- VkCommandPoolCreateInfo create_info {
+ VkCommandPoolCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
- .flags = 0U,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
};
for (auto& queue : queues) {
@@ -809,7 +912,7 @@ void vkdevice::pick_physical_device() {
assert(physical_devices_count > 0);
- std::vector<VkPhysicalDevice> physical_devices { physical_devices_count };
+ std::vector<VkPhysicalDevice> physical_devices{ physical_devices_count };
vkEnumeratePhysicalDevices(instance, &physical_devices_count, physical_devices.data());
for (auto& physical_dev : physical_devices) {
@@ -825,11 +928,11 @@ void vkdevice::pick_physical_device() {
bool vkdevice::device_support_features(VkPhysicalDevice physical_dev) {
// Vulkan 1.2 physical device features support
{
- VkPhysicalDeviceVulkan12Features vulkan_12_features {
+ VkPhysicalDeviceVulkan12Features vulkan_12_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
};
- VkPhysicalDeviceFeatures2 physical_device_features {
+ VkPhysicalDeviceFeatures2 physical_device_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
.pNext = &vulkan_12_features,
};
@@ -851,11 +954,11 @@ bool vkdevice::device_support_features(VkPhysicalDevice physical_dev) {
// Vulkan 1.3 physical device features support
{
- VkPhysicalDeviceVulkan13Features vulkan_13_features {
+ VkPhysicalDeviceVulkan13Features vulkan_13_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
};
- VkPhysicalDeviceFeatures2 physical_device_features {
+ VkPhysicalDeviceFeatures2 physical_device_features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
.pNext = &vulkan_13_features,
};
@@ -872,15 +975,15 @@ bool vkdevice::device_support_features(VkPhysicalDevice physical_dev) {
}
void vkdevice::create_debug_layer_callback() {
- VkDebugUtilsMessengerCreateInfoEXT create_info {
+ VkDebugUtilsMessengerCreateInfoEXT create_info{
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = 0U,
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
- .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
+ .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
.pfnUserCallback = debug_callback,
.pUserData = nullptr,
};
diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp
index 2cd1d75..31b1254 100644
--- a/include/api-test/command-buffer.hpp
+++ b/include/api-test/command-buffer.hpp
@@ -40,13 +40,17 @@ private:
public:
rect render_area;
std::span<handle<device_texture>> color_attachments;
- // optional viewport
- // optional scissor
+ // rect viewport;
+ // rect scissor;
};
struct draw_params {
handle<device_pipeline> pipeline;
+ handle<device_buffer> index_buffer;
uint32_t vertex_count;
+ uint32_t vertex_offset;
+ uint32_t index_offset;
uint32_t instance_count;
+ uint32_t uniforms_offset;
};
struct command_buffer {
diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp
index 2355191..956739d 100644
--- a/include/api-test/handle.hpp
+++ b/include/api-test/handle.hpp
@@ -6,5 +6,7 @@ template<typename T>
struct handle {
uint32_t id = handle::invalid_handle;
+ [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_handle; }
+
static constexpr uint32_t invalid_handle = -1;
};
diff --git a/include/api-test/vk-bindless.hpp b/include/api-test/vk-bindless.hpp
index c292878..80918fe 100644
--- a/include/api-test/vk-bindless.hpp
+++ b/include/api-test/vk-bindless.hpp
@@ -8,7 +8,8 @@
enum BindlessSetType : uint32_t {
GLOBAL,
- UNIFORMS,
+ INSTANCES_UNIFORMS,
+ DRAWS_UNIFORMS,
MAX,
};
@@ -34,7 +35,8 @@ struct bindless_model {
private:
VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
VkDescriptorPool descriptor_pool;
- handle<device_buffer> uniform_buffer;
+ handle<device_buffer> instances_uniform_buffer_handle;
+ handle<device_buffer> draws_uniform_buffer_handle;
static constexpr size_t descriptor_pool_allocable_sets_count = 64U;
static constexpr uint32_t set_descriptors_count[BindlessSetType::MAX]{ 1024U };
@@ -50,6 +52,9 @@ private:
void destroy_immutable_samplers(VkDevice device);
VkSampler samplers[SamplerType::MAX_SAMPLER];
+
+ static constexpr size_t instances_uniform_buffer_size = 64ULL * 1024ULL;
+ static constexpr size_t draws_uniform_buffer_size = 64ULL * 1024ULL;
#else
VkPipelineLayout layout;
VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp
index bca57af..987eb13 100644
--- a/include/api-test/vk-device-types.hpp
+++ b/include/api-test/vk-device-types.hpp
@@ -48,7 +48,7 @@ struct buffer_desc {
struct device_buffer {
VkBuffer vk_buffer;
VmaAllocation alloc;
- VkDeviceAddress device_address;
+ VkDeviceAddress device_address = 0U;
void* mapped_ptr;
buffer_desc desc;
diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp
index a30b18c..32a0707 100644
--- a/include/api-test/vk-device.hpp
+++ b/include/api-test/vk-device.hpp
@@ -15,6 +15,17 @@ using VmaAllocator = struct VmaAllocator_T*;
class window;
+struct vksurface {
+ VkSurfaceKHR vk_surface;
+ VkSwapchainKHR vk_swapchain;
+ uint32_t image_index;
+};
+
+struct vksemaphore {
+ VkSemaphore vk_semaphore = nullptr;
+ uint64_t value = 0U;
+};
+
class vkdevice {
struct queue {
VkQueue vk_queue;
@@ -38,6 +49,8 @@ class vkdevice {
handle<device_pipeline> create_pipeline(const pipeline_desc& desc);
+ vksemaphore create_semaphore();
+
void destroy_texture(const device_texture& texture);
void destroy_texture(handle<device_texture> handle);
@@ -72,9 +85,11 @@ class vkdevice {
return device;
}
- void submit(command_buffer* buffers, size_t count);
+ void wait(vksemaphore& semaphore);
+
+ void submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal);
- void present();
+ void present(vksurface& surface, const vksemaphore& semaphore);
private:
vkdevice(const window& window);
diff --git a/include/vulkan-loader.hpp b/include/vulkan-loader.hpp
index cd93415..f229509 100644
--- a/include/vulkan-loader.hpp
+++ b/include/vulkan-loader.hpp
@@ -75,6 +75,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES;
X(vkDestroyDevice) \
X(vkDeviceWaitIdle) \
X(vkQueueSubmit) \
+ X(vkQueueSubmit2) \
X(vkCreateSemaphore) \
X(vkDestroySemaphore) \
X(vkWaitSemaphores) \
diff --git a/shaders/api-test-ui.frag b/shaders/api-test-ui.frag
index 0272ba2..fc1c1ee 100644
--- a/shaders/api-test-ui.frag
+++ b/shaders/api-test-ui.frag
@@ -7,15 +7,17 @@ layout(location = 0) in struct {
vec4 color;
} In;
-// layout(set = 0, binding = 0) uniform sampler samplers[];
-// layout(set = 0, binding = 1) uniform texture2D textures[];
-// layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
-// layout(set = 1, binding = 0) uniform parameters {
-// uint texture_index;
-// uint sampler_index;
-// } params;
+layout(set = 0, binding = 0) uniform sampler samplers[];
+layout(set = 0, binding = 1) uniform texture2D textures[];
+layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(set = 2, binding = 0) uniform parameters {
+ uint vertex_buffer;
+ vec2 scale;
+ vec2 translate;
+ uint texture_index;
+} params;
void main() {
- // o_Color = In.color * texture(sampler2D(textures[params.texture_index], samplers[params.sampler_index]), In.uv.xy);
- o_Color = vec4(1, 0, 0, 1);
+ o_Color = In.color * texture(sampler2D(textures[nonuniformEXT(params.texture_index)], samplers[nonuniformEXT(0U)]), In.uv.xy);
+ // o_Color = vec4(1, 0, 0, 1);
}
diff --git a/shaders/api-test-ui.vert b/shaders/api-test-ui.vert
index 3b6d0b5..8dd05a8 100644
--- a/shaders/api-test-ui.vert
+++ b/shaders/api-test-ui.vert
@@ -4,18 +4,19 @@ struct vertex {
vec2 pos;
vec2 uv;
uint color;
- uint[3] padding;
+ uint padding;
};
layout(buffer_reference) readonly buffer vertices {
vertex vertices[];
};
-// layout(set = 1, binding = 0) uniform parameters {
-// vertices vertex_buffer;
-// vec2 scale;
-// vec2 translate;
-// } params;
+layout(set = 2, binding = 0) uniform parameters {
+ vertices vertex_buffer;
+ vec2 scale;
+ vec2 translate;
+ uint texture_index;
+} params;
out gl_PerVertex {
vec4 gl_Position;
@@ -28,13 +29,13 @@ layout(location = 0) out struct {
void main() {
- // vertex v = params.vertex_buffer.vertices[gl_VertexIndex];
+ vertex v = params.vertex_buffer.vertices[gl_VertexIndex];
- // Out.color = unpackUnorm4x8(v.color);
- // Out.uv = v.uv;
+ Out.color = unpackUnorm4x8(v.color);
+ Out.uv = v.uv;
- // gl_Position = vec4(v.pos * params.scale + params.translate, 0.0, 1.0);
+ gl_Position = vec4(v.pos * params.scale + params.translate, 0.0, 1.0);
- vec2 pos[3] = vec2[3]( vec2(-0.7, 0.7), vec2(0.7, 0.7), vec2(0.0, -0.7) );
- gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
+ // vec2 pos[3] = vec2[3]( vec2(-0.7, 0.7), vec2(0.7, 0.7), vec2(0.0, -0.7) );
+ // gl_Position = vec4(pos[gl_VertexIndex], 1.0, 1.0);
}
diff --git a/shaders/test.comp b/shaders/test.comp
index 244533e..b3d2089 100644
--- a/shaders/test.comp
+++ b/shaders/test.comp
@@ -6,7 +6,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(set = 0, binding = 0) uniform sampler samplers[];
layout(set = 0, binding = 1) uniform texture2D textures[];
layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
-layout(set = 1, binding = 0) uniform parameters {
+layout(set = 2, binding = 0) uniform parameters {
uint input_id1;
uint input_id2;
uint output_id;