Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fcntl.h>
- #include <gbm.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <time.h>
- #include <unistd.h>
- #include <xf86drm.h>
- #include <xf86drmMode.h>
- typedef struct __attribute__((packed)) {
- uint8_t b;
- uint8_t g;
- uint8_t r;
- uint8_t x;
- } xrgb8888_pixel;
- typedef struct {
- int card_fd;
- struct gbm_device * gbm_dev;
- struct gbm_bo * gbm_bo;
- uint32_t crtc_id;
- uint32_t conn_id;
- uint32_t buffer_handle;
- drmModeModeInfo mode_info;
- } drm_app_context;
- #define COUNT_CARD_NAMES 2
- static const char *const card_names[]=
- {"/dev/dri/card0",
- "/dev/dri/card1"};
- uint32_t modeset_find_suitable_crtc(int fd, drmModeResPtr resources,
- drmModeConnector *conn) {
- drmModeEncoder *enc;
- for (int i = 0; i < resources->count_encoders; ++i) {
- enc = drmModeGetEncoder(fd, resources->encoders[i]);
- if (!enc) {
- continue;
- }
- for (int j = 0; j < resources->count_crtcs; ++j) {
- if (enc->possible_crtcs & (1 << j)) {
- drmModeFreeEncoder(enc);
- return resources->crtcs[j];
- }
- }
- }
- drmModeFreeEncoder(enc);
- return -1;
- }
- drm_app_context *init_drm_app() {
- int card_fd = -1;
- drmModeRes *res = NULL;
- drmModeConnector *conn = NULL;
- drmModeCrtc *crtc = NULL;
- drm_app_context *ctx = NULL;
- struct gbm_device *device = NULL;
- struct gbm_bo *bo = NULL;
- for (int i = 0; i < COUNT_CARD_NAMES; ++i) {
- card_fd = open(card_names[i], O_RDWR | O_NONBLOCK);
- if (card_fd >= 0) {
- break;
- }
- }
- if(card_fd < 0){
- fprintf(stderr, "Unable to open any of {card0, card1}\n");
- goto err;
- }
- if(drmSetMaster(card_fd) < 0){
- fprintf(stderr, "Master for card is already set");
- goto err;
- }
- if (card_fd < 0) {
- fprintf(stderr, "Could not open any dri cards\n");
- goto err;
- }
- res = drmModeGetResources(card_fd);
- if (!res) {
- fprintf(stderr, "Could not obtain drm resources\n");
- goto err;
- }
- for (int i = 0; i < res->count_connectors; ++i) {
- conn = drmModeGetConnector(card_fd, res->connectors[i]);
- if (conn && conn->count_modes > 0) {
- break;
- }
- }
- if (!conn || conn->count_modes == 0) {
- fprintf(stderr, "No active connectors found\n");
- goto err;
- }
- uint32_t crtc_id = modeset_find_suitable_crtc(card_fd, res, conn);
- if (crtc_id == -1) {
- fprintf(stderr, "No suitable crtcs found");
- goto err;
- }
- device = gbm_create_device(card_fd);
- if (!device) {
- fprintf(stderr, "GBM device creation failed");
- goto err;
- }
- bo = gbm_bo_create(device, conn->modes[0].hdisplay, conn->modes[0].vdisplay,
- GBM_FORMAT_XRGB8888,
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
- if (!bo) {
- fprintf(stderr, "Failed to create buffer object");
- goto err;
- }
- int plane_count = gbm_bo_get_plane_count(bo);
- uint32_t handles[4] = {};
- uint32_t pitches[4] = {};
- uint32_t offsets[4] = {};
- for (int i = 0; i < plane_count; ++i) {
- handles[i] = gbm_bo_get_handle_for_plane(bo, i).u32;
- pitches[i] = gbm_bo_get_stride_for_plane(bo, i);
- offsets[i] = gbm_bo_get_offset(bo, i);
- }
- uint32_t buf_id;
- uint32_t bo_format = gbm_bo_get_format(bo);
- if (drmModeAddFB2(card_fd, conn->modes[0].hdisplay, conn->modes[0].vdisplay,
- bo_format, handles, pitches, offsets, &buf_id, 0) != 0) {
- fprintf(stderr, "Unable to add FB");
- goto err;
- }
- uint32_t connector_id = conn->connector_id;
- drmModeModeInfo mode_info = conn->modes[0];
- drmModeFreeResources(res);
- drmModeFreeConnector(conn);
- drmModeFreeCrtc(crtc);
- ctx = (drm_app_context *)malloc(sizeof(drm_app_context));
- ctx->card_fd = card_fd;
- ctx->gbm_bo = bo;
- ctx->gbm_dev = device;
- ctx->mode_info = mode_info;
- ctx->crtc_id = crtc_id;
- ctx->conn_id = connector_id;
- ctx->buffer_handle = buf_id;
- return ctx;
- err:
- // works fine with NULL pointers
- drmModeFreeResources(res);
- drmModeFreeConnector(conn);
- drmModeFreeCrtc(crtc);
- if (card_fd > 0) {
- drmDropMaster(card_fd);
- drmModeRmFB(card_fd, buf_id);
- }
- if (bo)
- gbm_bo_destroy(bo);
- if (device)
- gbm_device_destroy(device);
- close(card_fd);
- return NULL;
- }
- void destroy_context(drm_app_context *ctx) {
- drmDropMaster(ctx->card_fd);
- drmModeRmFB(ctx->card_fd, ctx->buffer_handle);
- gbm_bo_destroy(ctx->gbm_bo);
- gbm_device_destroy(ctx->gbm_dev);
- close(ctx->card_fd);
- }
- // This does work, but the buffer is mapped before rendering each frame
- int main() {
- drm_app_context *ctx = init_drm_app();
- if (ctx == NULL) {
- return 1;
- }
- xrgb8888_pixel *fb = NULL;
- uint32_t map_stride;
- void *map_data = NULL;
- for (int i = 0; i < 256; ++i) {
- fb = (xrgb8888_pixel *)gbm_bo_map(
- ctx->gbm_bo, 0, 0, gbm_bo_get_width(ctx->gbm_bo),
- gbm_bo_get_height(ctx->gbm_bo), GBM_BO_TRANSFER_READ_WRITE, &map_stride,
- &map_data);
- int bufsize = map_stride * ctx->mode_info.vdisplay;
- for (int j = 0; j < bufsize / 4; ++j) {
- fb[j].r = (2 * i + j) % 256;
- fb[j].g = (4 * i + 2*j) % 256;
- fb[j].b = (8 * i + 4*j) % 256;
- }
- gbm_bo_unmap(ctx->gbm_bo, map_data);
- map_data = NULL;
- drmModeSetCrtc(ctx->card_fd, ctx->crtc_id, ctx->buffer_handle, 0, 0,
- &ctx->conn_id, 1, &ctx->mode_info);
- }
- destroy_context(ctx);
- return 0;
- }
- // This doesn't work
- /* int main() {
- drm_app_context *ctx = init_drm_app();
- if (ctx == NULL) {
- return 1;
- }
- xrgb8888_pixel *fb = NULL;
- uint32_t map_stride;
- void *map_data = NULL;
- fb = (xrgb8888_pixel *)gbm_bo_map(
- ctx->gbm_bo, 0, 0, gbm_bo_get_width(ctx->gbm_bo),
- gbm_bo_get_height(ctx->gbm_bo), GBM_BO_TRANSFER_READ_WRITE, &map_stride,
- &map_data);
- for (int i = 0; i < 256; ++i) {
- int bufsize = map_stride * ctx->mode_info.vdisplay;
- for (int j = 0; j < bufsize / 4; ++j) {
- fb[j].r = (2 * i + j) % 256;
- fb[j].g = (4 * i + 2*j) % 256;
- fb[j].b = (8 * i + 4*j) % 256;
- }
- drmModeSetCrtc(ctx->card_fd, ctx->crtc_id, ctx->buffer_handle, 0, 0,
- &ctx->conn_id, 1, &ctx->mode_info);
- }
- gbm_bo_unmap(ctx->gbm_bo, map_data);
- destroy_context(ctx);
- return 0;
- } */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement