Path: blob/21.2-virgl/src/loader/loader_dri3_helper.h
4550 views
/*1* Copyright © 2013 Keith Packard2* Copyright © 2015 Boyan Ding3*4* Permission to use, copy, modify, distribute, and sell this software and its5* documentation for any purpose is hereby granted without fee, provided that6* the above copyright notice appear in all copies and that both that copyright7* notice and this permission notice appear in supporting documentation, and8* that the name of the copyright holders not be used in advertising or9* publicity pertaining to distribution of the software without specific,10* written prior permission. The copyright holders make no representations11* about the suitability of this software for any purpose. It is provided "as12* is" without express or implied warranty.13*14* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,15* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO16* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR17* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,18* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER19* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE20* OF THIS SOFTWARE.21*/2223#ifndef LOADER_DRI3_HEADER_H24#define LOADER_DRI3_HEADER_H2526#include <stdbool.h>27#include <stdint.h>2829#include <xcb/xcb.h>30#include <xcb/dri3.h>31#include <xcb/present.h>3233#include <GL/gl.h>34#include <GL/internal/dri_interface.h>35#include <c11/threads.h>3637enum loader_dri3_buffer_type {38loader_dri3_buffer_back = 0,39loader_dri3_buffer_front = 140};4142struct loader_dri3_buffer {43__DRIimage *image;44uint32_t pixmap;4546/* default case: linear buffer allocated in render gpu vram.47* p2p case: linear buffer allocated in display gpu vram and imported48* to render gpu. p2p case is enabled when driver name matches49* while creating screen in dri3_create_screen() function.50*/51__DRIimage *linear_buffer;5253/* Synchronization between the client and X server is done using an54* xshmfence that is mapped into an X server SyncFence. This lets the55* client check whether the X server is done using a buffer with a simple56* xshmfence call, rather than going to read X events from the wire.57*58* However, we can only wait for one xshmfence to be triggered at a time,59* so we need to know *which* buffer is going to be idle next. We do that60* by waiting for a PresentIdleNotify event. When that event arrives, the61* 'busy' flag gets cleared and the client knows that the fence has been62* triggered, and that the wait call will not block.63*/6465uint32_t sync_fence; /* XID of X SyncFence object */66struct xshmfence *shm_fence; /* pointer to xshmfence object */67bool busy; /* Set on swap, cleared on IdleNotify */68bool own_pixmap; /* We allocated the pixmap ID, free on destroy */69bool reallocate; /* Buffer should be reallocated and not reused */7071uint32_t num_planes;72uint32_t size;73int strides[4];74int offsets[4];75uint64_t modifier;76uint32_t cpp;77uint32_t flags;78uint32_t width, height;79uint64_t last_swap;80};818283#define LOADER_DRI3_MAX_BACK 484#define LOADER_DRI3_BACK_ID(i) (i)85#define LOADER_DRI3_FRONT_ID (LOADER_DRI3_MAX_BACK)8687static inline int88loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)89{90if (buffer_type == loader_dri3_buffer_back)91return LOADER_DRI3_BACK_ID(0);92else93return LOADER_DRI3_FRONT_ID;94}9596struct loader_dri3_extensions {97const __DRIcoreExtension *core;98const __DRIimageDriverExtension *image_driver;99const __DRI2flushExtension *flush;100const __DRI2configQueryExtension *config;101const __DRItexBufferExtension *tex_buffer;102const __DRIimageExtension *image;103};104105struct loader_dri3_drawable;106107struct loader_dri3_vtable {108void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);109bool (*in_current_context)(struct loader_dri3_drawable *);110__DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);111__DRIscreen *(*get_dri_screen)(void);112void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);113void (*show_fps)(struct loader_dri3_drawable *, uint64_t);114};115116#define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)117118struct loader_dri3_drawable {119xcb_connection_t *conn;120xcb_screen_t *screen;121__DRIdrawable *dri_drawable;122xcb_drawable_t drawable;123xcb_window_t window;124xcb_xfixes_region_t region;125int width;126int height;127int depth;128uint8_t have_back;129uint8_t have_fake_front;130uint8_t is_pixmap;131132/* Information about the GPU owning the buffer */133__DRIscreen *dri_screen;134bool is_different_gpu;135bool multiplanes_available;136137/* DRI screen created for display GPU in case of prime */138__DRIscreen *dri_screen_display_gpu;139140/* Present extension capabilities141*/142uint32_t present_capabilities;143144/* SBC numbers are tracked by using the serial numbers145* in the present request and complete events146*/147uint64_t send_sbc;148uint64_t recv_sbc;149150/* Last received UST/MSC values for pixmap present complete */151uint64_t ust, msc;152153/* Last received UST/MSC values from present notify msc event */154uint64_t notify_ust, notify_msc;155156struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];157int cur_back;158int cur_num_back;159int max_num_back;160int cur_blit_source;161162uint32_t *stamp;163164xcb_present_event_t eid;165xcb_gcontext_t gc;166xcb_special_event_t *special_event;167168bool first_init;169bool adaptive_sync;170bool adaptive_sync_active;171int swap_interval;172173struct loader_dri3_extensions *ext;174const struct loader_dri3_vtable *vtable;175176unsigned int swap_method;177unsigned int back_format;178xcb_present_complete_mode_t last_present_mode;179180bool is_protected_content;181182/* Currently protects the following fields:183* event_cnd, has_event_waiter,184* recv_sbc, ust, msc, recv_msc_serial,185* notify_ust, notify_msc186*/187mtx_t mtx;188cnd_t event_cnd;189unsigned last_special_event_sequence;190bool has_event_waiter;191};192193void194loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,195int interval);196197void198loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);199200int201loader_dri3_drawable_init(xcb_connection_t *conn,202xcb_drawable_t drawable,203__DRIscreen *dri_screen,204bool is_different_gpu,205bool is_multiplanes_available,206const __DRIconfig *dri_config,207struct loader_dri3_extensions *ext,208const struct loader_dri3_vtable *vtable,209struct loader_dri3_drawable*);210211bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,212int64_t target_msc,213int64_t divisor, int64_t remainder,214int64_t *ust, int64_t *msc, int64_t *sbc);215216int64_t217loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,218int64_t target_msc, int64_t divisor,219int64_t remainder, unsigned flush_flags,220const int *rects, int n_rects,221bool force_copy);222223int224loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,225int64_t target_sbc, int64_t *ust,226int64_t *msc, int64_t *sbc);227228int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);229230void231loader_dri3_flush(struct loader_dri3_drawable *draw,232unsigned flags,233enum __DRI2throttleReason throttle_reason);234235void236loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,237int x, int y,238int width, int height,239bool flush);240241void242loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,243xcb_drawable_t dest,244xcb_drawable_t src);245246void247loader_dri3_wait_x(struct loader_dri3_drawable *draw);248249void250loader_dri3_wait_gl(struct loader_dri3_drawable *draw);251252int loader_dri3_open(xcb_connection_t *conn,253xcb_window_t root,254uint32_t provider);255256__DRIimage *257loader_dri3_create_image(xcb_connection_t *c,258xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,259unsigned int format,260__DRIscreen *dri_screen,261const __DRIimageExtension *image,262void *loaderPrivate);263264#ifdef HAVE_DRI3_MODIFIERS265__DRIimage *266loader_dri3_create_image_from_buffers(xcb_connection_t *c,267xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,268unsigned int format,269__DRIscreen *dri_screen,270const __DRIimageExtension *image,271void *loaderPrivate);272#endif273int274loader_dri3_get_buffers(__DRIdrawable *driDrawable,275unsigned int format,276uint32_t *stamp,277void *loaderPrivate,278uint32_t buffer_mask,279struct __DRIimageList *buffers);280281void282loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);283284void285loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);286287void288loader_dri3_close_screen(__DRIscreen *dri_screen);289#endif290291292