diff --git a/spa/plugins/vulkan/vulkan-compute-filter.c b/spa/plugins/vulkan/vulkan-compute-filter.c index 96a0162f0..29c5137d9 100644 --- a/spa/plugins/vulkan/vulkan-compute-filter.c +++ b/spa/plugins/vulkan/vulkan-compute-filter.c @@ -292,18 +292,23 @@ static struct spa_pod *build_EnumFormat(uint32_t fmt, const struct vulkan_format // This function enumerates the available formats in vulkan_state::formats, announcing all formats capable to support DmaBufs // first and then falling back to those supported with SHM buffers. -static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t *fmt_idx, bool *has_modifier) { +static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t caps, uint32_t *fmt_idx, bool *has_modifier) { int64_t fmtIterator = 0; + int64_t maxIterator = 0; + if (caps & VULKAN_BUFFER_TYPE_CAP_SHM) + maxIterator += s->formatInfoCount; + if (caps & VULKAN_BUFFER_TYPE_CAP_DMABUF) + maxIterator += s->formatInfoCount; // Count available formats until index underflows, while fmtIterator indexes the current format. - // Iterate twice over formats first time with modifiers, second time without. - while (index < (uint32_t)-1 && fmtIterator < 2*s->formatInfoCount) { + // Iterate twice over formats first time with modifiers, second time without if both caps are supported. + while (index < (uint32_t)-1 && fmtIterator < maxIterator) { const struct vulkan_format_info *f_info = &s->formatInfos[fmtIterator%s->formatInfoCount]; - if (fmtIterator < s->formatInfoCount) { + if (caps & VULKAN_BUFFER_TYPE_CAP_DMABUF && fmtIterator < s->formatInfoCount) { // First round, check for modifiers if (f_info->modifierCount > 0) { index--; } - } else { + } else if (caps & VULKAN_BUFFER_TYPE_CAP_SHM) { // Second round, every format should be supported. index--; } @@ -318,7 +323,7 @@ static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t fmtIterator--; *fmt_idx = fmtIterator%s->formatInfoCount; // Loop finished in first round - *has_modifier = fmtIterator < s->formatInfoCount; + *has_modifier = caps & VULKAN_BUFFER_TYPE_CAP_DMABUF && fmtIterator < s->formatInfoCount; return true; } @@ -333,7 +338,7 @@ static int port_enum_formats(void *object, uint32_t fmt_index; bool has_modifier; - if (!find_EnumFormatInfo(&this->state.base, index, &fmt_index, &has_modifier)) + if (!find_EnumFormatInfo(&this->state.base, index, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier)) return 0; const struct vulkan_format_info *f_info = &this->state.base.formatInfos[fmt_index]; diff --git a/spa/plugins/vulkan/vulkan-compute-source.c b/spa/plugins/vulkan/vulkan-compute-source.c index cceb819b5..33488f9cf 100644 --- a/spa/plugins/vulkan/vulkan-compute-source.c +++ b/spa/plugins/vulkan/vulkan-compute-source.c @@ -526,18 +526,23 @@ static struct spa_pod *build_EnumFormat(uint32_t fmt, const struct vulkan_format // This function enumerates the available formats in vulkan_state::formats, announcing all formats capable to support DmaBufs // first and then falling back to those supported with SHM buffers. -static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t *fmt_idx, bool *has_modifier) { +static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t caps, uint32_t *fmt_idx, bool *has_modifier) { int64_t fmtIterator = 0; + int64_t maxIterator = 0; + if (caps & VULKAN_BUFFER_TYPE_CAP_SHM) + maxIterator += s->formatInfoCount; + if (caps & VULKAN_BUFFER_TYPE_CAP_DMABUF) + maxIterator += s->formatInfoCount; // Count available formats until index underflows, while fmtIterator indexes the current format. - // Iterate twice over formats first time with modifiers, second time without. - while (index < (uint32_t)-1 && fmtIterator < 2*s->formatInfoCount) { + // Iterate twice over formats first time with modifiers, second time without if both caps are supported. + while (index < (uint32_t)-1 && fmtIterator < maxIterator) { const struct vulkan_format_info *f_info = &s->formatInfos[fmtIterator%s->formatInfoCount]; - if (fmtIterator < s->formatInfoCount) { + if (caps & VULKAN_BUFFER_TYPE_CAP_DMABUF && fmtIterator < s->formatInfoCount) { // First round, check for modifiers if (f_info->modifierCount > 0) { index--; } - } else { + } else if (caps & VULKAN_BUFFER_TYPE_CAP_SHM) { // Second round, every format should be supported. index--; } @@ -552,7 +557,7 @@ static bool find_EnumFormatInfo(struct vulkan_base *s, uint32_t index, uint32_t fmtIterator--; *fmt_idx = fmtIterator%s->formatInfoCount; // Loop finished in first round - *has_modifier = fmtIterator < s->formatInfoCount; + *has_modifier = caps & VULKAN_BUFFER_TYPE_CAP_DMABUF && fmtIterator < s->formatInfoCount; return true; } @@ -567,7 +572,7 @@ static int port_enum_formats(void *object, uint32_t fmt_index; bool has_modifier; - if (!find_EnumFormatInfo(&this->state.base, index, &fmt_index, &has_modifier)) + if (!find_EnumFormatInfo(&this->state.base, index, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier)) return 0; const struct vulkan_format_info *f_info = &this->state.base.formatInfos[fmt_index]; diff --git a/spa/plugins/vulkan/vulkan-compute-utils.c b/spa/plugins/vulkan/vulkan-compute-utils.c index 54501762c..1e127581a 100644 --- a/spa/plugins/vulkan/vulkan-compute-utils.c +++ b/spa/plugins/vulkan/vulkan-compute-utils.c @@ -492,6 +492,17 @@ int spa_vulkan_process(struct vulkan_compute_state *s) return 0; } +int spa_vulkan_get_buffer_caps(struct vulkan_compute_state *s, enum spa_direction direction) +{ + switch (direction) { + case SPA_DIRECTION_INPUT: + return VULKAN_BUFFER_TYPE_CAP_DMABUF; + case SPA_DIRECTION_OUTPUT: + return VULKAN_BUFFER_TYPE_CAP_DMABUF; + } + return 0; +} + int spa_vulkan_init(struct vulkan_compute_state *s) { s->base.log = s->log; diff --git a/spa/plugins/vulkan/vulkan-compute-utils.h b/spa/plugins/vulkan/vulkan-compute-utils.h index 7be7bad88..725e45dbb 100644 --- a/spa/plugins/vulkan/vulkan-compute-utils.h +++ b/spa/plugins/vulkan/vulkan-compute-utils.h @@ -71,5 +71,7 @@ int spa_vulkan_ready(struct vulkan_compute_state *s); int spa_vulkan_process(struct vulkan_compute_state *s); int spa_vulkan_cleanup(struct vulkan_compute_state *s); +int spa_vulkan_get_buffer_caps(struct vulkan_compute_state *s, enum spa_direction direction); + int spa_vulkan_init(struct vulkan_compute_state *s); void spa_vulkan_deinit(struct vulkan_compute_state *s); diff --git a/spa/plugins/vulkan/vulkan-types.h b/spa/plugins/vulkan/vulkan-types.h index c2708ea87..45a281f2b 100644 --- a/spa/plugins/vulkan/vulkan-types.h +++ b/spa/plugins/vulkan/vulkan-types.h @@ -8,6 +8,11 @@ #define MAX_BUFFERS 16 #define DMABUF_MAX_PLANES 1 +enum buffer_type_caps { + VULKAN_BUFFER_TYPE_CAP_SHM = 1<<0, + VULKAN_BUFFER_TYPE_CAP_DMABUF = 1<<1, +}; + struct vulkan_modifier_info { VkDrmFormatModifierPropertiesEXT props; VkExtent2D max_extent;