Compare commits
4 commits
cmake_test
...
master
Author | SHA1 | Date | |
---|---|---|---|
f6310cdc91 | |||
516ecb4121 | |||
0bcb73c48d | |||
19e048b56a |
7 changed files with 135 additions and 87 deletions
21
.drone.yml
21
.drone.yml
|
@ -1,21 +0,0 @@
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: default
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: archlinux:latest
|
|
||||||
commands:
|
|
||||||
- pacman -Syu --noconfirm --needed base-devel libvncserver libxkbcommon libdrm libva git cmake clang
|
|
||||||
- export CFLAGS="-pipe -fno-plt -fexceptions -fstack-clash-protection -fcf-protection -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security"
|
|
||||||
- CC=gcc cmake -B gcc-out
|
|
||||||
- cmake --build gcc-out
|
|
||||||
- CC=clang cmake -B clang-out
|
|
||||||
- cmake --build clang-out
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- dev
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
27
.forgejo/workflows/default.yml
Normal file
27
.forgejo/workflows/default.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
name: Build with gcc + clang
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
if: "github.event_name != 'push' || !contains(github.event.head_commit.message, '[skip ci]')"
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: archlinux:latest
|
||||||
|
env:
|
||||||
|
CFLAGS: "-pipe -fno-plt -fexceptions -fstack-clash-protection -fcf-protection -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security"
|
||||||
|
steps:
|
||||||
|
- name: Prepare dependencies
|
||||||
|
run: |
|
||||||
|
pacman -Syu --noconfirm --needed nodejs git \
|
||||||
|
base-devel libvncserver libxkbcommon libdrm libva cmake clang
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Build with gcc
|
||||||
|
run: |
|
||||||
|
CC=gcc cmake -B gcc-out
|
||||||
|
cmake --build gcc-out
|
||||||
|
- name: Build with clang
|
||||||
|
run: |
|
||||||
|
CC=clang cmake -B clang-out
|
||||||
|
cmake --build clang-out
|
|
@ -13,13 +13,37 @@ pkg_search_module(XKBCOMMON REQUIRED xkbcommon)
|
||||||
pkg_search_module(LIBVA REQUIRED libva)
|
pkg_search_module(LIBVA REQUIRED libva)
|
||||||
pkg_search_module(LIBVA_DRM REQUIRED libva-drm)
|
pkg_search_module(LIBVA_DRM REQUIRED libva-drm)
|
||||||
|
|
||||||
|
add_executable(kmsvnc)
|
||||||
|
set(kmsvnc_SOURCES kmsvnc.c drm.c input.c keymap.c va.c drm_master.c)
|
||||||
|
|
||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
CHECK_INCLUDE_FILES("linux/uinput.h;linux/dma-buf.h" HAVE_LINUX_API_HEADERS)
|
CHECK_INCLUDE_FILES("linux/uinput.h;linux/dma-buf.h" HAVE_LINUX_API_HEADERS)
|
||||||
IF(NOT HAVE_LINUX_API_HEADERS)
|
IF(NOT HAVE_LINUX_API_HEADERS)
|
||||||
message(FATAL_ERROR "linux-api-headers not found")
|
message(FATAL_ERROR "linux-api-headers not found")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
add_executable(kmsvnc kmsvnc.c drm.c input.c keymap.c va.c drm_master.c)
|
include(CheckSymbolExists)
|
||||||
|
check_symbol_exists(SYS_pidfd_getfd "sys/syscall.h" HAVE_LIBC_SYS_pidfd_getfd)
|
||||||
|
IF(NOT HAVE_LIBC_SYS_pidfd_getfd)
|
||||||
|
message(WARNING "pidfd_getfd syscall not found, the --screen-blank options will be disabled")
|
||||||
|
target_compile_options(kmsvnc PUBLIC -DDISABLE_KMSVNC_SCREEN_BLANK)
|
||||||
|
list(REMOVE_ITEM kmsvnc_SOURCES drm_master.c)
|
||||||
|
ENDIF()
|
||||||
|
include(CMakePushCheckState)
|
||||||
|
cmake_push_check_state()
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${LIBDRM_INCLUDEDIR}/libdrm) # can't do anything about that
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${LIBDRM_LIBRARIES})
|
||||||
|
check_symbol_exists(drmGetFormatName "xf86drm.h" HAVE_LIBDRM_drmGetFormatName)
|
||||||
|
cmake_pop_check_state()
|
||||||
|
IF(NOT HAVE_LIBDRM_drmGetFormatName)
|
||||||
|
message(WARNING "drmGetFormatName not found, format name printing will be disabled")
|
||||||
|
target_compile_options(kmsvnc PUBLIC -DDISABLE_KMSVNC_drmGetFormatName)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
target_sources(kmsvnc PUBLIC
|
||||||
|
${kmsvnc_SOURCES}
|
||||||
|
)
|
||||||
target_include_directories(kmsvnc PUBLIC
|
target_include_directories(kmsvnc PUBLIC
|
||||||
${LIBDRM_INCLUDEDIR}
|
${LIBDRM_INCLUDEDIR}
|
||||||
${LIBDRM_INCLUDEDIR}/libdrm
|
${LIBDRM_INCLUDEDIR}/libdrm
|
||||||
|
|
40
drm.c
40
drm.c
|
@ -10,7 +10,25 @@
|
||||||
|
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "va.h"
|
#include "va.h"
|
||||||
#include "drm_master.h"
|
|
||||||
|
#ifndef DISABLE_KMSVNC_SCREEN_BLANK
|
||||||
|
#include "drm_master.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fourcc_mod_is_vendor
|
||||||
|
#define fourcc_mod_is_vendor(modifier, vendor) \
|
||||||
|
(fourcc_mod_get_vendor(modifier) == DRM_FORMAT_MOD_VENDOR_## vendor)
|
||||||
|
#endif
|
||||||
|
#ifdef DISABLE_KMSVNC_drmGetFormatName
|
||||||
|
static char* drmGetFormatName(uint32_t data) {
|
||||||
|
char *name = "missing drmGetFormatName";
|
||||||
|
char *out = malloc(strlen(name)+1);
|
||||||
|
if (out) {
|
||||||
|
memcpy(out, name, strlen(name)+1);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern struct kmsvnc_data *kmsvnc;
|
extern struct kmsvnc_data *kmsvnc;
|
||||||
|
|
||||||
|
@ -103,18 +121,8 @@ void convert_intel_x_tiled_kmsbuf(const char *in, int width, int height, char *b
|
||||||
static void convert_vaapi(const char *in, int width, int height, char *buff) {
|
static void convert_vaapi(const char *in, int width, int height, char *buff) {
|
||||||
va_hwframe_to_vaapi(buff);
|
va_hwframe_to_vaapi(buff);
|
||||||
if (
|
if (
|
||||||
!kmsvnc->va->selected_fmt->byte_order &&
|
|
||||||
(KMSVNC_FOURCC_TO_INT('R','G','B',0) & kmsvnc->va->selected_fmt->fourcc) == KMSVNC_FOURCC_TO_INT('R','G','B',0)
|
(KMSVNC_FOURCC_TO_INT('R','G','B',0) & kmsvnc->va->selected_fmt->fourcc) == KMSVNC_FOURCC_TO_INT('R','G','B',0)
|
||||||
) {}
|
) {}
|
||||||
else if (
|
|
||||||
kmsvnc->va->selected_fmt->byte_order &&
|
|
||||||
(KMSVNC_FOURCC_TO_INT(0,'B','G','R') & kmsvnc->va->selected_fmt->fourcc) == KMSVNC_FOURCC_TO_INT(0,'B','G','R')
|
|
||||||
) {
|
|
||||||
for (int i = 0; i < width * height * BYTES_PER_PIXEL; i += BYTES_PER_PIXEL) {
|
|
||||||
uint32_t *pixdata = (uint32_t*)(buff + i);
|
|
||||||
*pixdata = __builtin_bswap32(*pixdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// is 30 depth?
|
// is 30 depth?
|
||||||
if (kmsvnc->va->selected_fmt->depth == 30) {
|
if (kmsvnc->va->selected_fmt->depth == 30) {
|
||||||
|
@ -127,8 +135,8 @@ static void convert_vaapi(const char *in, int width, int height, char *buff) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// handle ihd and mesa byte order quirk
|
// actually, does anyone use this?
|
||||||
if (kmsvnc->va->selected_fmt->byte_order) {
|
if (!kmsvnc->va->selected_fmt->byte_order) {
|
||||||
for (int i = 0; i < width * height * BYTES_PER_PIXEL; i += BYTES_PER_PIXEL) {
|
for (int i = 0; i < width * height * BYTES_PER_PIXEL; i += BYTES_PER_PIXEL) {
|
||||||
uint32_t *pixdata = (uint32_t*)(buff + i);
|
uint32_t *pixdata = (uint32_t*)(buff + i);
|
||||||
*pixdata = __builtin_bswap32(*pixdata);
|
*pixdata = __builtin_bswap32(*pixdata);
|
||||||
|
@ -175,6 +183,7 @@ void drm_sync_noop(int drmfd)
|
||||||
|
|
||||||
void drm_cleanup() {
|
void drm_cleanup() {
|
||||||
if (kmsvnc->drm) {
|
if (kmsvnc->drm) {
|
||||||
|
#ifndef DISABLE_KMSVNC_SCREEN_BLANK
|
||||||
if (kmsvnc->drm->gamma && kmsvnc->drm->gamma->size && kmsvnc->drm->gamma->red && kmsvnc->drm->gamma->green && kmsvnc->drm->gamma->blue) {
|
if (kmsvnc->drm->gamma && kmsvnc->drm->gamma->size && kmsvnc->drm->gamma->red && kmsvnc->drm->gamma->green && kmsvnc->drm->gamma->blue) {
|
||||||
if (drmModeCrtcSetGamma(kmsvnc->drm->drm_master_fd ?: kmsvnc->drm->drm_fd, kmsvnc->drm->plane->crtc_id, kmsvnc->drm->gamma->size, kmsvnc->drm->gamma->red, kmsvnc->drm->gamma->green, kmsvnc->drm->gamma->blue)) perror("Failed to restore gamma");
|
if (drmModeCrtcSetGamma(kmsvnc->drm->drm_master_fd ?: kmsvnc->drm->drm_fd, kmsvnc->drm->plane->crtc_id, kmsvnc->drm->gamma->size, kmsvnc->drm->gamma->red, kmsvnc->drm->gamma->green, kmsvnc->drm->gamma->blue)) perror("Failed to restore gamma");
|
||||||
}
|
}
|
||||||
|
@ -186,6 +195,7 @@ void drm_cleanup() {
|
||||||
free(kmsvnc->drm->gamma);
|
free(kmsvnc->drm->gamma);
|
||||||
kmsvnc->drm->gamma = NULL;
|
kmsvnc->drm->gamma = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (kmsvnc->drm->drm_ver) {
|
if (kmsvnc->drm->drm_ver) {
|
||||||
drmFreeVersion(kmsvnc->drm->drm_ver);
|
drmFreeVersion(kmsvnc->drm->drm_ver);
|
||||||
kmsvnc->drm->drm_ver = NULL;
|
kmsvnc->drm->drm_ver = NULL;
|
||||||
|
@ -497,6 +507,7 @@ int drm_open() {
|
||||||
if (!kmsvnc->screen_blank && drmIsMaster(drm->drm_fd)) {
|
if (!kmsvnc->screen_blank && drmIsMaster(drm->drm_fd)) {
|
||||||
if (drmDropMaster(drm->drm_fd)) fprintf(stderr, "Failed to drop master");
|
if (drmDropMaster(drm->drm_fd)) fprintf(stderr, "Failed to drop master");
|
||||||
}
|
}
|
||||||
|
#ifndef DISABLE_KMSVNC_SCREEN_BLANK
|
||||||
if (kmsvnc->screen_blank && !drmIsMaster(drm->drm_fd)) {
|
if (kmsvnc->screen_blank && !drmIsMaster(drm->drm_fd)) {
|
||||||
drm->drm_master_fd = drm_get_master_fd();
|
drm->drm_master_fd = drm_get_master_fd();
|
||||||
drm->drm_master_fd = drm->drm_master_fd > 0 ? drm->drm_master_fd : 0;
|
drm->drm_master_fd = drm->drm_master_fd > 0 ? drm->drm_master_fd : 0;
|
||||||
|
@ -504,6 +515,7 @@ int drm_open() {
|
||||||
fprintf(stderr, "not master client, master fd %d\n", drm->drm_master_fd);
|
fprintf(stderr, "not master client, master fd %d\n", drm->drm_master_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
drm->drm_ver = drmGetVersion(drm->drm_fd);
|
drm->drm_ver = drmGetVersion(drm->drm_fd);
|
||||||
printf("drm driver is %s\n", drm->drm_ver->name);
|
printf("drm driver is %s\n", drm->drm_ver->name);
|
||||||
|
@ -516,6 +528,7 @@ int drm_open() {
|
||||||
|
|
||||||
if (drm_refresh_planes(1)) return 1;
|
if (drm_refresh_planes(1)) return 1;
|
||||||
|
|
||||||
|
#ifndef DISABLE_KMSVNC_SCREEN_BLANK
|
||||||
if (kmsvnc->screen_blank) {
|
if (kmsvnc->screen_blank) {
|
||||||
drm->gamma = malloc(sizeof(struct kmsvnc_drm_gamma_data));
|
drm->gamma = malloc(sizeof(struct kmsvnc_drm_gamma_data));
|
||||||
if (!drm->gamma) KMSVNC_FATAL("memory allocation error at %s:%d\n", __FILE__, __LINE__);
|
if (!drm->gamma) KMSVNC_FATAL("memory allocation error at %s:%d\n", __FILE__, __LINE__);
|
||||||
|
@ -575,6 +588,7 @@ int drm_open() {
|
||||||
target_crtc = NULL;
|
target_crtc = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
drm->mfb = drmModeGetFB2(drm->drm_fd, drm->plane->fb_id);
|
drm->mfb = drmModeGetFB2(drm->drm_fd, drm->plane->fb_id);
|
||||||
if (!drm->mfb) {
|
if (!drm->mfb) {
|
||||||
|
|
26
kmsvnc.c
26
kmsvnc.c
|
@ -6,6 +6,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
@ -222,7 +223,7 @@ void signal_handler(int signum){
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct argp_option kmsvnc_main_options[] = {
|
static struct argp_option kmsvnc_main_options[] = {
|
||||||
{"device", 'd', "/dev/dri/card0", 0, "DRM device"},
|
{"device", 'd', "/dev/dri/cardX", 0, "DRM device"},
|
||||||
{"source-plane", 0xfefc, "0", 0, "Use specific plane"},
|
{"source-plane", 0xfefc, "0", 0, "Use specific plane"},
|
||||||
{"source-crtc", 0xfefd, "0", 0, "Use specific crtc (to list all crtcs and planes, set this to -1)"},
|
{"source-crtc", 0xfefd, "0", 0, "Use specific crtc (to list all crtcs and planes, set this to -1)"},
|
||||||
{"force-driver", 0xfefe, "i915", 0, "force a certain driver (for debugging)"},
|
{"force-driver", 0xfefe, "i915", 0, "force a certain driver (for debugging)"},
|
||||||
|
@ -241,8 +242,11 @@ static struct argp_option kmsvnc_main_options[] = {
|
||||||
{"input-height", 0xff07, "0", 0, "Explicitly set input height"},
|
{"input-height", 0xff07, "0", 0, "Explicitly set input height"},
|
||||||
{"input-offx", 0xff08, "0", 0, "Set input offset of x axis on a multi display system"},
|
{"input-offx", 0xff08, "0", 0, "Set input offset of x axis on a multi display system"},
|
||||||
{"input-offy", 0xff09, "0", 0, "Set input offset of y axis on a multi display system"},
|
{"input-offy", 0xff09, "0", 0, "Set input offset of y axis on a multi display system"},
|
||||||
|
#ifndef DISABLE_KMSVNC_SCREEN_BLANK
|
||||||
{"screen-blank", 0xff0a, 0, OPTION_ARG_OPTIONAL, "Blank screen with gamma set on crtc"},
|
{"screen-blank", 0xff0a, 0, OPTION_ARG_OPTIONAL, "Blank screen with gamma set on crtc"},
|
||||||
{"screen-blank-restore-linear", 0xff0b, 0, OPTION_ARG_OPTIONAL, "Restore linear values on exit in case of messed up gamma"},
|
{"screen-blank-restore-linear", 0xff0b, 0, OPTION_ARG_OPTIONAL, "Restore linear values on exit in case of messed up gamma"},
|
||||||
|
#endif
|
||||||
|
{"va-byteorder-swap", 0xff0c, 0, OPTION_ARG_OPTIONAL, "Force swap vaapi image rgb byteorder"},
|
||||||
{"wakeup", 'w', 0, OPTION_ARG_OPTIONAL, "Move mouse to wake the system up before start"},
|
{"wakeup", 'w', 0, OPTION_ARG_OPTIONAL, "Move mouse to wake the system up before start"},
|
||||||
{"disable-input", 'i', 0, OPTION_ARG_OPTIONAL, "Disable uinput"},
|
{"disable-input", 'i', 0, OPTION_ARG_OPTIONAL, "Disable uinput"},
|
||||||
{"desktop-name", 'n', "kmsvnc", 0, "Specify vnc desktop name"},
|
{"desktop-name", 'n', "kmsvnc", 0, "Specify vnc desktop name"},
|
||||||
|
@ -360,6 +364,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||||
case 0xff0b:
|
case 0xff0b:
|
||||||
kmsvnc->screen_blank_restore = 1;
|
kmsvnc->screen_blank_restore = 1;
|
||||||
break;
|
break;
|
||||||
|
case 0xff0c:
|
||||||
|
kmsvnc->va_byteorder_swap = 1;
|
||||||
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
kmsvnc->input_wakeup = 1;
|
kmsvnc->input_wakeup = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -392,7 +399,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
kmsvnc->vnc_opt = vncopt;
|
kmsvnc->vnc_opt = vncopt;
|
||||||
|
|
||||||
kmsvnc->card = "/dev/dri/card0";
|
#define DEVICE_EXAMPLE_MAX_SIZE 15
|
||||||
|
#define DEVICE_EXAMPLE_FALLBACK "/dev/dri/card0"
|
||||||
|
static char device_example[DEVICE_EXAMPLE_MAX_SIZE] = DEVICE_EXAMPLE_FALLBACK;
|
||||||
|
kmsvnc->card = device_example;
|
||||||
kmsvnc->va_derive_enabled = -1;
|
kmsvnc->va_derive_enabled = -1;
|
||||||
kmsvnc->vnc_opt->bind = &(struct in_addr){0};
|
kmsvnc->vnc_opt->bind = &(struct in_addr){0};
|
||||||
kmsvnc->vnc_opt->always_shared = 1;
|
kmsvnc->vnc_opt->always_shared = 1;
|
||||||
|
@ -406,6 +416,18 @@ int main(int argc, char **argv)
|
||||||
struct argp argp = {kmsvnc_main_options, parse_opt, args_doc, doc};
|
struct argp argp = {kmsvnc_main_options, parse_opt, args_doc, doc};
|
||||||
argp_parse(&argp, argc, argv, 0, 0, NULL);
|
argp_parse(&argp, argc, argv, 0, 0, NULL);
|
||||||
|
|
||||||
|
if (kmsvnc->card == device_example) {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
snprintf(kmsvnc->card, DEVICE_EXAMPLE_MAX_SIZE, "/dev/dri/card%d", i);
|
||||||
|
if (!access(kmsvnc->card, F_OK)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(kmsvnc->card, DEVICE_EXAMPLE_MAX_SIZE, DEVICE_EXAMPLE_FALLBACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!kmsvnc->disable_input) {
|
if (!kmsvnc->disable_input) {
|
||||||
const char* XKB_DEFAULT_LAYOUT = getenv("XKB_DEFAULT_LAYOUT");
|
const char* XKB_DEFAULT_LAYOUT = getenv("XKB_DEFAULT_LAYOUT");
|
||||||
if (!XKB_DEFAULT_LAYOUT || strcmp(XKB_DEFAULT_LAYOUT, "") == 0) {
|
if (!XKB_DEFAULT_LAYOUT || strcmp(XKB_DEFAULT_LAYOUT, "") == 0) {
|
||||||
|
|
2
kmsvnc.h
2
kmsvnc.h
|
@ -45,6 +45,7 @@ struct kmsvnc_data
|
||||||
int input_offy;
|
int input_offy;
|
||||||
char screen_blank;
|
char screen_blank;
|
||||||
char screen_blank_restore;
|
char screen_blank_restore;
|
||||||
|
char va_byteorder_swap;
|
||||||
struct kmsvnc_drm_data *drm;
|
struct kmsvnc_drm_data *drm;
|
||||||
struct kmsvnc_input_data *input;
|
struct kmsvnc_input_data *input;
|
||||||
struct kmsvnc_keymap_data *keymap;
|
struct kmsvnc_keymap_data *keymap;
|
||||||
|
@ -139,6 +140,7 @@ struct kmsvnc_va_data
|
||||||
VAImageFormat* img_fmts;
|
VAImageFormat* img_fmts;
|
||||||
int img_fmt_count;
|
int img_fmt_count;
|
||||||
VAImageFormat* selected_fmt;
|
VAImageFormat* selected_fmt;
|
||||||
|
const char *vendor_string;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KMSVNC_FATAL(...) do{ fprintf(stderr, __VA_ARGS__); return 1; } while(0)
|
#define KMSVNC_FATAL(...) do{ fprintf(stderr, __VA_ARGS__); return 1; } while(0)
|
||||||
|
|
80
va.c
80
va.c
|
@ -6,6 +6,7 @@
|
||||||
#include <va/va_drm.h>
|
#include <va/va_drm.h>
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "va.h"
|
#include "va.h"
|
||||||
#include "kmsvnc.h"
|
#include "kmsvnc.h"
|
||||||
|
@ -38,6 +39,9 @@ void va_cleanup() {
|
||||||
VA_MAY(vaTerminate(kmsvnc->va->dpy));
|
VA_MAY(vaTerminate(kmsvnc->va->dpy));
|
||||||
kmsvnc->va->dpy = NULL;
|
kmsvnc->va->dpy = NULL;
|
||||||
}
|
}
|
||||||
|
if (kmsvnc->va->vendor_string) {
|
||||||
|
kmsvnc->va->vendor_string = NULL;
|
||||||
|
}
|
||||||
free(kmsvnc->va);
|
free(kmsvnc->va);
|
||||||
kmsvnc->va = NULL;
|
kmsvnc->va = NULL;
|
||||||
}
|
}
|
||||||
|
@ -80,26 +84,17 @@ struct va_fmt_data {
|
||||||
char is_alpha;
|
char is_alpha;
|
||||||
uint32_t va_rt_format;
|
uint32_t va_rt_format;
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
uint32_t blue_mask;
|
|
||||||
uint32_t green_mask;
|
|
||||||
uint32_t red_mask;
|
|
||||||
uint32_t byte_order;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static VAImageFormat* vaImgFmt_from_vaFmtData(struct va_fmt_data* data) {
|
static VAImageFormat* vaImgFmt_apply_quirks(struct va_fmt_data* data) {
|
||||||
static VAImageFormat ret = {0};
|
static VAImageFormat ret = {0};
|
||||||
VAImageFormat fmt = {
|
memcpy(&ret, data->fmt, sizeof(VAImageFormat));
|
||||||
.fourcc = data->va_fourcc,
|
if ((kmsvnc->va_byteorder_swap ^ !strncmp(kmsvnc->va->vendor_string, "Mesa", 4)) && data->depth != 30) {
|
||||||
.byte_order = data->byte_order,
|
printf("applying rgb mask byte order swap\n");
|
||||||
.bits_per_pixel = 32,
|
ret.blue_mask = __builtin_bswap32(data->fmt->blue_mask);
|
||||||
.depth = data->depth,
|
ret.green_mask = __builtin_bswap32(data->fmt->green_mask);
|
||||||
.blue_mask = data->blue_mask,
|
ret.red_mask = __builtin_bswap32(data->fmt->red_mask);
|
||||||
.green_mask = data->green_mask,
|
}
|
||||||
.red_mask = data->red_mask,
|
|
||||||
.alpha_mask = 0,
|
|
||||||
.va_reserved = {0}
|
|
||||||
};
|
|
||||||
memcpy(&ret, &fmt, sizeof(VAImageFormat));
|
|
||||||
return &ret;
|
return &ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +121,7 @@ int va_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("DISPLAY", "", 1);
|
setenv("DISPLAY", "", 1);
|
||||||
|
setenv("WAYLAND_DISPLAY", "", 1);
|
||||||
|
|
||||||
struct kmsvnc_va_data *va = malloc(sizeof(struct kmsvnc_va_data));
|
struct kmsvnc_va_data *va = malloc(sizeof(struct kmsvnc_va_data));
|
||||||
if (!va) KMSVNC_FATAL("memory allocation error at %s:%d\n", __FILE__, __LINE__);
|
if (!va) KMSVNC_FATAL("memory allocation error at %s:%d\n", __FILE__, __LINE__);
|
||||||
|
@ -161,8 +157,8 @@ int va_init() {
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
VA_MUST(vaInitialize(va->dpy, &major, &minor));
|
VA_MUST(vaInitialize(va->dpy, &major, &minor));
|
||||||
|
|
||||||
const char *vendor_string = vaQueryVendorString(va->dpy);
|
va->vendor_string = vaQueryVendorString(va->dpy);
|
||||||
printf("vaapi vendor %s\n", vendor_string);
|
printf("vaapi vendor %s\n", va->vendor_string);
|
||||||
|
|
||||||
VADRMPRIMESurfaceDescriptor prime_desc;
|
VADRMPRIMESurfaceDescriptor prime_desc;
|
||||||
VASurfaceAttrib prime_attrs[2] = {
|
VASurfaceAttrib prime_attrs[2] = {
|
||||||
|
@ -291,45 +287,29 @@ int va_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct va_fmt_data format_to_try[] = {
|
struct va_fmt_data format_to_try[] = {
|
||||||
{KMSVNC_FOURCC_TO_INT('R','G','B','X'), NULL, 0, VA_RT_FORMAT_RGB32, 24, 0xff00, 0xff0000, 0xff000000, 0},
|
{KMSVNC_FOURCC_TO_INT('R','G','B','X'), NULL, 0, VA_RT_FORMAT_RGB32, 24},
|
||||||
{KMSVNC_FOURCC_TO_INT('R','G','B','A'), NULL, 1, VA_RT_FORMAT_RGB32, 32, 0xff00, 0xff0000, 0xff000000, 0},
|
{KMSVNC_FOURCC_TO_INT('R','G','B','A'), NULL, 1, VA_RT_FORMAT_RGB32, 32},
|
||||||
|
|
||||||
{KMSVNC_FOURCC_TO_INT('X','B','G','R'), NULL, 0, VA_RT_FORMAT_RGB32, 24, 0xff0000, 0xff00, 0xff, 0},
|
{KMSVNC_FOURCC_TO_INT('X','B','G','R'), NULL, 0, VA_RT_FORMAT_RGB32, 24},
|
||||||
{KMSVNC_FOURCC_TO_INT('A','B','G','R'), NULL, 1, VA_RT_FORMAT_RGB32, 32, 0xff0000, 0xff00, 0xff, 0},
|
{KMSVNC_FOURCC_TO_INT('A','B','G','R'), NULL, 1, VA_RT_FORMAT_RGB32, 32},
|
||||||
|
|
||||||
{KMSVNC_FOURCC_TO_INT('X','R','G','B'), NULL, 0, VA_RT_FORMAT_RGB32, 24, 0xff, 0xff00, 0xff0000, 0},
|
{KMSVNC_FOURCC_TO_INT('X','R','G','B'), NULL, 0, VA_RT_FORMAT_RGB32, 24},
|
||||||
{KMSVNC_FOURCC_TO_INT('A','R','G','B'), NULL, 1, VA_RT_FORMAT_RGB32, 32, 0xff, 0xff00, 0xff0000, 0},
|
{KMSVNC_FOURCC_TO_INT('A','R','G','B'), NULL, 1, VA_RT_FORMAT_RGB32, 32},
|
||||||
|
|
||||||
{KMSVNC_FOURCC_TO_INT('B','G','R','X'), NULL, 0, VA_RT_FORMAT_RGB32, 24, 0xff000000, 0xff0000, 0xff00, 0},
|
{KMSVNC_FOURCC_TO_INT('B','G','R','X'), NULL, 0, VA_RT_FORMAT_RGB32, 24},
|
||||||
{KMSVNC_FOURCC_TO_INT('B','G','R','A'), NULL, 1, VA_RT_FORMAT_RGB32, 32, 0xff000000, 0xff0000, 0xff00, 0},
|
{KMSVNC_FOURCC_TO_INT('B','G','R','A'), NULL, 1, VA_RT_FORMAT_RGB32, 32},
|
||||||
|
|
||||||
|
|
||||||
{KMSVNC_FOURCC_TO_INT('X','R','3','0'), NULL, 0, VA_RT_FORMAT_RGB32_10, 30, 0x3ff, 0xffc00, 0x3ff00000, 0},
|
{KMSVNC_FOURCC_TO_INT('X','R','3','0'), NULL, 0, VA_RT_FORMAT_RGB32_10, 30},
|
||||||
{KMSVNC_FOURCC_TO_INT('A','R','3','0'), NULL, 1, VA_RT_FORMAT_RGB32_10, 30, 0x3ff, 0xffc00, 0x3ff00000, 0},
|
{KMSVNC_FOURCC_TO_INT('A','R','3','0'), NULL, 1, VA_RT_FORMAT_RGB32_10, 30},
|
||||||
{KMSVNC_FOURCC_TO_INT('X','B','3','0'), NULL, 0, VA_RT_FORMAT_RGB32_10, 30, 0x3ff00000, 0xffc00, 0x3ff, 0},
|
{KMSVNC_FOURCC_TO_INT('X','B','3','0'), NULL, 0, VA_RT_FORMAT_RGB32_10, 30},
|
||||||
{KMSVNC_FOURCC_TO_INT('A','B','3','0'), NULL, 1, VA_RT_FORMAT_RGB32_10, 30, 0x3ff00000, 0xffc00, 0x3ff, 0},
|
{KMSVNC_FOURCC_TO_INT('A','B','3','0'), NULL, 1, VA_RT_FORMAT_RGB32_10, 30},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < va->img_fmt_count; i++) {
|
for (int i = 0; i < va->img_fmt_count; i++) {
|
||||||
for (int j = 0; j < KMSVNC_ARRAY_ELEMENTS(format_to_try); j++) {
|
for (int j = 0; j < KMSVNC_ARRAY_ELEMENTS(format_to_try); j++) {
|
||||||
if (va->img_fmts[i].fourcc == format_to_try[j].va_fourcc) {
|
if (va->img_fmts[i].fourcc == format_to_try[j].va_fourcc) {
|
||||||
if (
|
format_to_try[j].fmt = va->img_fmts + i;
|
||||||
va->img_fmts[i].blue_mask == format_to_try[j].blue_mask &&
|
|
||||||
va->img_fmts[i].green_mask == format_to_try[j].green_mask &&
|
|
||||||
va->img_fmts[i].red_mask == format_to_try[j].red_mask
|
|
||||||
) {
|
|
||||||
format_to_try[j].fmt = va->img_fmts + i;
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
format_to_try[j].depth != 30 &&
|
|
||||||
va->img_fmts[i].blue_mask == __builtin_bswap32(format_to_try[j].blue_mask) &&
|
|
||||||
va->img_fmts[i].green_mask == __builtin_bswap32(format_to_try[j].green_mask) &&
|
|
||||||
va->img_fmts[i].red_mask == __builtin_bswap32(format_to_try[j].red_mask)
|
|
||||||
) {
|
|
||||||
// mesa quirk: mesa fourcc and pixel data is lsb_first for RGB32 formats, msb_first for RGB32_10 formats
|
|
||||||
format_to_try[j].byte_order = 1u;
|
|
||||||
format_to_try[j].fmt = va->img_fmts + i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +324,7 @@ int va_init() {
|
||||||
for (int i = 0; i < KMSVNC_ARRAY_ELEMENTS(format_to_try); i++) {
|
for (int i = 0; i < KMSVNC_ARRAY_ELEMENTS(format_to_try); i++) {
|
||||||
if (format_to_try[i].fmt == NULL) continue;
|
if (format_to_try[i].fmt == NULL) continue;
|
||||||
if (va->image->format.fourcc == format_to_try[i].fmt->fourcc) {
|
if (va->image->format.fourcc == format_to_try[i].fmt->fourcc) {
|
||||||
va->selected_fmt = vaImgFmt_from_vaFmtData(format_to_try + i);
|
va->selected_fmt = vaImgFmt_apply_quirks(format_to_try + i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,7 +369,7 @@ int va_init() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
va->selected_fmt = vaImgFmt_from_vaFmtData(format_to_try + i);
|
va->selected_fmt = vaImgFmt_apply_quirks(format_to_try + i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue