mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	vulkan: use images
The filter can now run shadertoy filters.
This commit is contained in:
		
							parent
							
								
									24fc972164
								
							
						
					
					
						commit
						b02ebec954
					
				
					 5 changed files with 102 additions and 63 deletions
				
			
		| 
						 | 
					@ -4,14 +4,7 @@
 | 
				
			||||||
#define WORKGROUP_SIZE 32
 | 
					#define WORKGROUP_SIZE 32
 | 
				
			||||||
layout (local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1 ) in;
 | 
					layout (local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1 ) in;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Pixel{
 | 
					layout(rgba32f, binding = 0) uniform image2D resultImage;
 | 
				
			||||||
  vec4 value;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
layout(std140, binding = 0) buffer buf
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
   Pixel imageData[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout( push_constant ) uniform Constants {
 | 
					layout( push_constant ) uniform Constants {
 | 
				
			||||||
  float time;
 | 
					  float time;
 | 
				
			||||||
| 
						 | 
					@ -42,8 +35,7 @@ void main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mainImage(outColor, coord);
 | 
						mainImage(outColor, coord);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	imageData[PushConstant.width * gl_GlobalInvocationID.y +
 | 
						imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), outColor);
 | 
				
			||||||
			gl_GlobalInvocationID.x].value = outColor;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#include "plasma-globe.comp"
 | 
					//#include "plasma-globe.comp"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,12 +91,7 @@ struct impl {
 | 
				
			||||||
	struct spa_hook_list hooks;
 | 
						struct spa_hook_list hooks;
 | 
				
			||||||
	struct spa_callbacks callbacks;
 | 
						struct spa_callbacks callbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool async;
 | 
					 | 
				
			||||||
	struct spa_source timer_source;
 | 
					 | 
				
			||||||
	struct itimerspec timerspec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool started;
 | 
						bool started;
 | 
				
			||||||
	uint64_t frame_count;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct vulkan_state state;
 | 
						struct vulkan_state state;
 | 
				
			||||||
	struct port port[2];
 | 
						struct port port[2];
 | 
				
			||||||
| 
						 | 
					@ -177,7 +172,7 @@ static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t i
 | 
				
			||||||
	struct buffer *b = &port->buffers[id];
 | 
						struct buffer *b = &port->buffers[id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) {
 | 
						if (SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) {
 | 
				
			||||||
		spa_log_info(this->log, NAME " %p: reuse buffer %d", this, id);
 | 
							spa_log_debug(this->log, NAME " %p: reuse buffer %d", this, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
 | 
							SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
 | 
				
			||||||
		spa_list_append(&port->empty, &b->link);
 | 
							spa_list_append(&port->empty, &b->link);
 | 
				
			||||||
| 
						 | 
					@ -196,7 +191,6 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
 | 
				
			||||||
		if (this->started)
 | 
							if (this->started)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this->frame_count = 0;
 | 
					 | 
				
			||||||
		this->started = true;
 | 
							this->started = true;
 | 
				
			||||||
		spa_vulkan_start(&this->state);
 | 
							spa_vulkan_start(&this->state);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -608,21 +602,31 @@ static int impl_node_process(void *object)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (spa_list_is_empty(&outport->empty)) {
 | 
						if (spa_list_is_empty(&outport->empty)) {
 | 
				
			||||||
		spa_log_error(this->log, NAME " %p: out of buffers", this);
 | 
							spa_log_debug(this->log, NAME " %p: out of buffers", this);
 | 
				
			||||||
		return -EPIPE;
 | 
							return -EPIPE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b = &inport->buffers[inio->buffer_id];
 | 
						b = &inport->buffers[inio->buffer_id];
 | 
				
			||||||
	this->state.streams[0].pending_buffer_id = b->id;
 | 
						this->state.streams[inport->stream_id].pending_buffer_id = b->id;
 | 
				
			||||||
 | 
						inio->status = SPA_STATUS_NEED_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b = spa_list_first(&outport->empty, struct buffer, link);
 | 
						b = spa_list_first(&outport->empty, struct buffer, link);
 | 
				
			||||||
	spa_list_remove(&b->link);
 | 
						spa_list_remove(&b->link);
 | 
				
			||||||
	this->state.streams[1].pending_buffer_id = b->id;
 | 
						SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
 | 
				
			||||||
 | 
						this->state.streams[outport->stream_id].pending_buffer_id = b->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->state.constants.time += 0.025;
 | 
				
			||||||
 | 
						this->state.constants.frame++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_log_debug(this->log, "filter into %d", b->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_vulkan_process(&this->state);
 | 
						spa_vulkan_process(&this->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->outbuf->datas[0].chunk->offset = 0;
 | 
				
			||||||
 | 
						b->outbuf->datas[0].chunk->size = b->outbuf->datas[0].maxsize;
 | 
				
			||||||
 | 
						b->outbuf->datas[0].chunk->stride = this->position->video.stride;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outio->buffer_id = b->id;
 | 
						outio->buffer_id = b->id;
 | 
				
			||||||
	outio->status = SPA_STATUS_HAVE_DATA;
 | 
						outio->status = SPA_STATUS_HAVE_DATA;
 | 
				
			||||||
	inio->status = SPA_STATUS_NEED_DATA;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA;
 | 
						return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -694,6 +698,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
						this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
				
			||||||
	this->state.log = this->log;
 | 
						this->state.log = this->log;
 | 
				
			||||||
 | 
						this->state.shaderName = "spa/plugins/vulkan/shaders/filter.spv";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_hook_list_init(&this->hooks);
 | 
						spa_hook_list_init(&this->hooks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -715,7 +720,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
	this->info.n_params = 2;
 | 
						this->info.n_params = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	port = &this->port[0];
 | 
						port = &this->port[0];
 | 
				
			||||||
	port->stream_id = 0;
 | 
						port->stream_id = 1;
 | 
				
			||||||
	port->direction = SPA_DIRECTION_INPUT;
 | 
						port->direction = SPA_DIRECTION_INPUT;
 | 
				
			||||||
	port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
						port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
				
			||||||
			SPA_PORT_CHANGE_MASK_PARAMS |
 | 
								SPA_PORT_CHANGE_MASK_PARAMS |
 | 
				
			||||||
| 
						 | 
					@ -729,13 +734,13 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
	port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
 | 
						port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
 | 
				
			||||||
	port->info.params = port->params;
 | 
						port->info.params = port->params;
 | 
				
			||||||
	port->info.n_params = 5;
 | 
						port->info.n_params = 5;
 | 
				
			||||||
	spa_vulkan_init_stream(&this->state, &this->state.streams[0],
 | 
						spa_vulkan_init_stream(&this->state, &this->state.streams[port->stream_id],
 | 
				
			||||||
			SPA_DIRECTION_INPUT, NULL);
 | 
								SPA_DIRECTION_INPUT, NULL);
 | 
				
			||||||
	spa_list_init(&port->empty);
 | 
						spa_list_init(&port->empty);
 | 
				
			||||||
	spa_list_init(&port->ready);
 | 
						spa_list_init(&port->ready);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	port = &this->port[1];
 | 
						port = &this->port[1];
 | 
				
			||||||
	port->stream_id = 1;
 | 
						port->stream_id = 0;
 | 
				
			||||||
	port->direction = SPA_DIRECTION_OUTPUT;
 | 
						port->direction = SPA_DIRECTION_OUTPUT;
 | 
				
			||||||
	port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
						port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
				
			||||||
			SPA_PORT_CHANGE_MASK_PARAMS |
 | 
								SPA_PORT_CHANGE_MASK_PARAMS |
 | 
				
			||||||
| 
						 | 
					@ -751,7 +756,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
	port->info.n_params = 5;
 | 
						port->info.n_params = 5;
 | 
				
			||||||
	spa_list_init(&port->empty);
 | 
						spa_list_init(&port->empty);
 | 
				
			||||||
	spa_list_init(&port->ready);
 | 
						spa_list_init(&port->ready);
 | 
				
			||||||
	spa_vulkan_init_stream(&this->state, &this->state.streams[1],
 | 
						spa_vulkan_init_stream(&this->state, &this->state.streams[port->stream_id],
 | 
				
			||||||
			SPA_DIRECTION_OUTPUT, NULL);
 | 
								SPA_DIRECTION_OUTPUT, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->state.n_streams = 2;
 | 
						this->state.n_streams = 2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -959,6 +959,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
	this->state.log = this->log;
 | 
						this->state.log = this->log;
 | 
				
			||||||
	spa_vulkan_init_stream(&this->state, &this->state.streams[0],
 | 
						spa_vulkan_init_stream(&this->state, &this->state.streams[0],
 | 
				
			||||||
			SPA_DIRECTION_OUTPUT, NULL);
 | 
								SPA_DIRECTION_OUTPUT, NULL);
 | 
				
			||||||
 | 
						this->state.shaderName = "spa/plugins/vulkan/shaders/main.spv";
 | 
				
			||||||
	this->state.n_streams = 1;
 | 
						this->state.n_streams = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <spa/utils/result.h>
 | 
					#include <spa/utils/result.h>
 | 
				
			||||||
 | 
					#include <spa/utils/string.h>
 | 
				
			||||||
#include <spa/support/log.h>
 | 
					#include <spa/support/log.h>
 | 
				
			||||||
#include <spa/debug/mem.h>
 | 
					#include <spa/debug/mem.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,10 +92,10 @@ static int vkresult_to_errno(VkResult result)
 | 
				
			||||||
#define VK_CHECK_RESULT(f)								\
 | 
					#define VK_CHECK_RESULT(f)								\
 | 
				
			||||||
{											\
 | 
					{											\
 | 
				
			||||||
	VkResult _result = (f);								\
 | 
						VkResult _result = (f);								\
 | 
				
			||||||
	int _res = -vkresult_to_errno(_result);						\
 | 
						int _r = -vkresult_to_errno(_result);						\
 | 
				
			||||||
	if (_result != VK_SUCCESS) {							\
 | 
						if (_result != VK_SUCCESS) {							\
 | 
				
			||||||
		spa_log_error(s->log, "error: %d (%s)", _result, spa_strerror(_res));	\
 | 
							spa_log_error(s->log, "error: %d (%d %s)", _result, _r, spa_strerror(_r));	\
 | 
				
			||||||
		return _res;								\
 | 
							return _r;								\
 | 
				
			||||||
	}										\
 | 
						}										\
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#define CHECK(f)									\
 | 
					#define CHECK(f)									\
 | 
				
			||||||
| 
						 | 
					@ -117,24 +118,32 @@ static int createInstance(struct vulkan_state *s)
 | 
				
			||||||
	static const char * const extensions[] = {
 | 
						static const char * const extensions[] = {
 | 
				
			||||||
		VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
 | 
							VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	static const char * const layers[] = {
 | 
						static const char * const checkLayers[] = {
 | 
				
			||||||
 | 
					#ifdef ENABLE_VALIDATION
 | 
				
			||||||
		"VK_LAYER_KHRONOS_validation",
 | 
							"VK_LAYER_KHRONOS_validation",
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							NULL
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	uint32_t i, layerCount;
 | 
						uint32_t i, j, layerCount, n_layers = 0;
 | 
				
			||||||
 | 
						const char *layers[1];
 | 
				
			||||||
	vkEnumerateInstanceLayerProperties(&layerCount, NULL);
 | 
						vkEnumerateInstanceLayerProperties(&layerCount, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkLayerProperties availableLayers[layerCount];
 | 
						VkLayerProperties availableLayers[layerCount];
 | 
				
			||||||
	vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
 | 
						vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < layerCount; i++)
 | 
						for (i = 0; i < layerCount; i++) {
 | 
				
			||||||
		spa_log_info(s->log, "%s", availableLayers[i].layerName);
 | 
							for (j = 0; j < SPA_N_ELEMENTS(checkLayers); j++) {
 | 
				
			||||||
 | 
								if (spa_streq(availableLayers[i].layerName, checkLayers[j]))
 | 
				
			||||||
 | 
									layers[n_layers++] = checkLayers[j];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const VkInstanceCreateInfo createInfo = {
 | 
						const VkInstanceCreateInfo createInfo = {
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
 | 
							.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
 | 
				
			||||||
		.pApplicationInfo = &applicationInfo,
 | 
							.pApplicationInfo = &applicationInfo,
 | 
				
			||||||
		.enabledExtensionCount = 1,
 | 
							.enabledExtensionCount = 1,
 | 
				
			||||||
		.ppEnabledExtensionNames = extensions,
 | 
							.ppEnabledExtensionNames = extensions,
 | 
				
			||||||
		.enabledLayerCount = 1,
 | 
							.enabledLayerCount = n_layers,
 | 
				
			||||||
		.ppEnabledLayerNames = layers,
 | 
							.ppEnabledLayerNames = layers,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,7 +248,7 @@ static int createDescriptors(struct vulkan_state *s)
 | 
				
			||||||
	uint32_t i;
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkDescriptorPoolSize descriptorPoolSize = {
 | 
						VkDescriptorPoolSize descriptorPoolSize = {
 | 
				
			||||||
		.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
 | 
							.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
 | 
				
			||||||
		.descriptorCount = s->n_streams,
 | 
							.descriptorCount = s->n_streams,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
 | 
						const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
 | 
				
			||||||
| 
						 | 
					@ -257,7 +266,7 @@ static int createDescriptors(struct vulkan_state *s)
 | 
				
			||||||
	for (i = 0; i < s->n_streams; i++) {
 | 
						for (i = 0; i < s->n_streams; i++) {
 | 
				
			||||||
		descriptorSetLayoutBinding[i] = (VkDescriptorSetLayoutBinding) {
 | 
							descriptorSetLayoutBinding[i] = (VkDescriptorSetLayoutBinding) {
 | 
				
			||||||
			.binding = i,
 | 
								.binding = i,
 | 
				
			||||||
			.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
 | 
								.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
 | 
				
			||||||
			.descriptorCount = 1,
 | 
								.descriptorCount = 1,
 | 
				
			||||||
			.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
 | 
								.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -281,13 +290,16 @@ static int createDescriptors(struct vulkan_state *s)
 | 
				
			||||||
	VK_CHECK_RESULT(vkAllocateDescriptorSets(s->device,
 | 
						VK_CHECK_RESULT(vkAllocateDescriptorSets(s->device,
 | 
				
			||||||
				&descriptorSetAllocateInfo,
 | 
									&descriptorSetAllocateInfo,
 | 
				
			||||||
				&s->descriptorSet));
 | 
									&s->descriptorSet));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int updateDescriptors(struct vulkan_state *s)
 | 
					static int updateDescriptors(struct vulkan_state *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i;
 | 
						uint32_t i;
 | 
				
			||||||
	VkDescriptorBufferInfo descriptorBufferInfo[s->n_streams];
 | 
						VkDescriptorImageInfo descriptorImageInfo[s->n_streams];
 | 
				
			||||||
	VkWriteDescriptorSet writeDescriptorSet[s->n_streams];
 | 
						VkWriteDescriptorSet writeDescriptorSet[s->n_streams];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < s->n_streams; i++) {
 | 
						for (i = 0; i < s->n_streams; i++) {
 | 
				
			||||||
| 
						 | 
					@ -301,18 +313,17 @@ static int updateDescriptors(struct vulkan_state *s)
 | 
				
			||||||
		p->busy_buffer_id = p->current_buffer_id;
 | 
							p->busy_buffer_id = p->current_buffer_id;
 | 
				
			||||||
		p->pending_buffer_id = SPA_ID_INVALID;
 | 
							p->pending_buffer_id = SPA_ID_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		descriptorBufferInfo[i] = (VkDescriptorBufferInfo) {
 | 
							descriptorImageInfo[i] = (VkDescriptorImageInfo) {
 | 
				
			||||||
			.buffer = p->buffers[p->current_buffer_id].buffer,
 | 
								.imageView = p->buffers[p->current_buffer_id].view,
 | 
				
			||||||
			.offset = 0,
 | 
								.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
				
			||||||
			.range = p->bufferSize,
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		writeDescriptorSet[i] = (VkWriteDescriptorSet) {
 | 
							writeDescriptorSet[i] = (VkWriteDescriptorSet) {
 | 
				
			||||||
			.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
								.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
 | 
				
			||||||
			.dstSet = s->descriptorSet,
 | 
								.dstSet = s->descriptorSet,
 | 
				
			||||||
			.dstBinding = i,
 | 
								.dstBinding = i,
 | 
				
			||||||
			.descriptorCount = 1,
 | 
								.descriptorCount = 1,
 | 
				
			||||||
			.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
 | 
								.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
 | 
				
			||||||
			.pBufferInfo = &descriptorBufferInfo[i],
 | 
								.pImageInfo = &descriptorImageInfo[i],
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	vkUpdateDescriptorSets(s->device, s->n_streams,
 | 
						vkUpdateDescriptorSets(s->device, s->n_streams,
 | 
				
			||||||
| 
						 | 
					@ -465,7 +476,8 @@ static void clear_buffers(struct vulkan_state *s, struct vulkan_stream *p)
 | 
				
			||||||
		if (p->buffers[i].fd != -1)
 | 
							if (p->buffers[i].fd != -1)
 | 
				
			||||||
			close(p->buffers[i].fd);
 | 
								close(p->buffers[i].fd);
 | 
				
			||||||
		vkFreeMemory(s->device, p->buffers[i].memory, NULL);
 | 
							vkFreeMemory(s->device, p->buffers[i].memory, NULL);
 | 
				
			||||||
		vkDestroyBuffer(s->device, p->buffers[i].buffer, NULL);
 | 
							vkDestroyImage(s->device, p->buffers[i].image, NULL);
 | 
				
			||||||
 | 
							vkDestroyImageView(s->device, p->buffers[i].view, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p->n_buffers = 0;
 | 
						p->n_buffers = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -487,30 +499,37 @@ int spa_vulkan_use_buffers(struct vulkan_state *s, struct vulkan_stream *p, uint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clear_buffers(s, p);
 | 
						clear_buffers(s, p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->bufferSize = s->constants.width * s->constants.height * sizeof(struct pixel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < n_buffers; i++) {
 | 
						for (i = 0; i < n_buffers; i++) {
 | 
				
			||||||
		VkExternalMemoryBufferCreateInfo extInfo;
 | 
							VkExternalMemoryImageCreateInfo extInfo;
 | 
				
			||||||
		VkBufferCreateInfo bufferCreateInfo = {
 | 
							VkImageCreateInfo imageCreateInfo = {
 | 
				
			||||||
			.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
								.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
 | 
				
			||||||
			.size = p->bufferSize,
 | 
								.imageType = VK_IMAGE_TYPE_2D,
 | 
				
			||||||
			.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
 | 
								.format = VK_FORMAT_R32G32B32A32_SFLOAT,
 | 
				
			||||||
 | 
								.extent.width = s->constants.width,
 | 
				
			||||||
 | 
								.extent.height = s->constants.height,
 | 
				
			||||||
 | 
								.extent.depth = 1,
 | 
				
			||||||
 | 
								.mipLevels = 1,
 | 
				
			||||||
 | 
								.arrayLayers = 1,
 | 
				
			||||||
 | 
								.samples = VK_SAMPLE_COUNT_1_BIT,
 | 
				
			||||||
 | 
								.tiling = VK_IMAGE_TILING_LINEAR,
 | 
				
			||||||
 | 
								.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
 | 
				
			||||||
			.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
								.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
				
			||||||
 | 
								.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		if (!(flags & SPA_NODE_BUFFERS_FLAG_ALLOC)) {
 | 
							if (!(flags & SPA_NODE_BUFFERS_FLAG_ALLOC)) {
 | 
				
			||||||
			extInfo = (VkExternalMemoryBufferCreateInfo) {
 | 
								extInfo = (VkExternalMemoryImageCreateInfo) {
 | 
				
			||||||
				.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
 | 
									.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
 | 
				
			||||||
				.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
 | 
									.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			bufferCreateInfo.pNext = &extInfo;
 | 
								imageCreateInfo.pNext = &extInfo;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VK_CHECK_RESULT(vkCreateBuffer(s->device,
 | 
							VK_CHECK_RESULT(vkCreateImage(s->device,
 | 
				
			||||||
					&bufferCreateInfo, NULL, &p->buffers[i].buffer));
 | 
										&imageCreateInfo, NULL, &p->buffers[i].image));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VkMemoryRequirements memoryRequirements;
 | 
							VkMemoryRequirements memoryRequirements;
 | 
				
			||||||
		vkGetBufferMemoryRequirements(s->device,
 | 
							vkGetImageMemoryRequirements(s->device,
 | 
				
			||||||
				p->buffers[i].buffer, &memoryRequirements);
 | 
									p->buffers[i].image, &memoryRequirements);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VkMemoryAllocateInfo allocateInfo = {
 | 
							VkMemoryAllocateInfo allocateInfo = {
 | 
				
			||||||
			.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
 | 
								.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
 | 
				
			||||||
| 
						 | 
					@ -534,12 +553,14 @@ int spa_vulkan_use_buffers(struct vulkan_state *s, struct vulkan_stream *p, uint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		        VK_CHECK_RESULT(vkGetMemoryFdKHR(s->device, &getFdInfo, &fd));
 | 
							        VK_CHECK_RESULT(vkGetMemoryFdKHR(s->device, &getFdInfo, &fd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								spa_log_info(s->log, "export DMABUF %zd", memoryRequirements.size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//			buffers[i]->datas[0].type = SPA_DATA_DmaBuf;
 | 
					//			buffers[i]->datas[0].type = SPA_DATA_DmaBuf;
 | 
				
			||||||
			buffers[i]->datas[0].type = SPA_DATA_MemFd;
 | 
								buffers[i]->datas[0].type = SPA_DATA_MemFd;
 | 
				
			||||||
			buffers[i]->datas[0].fd = fd;
 | 
								buffers[i]->datas[0].fd = fd;
 | 
				
			||||||
			buffers[i]->datas[0].flags = SPA_DATA_FLAG_READABLE;
 | 
								buffers[i]->datas[0].flags = SPA_DATA_FLAG_READABLE;
 | 
				
			||||||
			buffers[i]->datas[0].mapoffset = 0;
 | 
								buffers[i]->datas[0].mapoffset = 0;
 | 
				
			||||||
			buffers[i]->datas[0].maxsize = p->bufferSize;
 | 
								buffers[i]->datas[0].maxsize = memoryRequirements.size;
 | 
				
			||||||
			p->buffers[i].fd = fd;
 | 
								p->buffers[i].fd = fd;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			VkImportMemoryFdInfoKHR importInfo = {
 | 
								VkImportMemoryFdInfoKHR importInfo = {
 | 
				
			||||||
| 
						 | 
					@ -549,12 +570,30 @@ int spa_vulkan_use_buffers(struct vulkan_state *s, struct vulkan_stream *p, uint
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			allocateInfo.pNext = &importInfo;
 | 
								allocateInfo.pNext = &importInfo;
 | 
				
			||||||
			p->buffers[i].fd = -1;
 | 
								p->buffers[i].fd = -1;
 | 
				
			||||||
 | 
								spa_log_info(s->log, "import DMABUF");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			VK_CHECK_RESULT(vkAllocateMemory(s->device,
 | 
								VK_CHECK_RESULT(vkAllocateMemory(s->device,
 | 
				
			||||||
					&allocateInfo, NULL, &p->buffers[i].memory));
 | 
										&allocateInfo, NULL, &p->buffers[i].memory));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		VK_CHECK_RESULT(vkBindBufferMemory(s->device,
 | 
							VK_CHECK_RESULT(vkBindImageMemory(s->device,
 | 
				
			||||||
					p->buffers[i].buffer, p->buffers[i].memory, 0));
 | 
										p->buffers[i].image, p->buffers[i].memory, 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VkImageViewCreateInfo viewInfo = {
 | 
				
			||||||
 | 
								.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
 | 
				
			||||||
 | 
								.image = p->buffers[i].image,
 | 
				
			||||||
 | 
								.viewType = VK_IMAGE_VIEW_TYPE_2D,
 | 
				
			||||||
 | 
								.format = VK_FORMAT_R32G32B32A32_SFLOAT,
 | 
				
			||||||
 | 
								.components.r = VK_COMPONENT_SWIZZLE_R,
 | 
				
			||||||
 | 
								.components.g = VK_COMPONENT_SWIZZLE_G,
 | 
				
			||||||
 | 
								.components.b = VK_COMPONENT_SWIZZLE_B,
 | 
				
			||||||
 | 
								.components.a = VK_COMPONENT_SWIZZLE_A,
 | 
				
			||||||
 | 
								.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
				
			||||||
 | 
								.subresourceRange.levelCount = 1,
 | 
				
			||||||
 | 
								.subresourceRange.layerCount = 1,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VK_CHECK_RESULT(vkCreateImageView(s->device,
 | 
				
			||||||
 | 
										&viewInfo, NULL, &p->buffers[i].view));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	p->n_buffers = n_buffers;
 | 
						p->n_buffers = n_buffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -579,7 +618,7 @@ int spa_vulkan_prepare(struct vulkan_state *s)
 | 
				
			||||||
		CHECK(findPhysicalDevice(s));
 | 
							CHECK(findPhysicalDevice(s));
 | 
				
			||||||
		CHECK(createDevice(s));
 | 
							CHECK(createDevice(s));
 | 
				
			||||||
		CHECK(createDescriptors(s));
 | 
							CHECK(createDescriptors(s));
 | 
				
			||||||
		CHECK(createComputePipeline(s, "spa/plugins/vulkan/shaders/main.spv"));
 | 
							CHECK(createComputePipeline(s, s->shaderName));
 | 
				
			||||||
		CHECK(createCommandBuffer(s));
 | 
							CHECK(createCommandBuffer(s));
 | 
				
			||||||
		s->prepared = true;
 | 
							s->prepared = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -651,6 +690,7 @@ int spa_vulkan_process(struct vulkan_state *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CHECK(updateDescriptors(s));
 | 
						CHECK(updateDescriptors(s));
 | 
				
			||||||
	CHECK(runCommandBuffer(s));
 | 
						CHECK(runCommandBuffer(s));
 | 
				
			||||||
 | 
					        VK_CHECK_RESULT(vkDeviceWaitIdle(s->device));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,8 @@ struct push_constants {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct vulkan_buffer {
 | 
					struct vulkan_buffer {
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
	VkBuffer buffer;
 | 
						VkImage image;
 | 
				
			||||||
 | 
						VkImageView view;
 | 
				
			||||||
	VkDeviceMemory memory;
 | 
						VkDeviceMemory memory;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +33,6 @@ struct vulkan_stream {
 | 
				
			||||||
	uint32_t busy_buffer_id;
 | 
						uint32_t busy_buffer_id;
 | 
				
			||||||
	uint32_t ready_buffer_id;
 | 
						uint32_t ready_buffer_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t bufferSize;
 | 
					 | 
				
			||||||
	struct vulkan_buffer buffers[MAX_BUFFERS];
 | 
						struct vulkan_buffer buffers[MAX_BUFFERS];
 | 
				
			||||||
	uint32_t n_buffers;
 | 
						uint32_t n_buffers;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,7 @@ struct vulkan_state {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkPipeline pipeline;
 | 
						VkPipeline pipeline;
 | 
				
			||||||
	VkPipelineLayout pipelineLayout;
 | 
						VkPipelineLayout pipelineLayout;
 | 
				
			||||||
 | 
						const char *shaderName;
 | 
				
			||||||
	VkShaderModule computeShaderModule;
 | 
						VkShaderModule computeShaderModule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkCommandPool commandPool;
 | 
						VkCommandPool commandPool;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue