nvidia
This commit is contained in:
parent
642b1f9903
commit
00d252c958
1 changed files with 49 additions and 8 deletions
57
server.c
57
server.c
|
@ -13,6 +13,17 @@
|
|||
#include <math.h>
|
||||
|
||||
|
||||
struct drm_nvidia_gem_map_offset_params {
|
||||
uint32_t handle; /* IN Handle to gem object */
|
||||
uint32_t __pad;
|
||||
|
||||
uint64_t offset; /* OUT Fake offset */
|
||||
};
|
||||
#define DRM_NVIDIA_GEM_MAP_OFFSET 0x0a
|
||||
#define DRM_IOCTL_NVIDIA_GEM_MAP_OFFSET \
|
||||
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GEM_MAP_OFFSET), \
|
||||
struct drm_nvidia_gem_map_offset_params)
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
/* 10 frames per second (if we can) */
|
||||
#define PICTURE_TIMEOUT (1.0/10.0)
|
||||
|
@ -55,6 +66,30 @@ static void convert_bgrx_to_rgb(const char* in, int width, int height, char* buf
|
|||
}
|
||||
}
|
||||
|
||||
#define XSTRIPE 16
|
||||
#define YSTRIPE 128
|
||||
char *nv_stripe_buf = NULL;
|
||||
static void convert_nv_stripe(const char* in, int width, int height, char* buff) {
|
||||
if (width % XSTRIPE) {
|
||||
return;
|
||||
}
|
||||
if (!nv_stripe_buf) nv_stripe_buf = malloc(width * height * 4);
|
||||
convert_bgrx_to_rgb(in, width, height, nv_stripe_buf);
|
||||
for (int i = 0; i < height*width; i++)
|
||||
{
|
||||
int sno = i / (XSTRIPE * YSTRIPE);
|
||||
int ord = i % (XSTRIPE * YSTRIPE);
|
||||
int base_x = sno % (width / XSTRIPE) * XSTRIPE;
|
||||
int base_y = sno / (width / XSTRIPE) * YSTRIPE;
|
||||
int sx = ord % XSTRIPE + base_x;
|
||||
int sy = ord / XSTRIPE + base_y;
|
||||
int offset = sy * width + sx;
|
||||
if (offset < height*width) {
|
||||
memcpy(buff + offset*4, nv_stripe_buf + i*4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct vnc_xkb {
|
||||
struct xkb_context *ctx;
|
||||
struct xkb_keymap *map;
|
||||
|
@ -258,6 +293,8 @@ static void rfb_ptr_hook(int mask, int screen_x, int screen_y, rfbClientPtr cl)
|
|||
}
|
||||
|
||||
|
||||
static void drm_wait_vblank_noop(int x) {
|
||||
}
|
||||
static void drm_wait_vblank(int drmfd) {
|
||||
int ioctl_err;
|
||||
union drm_wait_vblank vbl;
|
||||
|
@ -373,6 +410,8 @@ int main(int argc, const char **argv)
|
|||
size_t mmap_size = 0;
|
||||
printf("drm driver is %s\n", drm_ver->name);
|
||||
char *mapped = NULL;
|
||||
void (*convert_func)(const char*, int, int, char*) = &convert_bgrx_to_rgb;
|
||||
void (*vblank_func)(int) = &drm_wait_vblank;
|
||||
if (strcmp(drm_ver->name, "i915") == 0) {
|
||||
struct drm_i915_gem_mmap_gtt mmap_arg;
|
||||
mmap_arg.handle = open_arg.handle;
|
||||
|
@ -394,16 +433,18 @@ int main(int argc, const char **argv)
|
|||
mmap_size = open_arg.size;
|
||||
mmap_offset = mmap_arg.out.addr_ptr;
|
||||
}
|
||||
else if (strcmp(drm_ver->name, "nothing") == 0) {
|
||||
struct drm_mode_map_dumb mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.handle = open_arg.handle;
|
||||
if (ioctl_err = drmIoctl(drmfd, DRM_IOCTL_MODE_MAP_DUMB, &mreq)) {
|
||||
else if (strcmp(drm_ver->name, "nvidia-drm") == 0) {
|
||||
convert_func = &convert_nv_stripe;
|
||||
vblank_func = &drm_wait_vblank_noop;
|
||||
struct drm_nvidia_gem_map_offset_params mmap_arg;
|
||||
memset(&mmap_arg, 0, sizeof(mmap_arg));
|
||||
mmap_arg.handle = open_arg.handle;
|
||||
if (ioctl_err = drmIoctl(drmfd, DRM_IOCTL_NVIDIA_GEM_MAP_OFFSET, &mmap_arg)) {
|
||||
fprintf(stderr, "DRM ioctl error %d on line %d\n", ioctl_err, __LINE__);
|
||||
goto cleanup;
|
||||
}
|
||||
mmap_size = open_arg.size;
|
||||
mmap_offset = mreq.offset;
|
||||
mmap_offset = mmap_arg.offset;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unimplemented drm driver\n");
|
||||
|
@ -442,10 +483,10 @@ int main(int argc, const char **argv)
|
|||
long usec;
|
||||
while (rfbIsActive(server)) {
|
||||
if (server->clientHead && TimeToTakePicture()) {
|
||||
drm_wait_vblank(drmfd);
|
||||
vblank_func(drmfd);
|
||||
// still tearing
|
||||
memcpy(buf2, mapped, buflen);
|
||||
convert_bgrx_to_rgb(buf2, fb->width, fb->height, buf);
|
||||
convert_func(buf2, fb->width, fb->height, buf);
|
||||
rfbMarkRectAsModified(server, 0, 0, fb->width, fb->height);
|
||||
}
|
||||
usec = server->deferUpdateTime*1000;
|
||||
|
|
Loading…
Reference in a new issue