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