@@ -50,11 +50,20 @@
VkApplicationInfo app = {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 = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
ci.pApplicationInfo = &app;
ci.enabledExtensionCount = instance_exts.size();
ci.ppEnabledExtensionNames = instance_exts.data();
VkInstance inst = VK_NULL_HANDLE;
if (vkCreateInstance(&ci, nullptr, &inst) != VK_SUCCESS) {
// Retry without the extension for loaders that don't support it
return {};
ci.enabledExtensionCount = 0;
ci.ppEnabledExtensionNames = nullptr;
if (vkCreateInstance(&ci, nullptr, &inst) != VK_SUCCESS) {
return {};
}
}
uint32_t count = 0;
@@ -435,5 +444,25 @@
}
}
/**
* @brief Query the driver-expected plane count for a format+modifier pair.
* @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};
fmt_props2.pNext = &mod_list;
vkGetPhysicalDeviceFormatProperties2(vk_dev.phys_dev, format, &fmt_props2);
std::vector<VkDrmFormatModifierPropertiesEXT> mod_props(mod_list.drmFormatModifierCount);
mod_list.pDrmFormatModifierProperties = mod_props.data();
vkGetPhysicalDeviceFormatProperties2(vk_dev.phys_dev, format, &fmt_props2);
for (const auto &mp : mod_props) {
if (mp.drmFormatModifier == modifier) {
return mp.drmFormatModifierPlaneCount;
}
}
return 0;
}
bool import_dmabuf(const egl::surface_descriptor_t &sd) {
destroy_src_image();
@@ -458,13 +487,23 @@
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
};
VkImageTiling tiling;
auto [vk_format, vk_swizzle] = drm_fourcc_to_vk_format(sd.fourcc);
if (sd.modifier != DRM_FORMAT_MOD_INVALID) {
int plane_count = 0;
int dmabuf_planes = 0;
for (int i = 0; i < 4 && sd.fds[i] >= 0; ++i) {
dmabuf_planes++;
}
// Query driver for the expected plane count for this format+modifier.
// DMA-BUF exports may include extra metadata planes (e.g. AMD DCC).
int expected = query_modifier_plane_count(vk_format, sd.modifier);
int plane_count = (expected > 0 && expected <= dmabuf_planes) ? expected : dmabuf_planes;
for (int i = 0; i < plane_count; ++i) {
drm_layouts[i].offset = sd.offsets[i];
drm_layouts[i].rowPitch = sd.pitches[i];
plane_count++;
}
drm_ci.drmFormatModifier = sd.modifier;
drm_ci.drmFormatModifierPlaneCount = plane_count;
@@ -475,8 +514,6 @@
tiling = VK_IMAGE_TILING_LINEAR;
}
auto [vk_format, vk_swizzle] = drm_fourcc_to_vk_format(sd.fourcc);
VkImageCreateInfo img_ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
img_ci.pNext = &ext_ci;
img_ci.imageType = VK_IMAGE_TYPE_2D;
@@ -781,6 +818,7 @@
for (int i = 0; i < AV_NUM_DATA_POINTERS && vk_frame->img[i]; i++) {
vk_frame->layout[i] = VK_IMAGE_LAYOUT_GENERAL;
vk_frame->access[i] = VK_ACCESS_SHADER_WRITE_BIT;
vk_frame->queue_family[i] = vk_dev.compute_qf;
}
target.initialized = true;