From 50b6435aa7e2202c61c11e3d529cd3fabe4d8e4e Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 27 Apr 2023 23:42:41 +0800 Subject: [PATCH] long way to go --- drm.c | 68 +++++++++++++++++++++++++++++--------------------------- drm.h | 2 ++ kmsvnc.h | 2 +- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/drm.c b/drm.c index 6d749e6..ced3b41 100644 --- a/drm.c +++ b/drm.c @@ -31,17 +31,17 @@ static char *kms_convert_buf = NULL; static size_t kms_convert_buf_len = 0; static char *kms_cpy_tmp_buf = NULL; static size_t kms_cpy_tmp_buf_len = 0; -static inline void convert_kmsbuf(const int XSTRIPE, const int YSTRIPE, const char *in, int width, int height, char *buff) +static inline void convert_x_tiled(const int tilex, const int tiley, const char *in, int width, int height, char *buff) { - if (width % XSTRIPE) + if (width % tilex) { return; } - if (height % YSTRIPE) + if (height % tiley) { - int sno = (width / XSTRIPE) + (height / YSTRIPE) * (width / XSTRIPE); - int ord = (width % XSTRIPE) + (height % YSTRIPE) * XSTRIPE; - int max_offset = sno * XSTRIPE * YSTRIPE + ord; + int sno = (width / tilex) + (height / tiley) * (width / tilex); + int ord = (width % tilex) + (height % tiley) * tilex; + int max_offset = sno * tilex * tiley + ord; if (kms_cpy_tmp_buf_len < max_offset * 4 + 4) { if (kms_cpy_tmp_buf) @@ -63,27 +63,22 @@ static inline void convert_kmsbuf(const int XSTRIPE, const int YSTRIPE, const ch { for (int x = 0; x < width; x++) { - int sno = (x / XSTRIPE) + (y / YSTRIPE) * (width / XSTRIPE); - int ord = (x % XSTRIPE) + (y % YSTRIPE) * XSTRIPE; - int offset = sno * XSTRIPE * YSTRIPE + ord; + int sno = (x / tilex) + (y / tiley) * (width / tilex); + int ord = (x % tilex) + (y % tiley) * tilex; + int offset = sno * tilex * tiley + ord; memcpy(kms_convert_buf + (x + y * width) * 4, in + offset * 4, 4); } } convert_bgrx_to_rgb(kms_convert_buf, width, height, buff); } -#define XSTRIPE_INTEL 128 -#define YSTRIPE_INTEL 8 -#define XSTRIPE_NVIDIA 16 -#define YSTRIPE_NVIDIA 128 - -void convert_nvidia_kmsbuf(const char *in, int width, int height, char *buff) +void convert_nvidia_x_tiled_kmsbuf(const char *in, int width, int height, char *buff) { - convert_kmsbuf(XSTRIPE_NVIDIA, YSTRIPE_NVIDIA, in, width, height, buff); + convert_x_tiled(16, 128, in, width, height, buff); } -void convert_intel_kmsbuf(const char *in, int width, int height, char *buff) +void convert_intel_x_tiled_kmsbuf(const char *in, int width, int height, char *buff) { - convert_kmsbuf(XSTRIPE_INTEL, YSTRIPE_INTEL, in, width, height, buff); + convert_x_tiled(128, 8, in, width, height, buff); } static inline void drm_sync(int drmfd, uint64_t flags) @@ -120,7 +115,7 @@ void drm_cleanup() { kmsvnc->drm->plane = NULL; } if (kmsvnc->drm->mfb) { - drmModeFreeFB(kmsvnc->drm->mfb); + drmModeFreeFB2(kmsvnc->drm->mfb); kmsvnc->drm->mfb = NULL; } if (kmsvnc->drm->mapped) { @@ -151,6 +146,8 @@ int drm_open() { DRM_FATAL("card %s open failed: %s\n", kmsvnc->card, strerror(errno)); } drm->drm_ver = drmGetVersion(drm->drm_fd); + printf("drm driver is %s\n", drm->drm_ver->name); + int err = drmSetClientCap(drm->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (err < 0) { @@ -204,27 +201,32 @@ int drm_open() { } uint32_t plane_id = drm->plane->plane_id; - drm->mfb = drmModeGetFB(drm->drm_fd, drm->plane->fb_id); - if (!drm->mfb) - { + + drm->mfb = drmModeGetFB2(drm->drm_fd, drm->plane->fb_id); + if (!drm->mfb) { DRM_FATAL("Failed to get framebuffer %u: %s\n", drm->plane->fb_id, strerror(errno)); } - printf("Template framebuffer is %u: %ux%u %ubpp %ub depth %u pitch\n", drm->mfb->fb_id, drm->mfb->width, drm->mfb->height, drm->mfb->bpp, drm->mfb->depth, drm->mfb->pitch); + printf("Template framebuffer is %u: %ux%u fourcc:%u mod:%u flags:%u\n", drm->mfb->fb_id, drm->mfb->width, drm->mfb->height, drm->mfb->pixel_format, drm->mfb->modifier, drm->mfb->flags); + printf("handles %u %u %u %u\n", drm->mfb->handles[0], drm->mfb->handles[1], drm->mfb->handles[2], drm->mfb->handles[3]); + printf("offsets %u %u %u %u\n", drm->mfb->offsets[0], drm->mfb->offsets[1], drm->mfb->offsets[2], drm->mfb->offsets[3]); + printf("pitches %u %u %u %u\n", drm->mfb->pitches[0], drm->mfb->pitches[1], drm->mfb->pitches[2], drm->mfb->pitches[3]); + printf("format %s, modifier %s:%s\n", drmGetFormatName(drm->mfb->pixel_format), drmGetFormatModifierVendor(drm->mfb->modifier), drmGetFormatModifierName(drm->mfb->modifier)); - if (drm->mfb->bpp != BYTES_PER_PIXEL * 8 || drm->mfb->depth != 24) + if ( + drm->mfb->pixel_format != KMSVNC_FOURCC_TO_INT('X', 'R', '2', '4') && + drm->mfb->pixel_format != KMSVNC_FOURCC_TO_INT('A', 'R', '2', '4') + ) { DRM_FATAL("Unsupported pixfmt\n"); } - if (!drm->mfb->handle) + if (!drm->mfb->handles[0]) { DRM_FATAL("No handle set on framebuffer: maybe you need some additional capabilities?\n"); } int ioctl_err = 0; - printf("drm driver is %s\n", drm->drm_ver->name); - drm->mmap_fd = drm->drm_fd; drm->mmap_size = drm->mfb->width * drm->mfb->height * BYTES_PER_PIXEL; drm->funcs = malloc(sizeof(struct kmsvnc_drm_funcs)); @@ -241,7 +243,7 @@ int drm_open() { static int drm_kmsbuf_prime() { struct kmsvnc_drm_data *drm = kmsvnc->drm; - int err = drmPrimeHandleToFD(drm->drm_fd, drm->mfb->handle, O_RDWR, &drm->prime_fd); + int err = drmPrimeHandleToFD(drm->drm_fd, drm->mfb->handles[0], O_RDWR, &drm->prime_fd); if (err < 0 || drm->prime_fd < 0) { DRM_FATAL("Failed to get PRIME fd from framebuffer handle"); @@ -256,7 +258,7 @@ static int drm_kmsbuf_dumb() { struct kmsvnc_drm_data *drm = kmsvnc->drm; struct drm_gem_flink flink; - flink.handle = drm->mfb->handle; + flink.handle = drm->mfb->handles[0]; DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink); struct drm_gem_open open_arg; @@ -287,13 +289,13 @@ int drm_vendors() { if (strcmp(driver_name, "i915") == 0) { - drm->funcs->convert = &convert_intel_kmsbuf; + drm->funcs->convert = &convert_intel_x_tiled_kmsbuf; if (drm_kmsbuf_prime()) return 1; } else if (strcmp(driver_name, "amdgpu") == 0) { struct drm_gem_flink flink; - flink.handle = drm->mfb->handle; + flink.handle = drm->mfb->handles[0]; DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink); struct drm_gem_open open_arg; @@ -311,7 +313,7 @@ int drm_vendors() { else if (strcmp(driver_name, "nvidia-drm") == 0) { // quirky and slow - drm->funcs->convert = &convert_nvidia_kmsbuf; + drm->funcs->convert = &convert_nvidia_x_tiled_kmsbuf; if (drm_kmsbuf_dumb()) return 1; } else if (strcmp(driver_name, "vmwgfx") == 0 || @@ -333,7 +335,7 @@ int drm_vendors() { else if (strcmp(driver_name, "test-i915-gem") == 0) { struct drm_gem_flink flink; - flink.handle = drm->mfb->handle; + flink.handle = drm->mfb->handles[0]; DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink); struct drm_gem_open open_arg; diff --git a/drm.h b/drm.h index f2b2bf9..12257a4 100644 --- a/drm.h +++ b/drm.h @@ -2,6 +2,8 @@ #include "kmsvnc.h" +#define KMSVNC_FOURCC_TO_INT(a,b,c,d) (((a) << 0) + ((b) << 8) + ((c) << 16) + ((d) << 24)) + #define DRM_FATAL(...) { fprintf(stderr, __VA_ARGS__); return 1; } #define DRM_IOCTL_MUST(...) { int e; if (e = drmIoctl(__VA_ARGS__)) DRM_FATAL("DRM ioctl error %d on line %d\n", e, __LINE__) } #define DRM_IOCTL_MAY(...) { int e; if (e = drmIoctl(__VA_ARGS__)) fprintf(stderr, "DRM ioctl error %d on line %d\n", e, __LINE__); } diff --git a/kmsvnc.h b/kmsvnc.h index 9f0263b..5ade530 100644 --- a/kmsvnc.h +++ b/kmsvnc.h @@ -77,7 +77,7 @@ struct kmsvnc_drm_data int source_crtc; drmModePlane *plane; drmModePlaneRes *plane_res; - drmModeFB *mfb; + drmModeFB2 *mfb; u_int32_t plane_id; int mmap_fd; size_t mmap_size;