| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <xf86drm.h>
- #include <xf86drmMode.h>
- #include <drm_fourcc.h>
- int main(void) {
- int fd = open("/dev/dri/card0", O_RDWR);
- if (fd < 0) { perror("open"); return 1; }
- drmModeRes *res = drmModeGetResources(fd);
- if (!res) { perror("getResources"); return 1; }
- drmModeCrtc *crtc = NULL;
- uint32_t crtc_id = 0;
- for (int i = 0; i < res->count_crtcs; i++) {
- crtc = drmModeGetCrtc(fd, res->crtcs[i]);
- if (crtc && crtc->buffer_id) { crtc_id = crtc->crtc_id; break; }
- if (crtc) { drmModeFreeCrtc(crtc); crtc = NULL; }
- }
- if (!crtc || !crtc->buffer_id) {
- fprintf(stderr, "No active CRTC\n");
- drmModeFreeResources(res);
- return 1;
- }
- fprintf(stderr, "CRTC %u -> FB %u, %ux%u\n",
- crtc_id, crtc->buffer_id, crtc->width, crtc->height);
- drmModeFB2 *fb = drmModeGetFB2(fd, crtc->buffer_id);
- if (!fb) {
- fprintf(stderr, "drmModeGetFB2 failed, trying FB...\n");
- drmModeFB *fb1 = drmModeGetFB(fd, crtc->buffer_id);
- if (!fb1) { perror("getFB"); return 1; }
- fprintf(stderr, "FB: %ux%u pitch=%u handle=%u\n",
- fb1->width, fb1->height, fb1->pitch, fb1->handle);
- uint32_t size = fb1->pitch * fb1->height;
- void *map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
- if (map == MAP_FAILED) {
- struct drm_mode_map_dumb mreq = { .handle = fb1->handle };
- if (ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq)) { perror("map"); return 1; }
- map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, mreq.offset);
- if (map == MAP_FAILED) { perror("mmap2"); return 1; }
- }
- FILE *fp = fopen("/tmp/frame.bin", "wb");
- fwrite(map, 1, size, fp);
- fclose(fp);
- fprintf(stderr, "Dumped %u bytes to /tmp/frame.bin\n", size);
- munmap(map, size);
- drmModeFreeFB(fb1);
- drmModeFreeCrtc(crtc);
- drmModeFreeResources(res);
- return 0;
- }
- fprintf(stderr, "FB2: %ux%u format=0x%x\n", fb->width, fb->height, fb->pixel_format);
- for (int i = 0; i < 4; i++)
- fprintf(stderr, " plane[%d]: handle=%u pitch=%u offset=%u\n",
- i, fb->handles[i], fb->pitches[i], fb->offsets[i]);
- if (fb->handles[0] == 0) {
- fprintf(stderr, "No handle on plane 0\n");
- drmModeFreeFB2(fb); drmModeFreeCrtc(crtc); drmModeFreeResources(res);
- return 1;
- }
- uint32_t w = fb->width, h = fb->height;
- uint32_t pitch = fb->pitches[0];
- uint32_t size = pitch * h;
- struct drm_mode_map_dumb mreq = { .handle = fb->handles[0] };
- if (ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq)) { perror("map_dumb"); return 1; }
- void *map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, mreq.offset);
- if (map == MAP_FAILED) { perror("mmap"); return 1; }
- FILE *fp = fopen("/tmp/frame.bin", "wb");
- fwrite(map, 1, size, fp);
- fclose(fp);
- fprintf(stderr, "Dumped %ux%u (pitch=%u, %u bytes) to /tmp/frame.bin\n", w, h, pitch, size);
- munmap(map, size);
- drmModeFreeFB2(fb);
- drmModeFreeCrtc(crtc);
- drmModeFreeResources(res);
- return 0;
- }
|