long way to go
This commit is contained in:
parent
c088426932
commit
50b6435aa7
3 changed files with 38 additions and 34 deletions
68
drm.c
68
drm.c
|
@ -31,17 +31,17 @@ static char *kms_convert_buf = NULL;
|
||||||
static size_t kms_convert_buf_len = 0;
|
static size_t kms_convert_buf_len = 0;
|
||||||
static char *kms_cpy_tmp_buf = NULL;
|
static char *kms_cpy_tmp_buf = NULL;
|
||||||
static size_t kms_cpy_tmp_buf_len = 0;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (height % YSTRIPE)
|
if (height % tiley)
|
||||||
{
|
{
|
||||||
int sno = (width / XSTRIPE) + (height / YSTRIPE) * (width / XSTRIPE);
|
int sno = (width / tilex) + (height / tiley) * (width / tilex);
|
||||||
int ord = (width % XSTRIPE) + (height % YSTRIPE) * XSTRIPE;
|
int ord = (width % tilex) + (height % tiley) * tilex;
|
||||||
int max_offset = sno * XSTRIPE * YSTRIPE + ord;
|
int max_offset = sno * tilex * tiley + ord;
|
||||||
if (kms_cpy_tmp_buf_len < max_offset * 4 + 4)
|
if (kms_cpy_tmp_buf_len < max_offset * 4 + 4)
|
||||||
{
|
{
|
||||||
if (kms_cpy_tmp_buf)
|
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++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
int sno = (x / XSTRIPE) + (y / YSTRIPE) * (width / XSTRIPE);
|
int sno = (x / tilex) + (y / tiley) * (width / tilex);
|
||||||
int ord = (x % XSTRIPE) + (y % YSTRIPE) * XSTRIPE;
|
int ord = (x % tilex) + (y % tiley) * tilex;
|
||||||
int offset = sno * XSTRIPE * YSTRIPE + ord;
|
int offset = sno * tilex * tiley + ord;
|
||||||
memcpy(kms_convert_buf + (x + y * width) * 4, in + offset * 4, 4);
|
memcpy(kms_convert_buf + (x + y * width) * 4, in + offset * 4, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
convert_bgrx_to_rgb(kms_convert_buf, width, height, buff);
|
convert_bgrx_to_rgb(kms_convert_buf, width, height, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XSTRIPE_INTEL 128
|
void convert_nvidia_x_tiled_kmsbuf(const char *in, int width, int height, char *buff)
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
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)
|
static inline void drm_sync(int drmfd, uint64_t flags)
|
||||||
|
@ -120,7 +115,7 @@ void drm_cleanup() {
|
||||||
kmsvnc->drm->plane = NULL;
|
kmsvnc->drm->plane = NULL;
|
||||||
}
|
}
|
||||||
if (kmsvnc->drm->mfb) {
|
if (kmsvnc->drm->mfb) {
|
||||||
drmModeFreeFB(kmsvnc->drm->mfb);
|
drmModeFreeFB2(kmsvnc->drm->mfb);
|
||||||
kmsvnc->drm->mfb = NULL;
|
kmsvnc->drm->mfb = NULL;
|
||||||
}
|
}
|
||||||
if (kmsvnc->drm->mapped) {
|
if (kmsvnc->drm->mapped) {
|
||||||
|
@ -151,6 +146,8 @@ int drm_open() {
|
||||||
DRM_FATAL("card %s open failed: %s\n", kmsvnc->card, strerror(errno));
|
DRM_FATAL("card %s open failed: %s\n", kmsvnc->card, strerror(errno));
|
||||||
}
|
}
|
||||||
drm->drm_ver = drmGetVersion(drm->drm_fd);
|
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);
|
int err = drmSetClientCap(drm->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
|
@ -204,27 +201,32 @@ int drm_open() {
|
||||||
}
|
}
|
||||||
uint32_t plane_id = drm->plane->plane_id;
|
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));
|
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");
|
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");
|
DRM_FATAL("No handle set on framebuffer: maybe you need some additional capabilities?\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ioctl_err = 0;
|
int ioctl_err = 0;
|
||||||
|
|
||||||
printf("drm driver is %s\n", drm->drm_ver->name);
|
|
||||||
|
|
||||||
drm->mmap_fd = drm->drm_fd;
|
drm->mmap_fd = drm->drm_fd;
|
||||||
drm->mmap_size = drm->mfb->width * drm->mfb->height * BYTES_PER_PIXEL;
|
drm->mmap_size = drm->mfb->width * drm->mfb->height * BYTES_PER_PIXEL;
|
||||||
drm->funcs = malloc(sizeof(struct kmsvnc_drm_funcs));
|
drm->funcs = malloc(sizeof(struct kmsvnc_drm_funcs));
|
||||||
|
@ -241,7 +243,7 @@ int drm_open() {
|
||||||
static int drm_kmsbuf_prime() {
|
static int drm_kmsbuf_prime() {
|
||||||
struct kmsvnc_drm_data *drm = kmsvnc->drm;
|
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)
|
if (err < 0 || drm->prime_fd < 0)
|
||||||
{
|
{
|
||||||
DRM_FATAL("Failed to get PRIME fd from framebuffer handle");
|
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 kmsvnc_drm_data *drm = kmsvnc->drm;
|
||||||
|
|
||||||
struct drm_gem_flink flink;
|
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);
|
DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||||
|
|
||||||
struct drm_gem_open open_arg;
|
struct drm_gem_open open_arg;
|
||||||
|
@ -287,13 +289,13 @@ int drm_vendors() {
|
||||||
|
|
||||||
if (strcmp(driver_name, "i915") == 0)
|
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;
|
if (drm_kmsbuf_prime()) return 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(driver_name, "amdgpu") == 0)
|
else if (strcmp(driver_name, "amdgpu") == 0)
|
||||||
{
|
{
|
||||||
struct drm_gem_flink flink;
|
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);
|
DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||||
|
|
||||||
struct drm_gem_open open_arg;
|
struct drm_gem_open open_arg;
|
||||||
|
@ -311,7 +313,7 @@ int drm_vendors() {
|
||||||
else if (strcmp(driver_name, "nvidia-drm") == 0)
|
else if (strcmp(driver_name, "nvidia-drm") == 0)
|
||||||
{
|
{
|
||||||
// quirky and slow
|
// quirky and slow
|
||||||
drm->funcs->convert = &convert_nvidia_kmsbuf;
|
drm->funcs->convert = &convert_nvidia_x_tiled_kmsbuf;
|
||||||
if (drm_kmsbuf_dumb()) return 1;
|
if (drm_kmsbuf_dumb()) return 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(driver_name, "vmwgfx") == 0 ||
|
else if (strcmp(driver_name, "vmwgfx") == 0 ||
|
||||||
|
@ -333,7 +335,7 @@ int drm_vendors() {
|
||||||
else if (strcmp(driver_name, "test-i915-gem") == 0)
|
else if (strcmp(driver_name, "test-i915-gem") == 0)
|
||||||
{
|
{
|
||||||
struct drm_gem_flink flink;
|
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);
|
DRM_IOCTL_MUST(drm->drm_fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||||
|
|
||||||
struct drm_gem_open open_arg;
|
struct drm_gem_open open_arg;
|
||||||
|
|
2
drm.h
2
drm.h
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "kmsvnc.h"
|
#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_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_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__); }
|
#define DRM_IOCTL_MAY(...) { int e; if (e = drmIoctl(__VA_ARGS__)) fprintf(stderr, "DRM ioctl error %d on line %d\n", e, __LINE__); }
|
||||||
|
|
2
kmsvnc.h
2
kmsvnc.h
|
@ -77,7 +77,7 @@ struct kmsvnc_drm_data
|
||||||
int source_crtc;
|
int source_crtc;
|
||||||
drmModePlane *plane;
|
drmModePlane *plane;
|
||||||
drmModePlaneRes *plane_res;
|
drmModePlaneRes *plane_res;
|
||||||
drmModeFB *mfb;
|
drmModeFB2 *mfb;
|
||||||
u_int32_t plane_id;
|
u_int32_t plane_id;
|
||||||
int mmap_fd;
|
int mmap_fd;
|
||||||
size_t mmap_size;
|
size_t mmap_size;
|
||||||
|
|
Loading…
Reference in a new issue