1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2016 Christian Gmeiner <christian.gmeiner@gmail.com> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Christian Gmeiner <christian.gmeiner@gmail.com> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "renderonly/renderonly.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include <errno.h> 30bf215546Sopenharmony_ci#include <fcntl.h> 31bf215546Sopenharmony_ci#include <stdio.h> 32bf215546Sopenharmony_ci#include <xf86drm.h> 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "frontend/drm_driver.h" 35bf215546Sopenharmony_ci#include "pipe/p_screen.h" 36bf215546Sopenharmony_ci#include "util/format/u_format.h" 37bf215546Sopenharmony_ci#include "util/u_inlines.h" 38bf215546Sopenharmony_ci#include "util/u_memory.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_civoid 41bf215546Sopenharmony_cirenderonly_scanout_destroy(struct renderonly_scanout *scanout, 42bf215546Sopenharmony_ci struct renderonly *ro) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci struct drm_mode_destroy_dumb destroy_dumb = {0}; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci if (ro->kms_fd != -1) { 47bf215546Sopenharmony_ci destroy_dumb.handle = scanout->handle; 48bf215546Sopenharmony_ci drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); 49bf215546Sopenharmony_ci } 50bf215546Sopenharmony_ci FREE(scanout); 51bf215546Sopenharmony_ci} 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistruct renderonly_scanout * 54bf215546Sopenharmony_cirenderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc, 55bf215546Sopenharmony_ci struct renderonly *ro, 56bf215546Sopenharmony_ci struct winsys_handle *out_handle) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci struct renderonly_scanout *scanout; 59bf215546Sopenharmony_ci int err; 60bf215546Sopenharmony_ci struct drm_mode_create_dumb create_dumb = { 61bf215546Sopenharmony_ci .width = rsc->width0, 62bf215546Sopenharmony_ci .height = rsc->height0, 63bf215546Sopenharmony_ci .bpp = util_format_get_blocksizebits(rsc->format), 64bf215546Sopenharmony_ci }; 65bf215546Sopenharmony_ci struct drm_mode_destroy_dumb destroy_dumb = {0}; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci scanout = CALLOC_STRUCT(renderonly_scanout); 68bf215546Sopenharmony_ci if (!scanout) 69bf215546Sopenharmony_ci return NULL; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci /* create dumb buffer at scanout GPU */ 72bf215546Sopenharmony_ci err = drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); 73bf215546Sopenharmony_ci if (err < 0) { 74bf215546Sopenharmony_ci fprintf(stderr, "DRM_IOCTL_MODE_CREATE_DUMB failed: %s\n", 75bf215546Sopenharmony_ci strerror(errno)); 76bf215546Sopenharmony_ci goto free_scanout; 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci scanout->handle = create_dumb.handle; 80bf215546Sopenharmony_ci scanout->stride = create_dumb.pitch; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci if (!out_handle) 83bf215546Sopenharmony_ci return scanout; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci /* fill in winsys handle */ 86bf215546Sopenharmony_ci memset(out_handle, 0, sizeof(*out_handle)); 87bf215546Sopenharmony_ci out_handle->type = WINSYS_HANDLE_TYPE_FD; 88bf215546Sopenharmony_ci out_handle->stride = create_dumb.pitch; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC, 91bf215546Sopenharmony_ci (int *)&out_handle->handle); 92bf215546Sopenharmony_ci if (err < 0) { 93bf215546Sopenharmony_ci fprintf(stderr, "failed to export dumb buffer: %s\n", strerror(errno)); 94bf215546Sopenharmony_ci goto free_dumb; 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci return scanout; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cifree_dumb: 100bf215546Sopenharmony_ci destroy_dumb.handle = scanout->handle; 101bf215546Sopenharmony_ci drmIoctl(ro->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_cifree_scanout: 104bf215546Sopenharmony_ci FREE(scanout); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci return NULL; 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_cistruct renderonly_scanout * 110bf215546Sopenharmony_cirenderonly_create_gpu_import_for_resource(struct pipe_resource *rsc, 111bf215546Sopenharmony_ci struct renderonly *ro, 112bf215546Sopenharmony_ci struct winsys_handle *out_handle) 113bf215546Sopenharmony_ci{ 114bf215546Sopenharmony_ci struct pipe_screen *screen = rsc->screen; 115bf215546Sopenharmony_ci struct renderonly_scanout *scanout; 116bf215546Sopenharmony_ci boolean status; 117bf215546Sopenharmony_ci int fd, err; 118bf215546Sopenharmony_ci struct winsys_handle handle = { 119bf215546Sopenharmony_ci .type = WINSYS_HANDLE_TYPE_FD 120bf215546Sopenharmony_ci }; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci scanout = CALLOC_STRUCT(renderonly_scanout); 123bf215546Sopenharmony_ci if (!scanout) 124bf215546Sopenharmony_ci return NULL; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci status = screen->resource_get_handle(screen, NULL, rsc, &handle, 127bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 128bf215546Sopenharmony_ci if (!status) 129bf215546Sopenharmony_ci goto free_scanout; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci scanout->stride = handle.stride; 132bf215546Sopenharmony_ci fd = handle.handle; 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci err = drmPrimeFDToHandle(ro->kms_fd, fd, &scanout->handle); 135bf215546Sopenharmony_ci close(fd); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci if (err < 0) 138bf215546Sopenharmony_ci goto free_scanout; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci return scanout; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cifree_scanout: 143bf215546Sopenharmony_ci FREE(scanout); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci return NULL; 146bf215546Sopenharmony_ci} 147bf215546Sopenharmony_ci 148