diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/SConscript | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/target-helpers/inline_drm_helper.h | 32 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri2.c | 63 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_screen.h | 3 | ||||
-rw-r--r-- | src/gallium/targets/dri/Makefile.am | 6 | ||||
-rw-r--r-- | src/gallium/targets/dri/SConscript | 4 | ||||
-rw-r--r-- | src/gallium/winsys/Makefile.am | 4 | ||||
-rw-r--r-- | src/gallium/winsys/sw/kms-dri/Makefile.am | 32 | ||||
-rw-r--r-- | src/gallium/winsys/sw/kms-dri/SConscript | 26 | ||||
-rw-r--r-- | src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 312 | ||||
-rw-r--r-- | src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h | 37 |
11 files changed, 523 insertions, 0 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 8d9849e0009..cb617200752 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -71,6 +71,10 @@ if env['dri']: ]) SConscript([ + 'winsys/sw/kms-dri/SConscript', + ]) + + SConscript([ 'winsys/svga/drm/SConscript', ]) diff --git a/src/gallium/auxiliary/target-helpers/inline_drm_helper.h b/src/gallium/auxiliary/target-helpers/inline_drm_helper.h index 5656ef076cf..751ceb1e70e 100644 --- a/src/gallium/auxiliary/target-helpers/inline_drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/inline_drm_helper.h @@ -8,6 +8,11 @@ #include "dri_screen.h" #endif +#if GALLIUM_SOFTPIPE +#include "target-helpers/inline_sw_helper.h" +#include "sw/kms-dri/kms_dri_sw_winsys.h" +#endif + #if GALLIUM_I915 #include "i915/drm/i915_drm_public.h" #include "i915/i915_public.h" @@ -53,6 +58,33 @@ static char* driver_name = NULL; /* XXX: We need to teardown the winsys if *screen_create() fails. */ +#if defined(GALLIUM_SOFTPIPE) +#if defined(DRI_TARGET) + +const __DRIextension **__driDriverGetExtensions_kms_swrast(void); + +PUBLIC const __DRIextension **__driDriverGetExtensions_kms_swrast(void) +{ + globalDriverAPI = &dri_kms_driver_api; + return galliumdrm_driver_extensions; +} + +struct pipe_screen * +kms_swrast_create_screen(int fd) +{ + struct sw_winsys *sws; + struct pipe_screen *screen; + + sws = kms_dri_create_winsys(fd); + if (!sws) + return NULL; + + screen = sw_screen_create(sws); + return screen ? debug_screen_wrap(screen) : NULL; +} +#endif +#endif + #if defined(GALLIUM_I915) #if defined(DRI_TARGET) diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index fcca4875229..f70b723a07b 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -1297,6 +1297,48 @@ fail: return NULL; } +/** + * This is the driver specific part of the createNewScreen entry point. + * + * Returns the struct gl_config supported by this driver. + */ +static const __DRIconfig ** +dri_kms_init_screen(__DRIscreen * sPriv) +{ +#if GALLIUM_STATIC_TARGETS + const __DRIconfig **configs; + struct dri_screen *screen; + struct pipe_screen *pscreen = NULL; + + screen = CALLOC_STRUCT(dri_screen); + if (!screen) + return NULL; + + screen->sPriv = sPriv; + screen->fd = sPriv->fd; + + sPriv->driverPrivate = (void *)screen; + + pscreen = kms_swrast_create_screen(screen->fd); + sPriv->extensions = dri_screen_extensions; + + /* dri_init_screen_helper checks pscreen for us */ + configs = dri_init_screen_helper(screen, pscreen, "swrast"); + if (!configs) + goto fail; + + screen->auto_fake_front = dri_with_format(sPriv); + screen->broken_invalidate = !sPriv->dri2.useInvalidate; + screen->lookup_egl_image = dri2_lookup_egl_image; + + return configs; +fail: + dri_destroy_screen_helper(screen); + FREE(screen); +#endif // GALLIUM_STATIC_TARGETS + return NULL; +} + static boolean dri2_create_buffer(__DRIscreen * sPriv, __DRIdrawable * dPriv, @@ -1335,6 +1377,27 @@ const struct __DriverAPIRec galliumdrm_driver_api = { .ReleaseBuffer = dri2_release_buffer, }; +/** + * DRI driver virtual function table. + * + * KMS/DRM version of the DriverAPI above sporting a different InitScreen + * hook. The latter is used to explicitly initialise the kms_swrast driver + * rather than selecting the approapriate driver as suggested by the loader. + */ +const struct __DriverAPIRec dri_kms_driver_api = { + .InitScreen = dri_kms_init_screen, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = dri2_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + + .AllocateBuffer = dri2_allocate_buffer, + .ReleaseBuffer = dri2_release_buffer, +}; + /* This is the table of extensions that the loader will dlsym() for. */ const __DRIextension *galliumdrm_driver_extensions[] = { &driCoreExtension.base, diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index f421b68aed7..993ad2abe09 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -146,6 +146,9 @@ dri_destroy_screen_helper(struct dri_screen * screen); void dri_destroy_screen(__DRIscreen * sPriv); +extern struct pipe_screen *kms_swrast_create_screen(int fd); +extern const struct __DriverAPIRec dri_kms_driver_api; + extern const struct __DriverAPIRec galliumdrm_driver_api; extern const __DRIextension *galliumdrm_driver_extensions[]; extern const struct __DriverAPIRec galliumsw_driver_api; diff --git a/src/gallium/targets/dri/Makefile.am b/src/gallium/targets/dri/Makefile.am index 0816b8c9b25..c7fe4106ab0 100644 --- a/src/gallium/targets/dri/Makefile.am +++ b/src/gallium/targets/dri/Makefile.am @@ -146,6 +146,12 @@ STATIC_TARGET_CPPFLAGS += -DGALLIUM_SOFTPIPE STATIC_TARGET_LIB_DEPS += \ $(top_builddir)/src/gallium/winsys/sw/dri/libswdri.la \ $(top_builddir)/src/gallium/drivers/softpipe/libsoftpipe.la + +if HAVE_DRI2 +MEGADRIVERS += kms_swrast +STATIC_TARGET_LIB_DEPS += \ + $(top_builddir)/src/gallium/winsys/sw/kms-dri/libswkmsdri.la +endif endif if NEED_GALLIUM_LLVMPIPE_DRIVER diff --git a/src/gallium/targets/dri/SConscript b/src/gallium/targets/dri/SConscript index faf370f2c34..8cb90b3153f 100644 --- a/src/gallium/targets/dri/SConscript +++ b/src/gallium/targets/dri/SConscript @@ -36,6 +36,7 @@ env.Prepend(LIBS = [ svgadrm, svga, ws_dri, + ws_kms_dri, softpipe, libloader, mesa, @@ -55,6 +56,9 @@ module = env.LoadableModule( env.Command('vmwgfx_dri.so', 'gallium_dri.so', "ln -f ${SOURCE} ${TARGET}") # swrast_dri.so env.Command('swrast_dri.so', 'gallium_dri.so', "ln -f ${SOURCE} ${TARGET}") +# kms_swrast_dri.so +env.Command('kms_swrast_dri.so', 'gallium_dri.so', "ln -f ${SOURCE} ${TARGET}") env.Alias('dri-vmwgfx', module) env.Alias('dri-swrast', module) +env.Alias('dri-kms-swrast', module) diff --git a/src/gallium/winsys/Makefile.am b/src/gallium/winsys/Makefile.am index 7c4e5ad564c..4c01afdee20 100644 --- a/src/gallium/winsys/Makefile.am +++ b/src/gallium/winsys/Makefile.am @@ -30,6 +30,10 @@ if HAVE_DRISW SUBDIRS += sw/dri endif +if HAVE_DRI2 +SUBDIRS += sw/kms-dri +endif + if HAVE_EGL_PLATFORM_FBDEV SUBDIRS += sw/fbdev endif diff --git a/src/gallium/winsys/sw/kms-dri/Makefile.am b/src/gallium/winsys/sw/kms-dri/Makefile.am new file mode 100644 index 00000000000..cb3b61deea6 --- /dev/null +++ b/src/gallium/winsys/sw/kms-dri/Makefile.am @@ -0,0 +1,32 @@ +# Copyright © 2012 Intel Corporation +# 2013 Red Hat, Inc. +# +# 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 $(top_srcdir)/src/gallium/Automake.inc + +AM_CFLAGS = \ + $(GALLIUM_WINSYS_CFLAGS) \ + $(LIBDRM_CFLAGS) + +noinst_LTLIBRARIES = libswkmsdri.la + +libswkmsdri_la_SOURCES = kms_dri_sw_winsys.c diff --git a/src/gallium/winsys/sw/kms-dri/SConscript b/src/gallium/winsys/sw/kms-dri/SConscript new file mode 100644 index 00000000000..0a6c335cbd7 --- /dev/null +++ b/src/gallium/winsys/sw/kms-dri/SConscript @@ -0,0 +1,26 @@ +####################################################################### +# SConscript for kms-dri winsys + + +Import('*') + +if env['platform'] not in ('linux'): + Return() + +env = env.Clone() + +env.PkgUseModules('DRM') + +env.Append(CPPPATH = [ +# 'include', + '#/src/gallium/include', + '#/src/gallium/auxiliary', +]) + +ws_kms_dri = env.ConvenienceLibrary( + target = 'ws_kms_dri', + source = [ + 'kms_dri_sw_winsys.c', + ] +) +Export('ws_kms_dri') diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c new file mode 100644 index 00000000000..e21c4c2627a --- /dev/null +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c @@ -0,0 +1,312 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * Copyright 2010 George Sapountzis <[email protected]> + * 2013 Red Hat, Inc. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <limits.h> + +#include <sys/types.h> +#include <sys/mman.h> +#include <unistd.h> +#include <dlfcn.h> +#include <xf86drm.h> + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_double_list.h" + +#include "state_tracker/sw_winsys.h" +#include "state_tracker/drm_driver.h" + +#if 0 +#define DEBUG(msg, ...) fprintf(stderr, msg, __VA_ARGS__) +#else +#define DEBUG(msg, ...) +#endif + +struct sw_winsys; + +struct sw_winsys *kms_dri_create_winsys(int fd); + +struct kms_sw_displaytarget +{ + enum pipe_format format; + unsigned width; + unsigned height; + unsigned stride; + unsigned size; + + uint32_t handle; + void *mapped; + + int ref_count; + struct list_head link; +}; + +struct kms_sw_winsys +{ + struct sw_winsys base; + + int fd; + struct list_head bo_list; +}; + +static INLINE struct kms_sw_displaytarget * +kms_sw_displaytarget( struct sw_displaytarget *dt ) +{ + return (struct kms_sw_displaytarget *)dt; +} + +static INLINE struct kms_sw_winsys * +kms_sw_winsys( struct sw_winsys *ws ) +{ + return (struct kms_sw_winsys *)ws; +} + + +static boolean +kms_sw_is_displaytarget_format_supported( struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format ) +{ + /* TODO: check visuals or other sensible thing here */ + return TRUE; +} + +static struct sw_displaytarget * +kms_sw_displaytarget_create(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) +{ + struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); + struct kms_sw_displaytarget *kms_sw_dt; + struct drm_mode_create_dumb create_req; + struct drm_mode_destroy_dumb destroy_req; + int ret; + + kms_sw_dt = CALLOC_STRUCT(kms_sw_displaytarget); + if(!kms_sw_dt) + goto no_dt; + + kms_sw_dt->ref_count = 1; + + kms_sw_dt->format = format; + kms_sw_dt->width = width; + kms_sw_dt->height = height; + + create_req.bpp = 32; + create_req.width = width; + create_req.height = height; + create_req.handle = 0; + ret = drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_req); + if (ret) + goto free_bo; + + kms_sw_dt->stride = create_req.pitch; + kms_sw_dt->size = create_req.size; + kms_sw_dt->handle = create_req.handle; + + list_add(&kms_sw_dt->link, &kms_sw->bo_list); + + DEBUG("KMS-DEBUG: created buffer %u (size %u)\n", kms_sw_dt->handle, kms_sw_dt->size); + + *stride = kms_sw_dt->stride; + return (struct sw_displaytarget *)kms_sw_dt; + + free_bo: + memset(&destroy_req, 0, sizeof destroy_req); + destroy_req.handle = create_req.handle; + drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_req); + FREE(kms_sw_dt); + no_dt: + return NULL; +} + +static void +kms_sw_displaytarget_destroy(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct drm_mode_destroy_dumb destroy_req; + + kms_sw_dt->ref_count --; + if (kms_sw_dt->ref_count > 0) + return; + + memset(&destroy_req, 0, sizeof destroy_req); + destroy_req.handle = kms_sw_dt->handle; + drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_req); + + list_del(&kms_sw_dt->link); + + DEBUG("KMS-DEBUG: destroyed buffer %u\n", kms_sw_dt->handle); + + FREE(kms_sw_dt); +} + +static void * +kms_sw_displaytarget_map(struct sw_winsys *ws, + struct sw_displaytarget *dt, + unsigned flags) +{ + struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + struct drm_mode_map_dumb map_req; + int prot, ret; + + memset(&map_req, 0, sizeof map_req); + map_req.handle = kms_sw_dt->handle; + ret = drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_req); + if (ret) + return NULL; + + prot = (flags == PIPE_TRANSFER_READ) ? PROT_READ : (PROT_READ | PROT_WRITE); + kms_sw_dt->mapped = mmap(0, kms_sw_dt->size, prot, MAP_SHARED, + kms_sw->fd, map_req.offset); + + if (kms_sw_dt->mapped == MAP_FAILED) + return NULL; + + DEBUG("KMS-DEBUG: mapped buffer %u (size %u) at %p\n", + kms_sw_dt->handle, kms_sw_dt->size, kms_sw_dt->mapped); + + return kms_sw_dt->mapped; +} + +static void +kms_sw_displaytarget_unmap(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + + DEBUG("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->mapped); + + munmap(kms_sw_dt->mapped, kms_sw_dt->size); + kms_sw_dt->mapped = NULL; +} + +static struct sw_displaytarget * +kms_sw_displaytarget_from_handle(struct sw_winsys *ws, + const struct pipe_resource *templ, + struct winsys_handle *whandle, + unsigned *stride) +{ + struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws); + struct kms_sw_displaytarget *kms_sw_dt; + + LIST_FOR_EACH_ENTRY(kms_sw_dt, &kms_sw->bo_list, link) { + if (kms_sw_dt->handle == whandle->handle) { + kms_sw_dt->ref_count++; + + DEBUG("KMS-DEBUG: imported buffer %u (size %u)\n", kms_sw_dt->handle, kms_sw_dt->size); + + *stride = kms_sw_dt->stride; + return (struct sw_displaytarget *)kms_sw_dt; + } + } + + assert(0); + return NULL; +} + +static boolean +kms_sw_displaytarget_get_handle(struct sw_winsys *winsys, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) +{ + struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt); + + assert(whandle->type == DRM_API_HANDLE_TYPE_SHARED); + whandle->handle = kms_sw_dt->handle; + whandle->stride = kms_sw_dt->stride; + return TRUE; +} + +static void +kms_sw_displaytarget_display(struct sw_winsys *ws, + struct sw_displaytarget *dt, + void *context_private, + struct pipe_box *box) +{ + /* This function should not be called, instead the dri2 loader should + handle swap buffers internally. + */ + assert(0); +} + + +static void +kms_destroy_sw_winsys(struct sw_winsys *winsys) +{ + FREE(winsys); +} + +struct sw_winsys * +kms_dri_create_winsys(int fd) +{ + struct kms_sw_winsys *ws; + + ws = CALLOC_STRUCT(kms_sw_winsys); + if (!ws) + return NULL; + + ws->fd = fd; + list_inithead(&ws->bo_list); + + ws->base.destroy = kms_destroy_sw_winsys; + + ws->base.is_displaytarget_format_supported = kms_sw_is_displaytarget_format_supported; + + /* screen texture functions */ + ws->base.displaytarget_create = kms_sw_displaytarget_create; + ws->base.displaytarget_destroy = kms_sw_displaytarget_destroy; + ws->base.displaytarget_from_handle = kms_sw_displaytarget_from_handle; + ws->base.displaytarget_get_handle = kms_sw_displaytarget_get_handle; + + /* texture functions */ + ws->base.displaytarget_map = kms_sw_displaytarget_map; + ws->base.displaytarget_unmap = kms_sw_displaytarget_unmap; + + ws->base.displaytarget_display = kms_sw_displaytarget_display; + + return &ws->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */
\ No newline at end of file diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h new file mode 100644 index 00000000000..e276a723466 --- /dev/null +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * Copyright 2010 George Sapountzis <[email protected]> + * 2013 Red Hat, Inc. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +#ifndef KMS_DRI_SW_WINSYS +#define KMS_DRI_SW_WINSYS + +struct sw_winsys; + +struct sw_winsys *kms_dri_create_winsys(int fd); + +#endif |