mirror of https://gitlab.freedesktop.org/mesa/mesa
649 lines
22 KiB
C
649 lines
22 KiB
C
/*
|
|
* Copyright © 2014-2018 NVIDIA Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include "drm-uapi/drm_fourcc.h"
|
|
#include "drm-uapi/tegra_drm.h"
|
|
#include <xf86drm.h>
|
|
|
|
#include "loader/loader.h"
|
|
#include "pipe/p_state.h"
|
|
#include "util/u_debug.h"
|
|
#include "util/format/u_format.h"
|
|
#include "util/u_inlines.h"
|
|
|
|
#include "frontend/drm_driver.h"
|
|
|
|
#include "nouveau/drm/nouveau_drm_public.h"
|
|
|
|
#include "tegra_context.h"
|
|
#include "tegra_resource.h"
|
|
#include "tegra_screen.h"
|
|
|
|
static void tegra_screen_destroy(struct pipe_screen *pscreen)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
screen->gpu->destroy(screen->gpu);
|
|
free(pscreen);
|
|
}
|
|
|
|
static const char *
|
|
tegra_screen_get_name(struct pipe_screen *pscreen)
|
|
{
|
|
return "tegra";
|
|
}
|
|
|
|
static const char *
|
|
tegra_screen_get_vendor(struct pipe_screen *pscreen)
|
|
{
|
|
return "NVIDIA";
|
|
}
|
|
|
|
static const char *
|
|
tegra_screen_get_device_vendor(struct pipe_screen *pscreen)
|
|
{
|
|
return "NVIDIA";
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_param(screen->gpu, param);
|
|
}
|
|
|
|
static float
|
|
tegra_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_paramf(screen->gpu, param);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_shader_param(struct pipe_screen *pscreen, enum pipe_shader_type shader,
|
|
enum pipe_shader_cap param)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_shader_param(screen->gpu, shader, param);
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_video_param(screen->gpu, profile, entrypoint,
|
|
param);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_compute_param(struct pipe_screen *pscreen,
|
|
enum pipe_shader_ir ir_type,
|
|
enum pipe_compute_cap param,
|
|
void *retp)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_compute_param(screen->gpu, ir_type, param,
|
|
retp);
|
|
}
|
|
|
|
static uint64_t
|
|
tegra_screen_get_timestamp(struct pipe_screen *pscreen)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_timestamp(screen->gpu);
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->is_format_supported(screen->gpu, format, target,
|
|
sample_count, storage_sample_count,
|
|
usage);
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->is_video_format_supported(screen->gpu, format, profile,
|
|
entrypoint);
|
|
}
|
|
|
|
static bool
|
|
tegra_screen_can_create_resource(struct pipe_screen *pscreen,
|
|
const struct pipe_resource *template)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->can_create_resource(screen->gpu, template);
|
|
}
|
|
|
|
static int tegra_screen_import_resource(struct tegra_screen *screen,
|
|
struct tegra_resource *resource)
|
|
{
|
|
struct winsys_handle handle;
|
|
bool status;
|
|
int fd, err;
|
|
|
|
memset(&handle, 0, sizeof(handle));
|
|
handle.modifier = DRM_FORMAT_MOD_INVALID;
|
|
handle.type = WINSYS_HANDLE_TYPE_FD;
|
|
|
|
status = screen->gpu->resource_get_handle(screen->gpu, NULL, resource->gpu,
|
|
&handle, 0);
|
|
if (!status)
|
|
return -EINVAL;
|
|
|
|
assert(handle.modifier != DRM_FORMAT_MOD_INVALID);
|
|
|
|
if (handle.modifier == DRM_FORMAT_MOD_INVALID) {
|
|
close(handle.handle);
|
|
return -EINVAL;
|
|
}
|
|
|
|
resource->modifier = handle.modifier;
|
|
resource->stride = handle.stride;
|
|
fd = handle.handle;
|
|
|
|
err = drmPrimeFDToHandle(screen->fd, fd, &resource->handle);
|
|
if (err < 0)
|
|
err = -errno;
|
|
|
|
close(fd);
|
|
|
|
return err;
|
|
}
|
|
|
|
static struct pipe_resource *
|
|
tegra_screen_resource_create(struct pipe_screen *pscreen,
|
|
const struct pipe_resource *template)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
uint64_t modifier = DRM_FORMAT_MOD_INVALID;
|
|
struct tegra_resource *resource;
|
|
int err;
|
|
|
|
resource = calloc(1, sizeof(*resource));
|
|
if (!resource)
|
|
return NULL;
|
|
|
|
/*
|
|
* Applications that create scanout resources without modifiers are very
|
|
* unlikely to support modifiers at all. In that case the resources need
|
|
* to be created with a pitch-linear layout so that they can be properly
|
|
* shared with scanout hardware.
|
|
*
|
|
* Technically it is possible for applications to create resources without
|
|
* specifying a modifier but still query the modifier associated with the
|
|
* resource (e.g. using gbm_bo_get_modifier()) before handing it to the
|
|
* framebuffer creation API (such as the DRM_IOCTL_MODE_ADDFB2 IOCTL).
|
|
*/
|
|
if (template->bind & PIPE_BIND_SCANOUT)
|
|
modifier = DRM_FORMAT_MOD_LINEAR;
|
|
|
|
resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
|
|
template,
|
|
&modifier, 1);
|
|
if (!resource->gpu)
|
|
goto free;
|
|
|
|
/* import scanout buffers for display */
|
|
if (template->bind & PIPE_BIND_SCANOUT) {
|
|
err = tegra_screen_import_resource(screen, resource);
|
|
if (err < 0)
|
|
goto destroy;
|
|
}
|
|
|
|
memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
|
|
pipe_reference_init(&resource->base.reference, 1);
|
|
resource->base.screen = &screen->base;
|
|
|
|
/* use private reference count for wrapped resources */
|
|
resource->gpu->reference.count += 100000000;
|
|
resource->refcount = 100000000;
|
|
|
|
return &resource->base;
|
|
|
|
destroy:
|
|
screen->gpu->resource_destroy(screen->gpu, resource->gpu);
|
|
free:
|
|
free(resource);
|
|
return NULL;
|
|
}
|
|
|
|
/* XXX */
|
|
static struct pipe_resource *
|
|
tegra_screen_resource_create_front(struct pipe_screen *pscreen,
|
|
const struct pipe_resource *template,
|
|
const void *map_front_private)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
struct pipe_resource *resource;
|
|
|
|
resource = screen->gpu->resource_create_front(screen->gpu, template,
|
|
map_front_private);
|
|
if (resource)
|
|
resource->screen = pscreen;
|
|
|
|
return resource;
|
|
}
|
|
|
|
static struct pipe_resource *
|
|
tegra_screen_resource_from_handle(struct pipe_screen *pscreen,
|
|
const struct pipe_resource *template,
|
|
struct winsys_handle *handle,
|
|
unsigned usage)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
struct tegra_resource *resource;
|
|
|
|
resource = calloc(1, sizeof(*resource));
|
|
if (!resource)
|
|
return NULL;
|
|
|
|
resource->gpu = screen->gpu->resource_from_handle(screen->gpu, template,
|
|
handle, usage);
|
|
if (!resource->gpu) {
|
|
free(resource);
|
|
return NULL;
|
|
}
|
|
|
|
memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
|
|
pipe_reference_init(&resource->base.reference, 1);
|
|
resource->base.screen = &screen->base;
|
|
|
|
return &resource->base;
|
|
}
|
|
|
|
/* XXX */
|
|
static struct pipe_resource *
|
|
tegra_screen_resource_from_user_memory(struct pipe_screen *pscreen,
|
|
const struct pipe_resource *template,
|
|
void *buffer)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
struct pipe_resource *resource;
|
|
|
|
resource = screen->gpu->resource_from_user_memory(screen->gpu, template,
|
|
buffer);
|
|
if (resource)
|
|
resource->screen = pscreen;
|
|
|
|
return resource;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct tegra_resource *resource = to_tegra_resource(presource);
|
|
struct tegra_context *context = to_tegra_context(pcontext);
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
bool ret = true;
|
|
|
|
/*
|
|
* Assume that KMS handles for scanout resources will only ever be used
|
|
* to pass buffers into Tegra DRM for display. In all other cases, return
|
|
* the Nouveau handle, assuming they will be used for sharing in DRI2/3.
|
|
*/
|
|
if (handle->type == WINSYS_HANDLE_TYPE_KMS &&
|
|
presource->bind & PIPE_BIND_SCANOUT) {
|
|
handle->modifier = resource->modifier;
|
|
handle->handle = resource->handle;
|
|
handle->stride = resource->stride;
|
|
} else {
|
|
ret = screen->gpu->resource_get_handle(screen->gpu,
|
|
context ? context->gpu : NULL,
|
|
resource->gpu, handle, usage);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
tegra_screen_resource_destroy(struct pipe_screen *pscreen,
|
|
struct pipe_resource *presource)
|
|
{
|
|
struct tegra_resource *resource = to_tegra_resource(presource);
|
|
|
|
/* adjust private reference count */
|
|
p_atomic_add(&resource->gpu->reference.count, -resource->refcount);
|
|
pipe_resource_reference(&resource->gpu, NULL);
|
|
free(resource);
|
|
}
|
|
|
|
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,
|
|
unsigned nboxes,
|
|
struct pipe_box *box)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
struct tegra_context *context = to_tegra_context(pcontext);
|
|
|
|
/* TODO: maybe rejigger for damage regions */
|
|
screen->gpu->flush_frontbuffer(screen->gpu,
|
|
context ? context->gpu : NULL,
|
|
resource, level, layer,
|
|
winsys_drawable_handle, nboxes, box);
|
|
}
|
|
|
|
static void
|
|
tegra_screen_fence_reference(struct pipe_screen *pscreen,
|
|
struct pipe_fence_handle **ptr,
|
|
struct pipe_fence_handle *fence)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
screen->gpu->fence_reference(screen->gpu, ptr, fence);
|
|
}
|
|
|
|
static bool
|
|
tegra_screen_fence_finish(struct pipe_screen *pscreen,
|
|
struct pipe_context *pcontext,
|
|
struct pipe_fence_handle *fence,
|
|
uint64_t timeout)
|
|
{
|
|
struct tegra_context *context = to_tegra_context(pcontext);
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->fence_finish(screen->gpu,
|
|
context ? context->gpu : NULL,
|
|
fence, timeout);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_fence_get_fd(struct pipe_screen *pscreen,
|
|
struct pipe_fence_handle *fence)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->fence_get_fd(screen->gpu, fence);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_driver_query_info(struct pipe_screen *pscreen,
|
|
unsigned int index,
|
|
struct pipe_driver_query_info *info)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_driver_query_info(screen->gpu, index, info);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
|
|
unsigned int index,
|
|
struct pipe_driver_query_group_info *info)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_driver_query_group_info(screen->gpu, index, info);
|
|
}
|
|
|
|
static void
|
|
tegra_screen_query_memory_info(struct pipe_screen *pscreen,
|
|
struct pipe_memory_info *info)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
screen->gpu->query_memory_info(screen->gpu, info);
|
|
}
|
|
|
|
static const void *
|
|
tegra_screen_get_compiler_options(struct pipe_screen *pscreen,
|
|
enum pipe_shader_ir ir,
|
|
enum pipe_shader_type shader)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
const void *options = NULL;
|
|
|
|
if (screen->gpu->get_compiler_options)
|
|
options = screen->gpu->get_compiler_options(screen->gpu, ir, shader);
|
|
|
|
return options;
|
|
}
|
|
|
|
static struct disk_cache *
|
|
tegra_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_disk_shader_cache(screen->gpu);
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
struct pipe_resource tmpl = *template;
|
|
struct tegra_resource *resource;
|
|
int err;
|
|
|
|
resource = calloc(1, sizeof(*resource));
|
|
if (!resource)
|
|
return NULL;
|
|
|
|
/*
|
|
* Assume that resources created with modifiers will always be used for
|
|
* scanout. This is necessary because some of the APIs that are used to
|
|
* create resources with modifiers (e.g. gbm_bo_create_with_modifiers())
|
|
* can't pass along usage information. Adding that capability might be
|
|
* worth adding to remove this ambiguity. Not all future use-cases that
|
|
* involve modifiers may always be targetting scanout hardware.
|
|
*/
|
|
tmpl.bind |= PIPE_BIND_SCANOUT;
|
|
|
|
resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
|
|
&tmpl,
|
|
modifiers,
|
|
count);
|
|
if (!resource->gpu)
|
|
goto free;
|
|
|
|
err = tegra_screen_import_resource(screen, resource);
|
|
if (err < 0)
|
|
goto destroy;
|
|
|
|
memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu));
|
|
pipe_reference_init(&resource->base.reference, 1);
|
|
resource->base.screen = &screen->base;
|
|
|
|
return &resource->base;
|
|
|
|
destroy:
|
|
screen->gpu->resource_destroy(screen->gpu, resource->gpu);
|
|
free:
|
|
free(resource);
|
|
return NULL;
|
|
}
|
|
|
|
static void tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
|
|
enum pipe_format format,
|
|
int max, uint64_t *modifiers,
|
|
unsigned int *external_only,
|
|
int *count)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
screen->gpu->query_dmabuf_modifiers(screen->gpu, format, max, modifiers,
|
|
external_only, count);
|
|
}
|
|
|
|
static bool
|
|
tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
|
|
uint64_t modifier,
|
|
enum pipe_format format,
|
|
bool *external_only)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->is_dmabuf_modifier_supported(screen->gpu, modifier,
|
|
format, external_only);
|
|
}
|
|
|
|
static unsigned int
|
|
tegra_screen_get_dmabuf_modifier_planes(struct pipe_screen *pscreen,
|
|
uint64_t modifier,
|
|
enum pipe_format format)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->get_dmabuf_modifier_planes ?
|
|
screen->gpu->get_dmabuf_modifier_planes(screen->gpu, modifier, format) :
|
|
util_format_get_num_planes(format);
|
|
}
|
|
|
|
static struct pipe_memory_object *
|
|
tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
|
|
struct winsys_handle *handle,
|
|
bool dedicated)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->gpu->memobj_create_from_handle(screen->gpu, handle,
|
|
dedicated);
|
|
}
|
|
|
|
static int
|
|
tegra_screen_get_fd(struct pipe_screen *pscreen)
|
|
{
|
|
struct tegra_screen *screen = to_tegra_screen(pscreen);
|
|
|
|
return screen->fd;
|
|
}
|
|
|
|
struct pipe_screen *
|
|
tegra_screen_create(int fd)
|
|
{
|
|
struct tegra_screen *screen;
|
|
const char * const drivers[] = {"nouveau"};
|
|
|
|
screen = calloc(1, sizeof(*screen));
|
|
if (!screen)
|
|
return NULL;
|
|
|
|
screen->fd = fd;
|
|
|
|
screen->gpu_fd =
|
|
loader_open_render_node_platform_device(drivers, ARRAY_SIZE(drivers));
|
|
if (screen->gpu_fd < 0) {
|
|
if (errno != ENOENT)
|
|
fprintf(stderr, "failed to open GPU device: %s\n", strerror(errno));
|
|
|
|
free(screen);
|
|
return NULL;
|
|
}
|
|
|
|
screen->gpu = nouveau_drm_screen_create(screen->gpu_fd);
|
|
if (!screen->gpu) {
|
|
fprintf(stderr, "failed to create GPU screen\n");
|
|
close(screen->gpu_fd);
|
|
free(screen);
|
|
return NULL;
|
|
}
|
|
|
|
screen->base.destroy = tegra_screen_destroy;
|
|
screen->base.get_name = tegra_screen_get_name;
|
|
screen->base.get_vendor = tegra_screen_get_vendor;
|
|
screen->base.get_device_vendor = tegra_screen_get_device_vendor;
|
|
screen->base.get_screen_fd = tegra_screen_get_fd;
|
|
screen->base.get_param = tegra_screen_get_param;
|
|
screen->base.get_paramf = tegra_screen_get_paramf;
|
|
screen->base.get_shader_param = tegra_screen_get_shader_param;
|
|
screen->base.get_video_param = tegra_screen_get_video_param;
|
|
screen->base.get_compute_param = tegra_screen_get_compute_param;
|
|
screen->base.get_timestamp = tegra_screen_get_timestamp;
|
|
screen->base.context_create = tegra_screen_context_create;
|
|
screen->base.is_format_supported = tegra_screen_is_format_supported;
|
|
screen->base.is_video_format_supported = tegra_screen_is_video_format_supported;
|
|
|
|
/* allow fallback implementation if GPU driver doesn't implement it */
|
|
if (screen->gpu->can_create_resource)
|
|
screen->base.can_create_resource = tegra_screen_can_create_resource;
|
|
|
|
screen->base.resource_create = tegra_screen_resource_create;
|
|
screen->base.resource_create_front = tegra_screen_resource_create_front;
|
|
screen->base.resource_from_handle = tegra_screen_resource_from_handle;
|
|
screen->base.resource_from_user_memory = tegra_screen_resource_from_user_memory;
|
|
screen->base.resource_get_handle = tegra_screen_resource_get_handle;
|
|
screen->base.resource_destroy = tegra_screen_resource_destroy;
|
|
|
|
screen->base.flush_frontbuffer = tegra_screen_flush_frontbuffer;
|
|
screen->base.fence_reference = tegra_screen_fence_reference;
|
|
screen->base.fence_finish = tegra_screen_fence_finish;
|
|
screen->base.fence_get_fd = tegra_screen_fence_get_fd;
|
|
|
|
screen->base.get_driver_query_info = tegra_screen_get_driver_query_info;
|
|
screen->base.get_driver_query_group_info = tegra_screen_get_driver_query_group_info;
|
|
screen->base.query_memory_info = tegra_screen_query_memory_info;
|
|
|
|
screen->base.get_compiler_options = tegra_screen_get_compiler_options;
|
|
screen->base.get_disk_shader_cache = tegra_screen_get_disk_shader_cache;
|
|
|
|
screen->base.resource_create_with_modifiers = tegra_screen_resource_create_with_modifiers;
|
|
screen->base.query_dmabuf_modifiers = tegra_screen_query_dmabuf_modifiers;
|
|
screen->base.is_dmabuf_modifier_supported = tegra_screen_is_dmabuf_modifier_supported;
|
|
screen->base.get_dmabuf_modifier_planes = tegra_screen_get_dmabuf_modifier_planes;
|
|
screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
|
|
|
|
return &screen->base;
|
|
}
|