vkdecoder: support layered and non dedicated DPB

As NVIDIA Amperium. In this case the each output buffer is also a DPB,
but using a different view layer.

Still pending a validation layer issue:

VUID-VkVideoBeginCodingInfoKHR-flags-07244

Co-authored-by: Victor Jaquez <vjaquez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6954>
This commit is contained in:
Stéphane Cerveau 2024-05-28 09:55:05 +02:00 committed by GStreamer Marge Bot
parent 8d845d4a02
commit a4c976dd20
3 changed files with 6 additions and 15 deletions

View file

@ -1081,7 +1081,7 @@ _fill_ref_slot (GstVulkanH264Decoder * self, GstH264Picture * picture,
.width = self->coded_width,
.height = self->coded_height,
},
.baseArrayLayer = self->decoder->layered_dpb ? pic->slot_idx : 0,
.baseArrayLayer = (self->decoder->layered_dpb && self->decoder->dedicated_dpb) ? pic->slot_idx : 0,
.imageViewBinding = pic->base.img_view_ref->view,
};

View file

@ -1375,7 +1375,7 @@ _fill_ref_slot (GstVulkanH265Decoder * self, GstH265Picture * picture,
.sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
.codedOffset = { self->x, self->y },
.codedExtent = { self->coded_width, self->coded_height },
.baseArrayLayer = self->decoder->layered_dpb ? pic->slot_idx : 0,
.baseArrayLayer = (self->decoder->layered_dpb && self->decoder->dedicated_dpb) ? pic->slot_idx : 0,
.imageViewBinding = pic->base.img_view_ref->view,
};

View file

@ -298,15 +298,6 @@ gst_vulkan_decoder_start (GstVulkanDecoder * self,
self->layered_dpb = ((priv->caps.caps.flags &
VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR) == 0);
if (self->layered_dpb && !self->dedicated_dpb) {
g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INCOMPATIBLE_DRIVER,
"Buggy driver: "
"VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR set but "
"VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR is unset!");
goto failed;
}
priv->caps.caps.pNext = NULL;
/* Get output format */
@ -697,7 +688,7 @@ gst_vulkan_decoder_decode (GstVulkanDecoder * self,
return FALSE;
}
new_layout = (self->layered_dpb || pic->dpb) ?
new_layout = ((self->layered_dpb && self->dedicated_dpb) || pic->dpb) ?
VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR :
VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR;
gst_vulkan_operation_add_frame_barrier (priv->exec, pic->out,
@ -713,7 +704,7 @@ gst_vulkan_decoder_decode (GstVulkanDecoder * self,
}
}
if (!self->layered_dpb) {
if (!self->layered_buffer) {
/* All references (apart from the current) for non-layered refs */
for (i = 0; i < pic->decode_info.referenceSlotCount; i++) {
@ -1148,7 +1139,7 @@ gst_vulkan_decoder_picture_init (GstVulkanDecoder * self,
priv = gst_vulkan_decoder_get_instance_private (self);
if (self->layered_dpb)
if (self->layered_dpb && self->dedicated_dpb)
g_return_val_if_fail (GST_IS_BUFFER (self->layered_buffer), FALSE);
else if (self->dedicated_dpb)
g_return_val_if_fail (GST_IS_BUFFER_POOL (priv->dpb_pool), FALSE);
@ -1161,7 +1152,7 @@ gst_vulkan_decoder_picture_init (GstVulkanDecoder * self,
pic->dpb = NULL;
pic->img_view_ref = NULL;
if (self->layered_dpb) {
if (self->layered_dpb && self->dedicated_dpb) {
pic->img_view_ref =
gst_vulkan_decoder_picture_create_view (self, self->layered_buffer,
FALSE);