aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2023-01-25 23:06:30 +0100
committerladevieq <ladevie.quentin@gmail.com>2023-01-25 23:06:30 +0100
commit90a0afd18f080088cac068d92810fb630225d6be (patch)
tree341310124fec15c6a02708815377db0cddb6b252
parent0a882c4b85423a170455f05a52d18f7fa7c9220b (diff)
Working compute api with uniforms
-rw-r--r--api-test/CMakeLists.txt1
-rw-r--r--api-test/command-buffer.cpp17
-rw-r--r--api-test/main.cpp24
-rw-r--r--api-test/vk-bindless.cpp75
-rw-r--r--api-test/vk-device.cpp186
-rw-r--r--api-test/vk-utils.cpp44
-rw-r--r--include/api-test/command-buffer.hpp1
-rw-r--r--include/api-test/freelist.hpp4
-rw-r--r--include/api-test/handle.hpp4
-rw-r--r--include/api-test/vk-bindless.hpp21
-rw-r--r--include/api-test/vk-device.hpp6
-rw-r--r--include/api-test/vk-utils.hpp5
-rw-r--r--shaders/api-test-ui.frag20
-rw-r--r--shaders/api-test-ui.vert37
-rw-r--r--shaders/test.comp11
15 files changed, 376 insertions, 80 deletions
diff --git a/api-test/CMakeLists.txt b/api-test/CMakeLists.txt
index 402ae10..93eceee 100644
--- a/api-test/CMakeLists.txt
+++ b/api-test/CMakeLists.txt
@@ -4,6 +4,7 @@ add_executable(
vk-device.cpp
command-buffer.cpp
vk-bindless.cpp
+ vk-utils.cpp
${CMAKE_SOURCE_DIR}/src/window.cpp
${CMAKE_SOURCE_DIR}/src/utils.cpp
${CMAKE_SOURCE_DIR}/src/vulkan-loader.cpp
diff --git a/api-test/command-buffer.cpp b/api-test/command-buffer.cpp
index 8d2d8c7..799968c 100644
--- a/api-test/command-buffer.cpp
+++ b/api-test/command-buffer.cpp
@@ -18,12 +18,13 @@ void command_buffer::start() const {
VKCHECK(vkBeginCommandBuffer(vk_command_buffer, &begin_info));
- const auto& bindless = vkdevice::get_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, BindlessSetType::MAX, bindless.sets, 0, nullptr);
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, 0, BindlessSetType::MAX, bindless.sets, 0, nullptr);
+ 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);
} else if (queue_type == QueueType::ASYNC_COMPUTE) {
- vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, 0, BindlessSetType::MAX, bindless.sets, 0, nullptr);
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, 0, 1U, global_set, 0U, nullptr);
}
}
@@ -32,7 +33,7 @@ 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_device()->get_texture(texture_handle);
+ 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;
@@ -79,7 +80,7 @@ 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_device();
+ 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)
@@ -109,7 +110,9 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t
}
void graphics_command_buffer::dispatch(const dispatch_params& params) {
- const auto& pipeline = vkdevice::get_device()->get_pipeline(params.pipeline);
+ const auto& pipeline = vkdevice::get_render_device()->get_pipeline(params.pipeline);
+ const auto& bindless = vkdevice::get_render_device()->get_bindingmodel();
+ vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, bindless.layout, static_cast<uint32_t>(BindlessSetType::UNIFORMS), 1U, &bindless.sets[BindlessSetType::UNIFORMS], 1U, &params.uniforms_offset);
vkCmdBindPipeline(vk_command_buffer, pipeline.bind_point, pipeline.vk_pipeline);
diff --git a/api-test/main.cpp b/api-test/main.cpp
index 4ac68ad..35b8639 100644
--- a/api-test/main.cpp
+++ b/api-test/main.cpp
@@ -97,6 +97,13 @@ int main() {
.cs_code = std::span(code),
});
+ auto vertex_code = read_file("shaders/api-test-ui.vert.spv");
+ auto fragment_code = read_file("shaders/api-test-ui.frag.spv");
+ auto graphics = device->create_pipeline({
+ .vs_code = std::span(vertex_code),
+ .fs_code = std::span(fragment_code),
+ });
+
graphics_command_buffer command_buffer;
device->allocate_command_buffers(&command_buffer, 1, QueueType::GRAPHICS);
@@ -108,14 +115,27 @@ int main() {
command_buffer.copy(staging_buffer_handle, gpu_texture_handle);
command_buffer.copy(staging_buffer_handle, second_texture, static_cast<VkDeviceSize>(offset));
- command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ command_buffer.barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
command_buffer.barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
- command_buffer.barrier(output_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+ 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).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));
command_buffer.dispatch({
.pipeline = compute,
.group_size = { image_size, image_size, 1U },
.local_group_size = { 8U, 8U, 1U },
+ .uniforms_offset = 0U,
});
command_buffer.stop();
diff --git a/api-test/vk-bindless.cpp b/api-test/vk-bindless.cpp
index d1dbf03..c07db8e 100644
--- a/api-test/vk-bindless.cpp
+++ b/api-test/vk-bindless.cpp
@@ -1,15 +1,53 @@
#include "vk-bindless.hpp"
+#include <vma/vk_mem_alloc.h>
+
+#include "vk-device.hpp"
#include "vk-utils.hpp"
#include "vulkan-loader.hpp"
-bindless_model bindless_model::create_bindless_model(VkDevice device) {
+const device_buffer& bindless_model::get_uniform_buffer() const {
+ auto* render_device = vkdevice::get_render_device();
+ return render_device->get_buffer(uniform_buffer);
+}
+
+bindless_model bindless_model::create_bindless_model() {
bindless_model bindless;
+ 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);
bindless.create_descriptor_pool(device);
bindless.allocate_sets(device);
+ bindless.uniform_buffer = render_device->create_buffer({
+ .size = 64U * 1024U,
+ .usages = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ });
+
+ const auto& buffer = render_device->get_buffer(bindless.uniform_buffer);
+ VkDescriptorBufferInfo buffer_info {
+ .buffer = buffer.vk_buffer,
+ .offset = 0U,
+ .range = VK_WHOLE_SIZE,
+ };
+
+ VkWriteDescriptorSet write_descriptor_set {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .pNext = nullptr,
+ .dstSet = bindless.sets[BindlessSetType::UNIFORMS],
+ .dstBinding = 0U,
+ .dstArrayElement = 0U,
+ .descriptorCount = 1U,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .pImageInfo = nullptr,
+ .pBufferInfo = &buffer_info,
+ .pTexelBufferView = nullptr,
+ };
+
+ vkUpdateDescriptorSets(device, 1U, &write_descriptor_set, 0U, nullptr);
#else
VkBufferCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -23,7 +61,6 @@ bindless_model bindless_model::create_bindless_model(VkDevice device) {
};
VmaAllocatorCreateFlags alloc_create_flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
-
VmaAllocationCreateInfo alloc_create_info{
.flags = alloc_create_flags,
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
@@ -46,7 +83,8 @@ bindless_model bindless_model::create_bindless_model(VkDevice device) {
return bindless;
}
-void bindless_model::destroy_bindless_model(VkDevice device, bindless_model& bindless) {
+void bindless_model::destroy_bindless_model(bindless_model& bindless) {
+ auto* device = vkdevice::get_render_device()->get_device();
vkDestroyDescriptorPool(device, bindless.descriptor_pool, nullptr);
for (auto index{ 0U }; index < BindlessSetType::MAX; index++) {
@@ -112,6 +150,30 @@ void bindless_model::create_layout(VkDevice device) {
VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::GLOBAL]));
}
+ // Set 1 uniforms
+ // Binding 0 Uniforms
+ {
+ VkDescriptorSetLayoutBinding set_layout_bindings[]{
+ {
+ .binding = 0U,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
+ .pImmutableSamplers = nullptr,
+ },
+ };
+
+ VkDescriptorSetLayoutCreateInfo create_info{
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .bindingCount = sizeof(set_layout_bindings) / sizeof(VkDescriptorSetLayoutBinding),
+ .pBindings = set_layout_bindings,
+ };
+
+ VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &sets_layout[BindlessSetType::UNIFORMS]));
+ }
+
VkPipelineLayoutCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
@@ -140,6 +202,10 @@ void bindless_model::create_descriptor_pool(VkDevice device) {
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.descriptorCount = set_descriptors_count[BindlessSetType::MAX],
},
+ {
+ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+ .descriptorCount = set_descriptors_count[BindlessSetType::MAX],
+ },
};
VkDescriptorPoolCreateInfo descriptor_pool_create_info{
@@ -162,6 +228,9 @@ void bindless_model::allocate_sets(VkDevice device) {
.pSetLayouts = &sets_layout[BindlessSetType::GLOBAL],
};
VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::GLOBAL]));
+
+ allocate_info.pSetLayouts = &sets_layout[BindlessSetType::UNIFORMS],
+ VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &sets[BindlessSetType::UNIFORMS]));
}
void bindless_model::create_immutable_samplers(VkDevice device) {
diff --git a/api-test/vk-device.cpp b/api-test/vk-device.cpp
index 404cd43..0815592 100644
--- a/api-test/vk-device.cpp
+++ b/api-test/vk-device.cpp
@@ -1,7 +1,6 @@
#include "vk-device.hpp"
#include <cassert>
-#include <iostream>
#include <vector>
#define VMA_IMPLEMENTATION
@@ -13,47 +12,6 @@
vkdevice* vkdevice::render_device = nullptr;
-VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
- VkDebugUtilsMessageTypeFlagsEXT type,
- const VkDebugUtilsMessengerCallbackDataEXT* data,
- void*) {
- const char* severity_cstr = nullptr;
- switch (severity) {
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
- severity_cstr = "VERBOSE";
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
- severity_cstr = "INFO";
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
- severity_cstr = "WARNING";
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
- severity_cstr = "ERROR";
- break;
- default:
- break;
- }
-
- const char* type_cstr = nullptr;
- switch (type) {
- case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
- type_cstr = "GENERAL";
- break;
- case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
- type_cstr = "VALIDATION";
- break;
- case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
- type_cstr = "PERFORMANCE";
- break;
- default:
- break;
- }
-
- std::cerr << "[" << severity_cstr << "_" << type_cstr << "]: " << data->pMessage << std::endl;
- return VK_FALSE;
-}
-
vkdevice::vkdevice(const window& window)
: queues{
{
@@ -84,11 +42,12 @@ vkdevice::vkdevice(const window& window)
create_swapchain();
- bindless = bindless_model::create_bindless_model(device);
+ bindless = bindless_model::create_bindless_model();
}
vkdevice* vkdevice::init_device(const window& window) {
- vkdevice::render_device = new vkdevice(window);
+ vkdevice::render_device = static_cast<vkdevice*>(malloc(sizeof(vkdevice)));
+ vkdevice::render_device = new (vkdevice::render_device) vkdevice(window);
return render_device;
}
@@ -100,7 +59,7 @@ void vkdevice::free_device() {
vkdevice::~vkdevice() {
vkDeviceWaitIdle(device);
- bindless_model::destroy_bindless_model(device, bindless);
+ bindless_model::destroy_bindless_model(bindless);
for (auto& texture : textures) {
destroy_texture(texture);
@@ -271,17 +230,19 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
.bindless = &bindless,
};
if (!desc.cs_code.empty()) {
- const auto& code = desc.cs_code;
VkShaderModule shader_module;
- VkShaderModuleCreateInfo module_create_info {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .codeSize = code.size(),
- .pCode = (uint32_t*)code.data(),
- };
+ {
+ 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, &module_create_info, nullptr, &shader_module));
+ VKCHECK(vkCreateShaderModule(device, &create_info, nullptr, &shader_module));
+ }
VkPipelineShaderStageCreateInfo stage_create_info {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@@ -308,12 +269,127 @@ handle<device_pipeline> vkdevice::create_pipeline(const pipeline_desc& desc) {
vkDestroyShaderModule(device, shader_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,
+ .pName = "main",
+ .pSpecializationInfo = nullptr,
+ },
+ {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+ .pName = "main",
+ .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,
+ };
+
+ VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ .primitiveRestartEnable = VK_FALSE,
+ };
+
+ VkPipelineViewportStateCreateInfo viewport_state_create_info {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .viewportCount = 0U,
+ .pViewports = nullptr,
+ .scissorCount = 0U,
+ .pScissors = nullptr,
+ };
+
+ 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,
+ };
+
+ VkDynamicState dynamic_states[] {
+ VK_DYNAMIC_STATE_VIEWPORT,
+ VK_DYNAMIC_STATE_SCISSOR,
+ };
+
+ VkPipelineDynamicStateCreateInfo dynamic_state_create_info {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0U,
+ .dynamicStateCount = sizeof(dynamic_states) / sizeof(VkDynamicState),
+ .pDynamicStates = dynamic_states,
+ };
+
+ VkPipelineRenderingCreateInfo pipeline_rendering_create_info {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
+ .pNext = nullptr,
+ .viewMask = 0U,
+ .colorAttachmentCount = 0U,
+ .pColorAttachmentFormats = nullptr,
+ .depthAttachmentFormat = VK_FORMAT_UNDEFINED,
+ .stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
+ };
VkGraphicsPipelineCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
+ .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 = nullptr,
+ .pDepthStencilState = nullptr,
+ .pColorBlendState = nullptr,
+ .pDynamicState = &dynamic_state_create_info,
.layout = bindless.layout,
+ .renderPass = nullptr,
+ .subpass = 0U,
.basePipelineHandle = nullptr,
.basePipelineIndex = 0,
};
diff --git a/api-test/vk-utils.cpp b/api-test/vk-utils.cpp
new file mode 100644
index 0000000..c9ad9c9
--- /dev/null
+++ b/api-test/vk-utils.cpp
@@ -0,0 +1,44 @@
+#include "vk-utils.hpp"
+
+#include <iostream>
+
+VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
+ VkDebugUtilsMessageTypeFlagsEXT type,
+ const VkDebugUtilsMessengerCallbackDataEXT* data,
+ void*) {
+ const char* severity_cstr = nullptr;
+ switch (severity) {
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
+ severity_cstr = "VERBOSE";
+ break;
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
+ severity_cstr = "INFO";
+ break;
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
+ severity_cstr = "WARNING";
+ break;
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
+ severity_cstr = "ERROR";
+ break;
+ default:
+ break;
+ }
+
+ const char* type_cstr = nullptr;
+ switch (type) {
+ case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
+ type_cstr = "GENERAL";
+ break;
+ case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
+ type_cstr = "VALIDATION";
+ break;
+ case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
+ type_cstr = "PERFORMANCE";
+ break;
+ default:
+ break;
+ }
+
+ std::cerr << "[" << severity_cstr << "_" << type_cstr << "]: " << data->pMessage << std::endl;
+ return VK_FALSE;
+}
diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp
index 1a0e553..ffeafc4 100644
--- a/include/api-test/command-buffer.hpp
+++ b/include/api-test/command-buffer.hpp
@@ -24,6 +24,7 @@ struct dispatch_params {
handle<device_pipeline> pipeline;
vec3u group_size;
vec3u local_group_size;
+ uint32_t uniforms_offset;
};
struct command_buffer {
diff --git a/include/api-test/freelist.hpp b/include/api-test/freelist.hpp
index 9553a15..b231d9a 100644
--- a/include/api-test/freelist.hpp
+++ b/include/api-test/freelist.hpp
@@ -38,7 +38,7 @@ class freelist {
}
}
- return invalid_handle;
+ return invalid_id;
}
auto begin() {
@@ -49,7 +49,7 @@ class freelist {
return items.end();
}
- static constexpr uint32_t invalid_handle = -1;
+ static constexpr uint32_t invalid_id = -1;
private:
std::vector<T> items;
diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp
index c14e212..2355191 100644
--- a/include/api-test/handle.hpp
+++ b/include/api-test/handle.hpp
@@ -4,5 +4,7 @@
template<typename T>
struct handle {
- const uint32_t id;
+ uint32_t id = handle::invalid_handle;
+
+ static constexpr uint32_t invalid_handle = -1;
};
diff --git a/include/api-test/vk-bindless.hpp b/include/api-test/vk-bindless.hpp
index d8fac3c..c292878 100644
--- a/include/api-test/vk-bindless.hpp
+++ b/include/api-test/vk-bindless.hpp
@@ -4,8 +4,11 @@
#include <vulkan/vulkan_core.h>
+#include "handle.hpp"
+
enum BindlessSetType : uint32_t {
GLOBAL,
+ UNIFORMS,
MAX,
};
@@ -15,21 +18,27 @@ enum SamplerType : uint32_t {
MAX_SAMPLER,
};
+struct device_buffer;
+
struct bindless_model {
#ifndef USE_VK_DESCRIPTOR_BUFFERS
+ [[nodiscard]] const device_buffer& get_uniform_buffer() const;
+
+ static bindless_model create_bindless_model();
+
+ static void destroy_bindless_model(bindless_model& bindless);
+
VkPipelineLayout layout;
- VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
VkDescriptorSet sets[BindlessSetType::MAX];
+
+private:
+ VkDescriptorSetLayout sets_layout[BindlessSetType::MAX];
VkDescriptorPool descriptor_pool;
+ handle<device_buffer> uniform_buffer;
static constexpr size_t descriptor_pool_allocable_sets_count = 64U;
static constexpr uint32_t set_descriptors_count[BindlessSetType::MAX]{ 1024U };
- static bindless_model create_bindless_model(VkDevice device);
-
- static void destroy_bindless_model(VkDevice device, bindless_model& bindless);
-
- private:
void create_layout(VkDevice device);
void create_descriptor_pool(VkDevice device);
void allocate_sets(VkDevice device);
diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp
index b09ed9e..a30b18c 100644
--- a/include/api-test/vk-device.hpp
+++ b/include/api-test/vk-device.hpp
@@ -28,7 +28,7 @@ class vkdevice {
static void free_device();
- static inline vkdevice* get_device() {
+ static inline vkdevice* get_render_device() {
return render_device;
}
@@ -68,6 +68,10 @@ class vkdevice {
return bindless;
}
+ inline VkDevice get_device() {
+ return device;
+ }
+
void submit(command_buffer* buffers, size_t count);
void present();
diff --git a/include/api-test/vk-utils.hpp b/include/api-test/vk-utils.hpp
index fb02737..a107d3b 100644
--- a/include/api-test/vk-utils.hpp
+++ b/include/api-test/vk-utils.hpp
@@ -9,3 +9,8 @@
#else
#define VKCHECK(result) (result)
#endif
+
+VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
+ VkDebugUtilsMessageTypeFlagsEXT type,
+ const VkDebugUtilsMessengerCallbackDataEXT* data,
+ void*);
diff --git a/shaders/api-test-ui.frag b/shaders/api-test-ui.frag
new file mode 100644
index 0000000..5c6a61f
--- /dev/null
+++ b/shaders/api-test-ui.frag
@@ -0,0 +1,20 @@
+#extension GL_EXT_nonuniform_qualifier : require
+
+layout(location = 0) out vec4 o_Color;
+
+layout(location = 0) in struct {
+ vec2 uv;
+ vec4 color;
+} In;
+
+layout(set = 0, binding = 0) uniform sampler samplers[];
+layout(set = 0, binding = 1) uniform texture2D textures[];
+layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(set = 1, binding = 0) uniform parameters {
+ uint texture_index;
+ uint sampler_index;
+} params;
+
+void main() {
+ o_Color = In.color * texture(sampler2D(textures[params.texture_index], samplers[params.sampler_index]), In.uv.xy);
+}
diff --git a/shaders/api-test-ui.vert b/shaders/api-test-ui.vert
new file mode 100644
index 0000000..6a37abc
--- /dev/null
+++ b/shaders/api-test-ui.vert
@@ -0,0 +1,37 @@
+#extension GL_EXT_buffer_reference : require
+
+struct vertex {
+ vec2 pos;
+ vec2 uv;
+ uint color;
+ uint[3] padding;
+};
+
+layout(buffer_reference) readonly buffer vertices {
+ vertex vertices[];
+};
+
+layout(set = 1, binding = 0) uniform parameters {
+ vertices vertex_buffer;
+ vec2 scale;
+ vec2 translate;
+} params;
+
+out gl_PerVertex {
+ vec4 gl_Position;
+};
+
+layout(location = 0) out struct {
+ vec2 uv;
+ vec4 color;
+} Out;
+
+
+void main() {
+ vertex v = params.vertex_buffer.vertices[gl_VertexIndex];
+
+ Out.color = unpackUnorm4x8(v.color);
+ Out.uv = v.uv;
+
+ gl_Position = vec4(v.pos * params.scale + params.translate, 0.0, 1.0);
+}
diff --git a/shaders/test.comp b/shaders/test.comp
index 541cb93..244533e 100644
--- a/shaders/test.comp
+++ b/shaders/test.comp
@@ -6,13 +6,18 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(set = 0, binding = 0) uniform sampler samplers[];
layout(set = 0, binding = 1) uniform texture2D textures[];
layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(set = 1, binding = 0) uniform parameters {
+ uint input_id1;
+ uint input_id2;
+ uint output_id;
+} params;
void main() {
ivec2 coords = ivec2(gl_GlobalInvocationID.xy);
float t = 0.5;
- vec3 color_1 = imageLoad(images[nonuniformEXT(0)], coords).xyz;
- vec3 color_2 = imageLoad(images[nonuniformEXT(1)], coords).xyz;
+ vec3 color_1 = imageLoad(images[nonuniformEXT(params.input_id1)], coords).xyz;
+ vec3 color_2 = imageLoad(images[nonuniformEXT(params.input_id2)], coords).xyz;
vec3 out_color = (t * color_1) + ((1.0 - t) * color_2);
- imageStore(images[nonuniformEXT(0)], coords, vec4(out_color, 1.0));
+ imageStore(images[nonuniformEXT(params.output_id)], coords, vec4(out_color, 1.0));
}