2 * Copyright (C) 2016 Christian Gmeiner <christian.gmeiner@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Christian Gmeiner <christian.gmeiner@gmail.com>
27 #include "renderonly/renderonly.h"
34 #include "state_tracker/drm_driver.h"
35 #include "pipe/p_screen.h"
36 #include "util/u_inlines.h"
37 #include "util/u_memory.h"
40 renderonly_dup(const struct renderonly
*ro
)
42 struct renderonly
*copy
;
44 copy
= CALLOC_STRUCT(renderonly
);
48 memcpy(copy
, ro
, sizeof(*ro
));
53 struct renderonly_scanout
*
54 renderonly_scanout_for_prime(struct pipe_resource
*rsc
, struct renderonly
*ro
)
56 struct renderonly_scanout
*scanout
;
58 scanout
= CALLOC_STRUCT(renderonly_scanout
);
68 renderonly_scanout_destroy(struct renderonly_scanout
*scanout
,
69 struct renderonly
*ro
)
71 struct drm_mode_destroy_dumb destroy_dumb
= { };
73 pipe_resource_reference(&scanout
->prime
, NULL
);
74 if (ro
->kms_fd
!= -1) {
75 destroy_dumb
.handle
= scanout
->handle
;
76 drmIoctl(ro
->kms_fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &destroy_dumb
);
81 struct renderonly_scanout
*
82 renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource
*rsc
,
83 struct renderonly
*ro
)
85 struct pipe_screen
*screen
= rsc
->screen
;
86 struct renderonly_scanout
*scanout
;
87 struct winsys_handle handle
;
89 struct drm_mode_create_dumb create_dumb
= {
91 .height
= rsc
->height0
,
94 struct drm_mode_destroy_dumb destroy_dumb
= { };
96 scanout
= CALLOC_STRUCT(renderonly_scanout
);
100 /* create dumb buffer at scanout GPU */
101 err
= drmIoctl(ro
->kms_fd
, DRM_IOCTL_MODE_CREATE_DUMB
, &create_dumb
);
103 fprintf(stderr
, "DRM_IOCTL_MODE_CREATE_DUMB failed: %s\n",
108 scanout
->handle
= create_dumb
.handle
;
109 scanout
->stride
= create_dumb
.pitch
;
111 /* export dumb buffer */
112 err
= drmPrimeHandleToFD(ro
->kms_fd
, create_dumb
.handle
, O_CLOEXEC
,
115 fprintf(stderr
, "failed to export dumb buffer: %s\n", strerror(errno
));
119 /* import dumb buffer */
120 handle
.type
= DRM_API_HANDLE_TYPE_FD
;
121 handle
.handle
= prime_fd
;
122 handle
.stride
= create_dumb
.pitch
;
124 scanout
->prime
= screen
->resource_from_handle(screen
, rsc
,
125 &handle
, PIPE_HANDLE_USAGE_READ_WRITE
);
129 if (!scanout
->prime
) {
130 fprintf(stderr
, "failed to create resource_from_handle: %s\n", strerror(errno
));
137 destroy_dumb
.handle
= scanout
->handle
;
138 drmIoctl(ro
->kms_fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &destroy_dumb
);
146 struct renderonly_scanout
*
147 renderonly_create_gpu_import_for_resource(struct pipe_resource
*rsc
,
148 struct renderonly
*ro
)
150 struct pipe_screen
*screen
= rsc
->screen
;
151 struct renderonly_scanout
*scanout
;
154 struct winsys_handle handle
= {
155 .type
= DRM_API_HANDLE_TYPE_FD
158 scanout
= CALLOC_STRUCT(renderonly_scanout
);
162 status
= screen
->resource_get_handle(screen
, NULL
, rsc
, &handle
,
163 PIPE_HANDLE_USAGE_READ_WRITE
);
167 scanout
->stride
= handle
.stride
;
170 err
= drmPrimeFDToHandle(ro
->kms_fd
, fd
, &scanout
->handle
);
174 fprintf(stderr
, "drmPrimeFDToHandle() failed: %s\n", strerror(errno
));