mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
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:
parent
a673c56eea
commit
2c65eb6c2c
2 changed files with 98 additions and 4 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue