mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	spa: clamp required alignment to cpu alignment
pipewire will allocate buffers aligned to the max alignment required for the CPU. Take this into account and don't expect larger alignment. Fixes a warning in mixer-dsp when the CPU max alignment is 16 but the plugin requires 32 bytes alignment for the AVX2 path (that would never be chosen on the CPU). See #2074
This commit is contained in:
		
							parent
							
								
									36d78c41a0
								
							
						
					
					
						commit
						92198e4d0d
					
				
					 11 changed files with 44 additions and 17 deletions
				
			
		|  | @ -93,6 +93,8 @@ void channelmix_##name##_##arch(struct channelmix *mix,			\ | |||
| 		uint32_t n_src, const void * SPA_RESTRICT src[n_src],	\ | ||||
| 		uint32_t n_samples); | ||||
| 
 | ||||
| #define CHANNELMIX_OPS_MAX_ALIGN 16 | ||||
| 
 | ||||
| DEFINE_FUNCTION(copy, c); | ||||
| DEFINE_FUNCTION(f32_n_m, c); | ||||
| DEFINE_FUNCTION(f32_1_2, c); | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ | |||
| 
 | ||||
| #define MAX_BUFFERS	32 | ||||
| #define MAX_DATAS	SPA_AUDIO_MAX_CHANNELS | ||||
| #define MAX_ALIGN	CHANNELMIX_OPS_MAX_ALIGN | ||||
| 
 | ||||
| #define DEFAULT_CONTROL_BUFFER_SIZE	32768 | ||||
| 
 | ||||
|  | @ -164,6 +165,7 @@ struct impl { | |||
| 	unsigned int started:1; | ||||
| 	unsigned int is_passthrough:1; | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| }; | ||||
| 
 | ||||
| #define IS_CONTROL_PORT(this,d,id)	(id == 1 && d == SPA_DIRECTION_INPUT) | ||||
|  | @ -1207,7 +1209,7 @@ impl_node_port_use_buffers(void *object, | |||
| 					      buffers[i]); | ||||
| 				return -EINVAL; | ||||
| 			} | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, 16)) { | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, this->max_align)) { | ||||
| 				spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned", | ||||
| 						this, j, i); | ||||
| 			} | ||||
|  | @ -1559,8 +1561,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	spa_hook_list_init(&this->hooks); | ||||
| 
 | ||||
|  |  | |||
|  | @ -200,6 +200,8 @@ int convert_init(struct convert *conv); | |||
| void conv_##name##_##arch(struct convert *conv, void * SPA_RESTRICT dst[],	\ | ||||
| 		const void * SPA_RESTRICT src[], uint32_t n_samples)		\ | ||||
| 
 | ||||
| #define FMT_OPS_MAX_ALIGN	32 | ||||
| 
 | ||||
| DEFINE_FUNCTION(copy8d, c); | ||||
| DEFINE_FUNCTION(copy8, c); | ||||
| DEFINE_FUNCTION(copy16d, c); | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.fmtconvert"); | |||
| #define DEFAULT_CHANNELS	2 | ||||
| 
 | ||||
| #define MAX_BUFFERS	32 | ||||
| #define MAX_ALIGN	16 | ||||
| #define MAX_ALIGN	FMT_OPS_MAX_ALIGN | ||||
| #define MAX_DATAS	SPA_AUDIO_MAX_CHANNELS | ||||
| 
 | ||||
