diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h index ad91d0691f..2b4fe4bf35 100644 --- a/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -54,6 +54,11 @@ SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height, const uint32_t pitches[4], const uint32_t offsets[4], uint32_t *buf_id, uint32_t flags)) +SDL_KMSDRM_SYM(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width, + uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4], + const uint32_t pitches[4], const uint32_t offsets[4], + const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)) + SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId)) SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf)) SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId)) @@ -120,6 +125,10 @@ SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo)) +SDL_KMSDRM_SYM(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM(int,gbm_bo_get_plane_count,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane)) +SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane)) #undef SDL_KMSDRM_MODULE #undef SDL_KMSDRM_SYM diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index ccc72b6f55..4a873a32c4 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -352,8 +352,9 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(SDL_VideoDevice *_this, struct gbm_bo *bo) { SDL_VideoData *viddata = _this->driverdata; unsigned w, h; - int ret; - Uint32 stride, handle; + int ret, num_planes = 0; + Uint32 format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0; + uint64_t modifiers[4] = { 0 }; /* Check for an existing framebuffer */ KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo); @@ -372,20 +373,33 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(SDL_VideoDevice *_this, struct gbm_bo *bo) fb_info->drm_fd = viddata->drm_fd; - /* Create framebuffer object for the buffer */ + /* Create framebuffer object for the buffer using the modifiers requested by GBM. + Use of the modifiers is necessary on some platforms. */ w = KMSDRM_gbm_bo_get_width(bo); h = KMSDRM_gbm_bo_get_height(bo); - stride = KMSDRM_gbm_bo_get_stride(bo); - handle = KMSDRM_gbm_bo_get_handle(bo).u32; - ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle, - &fb_info->fb_id); + format = KMSDRM_gbm_bo_get_format(bo); + + modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo); + num_planes = KMSDRM_gbm_bo_get_plane_count(bo); + for (int i = 0; i < num_planes; i++) { + strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i); + handles[i] = KMSDRM_gbm_bo_get_handle(bo).u32; + offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i); + modifiers[i] = modifiers[0]; + } + + if (modifiers[0]) { + flags = DRM_MODE_FB_MODIFIERS; + } + + ret = KMSDRM_drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags); if (ret) { SDL_free(fb_info); return NULL; } - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", - fb_info->fb_id, w, h, stride, (void *)bo); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, from BO %p", + fb_info->fb_id, w, h, (void *)bo); /* Associate our DRM framebuffer with this buffer object */ KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);