1 /*
2 * Copyright © 2014-2018 NVIDIA Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <inttypes.h>
27 #include <stdio.h>
28
29 #include <sys/stat.h>
30
31 #include "drm-uapi/drm_fourcc.h"
32 #include "drm-uapi/tegra_drm.h"
33 #include <xf86drm.h>
34
35 #include "loader/loader.h"
36 #include "pipe/p_state.h"
37 #include "util/u_debug.h"
38 #include "util/format/u_format.h"
39 #include "util/u_inlines.h"
40
41 #include "frontend/drm_driver.h"
42
43 #include "nouveau/drm/nouveau_drm_public.h"
44
45 #include "tegra_context.h"
46 #include "tegra_resource.h"
47 #include "tegra_screen.h"
48
tegra_screen_destroy(struct pipe_screen *pscreen)49 static void tegra_screen_destroy(struct pipe_screen *pscreen)
50 {
51 struct tegra_screen *screen = to_tegra_screen(pscreen);
52
53 screen->gpu->destroy(screen->gpu);
54 free(pscreen);
55 }
56
57 static const char *
tegra_screen_get_name(struct pipe_screen *pscreen)58 tegra_screen_get_name(struct pipe_screen *pscreen)
59 {
60 return "tegra";
61 }
62
63 static const char *
tegra_screen_get_vendor(struct pipe_screen *pscreen)64 tegra_screen_get_vendor(struct pipe_screen *pscreen)
65 {
66 return "NVIDIA";
67 }
68
69 static const char *
tegra_screen_get_device_vendor(struct pipe_screen *pscreen)70 tegra_screen_get_device_vendor(struct pipe_screen *pscreen)
71 {
72 return "NVIDIA";
73 }
74
75 static int
tegra_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)76 tegra_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
77 {
78 struct tegra_screen *screen = to_tegra_screen(pscreen);
79
80 return screen->gpu->get_param(screen->gpu, param);
81 }
82
83 static float
tegra_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)84 tegra_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
85 {
86 struct tegra_screen *screen = to_tegra_screen(pscreen);
87
88 return screen->gpu->get_paramf(screen->gpu, param);
89 }
90
91 static int
tegra_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)92 tegra_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
93 enum pipe_shader_cap param)
94 {
95 struct tegra_screen *screen = to_tegra_screen(pscreen);
96
97 return screen->gpu->get_shader_param(screen->gpu, shader, param);
98 }
99
100 static int
tegra_screen_get_video_param(struct pipe_screen *pscreen, enum pipe_video_profile profile, enum pipe_video_entrypoint entrypoint, enum pipe_video_cap param)101 tegra_screen_get_video_param(struct pipe_screen *pscreen,
102 enum pipe_video_profile profile,
103 enum pipe_video_entrypoint entrypoint,
104 enum pipe_video_cap param)
105 {
106 struct tegra_screen *screen = to_tegra_screen(pscreen);
107
108 return screen->gpu->get_video_param(screen->gpu, profile, entrypoint,
109 param);
110 }
111
112 static int
tegra_screen_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, enum pipe_compute_cap param, void *retp)113 tegra_screen_get_compute_param(struct pipe_screen *pscreen,
114 enum pipe_shader_ir ir_type,
115 enum pipe_compute_cap param,
116 void *retp)
117 {
118 struct tegra_screen *screen = to_tegra_screen(pscreen);
119
120 return screen->gpu->get_compute_param(screen->gpu, ir_type, param,
121 retp);
122 }
123
124 static uint64_t
tegra_screen_get_timestamp(struct pipe_screen *pscreen)125 tegra_screen_get_timestamp(struct pipe_screen *pscreen)
126 {
127 struct tegra_screen *screen = to_tegra_screen(pscreen);
128
129 return screen->gpu->get_timestamp(screen->gpu);
130 }
131
132 static bool
tegra_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned storage_sample_count, unsigned usage)133 tegra_screen_is_format_supported(struct pipe_screen *pscreen,
134 enum pipe_format format,
135 enum pipe_texture_target target,
136 unsigned sample_count,
137 unsigned storage_sample_count,
138 unsigned usage)
139 {
140 struct tegra_screen *screen = to_tegra_screen(pscreen);
141
142 return screen->gpu->is_format_supported(screen->gpu, format, target,
143 sample_count, storage_sample_count,
144 usage);
145 }
146
147 static bool
tegra_screen_is_video_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_video_profile profile, enum pipe_video_entrypoint entrypoint)148 tegra_screen_is_video_format_supported(struct pipe_screen *pscreen,
149 enum pipe_format format,
150 enum pipe_video_profile profile,
151 enum pipe_video_entrypoint entrypoint)
152 {
153 struct tegra_screen *screen = to_tegra_screen(pscreen);
154
155 return screen->gpu->is_video_format_supported(screen->gpu, format, profile,
156 entrypoint);
157 }
158
159 static bool
tegra_screen_can_create_resource(struct pipe_screen *pscreen, const struct pipe_resource *template)160 tegra_screen_can_create_resource(struct pipe_screen *pscreen,
161 const struct pipe_resource *template)
162 {
163 struct tegra_screen *screen = to_tegra_screen(pscreen);
164
165 return screen->gpu->can_create_resource(screen->gpu, template);
166 }
167
tegra_screen_import_resource(struct tegra_screen *screen, struct tegra_resource *resource)168 static int tegra_screen_import_resource(struct tegra_screen *screen,
169 struct tegra_resource *resource)
170 {
171 struct winsys_handle handle;
172 bool status;
173 int fd, err;
174
175 memset(&handle, 0, sizeof(handle));
176 handle.modifier = DRM_FORMAT_MOD_INVALID;
177 handle.type = WINSYS_HANDLE_TYPE_FD;
178
179 status = screen->gpu->resource_get_handle(screen->gpu, NULL, resource->gpu,
180 &handle, 0);
181 if (!status)
182 return -EINVAL;
183
184 assert(handle.modifier != DRM_FORMAT_MOD_INVALID);
185
186 if (handle.modifier == DRM_FORMAT_MOD_INVALID) {
187 close(handle.handle);
188 return -EINVAL;
189 }
190
191 resource->modifier = handle.modifier;
192 resource->stride = handle.stride;
193 fd = handle.handle;
194
195 err = drmPrimeFDToHandle(screen->fd, fd, &resource->handle);
196 if (err < 0)
197 err = -errno;
198
199 close(fd);
200
201 return err;
202 }
203
204 static struct pipe_resource *
tegra_screen_resource_create(struct pipe_screen *pscreen, const struct pipe_resource *template)205 tegra_screen_resource_create(struct pipe_screen *pscreen,
206 const struct pipe_resource *template)
207 {
208 struct tegra_screen *screen = to_tegra_screen(pscreen);
209 uint64_t modifier = DRM_FORMAT_MOD_INVALID;
210 struct tegra_resource *resource;
211 int err;
212
213 resource = calloc(1, sizeof(*resource));
214 if (!resource)
215 return NULL;
216
217 /*
218 * Applications that create scanout resources without modifiers are very
219 * unlikely to support modifiers at all. In that case the resources need
220 * to be created with a pitch-linear layout so that they can be properly
221 * shared with scanout hardware.
222 *
223 * Technically it is possible for applications to create resources without
224 * specifying a modifier but still query the modifier associated with the
225 * resource (e.g. using gbm_bo_get_modifier()) before handing it to the
226 * framebuffer creation API (such as the DRM_IOCTL_MODE_ADDFB2 IOCTL).
227 */
228 if (template->bind & PIPE_BIND_SCANOUT)
229 modifier = DRM_FORMAT_MOD_LINEAR;
230
231 resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
232 template,
233 &modifier, 1);
234 if (!resource->gpu)
235 goto free;
236
237 /* import scanout buffers for display */
238 if (template->bind & PIPE_BIND_SCANOUT) {
239 err = tegra_screen_import_resource(screen, resource);
240 if (err < 0)
241 goto destroy;
242 }
243
244 memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
245 pipe_reference_init(&resource->base.reference, 1);
246 resource->base.screen = &screen->base;
247
248 /* use private reference count for wrapped resources */
249 resource->gpu->reference.count += 100000000;
250 resource->refcount = 100000000;
251
252 return &resource->base;
253
254 destroy:
255 screen->gpu->resource_destroy(screen->gpu, resource->gpu);
256 free:
257 free(resource);
258 return NULL;
259 }
260
261 /* XXX */
262 static struct pipe_resource *
tegra_screen_resource_create_front(struct pipe_screen *pscreen, const struct pipe_resource *template, const void *map_front_private)263 tegra_screen_resource_create_front(struct pipe_screen *pscreen,
264 const struct pipe_resource *template,
265 const void *map_front_private)
266 {
267 struct tegra_screen *screen = to_tegra_screen(pscreen);
268 struct pipe_resource *resource;
269
270 resource = screen->gpu->resource_create_front(screen->gpu, template,
271 map_front_private);
272 if (resource)
273 resource->screen = pscreen;
274
275 return resource;
276 }
277
278 static struct pipe_resource *
tegra_screen_resource_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *handle, unsigned usage)279 tegra_screen_resource_from_handle(struct pipe_screen *pscreen,
280 const struct pipe_resource *template,
281 struct winsys_handle *handle,
282 unsigned usage)
283 {
284 struct tegra_screen *screen = to_tegra_screen(pscreen);
285 struct tegra_resource *resource;
286
287 resource = calloc(1, sizeof(*resource));
288 if (!resource)
289 return NULL;
290
291 resource->gpu = screen->gpu->resource_from_handle(screen->gpu, template,
292 handle, usage);
293 if (!resource->gpu) {
294 free(resource);
295 return NULL;
296 }
297
298 memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
299 pipe_reference_init(&resource->base.reference, 1);
300 resource->base.screen = &screen->base;
301
302 return &resource->base;
303 }
304
305 /* XXX */
306 static struct pipe_resource *
tegra_screen_resource_from_user_memory(struct pipe_screen *pscreen, const struct pipe_resource *template, void *buffer)307 tegra_screen_resource_from_user_memory(struct pipe_screen *pscreen,
308 const struct pipe_resource *template,
309 void *buffer)
310 {
311 struct tegra_screen *screen = to_tegra_screen(pscreen);
312 struct pipe_resource *resource;
313
314 resource = screen->gpu->resource_from_user_memory(screen->gpu, template,
315 buffer);
316 if (resource)
317 resource->screen = pscreen;
318
319 return resource;
320 }
321
322 static bool
tegra_screen_resource_get_handle(struct pipe_screen *pscreen, struct pipe_context *pcontext, struct pipe_resource *presource, struct winsys_handle *handle, unsigned usage)323 tegra_screen_resource_get_handle(struct pipe_screen *pscreen,
324 struct pipe_context *pcontext,
325 struct pipe_resource *presource,
326 struct winsys_handle *handle,
327 unsigned usage)
328 {
329 struct tegra_resource *resource = to_tegra_resource(presource);
330 struct tegra_context *context = to_tegra_context(pcontext);
331 struct tegra_screen *screen = to_tegra_screen(pscreen);
332 bool ret = true;
333
334 /*
335 * Assume that KMS handles for scanout resources will only ever be used
336 * to pass buffers into Tegra DRM for display. In all other cases, return
337 * the Nouveau handle, assuming they will be used for sharing in DRI2/3.
338 */
339 if (handle->type == WINSYS_HANDLE_TYPE_KMS &&
340 presource->bind & PIPE_BIND_SCANOUT) {
341 handle->modifier = resource->modifier;
342 handle->handle = resource->handle;
343 handle->stride = resource->stride;
344 } else {
345 ret = screen->gpu->resource_get_handle(screen->gpu,
346 context ? context->gpu : NULL,
347 resource->gpu, handle, usage);
348 }
349
350 return ret;
351 }
352
353 static void
tegra_screen_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *presource)354 tegra_screen_resource_destroy(struct pipe_screen *pscreen,
355 struct pipe_resource *presource)
356 {
357 struct tegra_resource *resource = to_tegra_resource(presource);
358
359 /* adjust private reference count */
360 p_atomic_add(&resource->gpu->reference.count, -resource->refcount);
361 pipe_resource_reference(&resource->gpu, NULL);
362 free(resource);
363 }
364
365 static void
tegra_screen_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_context *pcontext, struct pipe_resource *resource, unsigned int level, unsigned int layer, void *winsys_drawable_handle, struct pipe_box *box)366 tegra_screen_flush_frontbuffer(struct pipe_screen *pscreen,
367 struct pipe_context *pcontext,
368 struct pipe_resource *resource,
369 unsigned int level,
370 unsigned int layer,
371 void *winsys_drawable_handle,
372 struct pipe_box *box)
373 {
374 struct tegra_screen *screen = to_tegra_screen(pscreen);
375 struct tegra_context *context = to_tegra_context(pcontext);
376
377 screen->gpu->flush_frontbuffer(screen->gpu,
378 context ? context->gpu : NULL,
379 resource, level, layer,
380 winsys_drawable_handle, box);
381 }
382
383 static void
tegra_screen_fence_reference(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence)384 tegra_screen_fence_reference(struct pipe_screen *pscreen,
385 struct pipe_fence_handle **ptr,
386 struct pipe_fence_handle *fence)
387 {
388 struct tegra_screen *screen = to_tegra_screen(pscreen);
389
390 screen->gpu->fence_reference(screen->gpu, ptr, fence);
391 }
392
393 static bool
tegra_screen_fence_finish(struct pipe_screen *pscreen, struct pipe_context *pcontext, struct pipe_fence_handle *fence, uint64_t timeout)394 tegra_screen_fence_finish(struct pipe_screen *pscreen,
395 struct pipe_context *pcontext,
396 struct pipe_fence_handle *fence,
397 uint64_t timeout)
398 {
399 struct tegra_context *context = to_tegra_context(pcontext);
400 struct tegra_screen *screen = to_tegra_screen(pscreen);
401
402 return screen->gpu->fence_finish(screen->gpu,
403 context ? context->gpu : NULL,
404 fence, timeout);
405 }
406
407 static int
tegra_screen_fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *fence)408 tegra_screen_fence_get_fd(struct pipe_screen *pscreen,
409 struct pipe_fence_handle *fence)
410 {
411 struct tegra_screen *screen = to_tegra_screen(pscreen);
412
413 return screen->gpu->fence_get_fd(screen->gpu, fence);
414 }
415
416 static int
tegra_screen_get_driver_query_info(struct pipe_screen *pscreen, unsigned int index, struct pipe_driver_query_info *info)417 tegra_screen_get_driver_query_info(struct pipe_screen *pscreen,
418 unsigned int index,
419 struct pipe_driver_query_info *info)
420 {
421 struct tegra_screen *screen = to_tegra_screen(pscreen);
422
423 return screen->gpu->get_driver_query_info(screen->gpu, index, info);
424 }
425
426 static int
tegra_screen_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned int index, struct pipe_driver_query_group_info *info)427 tegra_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
428 unsigned int index,
429 struct pipe_driver_query_group_info *info)
430 {
431 struct tegra_screen *screen = to_tegra_screen(pscreen);
432
433 return screen->gpu->get_driver_query_group_info(screen->gpu, index, info);
434 }
435
436 static void
tegra_screen_query_memory_info(struct pipe_screen *pscreen, struct pipe_memory_info *info)437 tegra_screen_query_memory_info(struct pipe_screen *pscreen,
438 struct pipe_memory_info *info)
439 {
440 struct tegra_screen *screen = to_tegra_screen(pscreen);
441
442 screen->gpu->query_memory_info(screen->gpu, info);
443 }
444
445 static const void *
tegra_screen_get_compiler_options(struct pipe_screen *pscreen, enum pipe_shader_ir ir, unsigned int shader)446 tegra_screen_get_compiler_options(struct pipe_screen *pscreen,
447 enum pipe_shader_ir ir,
448 unsigned int shader)
449 {
450 struct tegra_screen *screen = to_tegra_screen(pscreen);
451 const void *options = NULL;
452
453 if (screen->gpu->get_compiler_options)
454 options = screen->gpu->get_compiler_options(screen->gpu, ir, shader);
455
456 return options;
457 }
458
459 static struct disk_cache *
tegra_screen_get_disk_shader_cache(struct pipe_screen *pscreen)460 tegra_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
461 {
462 struct tegra_screen *screen = to_tegra_screen(pscreen);
463
464 return screen->gpu->get_disk_shader_cache(screen->gpu);
465 }
466
467 static struct pipe_resource *
tegra_screen_resource_create_with_modifiers(struct pipe_screen *pscreen, const struct pipe_resource *template, const uint64_t *modifiers, int count)468 tegra_screen_resource_create_with_modifiers(struct pipe_screen *pscreen,
469 const struct pipe_resource *template,
470 const uint64_t *modifiers,
471 int count)
472 {
473 struct tegra_screen *screen = to_tegra_screen(pscreen);
474 struct pipe_resource tmpl = *template;
475 struct tegra_resource *resource;
476 int err;
477
478 resource = calloc(1, sizeof(*resource));
479 if (!resource)
480 return NULL;
481
482 /*
483 * Assume that resources created with modifiers will always be used for
484 * scanout. This is necessary because some of the APIs that are used to
485 * create resources with modifiers (e.g. gbm_bo_create_with_modifiers())
486 * can't pass along usage information. Adding that capability might be
487 * worth adding to remove this ambiguity. Not all future use-cases that
488 * involve modifiers may always be targetting scanout hardware.
489 */
490 tmpl.bind |= PIPE_BIND_SCANOUT;
491
492 resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
493 &tmpl,
494 modifiers,
495 count);
496 if (!resource->gpu)
497 goto free;
498
499 err = tegra_screen_import_resource(screen, resource);
500 if (err < 0)
501 goto destroy;
502
503 memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
504 pipe_reference_init(&resource->base.reference, 1);
505 resource->base.screen = &screen->base;
506
507 return &resource->base;
508
509 destroy:
510 screen->gpu->resource_destroy(screen->gpu, resource->gpu);
511 free:
512 free(resource);
513 return NULL;
514 }
515
tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count)516 static void tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
517 enum pipe_format format,
518 int max, uint64_t *modifiers,
519 unsigned int *external_only,
520 int *count)
521 {
522 struct tegra_screen *screen = to_tegra_screen(pscreen);
523
524 screen->gpu->query_dmabuf_modifiers(screen->gpu, format, max, modifiers,
525 external_only, count);
526 }
527
528 static bool
tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format, bool *external_only)529 tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
530 uint64_t modifier,
531 enum pipe_format format,
532 bool *external_only)
533 {
534 struct tegra_screen *screen = to_tegra_screen(pscreen);
535
536 return screen->gpu->is_dmabuf_modifier_supported(screen->gpu, modifier,
537 format, external_only);
538 }
539
540 static unsigned int
tegra_screen_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier, enum pipe_format format)541 tegra_screen_get_dmabuf_modifier_planes(struct pipe_screen *pscreen,
542 uint64_t modifier,
543 enum pipe_format format)
544 {
545 struct tegra_screen *screen = to_tegra_screen(pscreen);
546
547 return screen->gpu->get_dmabuf_modifier_planes ?
548 screen->gpu->get_dmabuf_modifier_planes(screen->gpu, modifier, format) :
549 util_format_get_num_planes(format);
550 }
551
552 static struct pipe_memory_object *
tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handle *handle, bool dedicated)553 tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
554 struct winsys_handle *handle,
555 bool dedicated)
556 {
557 struct tegra_screen *screen = to_tegra_screen(pscreen);
558
559 return screen->gpu->memobj_create_from_handle(screen->gpu, handle,
560 dedicated);
561 }
562
563 struct pipe_screen *
tegra_screen_create(int fd)564 tegra_screen_create(int fd)
565 {
566 struct tegra_screen *screen;
567
568 screen = calloc(1, sizeof(*screen));
569 if (!screen)
570 return NULL;
571
572 screen->fd = fd;
573
574 screen->gpu_fd = loader_open_render_node("nouveau");
575 if (screen->gpu_fd < 0) {
576 if (errno != ENOENT)
577 fprintf(stderr, "failed to open GPU device: %s\n", strerror(errno));
578
579 free(screen);
580 return NULL;
581 }
582
583 screen->gpu = nouveau_drm_screen_create(screen->gpu_fd);
584 if (!screen->gpu) {
585 fprintf(stderr, "failed to create GPU screen\n");
586 close(screen->gpu_fd);
587 free(screen);
588 return NULL;
589 }
590
591 screen->base.destroy = tegra_screen_destroy;
592 screen->base.get_name = tegra_screen_get_name;
593 screen->base.get_vendor = tegra_screen_get_vendor;
594 screen->base.get_device_vendor = tegra_screen_get_device_vendor;
595 screen->base.get_param = tegra_screen_get_param;
596 screen->base.get_paramf = tegra_screen_get_paramf;
597 screen->base.get_shader_param = tegra_screen_get_shader_param;
598 screen->base.get_video_param = tegra_screen_get_video_param;
599 screen->base.get_compute_param = tegra_screen_get_compute_param;
600 screen->base.get_timestamp = tegra_screen_get_timestamp;
601 screen->base.context_create = tegra_screen_context_create;
602 screen->base.is_format_supported = tegra_screen_is_format_supported;
603 screen->base.is_video_format_supported = tegra_screen_is_video_format_supported;
604
605 /* allow fallback implementation if GPU driver doesn't implement it */
606 if (screen->gpu->can_create_resource)
607 screen->base.can_create_resource = tegra_screen_can_create_resource;
608
609 screen->base.resource_create = tegra_screen_resource_create;
610 screen->base.resource_create_front = tegra_screen_resource_create_front;
611 screen->base.resource_from_handle = tegra_screen_resource_from_handle;
612 screen->base.resource_from_user_memory = tegra_screen_resource_from_user_memory;
613 screen->base.resource_get_handle = tegra_screen_resource_get_handle;
614 screen->base.resource_destroy = tegra_screen_resource_destroy;
615
616 screen->base.flush_frontbuffer = tegra_screen_flush_frontbuffer;
617 screen->base.fence_reference = tegra_screen_fence_reference;
618 screen->base.fence_finish = tegra_screen_fence_finish;
619 screen->base.fence_get_fd = tegra_screen_fence_get_fd;
620
621 screen->base.get_driver_query_info = tegra_screen_get_driver_query_info;
622 screen->base.get_driver_query_group_info = tegra_screen_get_driver_query_group_info;
623 screen->base.query_memory_info = tegra_screen_query_memory_info;
624
625 screen->base.get_compiler_options = tegra_screen_get_compiler_options;
626 screen->base.get_disk_shader_cache = tegra_screen_get_disk_shader_cache;
627
628 screen->base.resource_create_with_modifiers = tegra_screen_resource_create_with_modifiers;
629 screen->base.query_dmabuf_modifiers = tegra_screen_query_dmabuf_modifiers;
630 screen->base.is_dmabuf_modifier_supported = tegra_screen_is_dmabuf_modifier_supported;
631 screen->base.get_dmabuf_modifier_planes = tegra_screen_get_dmabuf_modifier_planes;
632 screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
633
634 return &screen->base;
635 }
636