diff options
| -rw-r--r-- | api-test/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | api-test/command-buffer.cpp | 17 | ||||
| -rw-r--r-- | api-test/main.cpp | 24 | ||||
| -rw-r--r-- | api-test/vk-bindless.cpp | 75 | ||||
| -rw-r--r-- | api-test/vk-device.cpp | 186 | ||||
| -rw-r--r-- | api-test/vk-utils.cpp | 44 | ||||
| -rw-r--r-- | include/api-test/command-buffer.hpp | 1 | ||||
| -rw-r--r-- | include/api-test/freelist.hpp | 4 | ||||
| -rw-r--r-- | include/api-test/handle.hpp | 4 | ||||
| -rw-r--r-- | include/api-test/vk-bindless.hpp | 21 | ||||
| -rw-r--r-- | include/api-test/vk-device.hpp | 6 | ||||
| -rw-r--r-- | include/api-test/vk-utils.hpp | 5 | ||||
| -rw-r--r-- | shaders/api-test-ui.frag | 20 | ||||
| -rw-r--r-- | shaders/api-test-ui.vert | 37 | ||||
| -rw-r--r-- | shaders/test.comp | 11 |
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, ¶ms.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, ¶ms, 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)); } |
