vulkan: vulkan_compute fixate modifier

If the modifier for a format is not fixated yet, we will use vulkan to
fixate a modifier, update the parsed format, change the EnumFormats mask
and exit early. This triggers a new enum_params with EnumFormats and a
new set_param for Format.
This commit is contained in:
columbarius 2023-08-12 00:18:53 +02:00 committed by Wim Taymans
parent a673c56eea
commit 2c65eb6c2c
2 changed files with 98 additions and 4 deletions

View file

@ -338,8 +338,21 @@ static int port_enum_formats(void *object,
uint32_t fmt_index;
bool has_modifier;
if (!find_EnumFormatInfo(&this->state.base, index, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier))
return 0;
if (this->port[port_id].have_format
&& this->port[port_id].current_format.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER
&& this->port[port_id].current_format.info.dsp.flags ^ SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED) {
if (index == 0) {
spa_log_info(this->log, "vulkan-compute-filter: enum_formats fixated format idx: %d, format %d, has_modifier 1",
index, this->port[port_id].current_format.info.dsp.format);
*param = spa_format_video_dsp_build(builder, SPA_PARAM_EnumFormat, &this->port[port_id].current_format.info.dsp);
return 1;
}
if (!find_EnumFormatInfo(&this->state.base, index-1, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier))
return 0;
} else {
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];
spa_log_info(this->log, "vulkan-compute-filter: enum_formats idx: %d, format %d, has_modifier %d", index, f_info->spa_format, has_modifier);
@ -498,8 +511,42 @@ static int port_set_format(struct impl *this, struct port *port,
this->state.constants.width = this->position->video.size.width;
this->state.constants.height = this->position->video.size.height;
bool modifier_fixed = false;
if (port->direction == SPA_DIRECTION_OUTPUT
&& info.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER
&& info.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED) {
const struct spa_pod_prop *mod_prop;
if ((mod_prop = spa_pod_find_prop(format, NULL, SPA_FORMAT_VIDEO_modifier)) == NULL)
return -EINVAL;
const struct spa_pod *mod_pod = &mod_prop->value;
uint32_t modifierCount = SPA_POD_CHOICE_N_VALUES(mod_pod);
uint64_t *modifiers = SPA_POD_CHOICE_VALUES(mod_pod);
if (modifierCount <= 1)
return -EINVAL;
// SPA_POD_CHOICE carries the "preferred" value at position 0
modifierCount -= 1;
modifiers++;
uint64_t fixed_modifier;
if (spa_vulkan_fixate_modifier(&this->state, &this->state.streams[port->stream_id], &info.info.dsp, modifierCount, modifiers, &fixed_modifier) != 0)
return -EINVAL;
spa_log_info(this->log, NAME ": modifier fixated %"PRIu64, fixed_modifier);
info.info.dsp.modifier = fixed_modifier;
info.info.dsp.flags &= ~SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED;
modifier_fixed = true;
}
port->current_format = info;
port->have_format = true;
if (modifier_fixed) {
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
port->params[0].flags ^= SPA_PARAM_INFO_SERIAL;
emit_port_info(this, port, false);
return 0;
}
}
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;

View file

@ -572,8 +572,21 @@ static int port_enum_formats(void *object,
uint32_t fmt_index;
bool has_modifier;
if (!find_EnumFormatInfo(&this->state.base, index, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier))
return 0;
if (this->port.have_format
&& this->port.current_format.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER
&& this->port.current_format.info.dsp.flags ^ SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED) {
if (index == 0) {
spa_log_info(this->log, "vulkan-compute-source: enum_formats fixated format idx: %d, format %d, has_modifier 1",
index, this->port.current_format.info.dsp.format);
*param = spa_format_video_dsp_build(builder, SPA_PARAM_EnumFormat, &this->port.current_format.info.dsp);
return 1;
}
if (!find_EnumFormatInfo(&this->state.base, index-1, spa_vulkan_get_buffer_caps(&this->state, direction), &fmt_index, &has_modifier))
return 0;
} else {
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];
spa_log_info(this->log, "vulkan-compute-source: enum_formats idx: %d, format %d, has_modifier %d", index, f_info->spa_format, has_modifier);
@ -733,9 +746,43 @@ static int port_set_format(struct impl *this, struct port *port,
this->state.constants.width = this->position->video.size.width;
this->state.constants.height = this->position->video.size.height;
bool modifier_fixed = false;
if (info.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER
&& info.info.dsp.flags & SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED) {
const struct spa_pod_prop *mod_prop;
if ((mod_prop = spa_pod_find_prop(format, NULL, SPA_FORMAT_VIDEO_modifier)) == NULL)
return -EINVAL;
const struct spa_pod *mod_pod = &mod_prop->value;
uint32_t modifierCount = SPA_POD_CHOICE_N_VALUES(mod_pod);
uint64_t *modifiers = SPA_POD_CHOICE_VALUES(mod_pod);
if (modifierCount <= 1)
return -EINVAL;
// SPA_POD_CHOICE carries the "preferred" value at position 0
modifierCount -= 1;
modifiers++;
uint64_t fixed_modifier;
if (spa_vulkan_fixate_modifier(&this->state, &this->state.streams[0], &info.info.dsp, modifierCount, modifiers, &fixed_modifier) != 0)
return -EINVAL;
spa_log_info(this->log, NAME ": modifier fixated %"PRIu64, fixed_modifier);
info.info.dsp.modifier = fixed_modifier;
info.info.dsp.flags &= ~SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED;
modifier_fixed = true;
}
port->current_format = info;
port->have_format = true;
spa_vulkan_prepare(&this->state);
if (modifier_fixed) {
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
port->params[0].flags ^= SPA_PARAM_INFO_SERIAL;
emit_port_info(this, port, false);
return 0;
}
}
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;