mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 00:30:13 +01:00
gallium: add renderonly library
This a very lightweight library to add basic support for renderonly
GPUs. A kms gallium driver must specify how a renderonly_scanout
objects gets created. Also it must provide file handles to the used
kms device and the used gpu device.
This could look like:
struct renderonly ro = {
.create_for_resource = renderonly_create_gpu_import_for_resource,
.kms_fd = fd,
.gpu_fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC)
};
The renderonly_scanout object exits for two reasons:
- Do any special treatment for a scanout resource like importing the
GPU resource into the scanout hw.
- Make it easier for a gallium driver to detect if anything special
needs to be done in flush_resource(..) like a resolve to linear.
A GPU gallium driver which gets used as renderonly GPU needs to be
aware of the renderonly library.
This library will likely break android support and hopefully will get
replaced with a better solution based on gbm2.
Changes from V1 -> V2:
- reworked the lifecycle of renderonly object (suggested by Nicolai Hähnle)
- killed the midlayer (suggested by Thierry Reding)
- made the API more explicit regarding gpu and kms fd's
- added some docs
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Acked-by: Emil Velikov <emil.velikov@collabora.com>
Tested-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
parent
27a1c7ffbd
commit
848b49b288
5 changed files with 303 additions and 0 deletions
|
|
@ -50,6 +50,11 @@ GALLIUM_COMMON_LIB_DEPS = \
|
||||||
$(PTHREAD_LIBS) \
|
$(PTHREAD_LIBS) \
|
||||||
$(DLOPEN_LIBS)
|
$(DLOPEN_LIBS)
|
||||||
|
|
||||||
|
if HAVE_LIBDRM
|
||||||
|
GALLIUM_COMMON_LIB_DEPS += \
|
||||||
|
$(LIBDRM_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
GALLIUM_WINSYS_CFLAGS = \
|
GALLIUM_WINSYS_CFLAGS = \
|
||||||
-I$(top_srcdir)/src \
|
-I$(top_srcdir)/src \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,16 @@ libgallium_la_SOURCES = \
|
||||||
$(NIR_SOURCES) \
|
$(NIR_SOURCES) \
|
||||||
$(GENERATED_SOURCES)
|
$(GENERATED_SOURCES)
|
||||||
|
|
||||||
|
if HAVE_LIBDRM
|
||||||
|
|
||||||
|
AM_CFLAGS += \
|
||||||
|
$(LIBDRM_CFLAGS)
|
||||||
|
|
||||||
|
libgallium_la_SOURCES += \
|
||||||
|
$(RENDERONLY_SOURCES)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
if HAVE_GALLIUM_LLVM
|
if HAVE_GALLIUM_LLVM
|
||||||
|
|
||||||
AM_CFLAGS += \
|
AM_CFLAGS += \
|
||||||
|
|
|
||||||
|
|
@ -435,3 +435,7 @@ GALLIVM_SOURCES := \
|
||||||
draw/draw_llvm_sample.c \
|
draw/draw_llvm_sample.c \
|
||||||
draw/draw_pt_fetch_shade_pipeline_llvm.c \
|
draw/draw_pt_fetch_shade_pipeline_llvm.c \
|
||||||
draw/draw_vs_llvm.c
|
draw/draw_vs_llvm.c
|
||||||
|
|
||||||
|
RENDERONLY_SOURCES := \
|
||||||
|
renderonly/renderonly.c \
|
||||||
|
renderonly/renderonly.h
|
||||||
|
|
|
||||||
175
src/gallium/auxiliary/renderonly/renderonly.c
Normal file
175
src/gallium/auxiliary/renderonly/renderonly.c
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "renderonly/renderonly.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
|
#include "state_tracker/drm_driver.h"
|
||||||
|
#include "pipe/p_screen.h"
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
|
||||||
|
struct renderonly *
|
||||||
|
renderonly_dup(const struct renderonly *ro)
|
||||||
|
{
|
||||||
|
struct renderonly *copy;
|
||||||
|
|
||||||
|
copy = CALLOC_STRUCT(renderonly);
|
||||||
|
if (!copy)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(copy, ro, sizeof(*ro));
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_scanout_for_prime(struct pipe_resource *rsc, struct renderonly *ro)
|
||||||
|
{
|
||||||
|
struct renderonly_scanout *scanout;
|
||||||
|
|
||||||
|
scanout = CALLOC_STRUCT(renderonly_scanout);
|
||||||
|
if (!scanout)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
scanout->prime = rsc;
|
||||||
|
|
||||||
|
return scanout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
renderonly_scanout_destroy(struct renderonly_scanout *scanout)
|
||||||
|
{
|
||||||
|
FREE(scanout);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc,
|
||||||
|
struct renderonly *ro)
|
||||||
|
{
|
||||||
|
struct pipe_screen *screen = rsc->screen;
|
||||||
|
struct renderonly_scanout *scanout;
|
||||||
|
struct winsys_handle handle;
|
||||||
|
int prime_fd, err;
|
||||||
|
struct drm_mode_create_dumb create_dumb = {
|
||||||
|
.width = rsc->width0,
|
||||||
|
.height = rsc->height0,
|
||||||
|
.bpp = 32,
|
||||||
|
};
|
||||||
|
struct drm_mode_destroy_dumb destroy_dumb = { };
|
||||||
|
|
||||||
|
scanout = CALLOC_STRUCT(renderonly_scanout);
|
||||||
|
if (!scanout)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* create dumb buffer at scanout GPU */
|
||||||
|
err = ioctl(ro->kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
|
||||||
|
if (err < 0) {
|
||||||
|
fprintf(stderr, "DRM_IOCTL_MODE_CREATE_DUMB failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
goto free_scanout;
|
||||||
|
}
|
||||||
|
|
||||||
|
scanout->handle = create_dumb.handle;
|
||||||
|
scanout->stride = create_dumb.pitch;
|
||||||
|
|
||||||
|
/* export dumb buffer */
|
||||||
|
err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC,
|
||||||
|
&prime_fd);
|
||||||
|
if (err < 0) {
|
||||||
|
fprintf(stderr, "failed to export dumb buffer: %s\n", strerror(errno));
|
||||||
|
goto free_dumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* import dumb buffer */
|
||||||
|
handle.type = DRM_API_HANDLE_TYPE_FD;
|
||||||
|
handle.handle = prime_fd;
|
||||||
|
handle.stride = create_dumb.pitch;
|
||||||
|
|
||||||
|
scanout->prime = screen->resource_from_handle(screen, rsc,
|
||||||
|
&handle, PIPE_HANDLE_USAGE_READ_WRITE);
|
||||||
|
|
||||||
|
if (!scanout->prime) {
|
||||||
|
fprintf(stderr, "failed to create resource_from_handle: %s\n", strerror(errno));
|
||||||
|
goto free_dumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scanout;
|
||||||
|
|
||||||
|
free_dumb:
|
||||||
|
destroy_dumb.handle = scanout->handle;
|
||||||
|
ioctl(ro->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
|
||||||
|
|
||||||
|
free_scanout:
|
||||||
|
FREE(scanout);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc,
|
||||||
|
struct renderonly *ro)
|
||||||
|
{
|
||||||
|
struct pipe_screen *screen = rsc->screen;
|
||||||
|
struct renderonly_scanout *scanout;
|
||||||
|
boolean status;
|
||||||
|
int fd, err;
|
||||||
|
struct winsys_handle handle = {
|
||||||
|
.type = DRM_API_HANDLE_TYPE_FD
|
||||||
|
};
|
||||||
|
|
||||||
|
scanout = CALLOC_STRUCT(renderonly_scanout);
|
||||||
|
if (!scanout)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
status = screen->resource_get_handle(screen, NULL, rsc, &handle,
|
||||||
|
PIPE_HANDLE_USAGE_READ_WRITE);
|
||||||
|
if (!status)
|
||||||
|
goto free_scanout;
|
||||||
|
|
||||||
|
scanout->stride = handle.stride;
|
||||||
|
fd = handle.handle;
|
||||||
|
|
||||||
|
err = drmPrimeFDToHandle(ro->kms_fd, fd, &scanout->handle);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
fprintf(stderr, "drmPrimeFDToHandle() failed: %s\n", strerror(errno));
|
||||||
|
goto free_scanout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scanout;
|
||||||
|
|
||||||
|
free_scanout:
|
||||||
|
FREE(scanout);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
109
src/gallium/auxiliary/renderonly/renderonly.h
Normal file
109
src/gallium/auxiliary/renderonly/renderonly.h
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RENDERONLY_H
|
||||||
|
#define RENDERONLY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "state_tracker/drm_driver.h"
|
||||||
|
#include "pipe/p_state.h"
|
||||||
|
|
||||||
|
struct renderonly_scanout {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t stride;
|
||||||
|
|
||||||
|
struct pipe_resource *prime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct renderonly {
|
||||||
|
/**
|
||||||
|
* Create a renderonly_scanout object for scanout resource.
|
||||||
|
*
|
||||||
|
* This function creates a renderonly_scanout object based on the provided
|
||||||
|
* resource. The library is designed that the driver specific pipe_resource
|
||||||
|
* struct holds a pointer to a renderonly_scanout struct.
|
||||||
|
*
|
||||||
|
* struct driver_resource {
|
||||||
|
* struct pipe_resource base;
|
||||||
|
* struct renderonly_scanout *scanout;
|
||||||
|
* ...
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* The renderonly_scanout object exits for two reasons:
|
||||||
|
* - Do any special treatment for a scanout resource like importing the GPU
|
||||||
|
* resource into the scanout hw.
|
||||||
|
* - Make it easier for a gallium driver to detect if anything special needs
|
||||||
|
* to be done in flush_resource(..) like a resolve to linear.
|
||||||
|
*/
|
||||||
|
struct renderonly_scanout *(*create_for_resource)(struct pipe_resource *rsc,
|
||||||
|
struct renderonly *ro);
|
||||||
|
int kms_fd;
|
||||||
|
int gpu_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct renderonly *
|
||||||
|
renderonly_dup(const struct renderonly *ro);
|
||||||
|
|
||||||
|
static inline struct renderonly_scanout *
|
||||||
|
renderonly_scanout_for_resource(struct pipe_resource *rsc, struct renderonly *ro)
|
||||||
|
{
|
||||||
|
return ro->create_for_resource(rsc, ro);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_scanout_for_prime(struct pipe_resource *rsc, struct renderonly *ro);
|
||||||
|
|
||||||
|
void
|
||||||
|
renderonly_scanout_destroy(struct renderonly_scanout *scanout);
|
||||||
|
|
||||||
|
static inline boolean
|
||||||
|
renderonly_get_handle(struct renderonly_scanout *scanout,
|
||||||
|
struct winsys_handle *handle)
|
||||||
|
{
|
||||||
|
if (!scanout)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
handle->handle = scanout->handle;
|
||||||
|
handle->stride = scanout->stride;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a dumb buffer object for a resource at scanout hw.
|
||||||
|
*/
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc,
|
||||||
|
struct renderonly *ro);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import GPU resource into scanout hw.
|
||||||
|
*/
|
||||||
|
struct renderonly_scanout *
|
||||||
|
renderonly_create_gpu_import_for_resource(struct pipe_resource *rsc,
|
||||||
|
struct renderonly *ro);
|
||||||
|
|
||||||
|
#endif /* RENDERONLY_H_ */
|
||||||
Loading…
Add table
Reference in a new issue