@@ -50,11 +50,11 @@
auto target_major = major(node_stat.st_rdev);
auto target_minor = minor(node_stat.st_rdev);
VkApplicationInfo app = {VK_STRUCTURE_TYPE_APPLICATION_INFO};
VkApplicationInfo app = {.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO};
app.apiVersion = VK_API_VERSION_1_1;
static const std::array<const char *, 1> instance_exts = {VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME};
VkInstanceCreateInfo ci = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
VkInstanceCreateInfo ci = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
ci.pApplicationInfo = &app;
ci.enabledExtensionCount = instance_exts.size();
ci.ppEnabledExtensionNames = instance_exts.data();
@@ -75,8 +75,8 @@
std::string result;
for (uint32_t i = 0; i < count; i++) {
VkPhysicalDeviceDrmPropertiesEXT drm = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT};
VkPhysicalDeviceDrmPropertiesEXT drm = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT};
VkPhysicalDeviceProperties2 props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
VkPhysicalDeviceProperties2 props2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
props2.pNext = &drm;
vkGetPhysicalDeviceProperties2(devs[i], &props2);
if (drm.hasRender && drm.renderMajor == (int64_t) target_major && drm.renderMinor == (int64_t) target_minor) {
@@ -238,7 +238,7 @@
// (when VK_KHR_internally_synchronized_queues is available). The Vulkan spec requires
// vkGetDeviceQueue2 to retrieve such queues; plain vkGetDeviceQueue would return an
// incompatible queue handle, breaking synchronization with the encoder.
VkDeviceQueueInfo2 queue_info = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2};
VkDeviceQueueInfo2 queue_info = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2};
queue_info.flags = vk_dev.ctx->queue_flags;
queue_info.queueFamilyIndex = vk_dev.compute_qf;
queue_info.queueIndex = 0;
@@ -391,7 +391,7 @@
private:
bool create_compute_pipeline() {
// Shader module
VkShaderModuleCreateInfo shader_ci = {.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
VkShaderModuleCreateInfo shader_ci = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
shader_ci.codeSize = rgb2yuv_comp_spv_size;
shader_ci.pCode = rgb2yuv_comp_spv_data.data();
VK_CHECK_BOOL(vkCreateShaderModule(vk_dev.dev, &shader_ci, nullptr, &compute.shader_module));
@@ -403,7 +403,7 @@
bindings[2] = {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
bindings[3] = {3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
VkDescriptorSetLayoutCreateInfo ds_layout_ci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
VkDescriptorSetLayoutCreateInfo ds_layout_ci = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
ds_layout_ci.bindingCount = bindings.size();
ds_layout_ci.pBindings = bindings.data();
VK_CHECK_BOOL(vkCreateDescriptorSetLayout(vk_dev.dev, &ds_layout_ci, nullptr, &compute.ds_layout));
@@ -411,7 +411,7 @@
// Push constant range
VkPushConstantRange pc_range = {VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(PushConstants)};
VkPipelineLayoutCreateInfo pl_ci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
VkPipelineLayoutCreateInfo pl_ci = {.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
pl_ci.setLayoutCount = 1;
pl_ci.pSetLayouts = &compute.ds_layout;
pl_ci.pushConstantRangeCount = 1;
@@ -419,8 +419,8 @@
VK_CHECK_BOOL(vkCreatePipelineLayout(vk_dev.dev, &pl_ci, nullptr, &compute.pipeline_layout));
// Compute pipeline
VkComputePipelineCreateInfo comp_ci = {.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
comp_ci.stage = {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
VkComputePipelineCreateInfo comp_ci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
comp_ci.stage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
comp_ci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
comp_ci.stage.module = compute.shader_module;
comp_ci.stage.pName = "main";
@@ -432,20 +432,20 @@
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2},
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2},
}};
VkDescriptorPoolCreateInfo pool_ci = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
VkDescriptorPoolCreateInfo pool_ci = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
pool_ci.maxSets = 1;
pool_ci.poolSizeCount = pool_sizes.size();
pool_ci.pPoolSizes = pool_sizes.data();
VK_CHECK_BOOL(vkCreateDescriptorPool(vk_dev.dev, &pool_ci, nullptr, &compute.desc_pool));
VkDescriptorSetAllocateInfo alloc_info = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};
VkDescriptorSetAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};
alloc_info.descriptorPool = compute.desc_pool;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &compute.ds_layout;
VK_CHECK_BOOL(vkAllocateDescriptorSets(vk_dev.dev, &alloc_info, &compute.desc_set));
// Sampler for source image
VkSamplerCreateInfo sampler_ci = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
VkSamplerCreateInfo sampler_ci = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
sampler_ci.magFilter = VK_FILTER_LINEAR;
sampler_ci.minFilter = VK_FILTER_LINEAR;
sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
@@ -460,12 +460,12 @@
}
bool create_command_resources() {
VkCommandPoolCreateInfo pool_ci = {.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
VkCommandPoolCreateInfo pool_ci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
pool_ci.queueFamilyIndex = vk_dev.compute_qf;
pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VK_CHECK_BOOL(vkCreateCommandPool(vk_dev.dev, &pool_ci, nullptr, &cmd.pool));
VkCommandBufferAllocateInfo alloc_ci = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
VkCommandBufferAllocateInfo alloc_ci = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
alloc_ci.commandPool = cmd.pool;
alloc_ci.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
alloc_ci.commandBufferCount = CMD_RING_SIZE;
@@ -529,8 +529,8 @@
* @return Expected plane count, or 0 if unknown.
*/
int query_modifier_plane_count(VkFormat format, uint64_t modifier) {
VkDrmFormatModifierPropertiesListEXT mod_list = {VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT};
VkFormatProperties2 fmt_props2 = {VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
VkDrmFormatModifierPropertiesListEXT mod_list = {.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT};
VkFormatProperties2 fmt_props2 = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
fmt_props2.pNext = &mod_list;
vkGetPhysicalDeviceFormatProperties2(vk_dev.phys_dev, format, &fmt_props2);
std::vector<VkDrmFormatModifierPropertiesEXT> mod_props(mod_list.drmFormatModifierCount);
@@ -553,17 +553,17 @@
}
// Query memory requirements for this DMA-BUF
VkMemoryFdPropertiesKHR fd_props = {VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR};
VkMemoryFdPropertiesKHR fd_props = {.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR};
if (vk_dev.getMemoryFdProperties) {
vk_dev.getMemoryFdProperties(vk_dev.dev, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, fd, &fd_props);
}
// Create VkImage for the DMA-BUF
VkExternalMemoryImageCreateInfo ext_ci = {.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO};
VkExternalMemoryImageCreateInfo ext_ci = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO};
ext_ci.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
std::array<VkSubresourceLayout, 4> drm_layouts = {};
VkImageDrmFormatModifierExplicitCreateInfoEXT drm_ci = {
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
};
VkImageTiling tiling;
@@ -594,7 +594,7 @@
tiling = VK_IMAGE_TILING_LINEAR;
}
VkImageCreateInfo img_ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
VkImageCreateInfo img_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
img_ci.pNext = &ext_ci;
img_ci.imageType = VK_IMAGE_TYPE_2D;
img_ci.format = vk_format;
@@ -619,11 +619,11 @@
VkMemoryRequirements mem_req;
vkGetImageMemoryRequirements(vk_dev.dev, src.image, &mem_req);
VkImportMemoryFdInfoKHR import_fd = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR};
VkImportMemoryFdInfoKHR import_fd = {.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR};
import_fd.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
import_fd.fd = fd; // Vulkan takes ownership
VkMemoryAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
VkMemoryAllocateInfo alloc_info = {.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
alloc_info.pNext = &import_fd;
alloc_info.allocationSize = mem_req.size;
alloc_info.memoryTypeIndex = find_memory_type(
@@ -643,7 +643,7 @@
vkBindImageMemory(vk_dev.dev, src.image, src_mem, 0);
// Create image view
VkImageViewCreateInfo view_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
VkImageViewCreateInfo view_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
view_ci.image = src.image;
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_ci.format = vk_format;
@@ -658,7 +658,7 @@
bool create_cursor_image(int w, int h, const uint8_t *pixels) {
destroy_cursor_image();
VkImageCreateInfo img_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
VkImageCreateInfo img_ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
img_ci.imageType = VK_IMAGE_TYPE_2D;
img_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
img_ci.extent = {(uint32_t) w, (uint32_t) h, 1};
@@ -672,7 +672,7 @@
VkMemoryRequirements mem_req;
vkGetImageMemoryRequirements(vk_dev.dev, cursor.image, &mem_req);
VkMemoryAllocateInfo alloc = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
VkMemoryAllocateInfo alloc = {.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
alloc.allocationSize = mem_req.size;
alloc.memoryTypeIndex = find_memory_type(mem_req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VK_CHECK_BOOL(vkAllocateMemory(vk_dev.dev, &alloc, nullptr, &cursor.mem));
@@ -690,7 +690,7 @@
vkUnmapMemory(vk_dev.dev, cursor.mem);
}
VkImageViewCreateInfo view_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
VkImageViewCreateInfo view_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
view_ci.image = cursor.image;
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
@@ -734,6 +734,6 @@
if (num_imgs == 1) {
// Single multiplane image — create plane views
VkImageViewCreateInfo view_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
VkImageViewCreateInfo view_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
view_ci.image = vk_frame->img[0];
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
@@ -749,6 +749,6 @@
VK_CHECK_BOOL(vkCreateImageView(vk_dev.dev, &view_ci, nullptr, &target.uv_view));
} else {
// Separate images per plane
VkImageViewCreateInfo view_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
VkImageViewCreateInfo view_ci = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
@@ -792,12 +792,12 @@
auto cmd_buf = cmd.ring[cmd.ring_idx];
cmd.ring_idx = (cmd.ring_idx + 1) % CMD_RING_SIZE;
VkCommandBufferBeginInfo begin_ci = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
VkCommandBufferBeginInfo begin_ci = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
begin_ci.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
VK_CHECK(vkBeginCommandBuffer(cmd_buf, &begin_ci));
// Transition source image to SHADER_READ_ONLY
VkImageMemoryBarrier src_barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
VkImageMemoryBarrier src_barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
src_barrier.srcAccessMask = 0;
src_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
src_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -811,7 +811,7 @@
// Transition cursor image if needed
if (cursor.needs_transition) {
VkImageMemoryBarrier cursor_barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
VkImageMemoryBarrier cursor_barrier = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
cursor_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
cursor_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
cursor_barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
@@ -828,7 +828,7 @@
std::array<VkImageMemoryBarrier, 2> dst_barriers = {};
int num_dst_barriers = (num_imgs == 1) ? 1 : 2;
for (int i = 0; i < num_dst_barriers; i++) {
dst_barriers[i] = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
dst_barriers[i] = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
dst_barriers[i].srcAccessMask = target.initialized ? VK_ACCESS_SHADER_READ_BIT : 0;
dst_barriers[i].dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
dst_barriers[i].oldLayout = target.initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED;
@@ -853,7 +853,7 @@
VK_CHECK(vkEndCommandBuffer(cmd_buf));
// Submit with timeline semaphore signaling for FFmpeg
VkTimelineSemaphoreSubmitInfo timeline_info = {VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO};
VkTimelineSemaphoreSubmitInfo timeline_info = {.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO};
std::array<VkSemaphore, AV_NUM_DATA_POINTERS> wait_sems = {};
std::array<VkSemaphore, AV_NUM_DATA_POINTERS> signal_sems = {};
std::array<uint64_t, AV_NUM_DATA_POINTERS> wait_vals = {};
@@ -877,7 +877,7 @@
timeline_info.signalSemaphoreValueCount = sem_count;
timeline_info.pSignalSemaphoreValues = signal_vals.data();
VkSubmitInfo submit = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
VkSubmitInfo submit = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO};
submit.pNext = &timeline_info;
submit.waitSemaphoreCount = sem_count;
submit.pWaitSemaphores = wait_sems.data();