| #define PROP_DEFAULT_TRUNCATE	false | ||||
|  | @ -118,6 +118,7 @@ struct impl { | |||
| 	struct spa_log *log; | ||||
| 	struct spa_cpu *cpu; | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| 	uint32_t quantum_limit; | ||||
| 
 | ||||
| 	struct spa_io_position *io_position; | ||||
|  | @ -812,7 +813,7 @@ impl_node_port_use_buffers(void *object, | |||
| 						this, j, i); | ||||
| 				return -EINVAL; | ||||
| 			} | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, MAX_ALIGN)) { | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, this->max_align)) { | ||||
| 				spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned", | ||||
| 						this, j, i); | ||||
| 			} | ||||
|  | @ -1091,8 +1092,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; info && i < info->n_items; i++) { | ||||
| 		const char *k = info->items[i].key; | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.merger"); | |||
| #define DEFAULT_RATE		48000 | ||||
| #define DEFAULT_CHANNELS	2 | ||||
| 
 | ||||
| #define MAX_ALIGN	16 | ||||
| #define MAX_ALIGN	FMT_OPS_MAX_ALIGN | ||||
| #define MAX_BUFFERS	32 | ||||
| #define MAX_DATAS	SPA_AUDIO_MAX_CHANNELS | ||||
| #define MAX_PORTS	SPA_AUDIO_MAX_CHANNELS | ||||
|  | @ -146,6 +146,7 @@ struct impl { | |||
| 	struct spa_cpu *cpu; | ||||
| 
 | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| 	uint32_t quantum_limit; | ||||
| 
 | ||||
| 	struct spa_io_position *io_position; | ||||
|  | @ -1265,7 +1266,7 @@ impl_node_port_use_buffers(void *object, | |||
| 						this, j, i, d[j].type, d[j].data); | ||||
| 				return -EINVAL; | ||||
| 			} | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, MAX_ALIGN)) { | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, this->max_align)) { | ||||
| 				spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned", | ||||
| 						this, j, i); | ||||
| 			} | ||||
|  | @ -1576,8 +1577,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; info && i < info->n_items; i++) { | ||||
| 		const char *k = info->items[i].key; | ||||
|  |  | |||
|  | @ -48,7 +48,6 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.resample"); | |||
| #define DEFAULT_RATE		48000 | ||||
| #define DEFAULT_CHANNELS	2 | ||||
| 
 | ||||
| #define MAX_ALIGN	16 | ||||
| #define MAX_BUFFERS	32 | ||||
| 
 | ||||
| struct impl; | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.splitter"); | |||
| #define DEFAULT_CHANNELS	2 | ||||
| #define DEFAULT_MASK		(1LL << SPA_AUDIO_CHANNEL_FL) | (1LL << SPA_AUDIO_CHANNEL_FR) | ||||
| 
 | ||||
| #define MAX_ALIGN	16 | ||||
| #define MAX_ALIGN	FMT_OPS_MAX_ALIGN | ||||
| #define MAX_BUFFERS	32 | ||||
| #define MAX_DATAS	SPA_AUDIO_MAX_CHANNELS | ||||
| #define MAX_PORTS	SPA_AUDIO_MAX_CHANNELS | ||||
|  | @ -107,6 +107,7 @@ struct impl { | |||
| 	struct spa_cpu *cpu; | ||||
| 
 | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| 	uint32_t quantum_limit; | ||||
| 
 | ||||
| 	struct spa_io_position *io_position; | ||||
|  | @ -916,7 +917,7 @@ impl_node_port_use_buffers(void *object, | |||
| 						this, j, i, d[j].type, d[j].data); | ||||
| 				return -EINVAL; | ||||
| 			} | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, MAX_ALIGN)) { | ||||
| 			if (!SPA_IS_ALIGNED(d[j].data, this->max_align)) { | ||||
| 				spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned", | ||||
| 						this, j, i); | ||||
| 			} | ||||
|  | @ -1164,8 +1165,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; info && i < info->n_items; i++) { | ||||
| 		const char *k = info->items[i].key; | ||||
|  |  | |||
|  | @ -56,6 +56,8 @@ void volume_##name##_##arch(struct volume *vol,		\ | |||
| 		const void * SPA_RESTRICT src,		\ | ||||
| 		float volume, uint32_t n_samples); | ||||
| 
 | ||||
| #define VOLUME_OPS_MAX_ALIGN	16 | ||||
| 
 | ||||
| DEFINE_FUNCTION(f32, c); | ||||
| 
 | ||||
