vulkan: Add pixel-formats to query format properties

We need a database of pixel format properties to remove hardcoded magic
numbers. This commit creates a simple function to query the bytes per
pixel for common RGBA formats.

This should be promoted to or superseeded by a common spa namespaced
version.
This commit is contained in:
columbarius 2023-09-24 00:09:14 +02:00 committed by Wim Taymans
parent 49b67742c6
commit c3327742cc
6 changed files with 57 additions and 3 deletions

View file

@ -1,5 +1,6 @@
spa_vulkan_sources = [ spa_vulkan_sources = [
'plugin.c', 'plugin.c',
'pixel-formats.c',
'vulkan-compute-filter.c', 'vulkan-compute-filter.c',
'vulkan-compute-source.c', 'vulkan-compute-source.c',
'vulkan-compute-utils.c', 'vulkan-compute-utils.c',

View file

@ -0,0 +1,33 @@
/* Spa */
/* SPDX-FileCopyrightText: Copyright © 2023 columbarius */
/* SPDX-License-Identifier: MIT */
#include "pixel-formats.h"
#include <spa/utils/defs.h>
#include <spa/param/video/raw.h>
struct pixel_info {
uint32_t format;
uint32_t bpp;
} pixel_infos[] = {
{ SPA_VIDEO_FORMAT_RGBA_F32, 16 },
{ SPA_VIDEO_FORMAT_BGRA, 4 },
{ SPA_VIDEO_FORMAT_RGBA, 4 },
{ SPA_VIDEO_FORMAT_BGRx, 4 },
{ SPA_VIDEO_FORMAT_RGBx, 4 },
{ SPA_VIDEO_FORMAT_BGR, 3 },
{ SPA_VIDEO_FORMAT_RGB, 3 },
};
bool get_pixel_format_info(uint32_t format, struct pixel_format_info *info)
{
struct pixel_info *p;
SPA_FOR_EACH_ELEMENT(pixel_infos, p) {
if (p->format != format)
continue;
info->bpp = p->bpp;
return true;
}
return false;
}

View file

@ -0,0 +1,12 @@
/* Spa */
/* SPDX-FileCopyrightText: Copyright © 2023 columbarius */
/* SPDX-License-Identifier: MIT */
#include <stdint.h>
#include <stdbool.h>
struct pixel_format_info {
uint32_t bpp; // bytes per pixel
};
bool get_pixel_format_info(uint32_t format, struct pixel_format_info *info);

View file

@ -28,6 +28,7 @@
#include "vulkan-compute-utils.h" #include "vulkan-compute-utils.h"
#include "vulkan-utils.h" #include "vulkan-utils.h"
#include "utils.h" #include "utils.h"
#include "pixel-formats.h"
#define VULKAN_INSTANCE_FUNCTION(name) \ #define VULKAN_INSTANCE_FUNCTION(name) \
PFN_##name name = (PFN_##name)vkGetInstanceProcAddr(s->base.instance, #name) PFN_##name name = (PFN_##name)vkGetInstanceProcAddr(s->base.instance, #name)
@ -247,13 +248,16 @@ static int runExportSHMBuffers(struct vulkan_compute_state *s) {
if (p->direction == SPA_DIRECTION_INPUT) if (p->direction == SPA_DIRECTION_INPUT)
continue; continue;
struct pixel_format_info pixel_info;
CHECK(get_pixel_format_info(p->format, &pixel_info));
if (p->spa_buffers[p->current_buffer_id]->datas[0].type == SPA_DATA_MemPtr) { if (p->spa_buffers[p->current_buffer_id]->datas[0].type == SPA_DATA_MemPtr) {
struct spa_buffer *spa_buf = p->spa_buffers[p->current_buffer_id]; struct spa_buffer *spa_buf = p->spa_buffers[p->current_buffer_id];
struct vulkan_read_pixels_info readInfo = { struct vulkan_read_pixels_info readInfo = {
.data = spa_buf->datas[0].data, .data = spa_buf->datas[0].data,
.offset = spa_buf->datas[0].chunk->offset, .offset = spa_buf->datas[0].chunk->offset,
.stride = spa_buf->datas[0].chunk->stride, .stride = spa_buf->datas[0].chunk->stride,
.bytes_per_pixel = 16, .bytes_per_pixel = pixel_info.bpp,
.size.width = s->constants.width, .size.width = s->constants.width,
.size.height = s->constants.height, .size.height = s->constants.height,
}; };
@ -479,6 +483,7 @@ int spa_vulkan_compute_use_buffers(struct vulkan_compute_state *s, struct vulkan
vulkan_wait_idle(&s->base); vulkan_wait_idle(&s->base);
clear_buffers(s, p); clear_buffers(s, p);
p->format = SPA_VIDEO_FORMAT_UNKNOWN;
bool alloc = flags & SPA_NODE_BUFFERS_FLAG_ALLOC; bool alloc = flags & SPA_NODE_BUFFERS_FLAG_ALLOC;
int ret; int ret;
@ -544,6 +549,7 @@ int spa_vulkan_compute_use_buffers(struct vulkan_compute_state *s, struct vulkan
p->spa_buffers[i] = buffers[i]; p->spa_buffers[i] = buffers[i];
p->n_buffers++; p->n_buffers++;
} }
p->format = dsp_info->format;
return 0; return 0;
} }

View file

@ -33,6 +33,8 @@ 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 format;
struct vulkan_buffer buffers[MAX_BUFFERS]; struct vulkan_buffer buffers[MAX_BUFFERS];
struct spa_buffer *spa_buffers[MAX_BUFFERS]; struct spa_buffer *spa_buffers[MAX_BUFFERS];
uint32_t n_buffers; uint32_t n_buffers;

View file

@ -248,13 +248,13 @@ int vulkan_read_pixels(struct vulkan_base *s, struct vulkan_read_pixels_info *in
const char *d = (const char *)v + img_sub_layout.offset; const char *d = (const char *)v + img_sub_layout.offset;
unsigned char *p = (unsigned char *)info->data + info->offset; unsigned char *p = (unsigned char *)info->data + info->offset;
uint32_t bytes_per_pixel = 16;
uint32_t pack_stride = img_sub_layout.rowPitch; uint32_t pack_stride = img_sub_layout.rowPitch;
spa_log_trace_fp(s->log, "Read pixels: %p to %p, stride: %d, width %d, height %d, offset %d, pack_stride %d", d, p, info->stride, info->size.width, info->size.height, info->offset, pack_stride);
if (pack_stride == info->stride) { if (pack_stride == info->stride) {
memcpy(p, d, info->stride * info->size.height); memcpy(p, d, info->stride * info->size.height);
} else { } else {
for (uint32_t i = 0; i < info->size.height; i++) { for (uint32_t i = 0; i < info->size.height; i++) {
memcpy(p + i * info->stride, d + i * pack_stride, info->size.width * bytes_per_pixel); memcpy(p + i * info->stride, d + i * pack_stride, info->size.width * info->bytes_per_pixel);
} }
} }
vkUnmapMemory(s->device, vk_buf->memory); vkUnmapMemory(s->device, vk_buf->memory);