loader: Add dri3 helper
v2: From Martin Peres - Try to fit in the 80-col limit as much as possible v3: From Martin Peres - introduce loader_dri3_helper.la to avoid dragging the xcb dep everywhere (Kristian & Emil) - get rid of the width, height, dri_screen and is_different_gpu vfuncs (Kristian) - replace the create/destroy functions with init/fini for dri3 drawables - prefix static functions with dri3_ and exported ones with loader_dri3 (Emil) - keep the function definition consistent (Emil) Signed-off-by: Boyan Ding <boyan.j.ding@gmail.com> Signed-off-by: Martin Peres <martin.peres@linux.intel.com> Reviewed-by: Kristian Høgsberg <krh@bitplanet.net> Reviewed-by: Emil Velikov <emil.velikov@collabora.co.uk>
This commit is contained in:
@@ -1226,7 +1226,8 @@ xyesno)
|
|||||||
|
|
||||||
if test x"$enable_dri3" = xyes; then
|
if test x"$enable_dri3" = xyes; then
|
||||||
PKG_CHECK_EXISTS([xcb >= $XCB_REQUIRED], [], AC_MSG_ERROR([DRI3 requires xcb >= $XCB_REQUIRED]))
|
PKG_CHECK_EXISTS([xcb >= $XCB_REQUIRED], [], AC_MSG_ERROR([DRI3 requires xcb >= $XCB_REQUIRED]))
|
||||||
dri_modules="$dri_modules xcb-dri3 xcb-present xcb-sync xshmfence >= $XSHMFENCE_REQUIRED"
|
dri3_modules="xcb-dri3 xcb-present xcb-sync xshmfence >= $XSHMFENCE_REQUIRED"
|
||||||
|
PKG_CHECK_MODULES([XCB_DRI3], [$dri3_modules])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test x"$dri_platform" = xapple ; then
|
if test x"$dri_platform" = xapple ; then
|
||||||
|
@@ -133,6 +133,8 @@ if HAVE_DRI3
|
|||||||
libglx_la_SOURCES += \
|
libglx_la_SOURCES += \
|
||||||
dri3_glx.c \
|
dri3_glx.c \
|
||||||
dri3_priv.h
|
dri3_priv.h
|
||||||
|
|
||||||
|
libglx_la_LIBADD += $(XCB_DRI3_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAVE_APPLEDRI
|
if HAVE_APPLEDRI
|
||||||
|
@@ -23,7 +23,7 @@ include Makefile.sources
|
|||||||
|
|
||||||
EXTRA_DIST = SConscript
|
EXTRA_DIST = SConscript
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libloader.la
|
noinst_LTLIBRARIES = libloader.la libloader_dri3_helper.la
|
||||||
|
|
||||||
libloader_la_CPPFLAGS = \
|
libloader_la_CPPFLAGS = \
|
||||||
$(DEFINES) \
|
$(DEFINES) \
|
||||||
@@ -55,3 +55,16 @@ libloader_la_CPPFLAGS += \
|
|||||||
libloader_la_LIBADD += \
|
libloader_la_LIBADD += \
|
||||||
$(LIBDRM_LIBS)
|
$(LIBDRM_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if HAVE_DRI3
|
||||||
|
libloader_dri3_helper_la_CPPFLAGS = \
|
||||||
|
$(DEFINES) \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_srcdir)/src \
|
||||||
|
$(LIBDRM_CFLAGS)
|
||||||
|
|
||||||
|
libloader_dri3_helper_la_SOURCES = \
|
||||||
|
loader_dri3_helper.c \
|
||||||
|
loader_dri3_helper.h
|
||||||
|
libloader_dri3_helper_la_LIBADD = $(XCB_DRI3_LIBS)
|
||||||
|
endif
|
||||||
|
1376
src/loader/loader_dri3_helper.c
Normal file
1376
src/loader/loader_dri3_helper.c
Normal file
File diff suppressed because it is too large
Load Diff
232
src/loader/loader_dri3_helper.h
Normal file
232
src/loader/loader_dri3_helper.h
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Keith Packard
|
||||||
|
* Copyright © 2015 Boyan Ding
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOADER_DRI3_HEADER_H
|
||||||
|
#define LOADER_DRI3_HEADER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/present.h>
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/internal/dri_interface.h>
|
||||||
|
|
||||||
|
enum loader_dri3_buffer_type {
|
||||||
|
loader_dri3_buffer_back = 0,
|
||||||
|
loader_dri3_buffer_front = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct loader_dri3_buffer {
|
||||||
|
__DRIimage *image;
|
||||||
|
__DRIimage *linear_buffer;
|
||||||
|
uint32_t pixmap;
|
||||||
|
|
||||||
|
/* Synchronization between the client and X server is done using an
|
||||||
|
* xshmfence that is mapped into an X server SyncFence. This lets the
|
||||||
|
* client check whether the X server is done using a buffer with a simple
|
||||||
|
* xshmfence call, rather than going to read X events from the wire.
|
||||||
|
*
|
||||||
|
* However, we can only wait for one xshmfence to be triggered at a time,
|
||||||
|
* so we need to know *which* buffer is going to be idle next. We do that
|
||||||
|
* by waiting for a PresentIdleNotify event. When that event arrives, the
|
||||||
|
* 'busy' flag gets cleared and the client knows that the fence has been
|
||||||
|
* triggered, and that the wait call will not block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t sync_fence; /* XID of X SyncFence object */
|
||||||
|
struct xshmfence *shm_fence; /* pointer to xshmfence object */
|
||||||
|
bool busy; /* Set on swap, cleared on IdleNotify */
|
||||||
|
bool own_pixmap; /* We allocated the pixmap ID, free on destroy */
|
||||||
|
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t cpp;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t width, height;
|
||||||
|
uint64_t last_swap;
|
||||||
|
|
||||||
|
enum loader_dri3_buffer_type buffer_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define LOADER_DRI3_MAX_BACK 4
|
||||||
|
#define LOADER_DRI3_BACK_ID(i) (i)
|
||||||
|
#define LOADER_DRI3_FRONT_ID (LOADER_DRI3_MAX_BACK)
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)
|
||||||
|
{
|
||||||
|
if (buffer_type == loader_dri3_buffer_back)
|
||||||
|
return LOADER_DRI3_BACK_ID(0);
|
||||||
|
else
|
||||||
|
return LOADER_DRI3_FRONT_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct loader_dri3_extensions {
|
||||||
|
const __DRIcoreExtension *core;
|
||||||
|
const __DRIimageDriverExtension *image_driver;
|
||||||
|
const __DRI2flushExtension *flush;
|
||||||
|
const __DRI2configQueryExtension *config;
|
||||||
|
const __DRItexBufferExtension *tex_buffer;
|
||||||
|
const __DRIimageExtension *image;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct loader_dri3_drawable;
|
||||||
|
|
||||||
|
struct loader_dri3_vtable {
|
||||||
|
int (*get_swap_interval)(struct loader_dri3_drawable *);
|
||||||
|
int (*clamp_swap_interval)(struct loader_dri3_drawable *, int);
|
||||||
|
void (*set_swap_interval)(struct loader_dri3_drawable *, int);
|
||||||
|
void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
|
||||||
|
bool (*in_current_context)(struct loader_dri3_drawable *);
|
||||||
|
__DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
|
||||||
|
void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
|
||||||
|
void (*show_fps)(struct loader_dri3_drawable *, uint64_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)
|
||||||
|
|
||||||
|
struct loader_dri3_drawable {
|
||||||
|
xcb_connection_t *conn;
|
||||||
|
__DRIdrawable *dri_drawable;
|
||||||
|
xcb_drawable_t drawable;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int depth;
|
||||||
|
uint8_t have_back;
|
||||||
|
uint8_t have_fake_front;
|
||||||
|
uint8_t is_pixmap;
|
||||||
|
uint8_t flipping;
|
||||||
|
|
||||||
|
/* Information about the GPU owning the buffer */
|
||||||
|
__DRIscreen *dri_screen;
|
||||||
|
bool is_different_gpu;
|
||||||
|
|
||||||
|
/* Present extension capabilities
|
||||||
|
*/
|
||||||
|
uint32_t present_capabilities;
|
||||||
|
|
||||||
|
/* SBC numbers are tracked by using the serial numbers
|
||||||
|
* in the present request and complete events
|
||||||
|
*/
|
||||||
|
uint64_t send_sbc;
|
||||||
|
uint64_t recv_sbc;
|
||||||
|
|
||||||
|
/* Last received UST/MSC values for pixmap present complete */
|
||||||
|
uint64_t ust, msc;
|
||||||
|
|
||||||
|
/* Last received UST/MSC values from present notify msc event */
|
||||||
|
uint64_t notify_ust, notify_msc;
|
||||||
|
|
||||||
|
/* Serial numbers for tracking wait_for_msc events */
|
||||||
|
uint32_t send_msc_serial;
|
||||||
|
uint32_t recv_msc_serial;
|
||||||
|
|
||||||
|
struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
|
||||||
|
int cur_back;
|
||||||
|
int num_back;
|
||||||
|
|
||||||
|
uint32_t *stamp;
|
||||||
|
|
||||||
|
xcb_present_event_t eid;
|
||||||
|
xcb_gcontext_t gc;
|
||||||
|
xcb_special_event_t *special_event;
|
||||||
|
|
||||||
|
bool first_init;
|
||||||
|
|
||||||
|
struct loader_dri3_extensions *ext;
|
||||||
|
struct loader_dri3_vtable *vtable;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,
|
||||||
|
int interval);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
|
int
|
||||||
|
loader_dri3_drawable_init(xcb_connection_t *conn,
|
||||||
|
xcb_drawable_t drawable,
|
||||||
|
__DRIscreen *dri_screen,
|
||||||
|
bool is_different_gpu,
|
||||||
|
const __DRIconfig *dri_config,
|
||||||
|
struct loader_dri3_extensions *ext,
|
||||||
|
struct loader_dri3_vtable *vtable,
|
||||||
|
struct loader_dri3_drawable*);
|
||||||
|
|
||||||
|
bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
|
||||||
|
int64_t target_msc,
|
||||||
|
int64_t divisor, int64_t remainder,
|
||||||
|
int64_t *ust, int64_t *msc, int64_t *sbc);
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
|
||||||
|
int64_t target_msc, int64_t divisor,
|
||||||
|
int64_t remainder, unsigned flush_flags,
|
||||||
|
bool force_copy);
|
||||||
|
|
||||||
|
int
|
||||||
|
loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
|
||||||
|
int64_t target_sbc, int64_t *ust,
|
||||||
|
int64_t *msc, int64_t *sbc);
|
||||||
|
|
||||||
|
int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_flush(struct loader_dri3_drawable *draw,
|
||||||
|
unsigned flags,
|
||||||
|
enum __DRI2throttleReason throttle_reason);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
|
||||||
|
int x, int y,
|
||||||
|
int width, int height,
|
||||||
|
bool flush);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
|
||||||
|
xcb_drawable_t dest,
|
||||||
|
xcb_drawable_t src);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_wait_x(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
|
void
|
||||||
|
loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
|
int loader_dri3_open(xcb_connection_t *conn,
|
||||||
|
xcb_window_t root,
|
||||||
|
uint32_t provider);
|
||||||
|
|
||||||
|
int
|
||||||
|
loader_dri3_get_buffers(__DRIdrawable *driDrawable,
|
||||||
|
unsigned int format,
|
||||||
|
uint32_t *stamp,
|
||||||
|
void *loaderPrivate,
|
||||||
|
uint32_t buffer_mask,
|
||||||
|
struct __DRIimageList *buffers);
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user