| #if defined (HAVE_SSE) | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audiomixer"); | |||
| #define MAX_BUFFERS     64 | ||||
| #define MAX_PORTS       128 | ||||
| #define MAX_CHANNELS    64 | ||||
| #define MAX_ALIGN	MIX_OPS_MAX_ALIGN | ||||
| 
 | ||||
| #define PORT_DEFAULT_VOLUME	1.0 | ||||
| #define PORT_DEFAULT_MUTE	false | ||||
|  | @ -103,6 +104,7 @@ struct impl { | |||
| 	struct spa_log *log; | ||||
| 	struct spa_cpu *cpu; | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| 	uint32_t quantum_limit; | ||||
| 
 | ||||
| 	struct mix_ops ops; | ||||
|  | @ -658,7 +660,7 @@ impl_node_port_use_buffers(void *object, | |||
| 				      buffers[i]); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 		if (!SPA_IS_ALIGNED(d[0].data, 16)) { | ||||
| 		if (!SPA_IS_ALIGNED(d[0].data, this->max_align)) { | ||||
| 			spa_log_warn(this->log, "%p: memory on buffer %d not aligned", this, i); | ||||
| 		} | ||||
| 		if (direction == SPA_DIRECTION_OUTPUT) | ||||
|  | @ -888,8 +890,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; info && i < info->n_items; i++) { | ||||
| 		const char *k = info->items[i].key; | ||||
|  |  | |||
|  | @ -125,6 +125,8 @@ void mix_##name##_##arch(struct mix_ops *ops, void * SPA_RESTRICT dst,	\ | |||
| 		const void * SPA_RESTRICT src[], uint32_t n_src,		\ | ||||
| 		uint32_t n_samples)						\ | ||||
| 
 | ||||
| #define MIX_OPS_MAX_ALIGN	32 | ||||
| 
 | ||||
| DEFINE_FUNCTION(s8, c); | ||||
| DEFINE_FUNCTION(u8, c); | ||||
| DEFINE_FUNCTION(s16, c); | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.mixer-dsp"); | |||
| 
 | ||||
| #define MAX_BUFFERS	64 | ||||
| #define MAX_PORTS	128 | ||||
| #define MAX_ALIGN	64 | ||||
| #define MAX_ALIGN	MIX_OPS_MAX_ALIGN | ||||
| 
 | ||||
| #define PORT_DEFAULT_VOLUME	1.0 | ||||
| #define PORT_DEFAULT_MUTE	false | ||||
|  | @ -103,6 +103,7 @@ struct impl { | |||
| 	struct spa_log *log; | ||||
| 	struct spa_cpu *cpu; | ||||
| 	uint32_t cpu_flags; | ||||
| 	uint32_t max_align; | ||||
| 
 | ||||
| 	uint32_t quantum_limit; | ||||
| 
 | ||||
|  | @ -604,7 +605,7 @@ impl_node_port_use_buffers(void *object, | |||
| 			spa_log_error(this->log, "%p: invalid memory on buffer %d", this, i); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 		if (!SPA_IS_ALIGNED(d[0].data, 32)) { | ||||
| 		if (!SPA_IS_ALIGNED(d[0].data, this->max_align)) { | ||||
| 			spa_log_warn(this->log, "%p: memory on buffer %d not aligned", this, i); | ||||
| 		} | ||||
| 		if (direction == SPA_DIRECTION_OUTPUT) | ||||
|  | @ -831,8 +832,10 @@ impl_init(const struct spa_handle_factory *factory, | |||
| 	spa_log_topic_init(this->log, log_topic); | ||||
| 
 | ||||
| 	this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); | ||||
| 	if (this->cpu) | ||||
| 	if (this->cpu) { | ||||
| 		this->cpu_flags = spa_cpu_get_flags(this->cpu); | ||||
| 		this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; info && i < info->n_items; i++) { | ||||
| 		const char *k = info->items[i].key; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wim Taymans
						Wim Taymans