aboutsummaryrefslogtreecommitdiffstats
path: root/api-test
diff options
context:
space:
mode:
Diffstat (limited to 'api-test')
-rw-r--r--api-test/CMakeLists.txt10
-rw-r--r--api-test/command-buffer.cpp68
-rw-r--r--api-test/main.cpp238
-rw-r--r--api-test/vk-bindless.cpp201
-rw-r--r--api-test/vk-device.cpp605
5 files changed, 753 insertions, 369 deletions
diff --git a/api-test/CMakeLists.txt b/api-test/CMakeLists.txt
index dc92ee3..b41c325 100644
--- a/api-test/CMakeLists.txt
+++ b/api-test/CMakeLists.txt
@@ -8,12 +8,18 @@ add_executable(
${CMAKE_SOURCE_DIR}/src/window.cpp
${CMAKE_SOURCE_DIR}/src/utils.cpp
${CMAKE_SOURCE_DIR}/src/vulkan-loader.cpp
+ ${CMAKE_SOURCE_DIR}/src/gltf.cpp
+ ${CMAKE_SOURCE_DIR}/src/vec3.cpp
+ ${CMAKE_SOURCE_DIR}/src/mesh.cpp
+ ${CMAKE_SOURCE_DIR}/src/scene.cpp
+ ${CMAKE_SOURCE_DIR}/src/camera.cpp
+ ${CMAKE_SOURCE_DIR}/src/bvh.cpp
)
-target_compile_definitions(api-test PUBLIC WINDOWS VK_NO_PROTOTYPES VK_USE_PLATFORM_WIN32_KHR)
+target_compile_definitions(api-test PUBLIC WINDOWS VK_NO_PROTOTYPES VK_USE_PLATFORM_WIN32_KHR API_TEST NOMINMAX)
target_compile_options(api-test
- PRIVATE -Wall -Wextra
+ PRIVATE -Wall -Wextra -msse4.1
)
target_include_directories(api-test SYSTEM PUBLIC ${Vulkan_INCLUDE_DIRS})
diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp
index 79b8aef..d694f9f 100644
--- a/api-test/command-buffer.cpp
+++ b/api-test/command-buffer.cpp
@@ -1,6 +1,5 @@
#include "command-buffer.hpp"
-#include <cassert>
#include <vulkan/vulkan_core.h>
#include "vulkan-loader.hpp"
@@ -20,11 +19,18 @@ void command_buffer::start() const {
const auto& bindless = vkdevice::get_render_device().get_bindingmodel();
const auto* global_set = &bindless.sets[BindlessSetType::GLOBAL];
+ // const auto global_uniforms = bindless.get_globals_uniform_buffer();
+ // if (queue_type == QueueType::GRAPHICS) {
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.graphics_layout, 0, 1U, global_set, 1U, &global_uniforms.offset);
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.compute_layout, 0, 1U, global_set, 1U, &global_uniforms.offset);
+ // } else if (queue_type == QueueType::ASYNC_COMPUTE) {
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.compute_layout, 0, 1U, global_set, 1U, &global_uniforms.offset);
+ // }
if (queue_type == QueueType::GRAPHICS) {
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.layout, 0, 1U, global_set, 0U, nullptr);
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, 0, 1U, global_set, 0U, nullptr);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.graphics_layout, 0, 1U, global_set, 0U, nullptr);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.compute_layout, 0, 1U, global_set, 0U, nullptr);
} else if (queue_type == QueueType::ASYNC_COMPUTE) {
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, 0, 1U, global_set, 0U, nullptr);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.compute_layout, 0, 1U, global_set, 0U, nullptr);
}
}
@@ -107,12 +113,19 @@ 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::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);
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.compute_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.compute_layout, static_cast<uint32_t>(BindlessSetType::DRAWS_UNIFORMS), 1U, &bindless.sets[BindlessSetType::DRAWS_UNIFORMS], 1U, &params.uniforms_offset);
+
+ for (uint32_t push_index = 0U; push_index < bindless_model::max_push_constants_slots; push_index++) {
+ vkCmdPushConstants(vk_command_buffer, bindless.compute_layout, VK_SHADER_STAGE_COMPUTE_BIT, push_index * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.params[push_index]);
+ }
vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline);
- vkCmdDispatch(vk_command_buffer, params.group_size.x / params.local_group_size.x, params.group_size.y / params.local_group_size.y, params.group_size.z / params.local_group_size.z);
+ auto x = params.group_size.vec.x / params.local_group_size.vec.x;
+ auto y = params.group_size.vec.y / params.local_group_size.vec.y;
+ auto z = params.group_size.vec.z / params.local_group_size.vec.z;
+ vkCmdDispatch(vk_command_buffer, x, y, z);
}
void graphics_command_buffer::begin_renderpass(const renderpass_params& params) const {
@@ -172,24 +185,47 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params)
vkCmdSetScissor(vk_command_buffer, 0U, 1U, &scissor);
vkCmdSetViewport(vk_command_buffer, 0U, 1U, &viewport);
+
+ // auto& device = vkdevice::get_render_device();
+ // const auto& bindless = device.get_bindingmodel();
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::GLOBAL), 1U, &bindless.sets[BindlessSetType::GLOBAL], 1U, &params.uniforms_offset);
+ // vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.layout, static_cast<uint32_t>(BindlessSetType::GLOBAL), 1U, &bindless.sets[BindlessSetType::GLOBAL], 1U, &params.uniforms_offset);
}
-void graphics_command_buffer::render(const draw_params& params) const {
+void graphics_command_buffer::draw(const draw_params& params) const {
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);
+ // 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);
- 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);
- }
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::GLOBALS * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.globals_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::INSTANCES * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.instances_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::DRAWS * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.uniforms_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::VERTEX_BUFFER * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.vertex_address);
+
+ vkCmdDraw(vk_command_buffer, params.vertex_count, params.instance_count, params.vertex_offset, 0U);
+}
+
+void graphics_command_buffer::draw_indexed(const draw_indexed_params& params) const {
+ 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);
+
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::GLOBALS * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.globals_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::INSTANCES * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.instances_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::DRAWS * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.uniforms_address);
+ vkCmdPushConstants(vk_command_buffer, bindless.graphics_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, ConstantType::VERTEX_BUFFER * bindless_model::max_push_constants_slots_size, bindless_model::max_push_constants_slots_size, &params.vertex_address);
+
+ 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);
}
void graphics_command_buffer::end_renderpass() const {
diff --git a/api-test/main.cpp b/api-test/main.cpp
index 583bced..0761070 100644
--- a/api-test/main.cpp
+++ b/api-test/main.cpp
@@ -1,7 +1,6 @@
#include <cassert>
#include <cstdio>
#include <ratio>
-#include <span>
#include <array>
#include <chrono>
#include <vk_mem_alloc.h>
@@ -22,6 +21,9 @@ struct device_texture;
#define ENABLE_RENDERDOC
#endif // _DEBUG
+#include "camera.hpp"
+#include "scene.hpp"
+
#ifdef ENABLE_RENDERDOC
#include <renderdoc.h>
@@ -93,9 +95,19 @@ int main() {
io.DisplaySize.x = window_width;
io.DisplaySize.y = window_height;
+ const float aspect_ratio = 16.0 / 9.0;
+
+ point3 position { 13.f, 2.f, -3.f };
+ point3 target {};
+ const auto v_fov = 90.f;
+ const auto aperture = 0.1f;
+ const auto focus_distance = 10.f;
+
auto& device = vkdevice::get_render_device();
device.init();
+ auto main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), window_width, window_height);
+
auto surface_handle = device.create_surface({
.window_handle = wnd.handle,
.surface_format = {
@@ -103,7 +115,7 @@ int main() {
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
},
.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR,
- .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
});
auto& surface = device.get_surface(surface_handle);
@@ -190,38 +202,47 @@ int main() {
auto index_buffer = device.get_buffer(index_buffer_handle);
auto code = read_file("shaders/test.comp.spv");
- auto compute = device.create_pipeline({
+ auto compute = device.create_compute_pipeline({
.cs_code = code,
});
+ auto rt_code = read_file("shaders/compute.comp.spv");
+ auto raytracing = device.create_compute_pipeline({
+ .cs_code = rt_code,
+ });
+ auto tonemapping_code = read_file("shaders/tonemapping.comp.spv");
+ auto tonemapping = device.create_compute_pipeline({
+ .cs_code = tonemapping_code,
+ });
+ const auto acc_handle = device.create_texture({
+ .width = static_cast<uint32_t>(window_width),
+ .height = static_cast<uint32_t>(window_height),
+ .usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+ .type = VK_IMAGE_TYPE_2D,
+ });
+ auto acc_storage_index = device.get_texture(acc_handle).get_storage_index();
+
+ const auto result_handle = device.create_texture({
+ .width = static_cast<uint32_t>(window_width),
+ .height = static_cast<uint32_t>(window_height),
+ .usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+ .type = VK_IMAGE_TYPE_2D,
+ });
+ auto result_storage_index = device.get_texture(result_handle).get_storage_index();
+
std::array<VkFormat, 1U> formats { surface.surface_format.format };
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({
+ auto graphics = device.create_graphics_pipeline({
.vs_code = vertex_code,
.fs_code = fragment_code,
.color_attachments_format = formats
});
- auto semaphore = device.create_semaphore({
- .type = VK_SEMAPHORE_TYPE_TIMELINE,
- });
- constexpr uint32_t virtual_frames_count = 2U;
- handle<device_semaphore> submit_semaphores[virtual_frames_count];
- for (auto& submit_semaphore : submit_semaphores) {
- submit_semaphore = device.create_semaphore({
- .type = VK_SEMAPHORE_TYPE_BINARY,
- });
- }
- handle<device_semaphore> acquire_semaphores[virtual_frames_count];
- for (auto& acquire_semaphore : acquire_semaphores) {
- acquire_semaphore = device.create_semaphore({
- .type = VK_SEMAPHORE_TYPE_BINARY,
- });
- }
-
std::array<graphics_command_buffer, 4U> graphics_command_buffers;
- device.allocate_command_buffers(graphics_command_buffers, QueueType::GRAPHICS);
+ device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), QueueType::GRAPHICS);
RD_START_CAPTURE;
@@ -237,47 +258,38 @@ int main() {
graphics_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);
graphics_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;
- uint32_t input2;
- uint32_t output;
- };
- const auto& uniform_buffer = device.get_bindingmodel().get_uniform_buffer();
- compute_params params {
- device.get_texture(second_texture).get_storage_index(),
- device.get_texture(gpu_texture_handle).get_storage_index(),
- device.get_texture(output_texture_handle).get_storage_index(),
- };
- memcpy(uniform_buffer.mapped_ptr, &params, sizeof(params));
-
- graphics_command_buffers[0].dispatch({
- .pipeline = compute,
- .group_size = { .vec = { image_size, image_size, 1U }},
- .local_group_size = { .vec = { 8U, 8U, 1U }},
- .uniforms_offset = 0U,
- });
+ {
+ graphics_command_buffers[0].dispatch({
+ .pipeline = compute,
+ .group_size = { .vec = { image_size, image_size, 1U }},
+ .local_group_size = { .vec = { 8U, 8U, 1U }},
+ .params = {
+ device.get_texture(second_texture).get_storage_index(), // Input 1
+ device.get_texture(gpu_texture_handle).get_storage_index(), // Input 2
+ device.get_texture(output_texture_handle).get_storage_index(), // Output
+ },
+ });
+ }
graphics_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);
graphics_command_buffers[0].stop();
- device.submit(std::span { static_cast<command_buffer*>(graphics_command_buffers.data()), 1 }, {}, semaphore);
+ device.submit(graphics_command_buffers.data(), 1);
+ device.wait();
RD_END_CAPTURE;
- // std::array<struct command_buffer, 1U> ui_command_buffers = {command_buffers[1]};
std::array<handle<device_texture>, 1U> color_attachment {};
- uint32_t frame_time;
+ constexpr uint32_t virtual_frames_count = 2U;
+ uint32_t frame_time = 1U;
uint32_t frame_count = 0U;
while(wnd.isOpen) {
auto start = std::chrono::system_clock::now();
wnd.poll_events();
uint32_t virtual_frame_index = frame_count % virtual_frames_count;
- auto& submit_semaphore = submit_semaphores[virtual_frame_index];
- auto& acquire_semaphore = acquire_semaphores[virtual_frame_index];
- auto command_buffers = std::span<struct command_buffer> { static_cast<struct command_buffer*>(graphics_command_buffers.data() + virtual_frame_index + 1U), 1 };
- graphics_command_buffer& command_buffer = graphics_command_buffers[virtual_frame_index + 1U];
+ auto command_buffer = graphics_command_buffers[2U + virtual_frame_index];
for (auto& event : wnd.events) {
if (event.type == EVENT_TYPES::MOUSE_MOVE) {
io.MousePos.x = static_cast<float>(event.x);
@@ -292,16 +304,71 @@ int main() {
auto* draw_data = ImGui::GetDrawData();
update_buffers(draw_data, vertex_buffer, index_buffer);
- // device.wait(semaphore);
- device.wait(submit_semaphore);
+ const auto& scene_buffer = device.get_buffer(main_scene.scene_buffer_handle);
+ main_scene.meta.sample_index = frame_count;
+ uint8_t* ptr = static_cast<uint8_t*>(scene_buffer.mapped_ptr);
+ memcpy(static_cast<void*>(ptr), &main_scene.meta, sizeof(main_scene.meta));
+ memcpy(static_cast<void*>(ptr + sizeof(main_scene.meta)), &main_scene.meta, sizeof(main_scene.meta));
+ memcpy(static_cast<void*>(ptr + sizeof(main_scene.meta) * 2U), &main_scene.meta, sizeof(main_scene.meta));
- surface.acquire_image_index(acquire_semaphore);
- color_attachment[0] = surface.get_backbuffer_image();
+ // TODO: Refactor backbuffer acquisition
+ auto backbuffer = surface.swapchain_images[device.acquire_image_index(surface_handle)];
+ color_attachment[0] = backbuffer;
RD_START_CAPTURE;
- command_buffer.start(),
+ command_buffer.start();
+
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+ {
+ uint64_t textures = (virtual_frame_index == 0U) ? ((uint64_t(acc_storage_index) << 32U) | result_storage_index) : ((uint64_t(result_storage_index) << 32U) | acc_storage_index);
+
+ if (virtual_frame_index == 0) {
+ command_buffer.barrier(result_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ command_buffer.barrier(acc_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ } else {
+ command_buffer.barrier(result_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ command_buffer.barrier(acc_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ }
+
+ command_buffer.dispatch({
+ .pipeline = raytracing,
+ .group_size = { .vec { window_width, window_height, 1U, } },
+ .local_group_size = { .vec { 8U, 8U, 1U, } },
+ .params = {
+ main_scene.scene_buffer_address(),
+ main_scene.bvh_buffer_address(),
+ main_scene.indices_buffer_address(),
+ main_scene.positions_buffer_address(),
+ main_scene.normals_buffer_address(),
+ main_scene.uvs_buffer_address(),
+ main_scene.materials_buffer_address(),
+ textures,
+ },
+ });
+
+ // TODO: Refactor backbuffer acquisition
+ auto backbuffer_storage_index = device.get_texture(backbuffer).get_storage_index();
+ uint64_t out = (virtual_frame_index == 0U) ? ((uint64_t(result_storage_index) << 32U) | backbuffer_storage_index) : ((uint64_t(acc_storage_index) << 32U) | backbuffer_storage_index);
+ command_buffer.dispatch({
+ .pipeline = tonemapping,
+ .group_size = { .vec { window_width, window_height, 1U, } },
+ .local_group_size = { .vec { 8U, 8U, 1U, } },
+ .params = {
+ main_scene.scene_buffer_address(),
+ main_scene.bvh_buffer_address(),
+ main_scene.indices_buffer_address(),
+ main_scene.positions_buffer_address(),
+ main_scene.normals_buffer_address(),
+ main_scene.uvs_buffer_address(),
+ main_scene.materials_buffer_address(),
+ out,
+ },
+ });
+ }
+
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- command_buffer.barrier(surface.get_backbuffer_image(), VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_ACCESS_2_NONE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
command_buffer.begin_renderpass({
.render_area = {
.x = static_cast<int32_t>(draw_data->DisplayPos.x),
@@ -312,21 +379,20 @@ int main() {
.color_attachments = color_attachment,
});
- struct draw_params {
- uintptr_t vertex_buffer;
- float scale[2U];
- float translate[2U];
- uint32_t texture_index;
- };
-
- uint32_t draw_index = 0U;
- std::array<draw_params, 100U> draws;
+ auto& draws_uniform_buffer = device.get_bindingmodel().get_draws_uniform_buffer();
for (auto index {0} ; 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,
+ auto offset = draws_uniform_buffer.offset;
+ {
+ struct ui_params {
+ // uintptr_t vertex_buffer;
+ float scale[2U];
+ float translate[2U];
+ uint32_t texture_index;
+ };
+ auto* ui_param = draws_uniform_buffer.allocate<ui_params>();
+ *ui_param = ui_params{
+ // .vertex_buffer = vertex_buffer.device_address,
.scale {
2.f / draw_data->DisplaySize.x,
2.f / draw_data->DisplaySize.y,
@@ -337,60 +403,52 @@ int main() {
},
.texture_index = ui_texture.get_sampled_index(),
};
+ }
- command_buffer.render({
+ for (auto& draw_command : cmd_list->CmdBuffer) {
+ command_buffer.draw_indexed({
.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,
+ .uniforms_address = draws_uniform_buffer.device_address + offset,
+ .vertex_address = vertex_buffer.device_address,
});
-
- draw_index++;
}
}
- memcpy(uniform_buffer.mapped_ptr, draws.data(), sizeof(draw_params) * draw_index);
-
command_buffer.end_renderpass();
- command_buffer.barrier(surface.get_backbuffer_image(), VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
command_buffer.stop();
- // device.submit(command_buffers, acquire_semaphore, semaphore);
- // device.wait(semaphore);
- // device.present(surface_handle, {});
-
- device.submit(command_buffers, acquire_semaphore, submit_semaphore);
- device.present(surface_handle, submit_semaphore);
+ device.submit_before_present(surface_handle, &command_buffer, 1U);
+ device.present(surface_handle);
+ device.wait();
auto end = std::chrono::system_clock::now();
frame_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
+ frame_count++;
RD_END_CAPTURE;
}
- device.wait(semaphore);
-
+ device.wait();
device.destroy_surface(surface_handle);
device.destroy_pipeline(compute);
device.destroy_pipeline(graphics);
-
- device.destroy_semaphore(semaphore);
- for (auto& submit_semaphore : submit_semaphores) {
- device.destroy_semaphore(submit_semaphore);
- }
- for (auto& acquire_semaphore : acquire_semaphores) {
- device.destroy_semaphore(acquire_semaphore);
- }
+ device.destroy_pipeline(raytracing);
+ device.destroy_pipeline(tonemapping);
device.destroy_texture(gpu_texture_handle);
device.destroy_texture(second_texture);
device.destroy_texture(output_texture_handle);
device.destroy_texture(ui_texture_handle);
+ device.destroy_texture(acc_handle);
+ device.destroy_texture(result_handle);
device.destroy_buffer(staging_buffer_handle);
device.destroy_buffer(vertex_buffer_handle);
diff --git a/api-test/vk-bindless.cpp b/api-test/vk-bindless.cpp
index 66fd59c..d3d6415 100644
--- a/api-test/vk-bindless.cpp
+++ b/api-test/vk-bindless.cpp
@@ -1,12 +1,18 @@
#include "vk-bindless.hpp"
#include <vk_mem_alloc.h>
+#include <vulkan/vulkan_core.h>
#include "vk-device.hpp"
#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
-const device_buffer& bindless_model::get_uniform_buffer() const {
+device_buffer& bindless_model::get_globals_uniform_buffer() const {
+ auto& render_device = vkdevice::get_render_device();
+ return render_device.get_buffer(globals_uniform_buffer_handle);
+}
+
+device_buffer& bindless_model::get_draws_uniform_buffer() const {
auto& render_device = vkdevice::get_render_device();
return render_device.get_buffer(draws_uniform_buffer_handle);
}
@@ -21,67 +27,96 @@ bindless_model bindless_model::create_bindless_model() {
bindless.create_descriptor_pool(device);
bindless.allocate_sets(device);
- VkWriteDescriptorSet writes_descriptor_set[2U];
+ // VkWriteDescriptorSet writes_descriptor_set[BindlessSetType::MAX];
- {
- bindless.instances_uniform_buffer_handle = render_device.create_buffer({
- .size = instances_uniform_buffer_size,
+ // {
+ bindless.globals_uniform_buffer_handle = render_device.create_buffer({
+ .size = globals_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,
- };
+ // const auto& buffer = render_device.get_buffer(bindless.globals_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,
- };
- }
+ // writes_descriptor_set[BindlessSetType::GLOBAL] = {
+ // .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ // .pNext = nullptr,
+ // .dstSet = bindless.sets[BindlessSetType::GLOBAL],
+ // .dstBinding = 3U,
+ // .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[BindlessSetType::INSTANCES_UNIFORMS] = {
+ // .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,
+ .usages = VK_BUFFER_USAGE_UNIFORM_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,
});
- 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,
- };
+ // const auto& buffer = render_device.get_buffer(bindless.draws_uniform_buffer_handle);
+ // VkDescriptorBufferInfo buffer_info {
+ // .buffer = buffer.vk_buffer,
+ // .offset = 0U,
+ // .range = draws_uniform_buffer_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,
- };
- }
+ // writes_descriptor_set[BindlessSetType::DRAWS_UNIFORMS] = {
+ // .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);
+ // vkUpdateDescriptorSets(device, sizeof(writes_descriptor_set) / sizeof(VkWriteDescriptorSet), writes_descriptor_set, 0U, nullptr);
#else
VkBufferCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -126,11 +161,12 @@ void bindless_model::destroy_bindless_model(bindless_model& bindless) {
vkDestroyDescriptorSetLayout(device, bindless.sets_layout[index], nullptr);
}
- vkDestroyPipelineLayout(device, bindless.layout, nullptr);
+ vkDestroyPipelineLayout(device, bindless.graphics_layout, nullptr);
+ vkDestroyPipelineLayout(device, bindless.compute_layout, nullptr);
bindless.destroy_immutable_samplers(device);
- render_device.destroy_buffer(bindless.instances_uniform_buffer_handle);
+ // render_device.destroy_buffer(bindless.instances_uniform_buffer_handle);
render_device.destroy_buffer(bindless.draws_uniform_buffer_handle);
}
@@ -139,6 +175,7 @@ void bindless_model::create_layout(VkDevice device) {
// Binding 0 Storage images
// Binding 1 Sampled images
// Binding 2 Samplers
+ // Binding 3 Dynamic Uniform Buffer
{
VkDescriptorSetLayoutBinding set_layout_bindings[]{
{
@@ -162,12 +199,21 @@ void bindless_model::create_layout(VkDevice device) {
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = nullptr,
},
+ // {
+ // .binding = 3U,
+ // .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ // .descriptorCount = 1U,
+ // .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
+ // .pImmutableSamplers = nullptr,
+ // },
};
VkDescriptorBindingFlags flags[]{
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+ // VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+ // 0U,
};
VkDescriptorSetLayoutBindingFlagsCreateInfo layout_binding_flags{
@@ -195,7 +241,7 @@ void bindless_model::create_layout(VkDevice device) {
{
.binding = 0U,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
- .descriptorCount = 1,
+ .descriptorCount = 1U,
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = nullptr,
},
@@ -236,17 +282,50 @@ void bindless_model::create_layout(VkDevice device) {
VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::DRAWS_UNIFORMS]));
}
- VkPipelineLayoutCreateInfo create_info{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .setLayoutCount = sizeof(sets_layout) / sizeof(VkDescriptorSetLayout),
- .pSetLayouts = sets_layout,
- .pushConstantRangeCount = 0U,
- .pPushConstantRanges = nullptr,
- };
+ {
+ VkPushConstantRange push_constants[] {
+ {
+ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
+ .offset = 0U,
+ .size = max_push_constants_slots_size * (max_push_constants_slots),
+ },
+ };
+
+ VkPipelineLayoutCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .setLayoutCount = sizeof(sets_layout) / sizeof(VkDescriptorSetLayout),
+ .pSetLayouts = sets_layout,
+ .pushConstantRangeCount = sizeof(push_constants) / sizeof(push_constants[0]),
+ .pPushConstantRanges = push_constants,
+ };
- VKCHECK(vkCreatePipelineLayout(device, &create_info, nullptr, &layout));
+ VKCHECK(vkCreatePipelineLayout(device, &create_info, nullptr, &graphics_layout));
+ }
+
+ {
+ VkPushConstantRange push_constants[] {
+ {
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
+ .offset = 0U,
+ .size = max_push_constants_slots_size * max_push_constants_slots,
+ },
+ };
+
+
+ VkPipelineLayoutCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .setLayoutCount = sizeof(sets_layout) / sizeof(VkDescriptorSetLayout),
+ .pSetLayouts = sets_layout,
+ .pushConstantRangeCount = sizeof(push_constants) / sizeof(push_constants[0]),
+ .pPushConstantRanges = push_constants,
+ };
+
+ VKCHECK(vkCreatePipelineLayout(device, &create_info, nullptr, &compute_layout));
+ }
}
#ifndef USE_VK_DESCRIPTOR_BUFFER
@@ -266,7 +345,7 @@ void bindless_model::create_descriptor_pool(VkDevice device) {
},
{
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
- .descriptorCount = set_descriptors_count,
+ .descriptorCount = 8U,
},
};
@@ -307,7 +386,7 @@ void bindless_model::create_immutable_samplers(VkDevice device) {
.mipLodBias = 0.f,
.anisotropyEnable = VK_FALSE,
.compareEnable = VK_FALSE,
- .compareOp = VK_COMPARE_OP_ALWAYS,
+ .compareOp = VK_COMPARE_OP_NEVER,
.minLod = 0.f,
.maxLod = 0.f,
.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp
index 2b9f7eb..e1d671f 100644
--- a/api-test/vk-device.cpp
+++ b/api-test/vk-device.cpp
@@ -37,6 +37,11 @@ void vkdevice::init() {
create_memory_allocator();
bindless = bindless_model::create_bindless_model();
+
+ auto semaphore = create_semaphore({
+ .type = VK_SEMAPHORE_TYPE_TIMELINE,
+ });
+ timeline_semaphore = get_semaphore(semaphore);
}
vkdevice::~vkdevice() {
@@ -50,6 +55,8 @@ vkdevice::~vkdevice() {
vkDestroyCommandPool(device, queue.command_pool, nullptr);
}
+ vkDestroySemaphore(device, timeline_semaphore.vk_semaphore, nullptr);
+
vkDestroyDevice(device, nullptr);
#ifdef _DEBUG
@@ -59,6 +66,8 @@ vkdevice::~vkdevice() {
vkDestroyInstance(instance, nullptr);
}
+void vkdevice::wait() { vkDeviceWaitIdle(device); };
+
handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
device_texture device_texture;
device_texture.init(desc);
@@ -66,6 +75,13 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
return textures.add(device_texture);
}
+handle<device_sampler> vkdevice::create_sampler(const sampler_desc& desc) {
+ device_sampler device_sampler;
+ device_sampler.init(desc);
+
+ return samplers.add(device_sampler);
+}
+
handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
device_buffer device_buffer{
.size = desc.size,
@@ -113,172 +129,177 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
return buffers.add(device_buffer);
}
-handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
+handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeline_desc& desc) {
device_pipeline device_pipeline{
};
- if (!desc.cs_code.empty()) {
- VkPipelineShaderStageCreateInfo stage_create_info{
+
+ VkPipelineShaderStageCreateInfo shader_stages_create_info[2U]{ {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
.flags = 0U,
- .stage = VK_SHADER_STAGE_COMPUTE_BIT,
- .module = create_shader_module(desc.cs_code),
+ .stage = VK_SHADER_STAGE_VERTEX_BIT,
+ .module = create_shader_module(desc.vs_code),
.pName = "main",
.pSpecializationInfo = nullptr,
- };
+ },
+ {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+ .module = create_shader_module(desc.fs_code),
+ .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,
- .basePipelineHandle = nullptr,
- .basePipelineIndex = 0,
- };
+ VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+ };
- device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
- VKCHECK(vkCreateComputePipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
+ 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,
+ };
- vkDestroyShaderModule(device, stage_create_info.module, nullptr);
- } else {
- 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,
- .module = create_shader_module(desc.vs_code),
- .pName = "main",
- .pSpecializationInfo = nullptr,
- },
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
- .module = create_shader_module(desc.fs_code),
- .pName = "main",
- .pSpecializationInfo = nullptr,
- },
- };
+ 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,
+ };
- VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- };
+ 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,
+ };
- 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,
- };
+ 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,
+ };
- 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,
- };
+ 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,
+ .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,
+ };
- 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,
- };
+ 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,
+ };
- 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,
- };
+ VkDynamicState dynamic_states[]{
+ VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_SCISSOR,
+ };
- 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,
- .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,
- };
+ 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,
+ };
- 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,
- };
+ 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,
+ .stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
+ };
- VkDynamicState dynamic_states[]{
- VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- };
+ 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,
+ .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.graphics_layout,
+ .renderPass = nullptr,
+ .subpass = 0U,
+ .basePipelineHandle = nullptr,
+ .basePipelineIndex = 0,
+ };
- 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,
- };
+ device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ VKCHECK(vkCreateGraphicsPipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
- 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,
- .stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
- };
+ for(auto& stage_create_info : shader_stages_create_info) {
+ vkDestroyShaderModule(device, stage_create_info.module, nullptr);
+ }
- 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,
- .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,
- };
+ return pipelines.add(device_pipeline);
+}
- device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
- VKCHECK(vkCreateGraphicsPipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
+handle<device_pipeline> vkdevice::create_compute_pipeline(const compute_pipeline_desc& desc) {
+ device_pipeline device_pipeline{
+ };
- for(auto& stage_create_info : shader_stages_create_info) {
- vkDestroyShaderModule(device, stage_create_info.module, nullptr);
- }
- }
+ VkPipelineShaderStageCreateInfo stage_create_info{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_COMPUTE_BIT,
+ .module = create_shader_module(desc.cs_code),
+ .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.compute_layout,
+ .basePipelineHandle = nullptr,
+ .basePipelineIndex = 0,
+ };
+
+ device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
+ VKCHECK(vkCreateComputePipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
+
+ vkDestroyShaderModule(device, stage_create_info.module, nullptr);
return pipelines.add(device_pipeline);
}
@@ -301,6 +322,17 @@ handle<device_surface> vkdevice::create_surface(const surface_desc& desc) {
create_swapchain(desc, device_surface);
+ assert(surface_desc::max_image_count >= device_surface.image_count);
+
+ for (uint32_t index = 0u; index < device_surface.image_count; index++) {
+ device_surface.acquire_semaphores[index] = create_semaphore({
+ .type = VK_SEMAPHORE_TYPE_BINARY,
+ });
+ device_surface.submit_semaphores[index] = create_semaphore({
+ .type = VK_SEMAPHORE_TYPE_BINARY,
+ });
+ }
+
return surfaces.add(device_surface);
}
@@ -355,39 +387,107 @@ void vkdevice::destroy_semaphore(handle<device_semaphore> handle) {
}
void vkdevice::destroy_surface(handle<device_surface> handle) {
- const auto& surface = vkdevice::get_surface(handle);
+ auto& surface = vkdevice::get_surface(handle);
for (auto texture_index{0U}; texture_index < surface.image_count; texture_index++) {
auto texture_handle = surface.swapchain_images[texture_index];
destroy_texture(texture_handle);
}
+ for (uint32_t index = 0u; index < surface.image_count; index++) {
+ destroy_semaphore(surface.acquire_semaphores[index]);
+ destroy_semaphore(surface.submit_semaphores[index]);
+ }
+
vkDestroySwapchainKHR(device, surface.vk_swapchain, nullptr);
vkDestroySurfaceKHR(instance, surface.vk_surface, nullptr);
}
-void vkdevice::wait(handle<device_semaphore> semaphore_handle) {
- const auto& semaphore = vkdevice::get_render_device().get_semaphore(semaphore_handle);
- 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));
- vkDeviceWaitIdle(device);
-}
+// uint64_t vkdevice::submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle, handle<device_semaphore> fence_handle) {
+// assert((max_submitable_command_buffers - buffers.size()) >= 0);
+// const auto queue_type = buffers[0].queue_type;
+//
+// 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_infos[2U];
+//
+// VkSubmitInfo2 submit_info{
+// .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
+// .pNext = nullptr,
+// .flags = 0U,
+// .waitSemaphoreInfoCount = 0U,
+// .commandBufferInfoCount = static_cast<uint32_t>(buffers.size()),
+// .pCommandBufferInfos = command_buffers_info,
+// .pSignalSemaphoreInfos = signal_semaphore_infos,
+// };
+//
+// if (wait_handle.is_valid()) {
+// const auto& wait = vkdevice::get_render_device().get_semaphore(wait_handle);
+// wait_semaphore_info.semaphore = wait.vk_semaphore;
+// wait_semaphore_info.value = wait.value;
+// submit_info.waitSemaphoreInfoCount++;
+// submit_info.pWaitSemaphoreInfos = &wait_semaphore_info;
+// }
+//
+// if (signal_handle.is_valid()) {
+// auto& signal = vkdevice::get_render_device().get_semaphore(signal_handle);
+// signal_semaphore_infos[0U] = {
+// .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+// .pNext = nullptr,
+// .semaphore = signal.vk_semaphore,
+// .value = signal.value,
+// .stageMask = VK_PIPELINE_STAGE_2_NONE,
+// .deviceIndex = 0U,
+// };
+// submit_info.signalSemaphoreInfoCount++;
+// }
+//
+// uint64_t ret = -1;
+//
+// if (fence_handle.is_valid()) {
+// auto& fence = vkdevice::get_render_device().get_semaphore(fence_handle);
+// auto fence_index = submit_info.signalSemaphoreInfoCount;
+// signal_semaphore_infos[fence_index] = {
+// .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+// .pNext = nullptr,
+// .semaphore = fence.vk_semaphore,
+// .value = ++fence.value,
+// .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+// .deviceIndex = 0U,
+// };
+// ret = fence.value;
+// }
+//
+// VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
+//
+// return ret;
+// }
-void vkdevice::submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle) {
- assert((max_submitable_command_buffers - buffers.size()) >= 0);
+uint32_t vkdevice::submit(command_buffer* buffers, uint32_t count) {
+ assert((max_submitable_command_buffers - count) >= 0);
const auto queue_type = buffers[0].queue_type;
- VkCommandBufferSubmitInfo command_buffers_info[buffers.size()];
+ VkCommandBufferSubmitInfo command_buffers_info[count];
- for (auto index{ 0U }; index < buffers.size(); index++) {
+ for (auto index{ 0U }; index < count; index++) {
assert(queue_type == buffers[index].queue_type);
auto& command_buffer_info = command_buffers_info[index];
@@ -397,50 +497,102 @@ void vkdevice::submit(std::span<command_buffer> buffers, handle<device_semaphore
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,
+ VkSubmitInfo2 submit_info{
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
+ .pNext = nullptr,
+ .flags = 0U,
+ .waitSemaphoreInfoCount = 0U,
+ .pWaitSemaphoreInfos = nullptr,
+ .commandBufferInfoCount = count,
+ .pCommandBufferInfos = command_buffers_info,
+ };
+
+ auto& fence = timeline_semaphore;
+ VkSemaphoreSubmitInfo signal_semaphore_infos[] = {
+ {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .semaphore = fence.vk_semaphore,
+ .value = ++fence.value,
+ .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ .deviceIndex = 0U,
+ },
};
+ submit_info.signalSemaphoreInfoCount = sizeof(signal_semaphore_infos) / sizeof(signal_semaphore_infos[0U]);
+ submit_info.pSignalSemaphoreInfos = signal_semaphore_infos;
+
+ VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
+
+ return fence.value;
+}
+
+uint32_t vkdevice::submit_before_present(handle<device_surface> surface_handle, command_buffer* buffers, uint32_t count) {
+ assert((max_submitable_command_buffers - count) >= 0);
+ const auto queue_type = buffers[0].queue_type;
+
+ VkCommandBufferSubmitInfo command_buffers_info[count];
+
+ for (auto index{ 0U }; index < count; index++) {
+ assert(queue_type == buffers[index].queue_type);
- VkSemaphoreSubmitInfo signal_semaphore_info{
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
- .pNext = nullptr,
- .stageMask = VK_PIPELINE_STAGE_2_NONE,
- .deviceIndex = 0U,
+ 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;
+ }
+
+ const auto& surface = get_surface(surface_handle);
+ auto& wait = get_semaphore(surface.acquire_semaphores[surface.frame_index]);
+ VkSemaphoreSubmitInfo wait_semaphore_info = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .semaphore = wait.vk_semaphore,
+ .value = wait.value,
+ .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ .deviceIndex = 0U,
};
VkSubmitInfo2 submit_info{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
.pNext = nullptr,
.flags = 0U,
- .commandBufferInfoCount = static_cast<uint32_t>(buffers.size()),
+ .waitSemaphoreInfoCount = 1U,
+ .pWaitSemaphoreInfos = &wait_semaphore_info,
+ .commandBufferInfoCount = count,
.pCommandBufferInfos = command_buffers_info,
};
- if (wait_handle.is_valid()) {
- const auto& wait = vkdevice::get_render_device().get_semaphore(wait_handle);
- 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_handle.is_valid()) {
- auto& signal = vkdevice::get_render_device().get_semaphore(signal_handle);
- signal_semaphore_info.semaphore = signal.vk_semaphore;
- signal_semaphore_info.value = ++signal.value;
-
- submit_info.signalSemaphoreInfoCount = 1U;
- submit_info.pSignalSemaphoreInfos = &signal_semaphore_info;
- }
+ auto& fence = timeline_semaphore;
+ auto& signal = get_semaphore(surface.submit_semaphores[surface.frame_index]);
+ VkSemaphoreSubmitInfo signal_semaphore_infos[] = {
+ {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .semaphore = fence.vk_semaphore,
+ .value = ++fence.value,
+ .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ .deviceIndex = 0U,
+ },
+ {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .semaphore = signal.vk_semaphore,
+ .value = signal.value,
+ .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ .deviceIndex = 0U,
+ },
+ };
+ submit_info.signalSemaphoreInfoCount = sizeof(signal_semaphore_infos) / sizeof(signal_semaphore_infos[0U]);
+ submit_info.pSignalSemaphoreInfos = signal_semaphore_infos;
VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
+
+ return fence.value;
}
-void vkdevice::present(handle<device_surface> surface_handle, handle<device_semaphore> semaphore_handle) {
- const auto& surface = vkdevice::get_render_device().get_surface(surface_handle);
+void vkdevice::present(handle<device_surface> surface_handle) {
+ auto& surface = vkdevice::get_render_device().get_surface(surface_handle);
VkResult result;
VkPresentInfoKHR present_info{
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
@@ -451,15 +603,14 @@ void vkdevice::present(handle<device_surface> surface_handle, handle<device_sema
.pResults = &result,
};
- if (semaphore_handle.is_valid()) {
- const auto& semaphore = vkdevice::get_render_device().get_semaphore(semaphore_handle);
- present_info.waitSemaphoreCount = 1U;
- present_info.pWaitSemaphores = &semaphore.vk_semaphore;
- }
+ const auto& semaphore = get_semaphore(surface.submit_semaphores[surface.frame_index]);
+ present_info.waitSemaphoreCount = 1U;
+ present_info.pWaitSemaphores = &semaphore.vk_semaphore;
VKCHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info));
VKCHECK(result);
+ surface.frame_index = (surface.frame_index + 1) % surface.image_count;
}
// private
@@ -847,6 +998,7 @@ void vkdevice::create_debug_layer_callback() {
idlist<> device_texture::sampled_indices = {};
idlist<> device_texture::storage_indices = {};
+idlist<> device_sampler::sampler_indices = {};
void device_texture::init(const texture_desc& desc) {
auto& render_device = vkdevice::get_render_device();
@@ -1009,14 +1161,67 @@ void device_texture::create_views() {
}
-void device_surface::acquire_image_index(handle<device_semaphore> signal_handle) {
+void device_sampler::init(const sampler_desc& desc) {
auto& render_device = vkdevice::get_render_device();
+ // const auto& bindless = render_device.get_bindingmodel();
auto* device = render_device.get_device();
- const auto& signal = render_device.get_semaphore(signal_handle);
- vkAcquireNextImageKHR(device, vk_swapchain, -1, signal.vk_semaphore, nullptr, &image_index);
+ VkSamplerCreateInfo sampler_create_info{
+ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .magFilter = desc.mag_filter,
+ .minFilter = desc.min_filter,
+ .mipmapMode = desc.mipmap_mode,
+ .addressModeU = desc.address_mode_u,
+ .addressModeV = desc.address_mode_v,
+ .addressModeW = desc.address_mode_w,
+ .mipLodBias = desc.mip_lod_bias,
+ .anisotropyEnable = desc.anisotropy,
+ .maxAnisotropy = desc.max_anisotropy,
+ .compareEnable = desc.compare_enabled,
+ .compareOp = desc.compare_op,
+ .minLod = desc.min_lod,
+ .maxLod = desc.max_lod,
+ .borderColor = desc.border_color,
+ .unnormalizedCoordinates = desc.unnomalized_coords,
+ };
+
+ VKCHECK(vkCreateSampler(device, &sampler_create_info, nullptr, &vk_sampler));
+
+ sampler_index = sampler_indices.add();
+
+ // VkWriteDescriptorSet write_descriptor_set{
+ // .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ // .pNext = nullptr,
+ // .dstSet = bindless.sets[BindlessSetType::GLOBAL],
+ // .dstBinding = 1U,
+ // .dstArrayElement = sampler_index.id,
+ // .descriptorCount = 1U,
+ // .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+ // .pImageInfo = images_info,
+ // .pBufferInfo = nullptr,
+ // .pTexelBufferView = nullptr,
+ // });
}
-handle<device_texture> device_surface::get_backbuffer_image() const {
- return swapchain_images[image_index];
+
+uint32_t vkdevice::acquire_image_index(handle<device_surface> surface_handle) {
+ auto& render_device = vkdevice::get_render_device();
+ auto* device = render_device.get_device();
+ auto& surface = get_surface(surface_handle);
+ const auto& signal = get_semaphore(surface.acquire_semaphores[surface.frame_index]);
+
+ VkSemaphoreWaitInfo wait_info {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .semaphoreCount = 1U,
+ .pSemaphores = &timeline_semaphore.vk_semaphore,
+ .pValues = &timeline_semaphore.value,
+ };
+ vkWaitSemaphores(device, &wait_info, -1);
+ VKCHECK(vkAcquireNextImageKHR(device, surface.vk_swapchain, -1, signal.vk_semaphore, nullptr, &surface.image_index));
+
+ return surface.image_index;
}