mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -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