aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api-test/command-buffer.cpp41
-rw-r--r--api-test/main.cpp62
-rw-r--r--api-test/vk-bindless.cpp20
-rw-r--r--api-test/vk-device.cpp381
-rw-r--r--include/api-test/command-buffer.hpp2
-rw-r--r--include/api-test/freelist.hpp12
-rw-r--r--include/api-test/handle.hpp6
-rw-r--r--include/api-test/vk-device-types.hpp85
-rw-r--r--include/api-test/vk-device.hpp123
9 files changed, 385 insertions, 347 deletions
diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp
index 78b1505..79b8aef 100644
--- a/api-test/command-buffer.cpp
+++ b/api-test/command-buffer.cpp
@@ -18,7 +18,7 @@ void command_buffer::start() const {
VKCHECK(vkBeginCommandBuffer(vk_command_buffer, &begin_info));
- const auto& bindless = vkdevice::get_render_device()->get_bindingmodel();
+ const auto& bindless = vkdevice::get_render_device().get_bindingmodel();
const auto* global_set = &bindless.sets[BindlessSetType::GLOBAL];
if (queue_type == QueueType::GRAPHICS) {
vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless.layout, 0, 1U, global_set, 0U, nullptr);
@@ -33,13 +33,10 @@ void command_buffer::stop() const {
}
void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const {
- auto& texture = vkdevice::get_render_device()->get_texture(texture_handle);
- VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U)
- ? VK_IMAGE_ASPECT_DEPTH_BIT
- : VK_IMAGE_ASPECT_COLOR_BIT;
+ auto& texture = vkdevice::get_render_device().get_texture(texture_handle);
VkImageSubresourceRange subresource_range{
- .aspectMask = aspect_mask,
+ .aspectMask = texture.aspects,
.baseMipLevel = 0U,
.levelCount = 1U,
.baseArrayLayer = 0U,
@@ -80,14 +77,12 @@ void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineSt
}
void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle, VkDeviceSize offset) const {
- auto* device = vkdevice::get_render_device();
- const auto& buffer = device->get_buffer(buffer_handle);
- const auto& texture = device->get_texture(texture_handle);
- VkImageAspectFlags aspect_mask = ((texture.desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U)
- ? VK_IMAGE_ASPECT_DEPTH_BIT
- : VK_IMAGE_ASPECT_COLOR_BIT;
+ auto& device = vkdevice::get_render_device();
+ const auto& buffer = device.get_buffer(buffer_handle);
+ const auto& texture = device.get_texture(texture_handle);
+
VkImageSubresourceLayers image_subresource_layers{
- .aspectMask = aspect_mask,
+ .aspectMask = texture.aspects,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
@@ -100,9 +95,9 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t
.imageSubresource = image_subresource_layers,
.imageOffset = { .x = 0, .y = 0, .z = 0 },
.imageExtent = {
- .width = texture.desc.width,
- .height = texture.desc.height,
- .depth = texture.desc.depth,
+ .width = texture.width,
+ .height = texture.height,
+ .depth = texture.depth,
},
};
@@ -110,8 +105,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();
+ 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);
@@ -125,7 +120,7 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params)
for (auto index{ 0U }; index < params.color_attachments.size(); index++) {
auto& attachment_info = attachments_info[index];
- auto& attachment = vkdevice::get_render_device()->get_texture(params.color_attachments[index]);
+ auto& attachment = vkdevice::get_render_device().get_texture(params.color_attachments[index]);
attachment_info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
attachment_info.pNext = nullptr;
@@ -180,16 +175,16 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params)
}
void graphics_command_buffer::render(const draw_params& params) const {
- auto* device = vkdevice::get_render_device();
- const auto& pipeline = 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();
+ 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);
if (params.index_buffer.is_valid()) {
- const auto& index_buffer = device->get_buffer(params.index_buffer);
+ 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 {
diff --git a/api-test/main.cpp b/api-test/main.cpp
index 7f30fda..807883d 100644
--- a/api-test/main.cpp
+++ b/api-test/main.cpp
@@ -9,6 +9,7 @@
#include "imgui.h"
+#include "handle.hpp"
#include "window.hpp"
#include "vk-device.hpp"
#include "utils.hpp"
@@ -85,17 +86,28 @@ int main() {
io.DisplaySize.x = 1024.f;
io.DisplaySize.y = 1024.f;
- auto* device = vkdevice::init_device(wnd);
+ auto& device = vkdevice::get_render_device();
+ device.init();
+
+ device.create_surface({
+ .window_handle = wnd.handle,
+ .surface_format = {
+ .format = VK_FORMAT_B8G8R8A8_UNORM,
+ .colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ },
+ .present_mode = VK_PRESENT_MODE_FIFO_KHR,
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ });
constexpr size_t image_size = 1024U;
constexpr size_t image_count = 4U;
- auto staging_buffer_handle = device->create_buffer({
+ auto staging_buffer_handle = device.create_buffer({
.size = image_size * image_size * sizeof(uint32_t) * image_count,
.usages = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
});
- const auto& staging_buffer = device->get_buffer(staging_buffer_handle);
+ const auto& staging_buffer = device.get_buffer(staging_buffer_handle);
int width;
int height;
@@ -104,7 +116,7 @@ int main() {
size_t size = static_cast<size_t>(width) * height * 4U;
memcpy(staging_buffer.mapped_ptr, data, size);
- auto gpu_texture_handle = device->create_texture({
+ auto gpu_texture_handle = device.create_texture({
.width = static_cast<uint32_t>(width),
.height = static_cast<uint32_t>(height),
.usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
@@ -118,7 +130,7 @@ int main() {
auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + offset);
memcpy(addr, data, size);
- auto second_texture = device->create_texture({
+ auto second_texture = device.create_texture({
.width = static_cast<uint32_t>(width),
.height = static_cast<uint32_t>(height),
.usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
@@ -126,7 +138,7 @@ int main() {
.type = VK_IMAGE_TYPE_2D,
});
- auto output_texture_handle = device->create_texture({
+ auto output_texture_handle = device.create_texture({
.width = static_cast<uint32_t>(width),
.height = static_cast<uint32_t>(height),
.usages = VK_IMAGE_USAGE_STORAGE_BIT,
@@ -138,14 +150,14 @@ int main() {
int atlas_width;
int atlas_height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
- const auto ui_texture_handle = device->create_texture({
+ 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);
+ const auto& ui_texture = device.get_texture(ui_texture_handle);
io.Fonts->SetTexID(*(void **)&ui_texture_handle.id);
off_t ui_offset = 2L * offset;
@@ -153,38 +165,40 @@ int main() {
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({
+ 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({
+ 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 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_pipeline({
.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({
+ auto graphics = device.create_pipeline({
.vs_code = vertex_code,
.fs_code = fragment_code,
.color_attachments_format = formats
});
- auto semaphore = device->create_semaphore();
+ auto semaphore = device.create_semaphore({
+ .type = VK_SEMAPHORE_TYPE_TIMELINE,
+ });
std::array<graphics_command_buffer, 2U> command_buffers;
- device->allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS);
+ device.allocate_command_buffers(command_buffers.data(), 2, QueueType::GRAPHICS);
RD_START_CAPTURE;
@@ -205,11 +219,11 @@ int main() {
uint32_t input2;
uint32_t output;
};
- const auto& uniform_buffer = device->get_bindingmodel().get_uniform_buffer();
+ const auto& uniform_buffer = device.get_bindingmodel().get_uniform_buffer();
compute_params params {
- device->get_texture(second_texture).storage_index,
- device->get_texture(gpu_texture_handle).storage_index,
- device->get_texture(output_texture_handle).storage_index,
+ device.get_texture(second_texture).storage_index,
+ device.get_texture(gpu_texture_handle).storage_index,
+ device.get_texture(output_texture_handle).storage_index,
};
memcpy(uniform_buffer.mapped_ptr, &params, sizeof(params));
@@ -225,7 +239,7 @@ int main() {
command_buffers[0].stop();
std::array<struct command_buffer, 1U> compute_command_buffers = {command_buffers[0]};
- device->submit(compute_command_buffers, nullptr, &semaphore);
+ device.submit(compute_command_buffers, {}, semaphore);
RD_END_CAPTURE;
@@ -239,7 +253,7 @@ int main() {
auto* draw_data = ImGui::GetDrawData();
update_buffers(draw_data, vertex_buffer, index_buffer);
- device->wait(semaphore);
+ device.wait(semaphore);
RD_START_CAPTURE;
command_buffers[1].start(),
@@ -261,8 +275,6 @@ int main() {
uint32_t texture_index;
};
- printf("%llu\n", sizeof(ImDrawVert));
-
uint32_t draw_index = 0U;
std::array<draw_params, 100U> draws;
for (auto index {0U} ; index < draw_data->CmdListsCount; index++) {
@@ -302,10 +314,8 @@ int main() {
command_buffers[1].stop();
- device->submit(ui_command_buffers, nullptr, &semaphore);
+ device.submit(ui_command_buffers, {}, semaphore);
RD_END_CAPTURE;
-
- break;
}
return 0;
diff --git a/api-test/vk-bindless.cpp b/api-test/vk-bindless.cpp
index 654ce0c..c48aea1 100644
--- a/api-test/vk-bindless.cpp
+++ b/api-test/vk-bindless.cpp
@@ -1,20 +1,20 @@
#include "vk-bindless.hpp"
-#include <vma/vk_mem_alloc.h>
+#include <vk_mem_alloc.h>
#include "vk-device.hpp"
#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
const device_buffer& bindless_model::get_uniform_buffer() const {
- auto* render_device = vkdevice::get_render_device();
- return render_device->get_buffer(draws_uniform_buffer_handle);
+ auto& render_device = vkdevice::get_render_device();
+ return render_device.get_buffer(draws_uniform_buffer_handle);
}
bindless_model bindless_model::create_bindless_model() {
bindless_model bindless;
- auto* render_device = vkdevice::get_render_device();
- auto* device = render_device->get_device();
+ auto& render_device = vkdevice::get_render_device();
+ auto* device = render_device.get_device();
#ifndef USE_VK_DESCRIPTOR_BUFFER
bindless.create_immutable_samplers(device);
bindless.create_layout(device);
@@ -24,14 +24,14 @@ bindless_model bindless_model::create_bindless_model() {
VkWriteDescriptorSet writes_descriptor_set[2U];
{
- bindless.instances_uniform_buffer_handle = render_device->create_buffer({
+ 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);
+ const auto& buffer = render_device.get_buffer(bindless.instances_uniform_buffer_handle);
VkDescriptorBufferInfo buffer_info {
.buffer = buffer.vk_buffer,
.offset = 0U,
@@ -53,14 +53,14 @@ bindless_model bindless_model::create_bindless_model() {
}
{
- bindless.draws_uniform_buffer_handle = render_device->create_buffer({
+ 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,
});
- const auto& buffer = render_device->get_buffer(bindless.draws_uniform_buffer_handle);
+ const auto& buffer = render_device.get_buffer(bindless.draws_uniform_buffer_handle);
VkDescriptorBufferInfo buffer_info {
.buffer = buffer.vk_buffer,
.offset = 0U,
@@ -118,7 +118,7 @@ bindless_model bindless_model::create_bindless_model() {
}
void bindless_model::destroy_bindless_model(bindless_model& bindless) {
- auto* device = vkdevice::get_render_device()->get_device();
+ auto* device = vkdevice::get_render_device().get_device();
vkDestroyDescriptorPool(device, bindless.descriptor_pool, nullptr);
for (auto index{ 0U }; index < BindlessSetType::MAX; index++) {
diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp
index 502143a..2258bdb 100644
--- a/api-test/vk-device.cpp
+++ b/api-test/vk-device.cpp
@@ -8,30 +8,26 @@
#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
-#include "window.hpp"
-vkdevice* vkdevice::render_device = nullptr;
+vkdevice vkdevice::render_device = vkdevice();
+
+void vkdevice::init() {
+ queues[0U] = {
+ .usages = VK_QUEUE_GRAPHICS_BIT |
+ VK_QUEUE_COMPUTE_BIT |
+ VK_QUEUE_TRANSFER_BIT,
+ };
+ queues[1U] = {
+ .usages = VK_QUEUE_COMPUTE_BIT,
+ };
+ queues[2U] = {
+ .usages = VK_QUEUE_TRANSFER_BIT,
+ };
-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,
- },
- } {
load_vulkan();
create_instance();
- create_surface(window);
-
#ifdef _DEBUG
create_debug_layer_callback();
#endif // _DEBUG
@@ -40,41 +36,32 @@ vkdevice::vkdevice(const window& window)
create_memory_allocator();
- create_swapchain();
-
bindless = bindless_model::create_bindless_model();
}
-vkdevice* vkdevice::init_device(const window& window) {
- vkdevice::render_device = static_cast<vkdevice*>(malloc(sizeof(vkdevice)));
- vkdevice::render_device = new (vkdevice::render_device) vkdevice(window);
- return render_device;
-}
-
-void vkdevice::free_device() {
- delete render_device;
- render_device = nullptr;
-}
-
vkdevice::~vkdevice() {
vkDeviceWaitIdle(device);
bindless_model::destroy_bindless_model(bindless);
- for (auto& texture : textures) {
+ for (const auto& texture : textures) {
destroy_texture(texture);
}
- for (auto& buffer : buffers) {
+ for (const auto& buffer : buffers) {
destroy_buffer(buffer);
}
- for (auto& pipeline : pipelines) {
+ for (const auto& pipeline : pipelines) {
destroy_pipeline(pipeline);
}
- if (swapchain != nullptr) {
- vkDestroySwapchainKHR(device, swapchain, nullptr);
+ for (const auto& semaphore : semaphores) {
+ destroy_semaphore(semaphore);
+ }
+
+ for (const auto& surface : surfaces) {
+ destroy_surface(surface);
}
vmaDestroyAllocator(gpu_allocator);
@@ -89,15 +76,15 @@ vkdevice::~vkdevice() {
vkDestroyDebugUtilsMessengerEXT(instance, debug_messenger, nullptr);
#endif // _DEBUG
- if (surface != nullptr) {
- vkDestroySurfaceKHR(instance, surface, nullptr);
- }
vkDestroyInstance(instance, nullptr);
}
handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
device_texture device_texture{
- .desc = desc,
+ .format = desc.format,
+ .width = desc.width,
+ .height = desc.height,
+ .mips = desc.mips,
};
assert(desc.mips <= texture_desc::max_mips);
@@ -135,7 +122,11 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
VKCHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &device_texture.vk_image, &device_texture.alloc, nullptr));
- create_views(device_texture);
+ device_texture.aspects = ((desc.usages & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0U)
+ ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
+ : VK_IMAGE_ASPECT_COLOR_BIT;
+
+ create_views(desc, device_texture);
// TODO: Handle mips views
VkDescriptorImageInfo images_info[]{
@@ -187,7 +178,6 @@ handle<device_texture> vkdevice::create_texture(const texture_desc& desc) {
handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
device_buffer device_buffer{
- .desc = desc,
};
VkBufferCreateInfo create_info{
@@ -234,29 +224,14 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
device_pipeline device_pipeline{
- .desc = desc,
};
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,
- .codeSize = code.size(),
- .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,
+ .module = create_shader_module(desc.cs_code),
.pName = "main",
.pSpecializationInfo = nullptr,
};
@@ -274,7 +249,7 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
VKCHECK(vkCreateComputePipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
- vkDestroyShaderModule(device, shader_module, nullptr);
+ vkDestroyShaderModule(device, stage_create_info.module, nullptr);
} else {
VkPipelineShaderStageCreateInfo shader_stages_create_info[2U]{
{
@@ -282,6 +257,7 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
.pNext = nullptr,
.flags = 0U,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
+ .module = create_shader_module(desc.vs_code),
.pName = "main",
.pSpecializationInfo = nullptr,
},
@@ -290,36 +266,12 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
.pNext = nullptr,
.flags = 0U,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+ .module = create_shader_module(desc.fs_code),
.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,
- .codeSize = code.size(),
- .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,
- .codeSize = code.size(),
- .pCode = (uint32_t*)code.data(),
- };
-
- VKCHECK(vkCreateShaderModule(device, &module_create_info, nullptr, &shader_stages_create_info[1U].module));
- }
-
VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
};
@@ -431,20 +383,49 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
device_pipeline.bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
VKCHECK(vkCreateGraphicsPipelines(device, nullptr, 1U, &create_info, nullptr, &device_pipeline.vk_pipeline));
+
+ for(auto& stage_create_info : shader_stages_create_info) {
+ vkDestroyShaderModule(device, stage_create_info.module, nullptr);
+ }
}
return { pipelines.add(device_pipeline) };
}
-vksemaphore vkdevice::create_semaphore() {
- vksemaphore semaphore{
- .value = 0,
+handle<device_surface> vkdevice::create_surface(const surface_desc& desc) {
+ device_surface device_surface {
+ };
+
+ {
+ VkWin32SurfaceCreateInfoKHR create_info{
+ .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0U,
+ .hinstance = GetModuleHandle(nullptr),
+ .hwnd = desc.window_handle,
+ };
+
+ VKCHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &device_surface.vk_surface));
+ }
+
+ create_swapchain(desc, device_surface);
+
+ vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, nullptr);
+ std::vector<VkImage> images {device_surface.image_count};
+ vkGetSwapchainImagesKHR(device, device_surface.vk_swapchain, &device_surface.image_count, images.data());
+
+ return { surfaces.add(device_surface) };
+}
+
+handle<device_semaphore> vkdevice::create_semaphore(const semaphore_desc& desc) {
+ device_semaphore semaphore {
+ .value = desc.initial_value,
};
VkSemaphoreTypeCreateInfo semaphore_type_create_info{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
.pNext = nullptr,
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
- .initialValue = 0U,
+ .initialValue = desc.initial_value,
};
VkSemaphoreCreateInfo create_info{
@@ -455,7 +436,7 @@ vksemaphore vkdevice::create_semaphore() {
VKCHECK(vkCreateSemaphore(device, &create_info, nullptr, &semaphore.vk_semaphore));
- return semaphore;
+ return { semaphores.add(semaphore) };
}
void vkdevice::destroy_texture(const device_texture& texture) {
@@ -495,7 +476,30 @@ void vkdevice::destroy_pipeline(handle<device_pipeline> handle) {
vkDestroyPipeline(device, pipeline.vk_pipeline, nullptr);
}
-void vkdevice::wait(vksemaphore& semaphore) {
+void vkdevice::destroy_semaphore(const device_semaphore& semaphore) {
+ destroy_semaphore({ .id = semaphores.find(semaphore)});
+}
+
+void vkdevice::destroy_semaphore(handle<device_semaphore> handle) {
+ auto& semaphore = vkdevice::get_semaphore(handle);
+
+ vkDestroySemaphore(device, semaphore.vk_semaphore, nullptr);
+}
+
+void vkdevice::destroy_surface(const device_surface& surface) {
+ destroy_surface({ .id = surfaces.find(surface)});
+}
+
+void vkdevice::destroy_surface(handle<device_surface> handle) {
+ const auto& surface = vkdevice::get_surface(handle);
+
+ 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,
@@ -507,32 +511,10 @@ void vkdevice::wait(vksemaphore& semaphore) {
VKCHECK(vkWaitSemaphores(device, &wait_info, -1));
}
-void vkdevice::submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal) {
-#define USE_SUBMIT2
+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);
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++) {
- assert(queue_type == buffers[index].queue_type);
- to_submit[index] = buffers[index].vk_command_buffer;
- }
- VkSubmitInfo submit_info{
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .pNext = nullptr,
- .waitSemaphoreCount = 0U,
- .pWaitSemaphores = nullptr,
- .pWaitDstStageMask = nullptr,
- .commandBufferCount = static_cast<uint32_t>(count),
- .pCommandBuffers = to_submit,
- .signalSemaphoreCount = 0U,
- .pSignalSemaphores = nullptr,
- };
-
- 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++) {
@@ -567,38 +549,44 @@ void vkdevice::submit(std::span<command_buffer> buffers, vksemaphore* wait, vkse
.pCommandBufferInfos = command_buffers_info,
};
- if (wait != nullptr) {
- wait_semaphore_info.semaphore = wait->vk_semaphore;
- wait_semaphore_info.value = wait->value;
+ 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 != nullptr) {
- signal_semaphore_info.semaphore = signal->vk_semaphore;
- signal_semaphore_info.value = ++signal->value;
+ 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;
}
VKCHECK(vkQueueSubmit2(queues[static_cast<uint32_t>(queue_type)].vk_queue, 1, &submit_info, nullptr));
-#endif
}
-void vkdevice::present(device_surface& surface, const vksemaphore& semaphore) {
+void vkdevice::present(handle<device_surface> surface_handle, handle<device_semaphore> semaphore_handle) {
+ const auto& surface = vkdevice::get_render_device().get_surface(surface_handle);
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,
};
+ 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;
+ }
+
VKCHECK(vkQueuePresentKHR(queues[static_cast<uint32_t>(QueueType::GRAPHICS)].vk_queue, &present_info));
VKCHECK(result);
@@ -626,17 +614,29 @@ void vkdevice::allocate_command_buffers(command_buffer* buffers, size_t count, Q
}
}
-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;
+VkShaderModule vkdevice::create_shader_module(const std::span<uint8_t>& shader_code) {
+ VkShaderModule shader_module;
+ const auto& code = shader_code;
+ VkShaderModuleCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .codeSize = code.size(),
+ .pCode = reinterpret_cast<uint32_t*>(code.data()),
+ };
+
+ VKCHECK(vkCreateShaderModule(device, &create_info, nullptr, &shader_module));
+ return shader_module;
+}
+
+void vkdevice::create_views(const texture_desc& desc, device_texture& texture) {
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,
+ .format = texture.format,
.components = {
.r = VK_COMPONENT_SWIZZLE_R,
.g = VK_COMPONENT_SWIZZLE_G,
@@ -644,7 +644,7 @@ void vkdevice::create_views(device_texture& texture) {
.a = VK_COMPONENT_SWIZZLE_A,
},
.subresourceRange = {
- .aspectMask = aspect_mask,
+ .aspectMask = texture.aspects,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
@@ -652,41 +652,32 @@ void vkdevice::create_views(device_texture& texture) {
},
};
- for (auto mip_index{ 0 }; mip_index < texture.desc.mips; mip_index++) {
+ for (auto mip_index{ 0 }; mip_index < texture.mips; mip_index++) {
create_info.subresourceRange.baseMipLevel = mip_index;
VKCHECK(vkCreateImageView(device, &create_info, nullptr, &texture.mips_views[mip_index]));
}
create_info.subresourceRange.baseMipLevel = 0;
- create_info.subresourceRange.levelCount = texture.desc.mips;
+ create_info.subresourceRange.levelCount = texture.mips;
VKCHECK(vkCreateImageView(device, &create_info, nullptr, &texture.whole_view));
}
-// 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,
- };
-
- VKCHECK(vkCreateWin32SurfaceKHR(instance, &create_info, nullptr, &surface));
-}
+void vkdevice::create_swapchain(const surface_desc& desc, device_surface& surface) {
+ VkSurfaceKHR vk_surface = surface.vk_surface;
-void vkdevice::create_swapchain() {
- VkBool32 supported = VK_FALSE;
auto& queue = queues[static_cast<uint32_t>(QueueType::GRAPHICS)];
- VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, surface, &supported));
- assert(supported);
+ {
+ VkBool32 supported = VK_FALSE;
+ VKCHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue.index, vk_surface, &supported));
+
+ assert(supported);
+ }
- VkSurfaceCapabilitiesKHR surface_capabilities = {};
- VKCHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_capabilities));
+ VkSurfaceCapabilitiesKHR surface_capabilities;
+ VKCHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, vk_surface, &surface_capabilities));
VkExtent2D extent = surface_capabilities.currentExtent;
-
if (extent.width < surface_capabilities.minImageExtent.width) {
extent.width = surface_capabilities.minImageExtent.width;
} else if (extent.width > surface_capabilities.maxImageExtent.width) {
@@ -699,65 +690,68 @@ void vkdevice::create_swapchain() {
extent.height = surface_capabilities.maxImageExtent.height;
}
- auto supported_formats_count = 0U;
- VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &supported_formats_count, nullptr));
+ {
+ auto supported = false;
+ auto supported_formats_count = 0U;
+ VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, nullptr));
- std::vector<VkSurfaceFormatKHR> supported_formats{ supported_formats_count };
- VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &supported_formats_count, supported_formats.data()));
+ std::vector<VkSurfaceFormatKHR> supported_formats{ supported_formats_count };
+ VKCHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, vk_surface, &supported_formats_count, supported_formats.data()));
+ for (auto& surface_format : supported_formats) {
+ if (surface_format.format == desc.surface_format.format &&
+ surface_format.colorSpace == desc.surface_format.colorSpace) {
+ supported = true;
+ break;
+ }
+ }
+
+ assert(supported);
+ }
+
+ {
+ auto supported = false;
+ auto supported_present_modes_count = 0U;
+ VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, nullptr));
- auto supported_present_modes_count = 0U;
- VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &supported_present_modes_count, nullptr));
+ std::vector<VkPresentModeKHR> supported_present_modes{ supported_present_modes_count };
+ VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, vk_surface, &supported_present_modes_count, supported_present_modes.data()));
- std::vector<VkPresentModeKHR> supported_present_modes{ supported_present_modes_count };
+ for (auto& present_mode : supported_present_modes) {
+ if (present_mode == desc.present_mode) {
+ supported = true;
+ break;
+ }
+ }
- VKCHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &supported_present_modes_count, supported_present_modes.data()));
+ assert(supported);
+ }
- auto min_image_count = (surface_capabilities.minImageCount <= virtual_frames_count) ? virtual_frames_count : surface_capabilities.minImageCount;
+ assert(desc.image_count >= surface_capabilities.minImageCount);
+ assert(desc.image_count <= surface_capabilities.maxImageCount);
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,
+ .surface = vk_surface,
+ .minImageCount = desc.image_count,
+ .imageFormat = desc.surface_format.format,
+ .imageColorSpace = desc.surface_format.colorSpace,
.imageExtent = extent,
.imageArrayLayers = 1U,
- .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ .imageUsage = desc.usages,
.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],
+ .presentMode = desc.present_mode,
.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++) {
- {
- 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, &semaphores[index]));
- }
- }
+ VKCHECK(vkCreateSwapchainKHR(device, &create_info, nullptr, &surface.vk_swapchain));
}
// ----------------- vkadapter -----------------
@@ -989,3 +983,16 @@ void vkdevice::create_debug_layer_callback() {
VKCHECK(vkCreateDebugUtilsMessengerEXT(instance, &create_info, nullptr, &debug_messenger));
}
+
+
+void device_surface::acquire_image_index(handle<device_semaphore> signal_handle) {
+ auto& render_device = vkdevice::get_render_device();
+ 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);
+}
+
+handle<device_texture> device_surface::get_backbuffer_image() {
+
+}
diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp
index 31b1254..f7a18b0 100644
--- a/include/api-test/command-buffer.hpp
+++ b/include/api-test/command-buffer.hpp
@@ -40,8 +40,6 @@ private:
public:
rect render_area;
std::span<handle<device_texture>> color_attachments;
- // rect viewport;
- // rect scissor;
};
struct draw_params {
handle<device_pipeline> pipeline;
diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp
index b231d9a..cfe8903 100644
--- a/include/api-test/freelist.hpp
+++ b/include/api-test/freelist.hpp
@@ -1,6 +1,7 @@
+#pragma once
#include <numeric>
#include <vector>
-
+#include <cassert>
static constexpr uint32_t default_element_count = 1024U;
@@ -27,6 +28,11 @@ class freelist {
}
T& operator[](uint32_t index) {
+ assert(index >= 0);
+ return items[index];
+ }
+
+ const T& operator[](uint32_t index) const {
return items[index];
}
@@ -41,11 +47,11 @@ class freelist {
return invalid_id;
}
- auto begin() {
+ auto begin() const {
return items.begin();
}
- auto end() {
+ auto end() const {
return items.end();
}
diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp
index 956739d..a81480a 100644
--- a/include/api-test/handle.hpp
+++ b/include/api-test/handle.hpp
@@ -4,9 +4,9 @@
template<typename T>
struct handle {
- uint32_t id = handle::invalid_handle;
+ uint32_t id = handle::invalid_id;
- [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_handle; }
+ [[nodiscard]] inline bool is_valid() const { return id != handle::invalid_id; }
- static constexpr uint32_t invalid_handle = -1;
+ static constexpr uint32_t invalid_id = -1U;
};
diff --git a/include/api-test/vk-device-types.hpp b/include/api-test/vk-device-types.hpp
index b069883..bd2274a 100644
--- a/include/api-test/vk-device-types.hpp
+++ b/include/api-test/vk-device-types.hpp
@@ -4,18 +4,16 @@
#include <span>
-#include "vk-bindless.hpp"
-
using VmaAllocation = struct VmaAllocation_T*;
struct texture_desc {
- uint32_t width = 1U;
- uint32_t height = 1U;
- uint32_t depth = 1U;
- uint32_t mips = 1U;
- VkImageUsageFlags usages;
- VkFormat format;
- VkImageType type;
+ uint32_t width = 1U;
+ uint32_t height = 1U;
+ uint32_t depth = 1U;
+ uint32_t mips = 1U;
+ VkImageUsageFlags usages;
+ VkFormat format;
+ VkImageType type;
static constexpr auto max_mips = 16U;
};
@@ -25,24 +23,27 @@ struct device_texture {
VkImageView whole_view;
VkImageView mips_views[texture_desc::max_mips] = { VK_NULL_HANDLE };
VkImageLayout layout;
- VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- VkAccessFlags2 access = VK_ACCESS_2_NONE;
+ VkPipelineStageFlags2 stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ VkAccessFlags2 access = VK_ACCESS_2_NONE;
+ VkFormat format;
+ VkImageAspectFlags aspects;
+
+ uint32_t width = 1U;
+ uint32_t height = 1U;
+ uint32_t depth = 1U;
+ uint32_t mips = 1U;
uint32_t storage_index = -1;
uint32_t sampled_index = -1;
- uint32_t sampler_index = -1;
VmaAllocation alloc;
-
- texture_desc desc;
};
-
struct buffer_desc {
- size_t size;
- VkBufferUsageFlags usages;
- VkMemoryPropertyFlags memory_properties;
- uint32_t memory_usage;
+ size_t size;
+ VkBufferUsageFlags usages;
+ VkMemoryPropertyFlags memory_properties;
+ uint32_t memory_usage;
};
struct device_buffer {
@@ -50,37 +51,57 @@ struct device_buffer {
VmaAllocation alloc;
VkDeviceAddress device_address = 0U;
void* mapped_ptr;
-
- buffer_desc desc;
+ size_t size;
};
struct pipeline_desc {
- std::span<uint8_t> vs_code;
- std::span<uint8_t> fs_code;
- std::span<uint8_t> cs_code;
+ std::span<uint8_t> cs_code;
+ std::span<uint8_t> vs_code;
+ std::span<uint8_t> fs_code;
std::span<VkFormat> color_attachments_format;
- VkFormat depth_attachment_format;
- VkFormat stencil_attachment_format;
+ VkFormat depth_attachment_format;
+ VkFormat stencil_attachment_format;
};
struct device_pipeline {
VkPipeline vk_pipeline;
VkPipelineBindPoint bind_point;
- pipeline_desc desc;
+};
- // bindless_model* bindless = nullptr;
+
+struct semaphore_desc {
+ VkSemaphoreType type;
+ uint64_t initial_value = 0U;
+};
+
+struct device_semaphore {
+ VkSemaphore vk_semaphore = nullptr;
+ uint64_t value;
};
+typedef struct HWND__* HWND;
+
struct surface_desc {
+ HWND window_handle;
+ VkSurfaceFormatKHR surface_format;
+ VkPresentModeKHR present_mode;
+ VkImageUsageFlags usages;
+ uint32_t image_count = surface_desc::default_image_count;
+ static constexpr uint32_t max_image_count = 3U;
+ static constexpr uint32_t default_image_count = 3U;
};
struct device_surface {
- VkSurfaceKHR vk_surface;
- VkSwapchainKHR vk_swapchain;
+ VkSurfaceKHR vk_surface;
+ VkSwapchainKHR vk_swapchain;
+
+ // handle<device_texture> swapchain_images;
+ uint32_t image_index;
+ uint32_t image_count;
- handle<device_texture> swapchain_images;
- uint32_t image_index;
+ void acquire_image_index(handle<device_semaphore> signal_handle);
+ handle<device_texture> get_backbuffer_image();
};
diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp
index 5b71529..fd69d60 100644
--- a/include/api-test/vk-device.hpp
+++ b/include/api-test/vk-device.hpp
@@ -15,11 +15,6 @@ using VmaAllocator = struct VmaAllocator_T*;
class window;
-struct vksemaphore {
- VkSemaphore vk_semaphore = nullptr;
- uint64_t value = 0U;
-};
-
class vkdevice {
struct queue {
VkQueue vk_queue;
@@ -29,49 +24,63 @@ class vkdevice {
};
public:
- static vkdevice* init_device(const window& window);
+ void init();
- static void free_device();
-
- static inline vkdevice* get_render_device() {
+ static inline vkdevice& get_render_device() {
return render_device;
}
- handle<device_texture> create_texture(const texture_desc& desc);
+ handle<device_texture> create_texture(const texture_desc& desc);
+
+ handle<device_buffer> create_buffer(const buffer_desc& desc);
- handle<device_buffer> create_buffer(const buffer_desc& desc);
+ handle<device_pipeline> create_pipeline(const pipeline_desc& desc);
- handle<device_pipeline> create_pipeline(const pipeline_desc& desc);
+ handle<device_surface> create_surface(const surface_desc& desc);
- vksemaphore create_semaphore();
+ handle<device_semaphore> create_semaphore(const semaphore_desc& desc);
- void destroy_texture(const device_texture& texture);
- void destroy_texture(handle<device_texture> handle);
+ void destroy_texture(const device_texture& texture);
+ void destroy_texture(handle<device_texture> handle);
- void destroy_buffer(const device_buffer& buffer);
- void destroy_buffer(handle<device_buffer> handle);
+ void destroy_buffer(const device_buffer& buffer);
+ void destroy_buffer(handle<device_buffer> handle);
- void destroy_pipeline(const device_pipeline& pipeline);
- void destroy_pipeline(handle<device_pipeline> handle);
+ void destroy_pipeline(const device_pipeline& pipeline);
+ void destroy_pipeline(handle<device_pipeline> handle);
+
+ void destroy_semaphore(const device_semaphore& semaphore);
+ void destroy_semaphore(handle<device_semaphore> handle);
+
+ void destroy_surface(const device_surface& surface);
+ void destroy_surface(handle<device_surface> handle);
template<typename cmd_buf_type>
void allocate_command_buffers(cmd_buf_type* buffers, size_t count, QueueType queue_type) {
allocate_command_buffers(static_cast<command_buffer*>(buffers), count, queue_type);
}
- inline device_texture& get_texture(handle<device_texture> handle) {
+ [[nodiscard]] inline device_texture& get_texture(handle<device_texture> handle) {
return textures[handle.id];
}
- inline const device_buffer& get_buffer(handle<device_buffer> handle) {
+ [[nodiscard]] inline const device_buffer& get_buffer(handle<device_buffer> handle) const {
return buffers[handle.id];
}
- inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) {
+ [[nodiscard]] inline const device_pipeline& get_pipeline(handle<device_pipeline> handle) const {
return pipelines[handle.id];
}
- inline const bindless_model& get_bindingmodel() {
+ [[nodiscard]] inline const device_surface& get_surface(handle<device_surface> handle) const {
+ return surfaces[handle.id];
+ }
+
+ [[nodiscard]] inline device_semaphore& get_semaphore(handle<device_semaphore> handle) {
+ return semaphores[handle.id];
+ }
+
+ [[nodiscard]] inline const bindless_model& get_bindingmodel() const {
return bindless;
}
@@ -79,70 +88,62 @@ class vkdevice {
return device;
}
- void wait(vksemaphore& semaphore);
+ void wait(handle<device_semaphore> semaphore_handle);
- void submit(std::span<command_buffer> buffers, vksemaphore* wait, vksemaphore* signal);
+ void submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle);
- void present(device_surface& surface, const vksemaphore& semaphore);
+ void present(handle<device_surface> surface_handle, handle<device_semaphore> semaphore_handle);
private:
- vkdevice(const window& window);
+ vkdevice() = default;
~vkdevice();
void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type);
- void create_views(device_texture& texture);
+ VkShaderModule create_shader_module(const std::span<uint8_t>& shader_code);
- // Presentation stuff
- void create_surface(const window& window);
+ void create_views(const texture_desc& desc, device_texture& texture);
- void create_swapchain();
-
- void create_virtual_frames();
-
- VkSurfaceKHR surface = nullptr;
- VkSwapchainKHR swapchain = nullptr;
+ void create_swapchain(const surface_desc& desc, device_surface& surface);
// TODO: Wrap in a struct called adapter ?
- void create_instance();
-
- void create_device();
+ void create_instance();
- void create_memory_allocator();
+ void create_device();
- void create_command_pools();
+ void create_memory_allocator();
- void pick_physical_device();
+ void create_command_pools();
- static bool device_support_features(VkPhysicalDevice physical_dev);
+ void pick_physical_device();
- void create_debug_layer_callback();
+ static bool device_support_features(VkPhysicalDevice physical_dev);
- // Virtual frames resources
- static constexpr uint32_t virtual_frames_count = 3U;
- VkSemaphore semaphores[virtual_frames_count];
+ void create_debug_layer_callback();
- queue queues[static_cast<uint32_t>(QueueType::MAX)];
+ queue queues[static_cast<uint32_t>(QueueType::MAX)];
- VkInstance instance;
- VkPhysicalDevice physical_device;
- VkDevice device;
+ VkInstance instance;
+ VkPhysicalDevice physical_device;
+ VkDevice device;
- VmaAllocator gpu_allocator;
+ VmaAllocator gpu_allocator;
- bindless_model bindless;
+ bindless_model bindless;
- static constexpr size_t max_allocable_command_buffers = 16;
- static constexpr size_t max_submitable_command_buffers = 16;
+ static constexpr size_t max_allocable_command_buffers = 16;
+ static constexpr size_t max_submitable_command_buffers = 16;
- freelist<device_texture*> storage_indices;
- freelist<device_texture*> sampled_indices;
+ freelist<device_texture*> storage_indices;
+ freelist<device_texture*> sampled_indices;
- freelist<device_texture> textures;
- freelist<device_buffer> buffers;
- freelist<device_pipeline> pipelines;
+ freelist<device_texture> textures;
+ freelist<device_buffer> buffers;
+ freelist<device_pipeline> pipelines;
+ freelist<device_surface> surfaces;
+ freelist<device_semaphore> semaphores;
- static vkdevice* render_device;
+ static vkdevice render_device;
#ifdef _DEBUG
VkDebugUtilsMessengerEXT debug_messenger;