sync with OpenBSD -current

This commit is contained in:
purplerain 2024-07-20 20:41:33 +00:00
parent b5b25afdb8
commit 2c72e27ed2
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
147 changed files with 41128 additions and 10 deletions

View file

@ -0,0 +1,59 @@
# Copyright (c) 2007 Intel Corporation. All Rights Reserved.
#
# 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 PRECISION INSIGHT 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.
AM_CPPFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/va \
$(X11_CFLAGS) \
$(DRM_CFLAGS) \
$(NULL)
source_c = \
dri2_util.c \
va_dri2.c \
va_dri3.c \
../drm/va_drm_utils.c \
va_dricommon.c \
va_fglrx.c \
va_nvctrl.c \
va_x11.c \
$(NULL)
source_h = \
va_dri2.h \
va_dricommon.h \
$(NULL)
source_h_priv = \
va_dri2_priv.h \
va_dri2str.h \
va_dri2tokens.h \
va_dri3.h \
va_fglrx.h \
va_nvctrl.h \
$(NULL)
noinst_LTLIBRARIES = libva_x11.la
libva_x11includedir = ${includedir}/va
libva_x11include_HEADERS = $(source_h)
libva_x11_la_SOURCES = $(source_c)
noinst_HEADERS = $(source_h_priv)

View file

@ -0,0 +1,265 @@
/*
* Copyright (c) 2012 Intel Corporation. All Rights Reserved.
*
* 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 PRECISION INSIGHT 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 <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>
#include <xf86drm.h>
#include <X11/Xlibint.h>
#include <X11/Xlib.h>
#include "va.h"
#include "va_backend.h"
#include "va_dri2.h"
#include "va_dri2tokens.h"
#include "va_dricommon.h"
#define __DRI_BUFFER_FRONT_LEFT 0
#define __DRI_BUFFER_BACK_LEFT 1
#define __DRI_BUFFER_FRONT_RIGHT 2
#define __DRI_BUFFER_BACK_RIGHT 3
#define __DRI_BUFFER_DEPTH 4
#define __DRI_BUFFER_STENCIL 5
#define __DRI_BUFFER_ACCUM 6
#define __DRI_BUFFER_FAKE_FRONT_LEFT 7
#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8
struct dri2_drawable {
struct dri_drawable base;
union dri_buffer buffers[5];
int width;
int height;
int has_backbuffer;
int back_index;
int front_index;
};
static int gsDRI2SwapAvailable;
static struct dri_drawable *
dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
{
struct dri2_drawable *dri2_drawable;
dri2_drawable = calloc(1, sizeof(*dri2_drawable));
if (!dri2_drawable)
return NULL;
dri2_drawable->base.x_drawable = x_drawable;
dri2_drawable->base.x = 0;
dri2_drawable->base.y = 0;
VA_DRI2CreateDrawable(ctx->native_dpy, x_drawable);
return &dri2_drawable->base;
}
static void
dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
VA_DRI2DestroyDrawable(ctx->native_dpy, dri_drawable->x_drawable);
free(dri_drawable);
}
static void
dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
XRectangle xrect;
XserverRegion region;
if (dri2_drawable->has_backbuffer) {
if (gsDRI2SwapAvailable) {
CARD64 ret;
VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable,
0, 1, 0,
&ret);
} else {
xrect.x = 0;
xrect.y = 0;
xrect.width = dri2_drawable->width;
xrect.height = dri2_drawable->height;
region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1);
VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(ctx->native_dpy, region);
}
}
}
static union dri_buffer *
dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
int i;
int count;
unsigned int attachments[5];
VA_DRI2Buffer *buffers;
i = 0;
if (dri_drawable->is_window)
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
else
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable,
&dri2_drawable->width, &dri2_drawable->height,
attachments, i, &count);
if (buffers == NULL)
return NULL;
dri2_drawable->has_backbuffer = 0;
for (i = 0; i < count; i++) {
dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment;
dri2_drawable->buffers[i].dri2.name = buffers[i].name;
dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch;
dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp;
dri2_drawable->buffers[i].dri2.flags = buffers[i].flags;
if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
dri2_drawable->has_backbuffer = 1;
dri2_drawable->back_index = i;
}
if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
dri2_drawable->front_index = i;
}
dri_drawable->width = dri2_drawable->width;
dri_drawable->height = dri2_drawable->height;
Xfree(buffers);
if (dri2_drawable->has_backbuffer)
return &dri2_drawable->buffers[dri2_drawable->back_index];
return &dri2_drawable->buffers[dri2_drawable->front_index];
}
static void
dri2Close(VADriverContextP ctx)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
va_dri_free_drawable_hashtable(ctx);
if (dri_state->base.fd >= 0)
close(dri_state->base.fd);
}
int
va_isRenderNodeFd(int fd)
{
struct stat st;
char *name;
/* Check by device node */
if (fstat(fd, &st) == 0)
return S_ISCHR(st.st_mode) && (st.st_rdev & 0x80);
/* Check by device name */
name = drmGetDeviceNameFromFd(fd);
if (name) {
/* drmGetDeviceNameFromFd returns a strdup'ed string */
int r = (strncmp(name, "/dev/dri/renderD", 16) == 0);
drmFree(name);
return r;
}
/* Unrecoverable error */
return -1;
}
Bool
va_isDRI2Connected(VADriverContextP ctx, char **driver_name)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
int major, minor;
int error_base;
int event_base;
char *device_name = NULL;
int is_render_nodes;
drm_magic_t magic;
*driver_name = NULL;
if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base))
goto err_out;
if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor))
goto err_out;
if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
driver_name, &device_name))
goto err_out;
if ((dri_state->base.fd != -1) && (dri_state->base.auth_type != VA_NONE))
goto success_out;
dri_state->base.fd = open(device_name, O_RDWR);
if (dri_state->base.fd < 0 || (is_render_nodes = va_isRenderNodeFd(dri_state->base.fd)) < 0)
goto err_out;
if (!is_render_nodes) {
if (drmGetMagic(dri_state->base.fd, &magic))
goto err_out;
if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
magic))
goto err_out;
}
dri_state->base.auth_type = VA_DRI2;
dri_state->createDrawable = dri2CreateDrawable;
dri_state->destroyDrawable = dri2DestroyDrawable;
dri_state->swapBuffer = dri2SwapBuffer;
dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
dri_state->close = dri2Close;
gsDRI2SwapAvailable = (minor >= 2);
success_out:
Xfree(device_name);
return True;
err_out:
if (device_name)
Xfree(device_name);
if (*driver_name)
Xfree(*driver_name);
if (dri_state->base.fd >= 0)
close(dri_state->base.fd);
*driver_name = NULL;
dri_state->base.fd = -1;
return False;
}

477
lib/libva/va/x11/va_dri2.c Normal file
View file

@ -0,0 +1,477 @@
/*
* Copyright © 2008 Red Hat, Inc.
* Copyright (c) 2023 Emil Velikov
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Kristian Høgsberg (krh@redhat.com)
*/
#define NEED_REPLIES
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include "xf86drm.h"
#include "va_dri2.h"
#include "va_dri2_priv.h"
#include "va_dricommon.h"
#include "va_dri2str.h"
#include "va_dri2tokens.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#ifndef DRI2DriverDRI
#define DRI2DriverDRI 0
#endif
static int
VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code);
static VA_DRI2Buffer *
VA_DRI2GetBuffers_internal(XExtDisplayInfo *info,
Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments,
int count,
int *outCount);
static char va_dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo _va_dri2_info_data;
static XExtensionInfo *va_dri2Info = &_va_dri2_info_data;
static XEXT_GENERATE_CLOSE_DISPLAY(VA_DRI2CloseDisplay, va_dri2Info)
static /* const */ XExtensionHooks va_dri2ExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
VA_DRI2CloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
VA_DRI2Error, /* error */
NULL, /* error_string */
};
static XEXT_GENERATE_FIND_DISPLAY(DRI2FindDisplay, va_dri2Info,
va_dri2ExtensionName,
&va_dri2ExtensionHooks,
0, NULL)
static CARD32 _va_resource_x_error_drawable = 0;
static Bool _va_resource_x_error_matched = False;
#define VA_EnterResourceError(drawable) \
do { \
_va_resource_x_error_drawable = (drawable); \
_va_resource_x_error_matched = False; \
} while (0)
#define VA_LeaveResourceError() \
do { \
_va_resource_x_error_drawable = 0; \
} while (0)
#define VA_ResourceErrorMatched() \
(_va_resource_x_error_matched)
static int
VA_DRI2Error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code)
{
if (_va_resource_x_error_drawable == err->resourceID) {
_va_resource_x_error_matched = True;
return True;
}
return False;
}
Bool VA_DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
if (XextHasExtension(info)) {
*eventBase = info->codes->first_event;
*errorBase = info->codes->first_error;
return True;
}
return False;
}
Bool VA_DRI2QueryVersion(Display *dpy, int *major, int *minor)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2QueryVersionReply rep;
xDRI2QueryVersionReq *req;
XextCheckExtension(dpy, info, va_dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2QueryVersion, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2QueryVersion;
req->majorVersion = DRI2_MAJOR;
req->minorVersion = DRI2_MINOR;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
*major = rep.majorVersion;
*minor = rep.minorVersion;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
Bool VA_DRI2Connect(Display *dpy, XID window,
char **driverName, char **deviceName)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2ConnectReply rep;
xDRI2ConnectReq *req;
XextCheckExtension(dpy, info, va_dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2Connect, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2Connect;
req->window = window;
req->driverType = DRI2DriverDRI;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
*driverName = Xmalloc(rep.driverNameLength + 1);
if (*driverName == NULL) {
_XEatData(dpy,
((rep.driverNameLength + 3) & ~3) +
((rep.deviceNameLength + 3) & ~3));
UnlockDisplay(dpy);
SyncHandle();
return False;
}
_XReadPad(dpy, *driverName, rep.driverNameLength);
(*driverName)[rep.driverNameLength] = '\0';
*deviceName = Xmalloc(rep.deviceNameLength + 1);
if (*deviceName == NULL) {
Xfree(*driverName);
_XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
UnlockDisplay(dpy);
SyncHandle();
return False;
}
_XReadPad(dpy, *deviceName, rep.deviceNameLength);
(*deviceName)[rep.deviceNameLength] = '\0';
UnlockDisplay(dpy);
SyncHandle();
return True;
}
Bool VA_DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2AuthenticateReq *req;
xDRI2AuthenticateReply rep;
XextCheckExtension(dpy, info, va_dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2Authenticate, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2Authenticate;
req->window = window;
req->magic = magic;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
UnlockDisplay(dpy);
SyncHandle();
return rep.authenticated;
}
void VA_DRI2CreateDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2CreateDrawableReq *req;
XextSimpleCheckExtension(dpy, info, va_dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2CreateDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2CreateDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
}
void VA_DRI2DestroyDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2DestroyDrawableReq *req;
unsigned int attachement = 0; // FRONT_LEFT
VA_DRI2Buffer *buffers;
XextSimpleCheckExtension(dpy, info, va_dri2ExtensionName);
XSync(dpy, False);
LockDisplay(dpy);
/*
* We have no way of catching DRI2DestroyDrawable errors because
* this message doesn't have a defined answer. So we test whether
* the drawable is still alive by sending DRIGetBuffers first and
* checking whether we get an error.
*/
VA_EnterResourceError(drawable);
buffers = VA_DRI2GetBuffers_internal(info, dpy, drawable,
NULL, NULL,
&attachement, 1, NULL);
VA_LeaveResourceError();
if (buffers)
XFree(buffers);
if (VA_ResourceErrorMatched()) {
UnlockDisplay(dpy);
SyncHandle();
return;
}
GetReq(DRI2DestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2DestroyDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
}
VA_DRI2Buffer *VA_DRI2GetBuffers_internal(XExtDisplayInfo *info,
Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount)
{
xDRI2GetBuffersReply rep;
xDRI2GetBuffersReq *req;
VA_DRI2Buffer *buffers;
xDRI2Buffer repBuffer;
CARD32 *p;
int i;
GetReqExtra(DRI2GetBuffers, count * 4, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2GetBuffers;
req->drawable = drawable;
req->count = count;
p = (CARD32 *) &req[1];
for (i = 0; i < count; i++)
p[i] = attachments[i];
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
return NULL;
}
if (width)
*width = rep.width;
if (height)
*height = rep.height;
if (outCount)
*outCount = rep.count;
buffers = Xmalloc(rep.count * sizeof buffers[0]);
if (buffers == NULL) {
_XEatData(dpy, rep.count * sizeof repBuffer);
return NULL;
}
for (i = 0; i < rep.count; i++) {
_XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
buffers[i].attachment = repBuffer.attachment;
buffers[i].name = repBuffer.name;
buffers[i].pitch = repBuffer.pitch;
buffers[i].cpp = repBuffer.cpp;
buffers[i].flags = repBuffer.flags;
}
return buffers;
}
VA_DRI2Buffer *VA_DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
VA_DRI2Buffer *buffers;
XextCheckExtension(dpy, info, va_dri2ExtensionName, False);
LockDisplay(dpy);
buffers = VA_DRI2GetBuffers_internal(info, dpy, drawable, width, height,
attachments, count, outCount);
UnlockDisplay(dpy);
SyncHandle();
return buffers;
}
void VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2CopyRegionReq *req;
xDRI2CopyRegionReply rep;
XextSimpleCheckExtension(dpy, info, va_dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2CopyRegion, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2CopyRegion;
req->drawable = drawable;
req->region = region;
req->dest = dest;
req->src = src;
_XReply(dpy, (xReply *)&rep, 0, xFalse);
UnlockDisplay(dpy);
SyncHandle();
}
static void
load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
CARD64 remainder)
{
req->target_msc_hi = target >> 32;
req->target_msc_lo = target & 0xffffffff;
req->divisor_hi = divisor >> 32;
req->divisor_lo = divisor & 0xffffffff;
req->remainder_hi = remainder >> 32;
req->remainder_lo = remainder & 0xffffffff;
}
static CARD64
vals_to_card64(CARD32 lo, CARD32 hi)
{
return (CARD64)hi << 32 | lo;
}
void VA_DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
CARD64 divisor, CARD64 remainder, CARD64 *count)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2SwapBuffersReq *req;
xDRI2SwapBuffersReply rep;
XextSimpleCheckExtension(dpy, info, va_dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2SwapBuffers, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2SwapBuffers;
req->drawable = drawable;
load_swap_req(req, target_msc, divisor, remainder);
_XReply(dpy, (xReply *)&rep, 0, xFalse);
*count = vals_to_card64(rep.swap_lo, rep.swap_hi);
UnlockDisplay(dpy);
SyncHandle();
}
VAStatus va_DRI2_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
)
{
#define MAX_NAMES 2 // Adjust if needed
static const struct {
const char * const dri_driver;
const char * const va_driver[MAX_NAMES];
} map[] = {
{ "i965", { "iHD", "i965" } }, // Intel Media and OTC GenX
{ "iris", { "iHD", "i965" } }, // Intel Media and OTC GenX
{ "crocus", { "i965" } }, // OTC GenX
};
VADriverContextP ctx = pDisplayContext->pDriverContext;
char *dri_driver;
unsigned count = 0;
if (!(va_isDRI2Connected(ctx, &dri_driver) && dri_driver))
return VA_STATUS_ERROR_UNKNOWN;
for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
if (strcmp(map[i].dri_driver, dri_driver) == 0) {
const char * const *va_drivers = map[i].va_driver;
for (; count < MAX_NAMES && va_drivers[count] && count < *num_drivers; count++)
drivers[count] = strdup(va_drivers[count]);
break;
}
}
/* Fallback to the dri driver, if there's no va equivalent in the map. */
if (!count) {
drivers[count] = dri_driver;
count++;
} else {
free(dri_driver);
}
*num_drivers = count;
return VA_STATUS_SUCCESS;
}

View file

@ -0,0 +1,73 @@
/*
* Copyright © 2007,2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Kristian Høgsberg (krh@redhat.com)
*/
#ifndef _VA_DRI2_H_
#define _VA_DRI2_H_
#include <X11/Xproto.h>
#include <X11/extensions/Xfixes.h>
#include <X11/Xfuncproto.h>
#include <xf86drm.h>
typedef struct {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
} VA_DRI2Buffer;
extern Bool
VA_DRI2QueryExtension(Display *display, int *eventBase, int *errorBase);
extern Bool
VA_DRI2QueryVersion(Display *display, int *major, int *minor);
extern Bool
VA_DRI2Connect(Display *display, XID window,
char **driverName, char **deviceName);
extern Bool
VA_DRI2Authenticate(Display *display, XID window, drm_magic_t magic);
extern void
VA_DRI2CreateDrawable(Display *display, XID drawable);
extern void
VA_DRI2DestroyDrawable(Display *display, XID handle);
extern VA_DRI2Buffer *
VA_DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount);
extern void
VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);
extern void
VA_DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
CARD64 remainder, CARD64 *count);
#endif

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 Emil Velikov
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*/
#ifndef _VA_DRI2_PRIV_H_
#define _VA_DRI2_PRIV_H_
#include "sysdeps.h"
#include "va_backend.h"
DLL_HIDDEN
VAStatus va_DRI2_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
);
#endif

View file

@ -0,0 +1,227 @@
/*
* Copyright © 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Kristian Høgsberg (krh@redhat.com)
*/
#ifndef _DRI2_PROTO_H_
#define _DRI2_PROTO_H_
#define DRI2_NAME "DRI2"
#define DRI2_MAJOR 1
#define DRI2_MINOR 2
#define DRI2NumberErrors 0
#define DRI2NumberEvents 2
#define DRI2NumberRequests 13
#define X_DRI2QueryVersion 0
#define X_DRI2Connect 1
#define X_DRI2Authenticate 2
#define X_DRI2CreateDrawable 3
#define X_DRI2DestroyDrawable 4
#define X_DRI2GetBuffers 5
#define X_DRI2CopyRegion 6
#define X_DRI2GetBuffersWithFormat 7
#define X_DRI2SwapBuffers 8
#define X_DRI2GetMSC 9
#define X_DRI2WaitMSC 10
#define X_DRI2WaitSBC 11
#define X_DRI2SwapInterval 12
typedef struct {
CARD32 attachment B32;
CARD32 name B32;
CARD32 pitch B32;
CARD32 cpp B32;
CARD32 flags B32;
} xDRI2Buffer;
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 majorVersion B32;
CARD32 minorVersion B32;
} xDRI2QueryVersionReq;
#define sz_xDRI2QueryVersionReq 12
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 majorVersion B32;
CARD32 minorVersion B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
} xDRI2QueryVersionReply;
#define sz_xDRI2QueryVersionReply 32
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 window B32;
CARD32 driverType B32;
} xDRI2ConnectReq;
#define sz_xDRI2ConnectReq 12
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 driverNameLength B32;
CARD32 deviceNameLength B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
} xDRI2ConnectReply;
#define sz_xDRI2ConnectReply 32
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 window B32;
CARD32 magic B32;
} xDRI2AuthenticateReq;
#define sz_xDRI2AuthenticateReq 12
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 authenticated B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xDRI2AuthenticateReply;
#define sz_xDRI2AuthenticateReply 32
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 drawable B32;
} xDRI2CreateDrawableReq;
#define sz_xDRI2CreateDrawableReq 8
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 drawable B32;
} xDRI2DestroyDrawableReq;
#define sz_xDRI2DestroyDrawableReq 8
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 drawable B32;
CARD32 count B32;
} xDRI2GetBuffersReq;
#define sz_xDRI2GetBuffersReq 12
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 width B32;
CARD32 height B32;
CARD32 count B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
} xDRI2GetBuffersReply;
#define sz_xDRI2GetBuffersReply 32
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 drawable B32;
CARD32 region B32;
CARD32 dest B32;
CARD32 src B32;
} xDRI2CopyRegionReq;
#define sz_xDRI2CopyRegionReq 20
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
} xDRI2CopyRegionReply;
#define sz_xDRI2CopyRegionReply 32
typedef struct {
CARD8 reqType;
CARD8 dri2ReqType;
CARD16 length B16;
CARD32 drawable B32;
CARD32 target_msc_hi B32;
CARD32 target_msc_lo B32;
CARD32 divisor_hi B32;
CARD32 divisor_lo B32;
CARD32 remainder_hi B32;
CARD32 remainder_lo B32;
} xDRI2SwapBuffersReq;
#define sz_xDRI2SwapBuffersReq 32
typedef struct {
BYTE type; /* X_Reply */
BYTE pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 swap_hi B32;
CARD32 swap_lo B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
} xDRI2SwapBuffersReply;
#define sz_xDRI2SwapBuffersReply 32
#endif

View file

@ -0,0 +1,48 @@
/*
* Copyright © 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Kristian Høgsberg (krh@redhat.com)
*/
#ifndef _DRI2_TOKENS_H_
#define _DRI2_TOKENS_H_
#define DRI2BufferFrontLeft 0
#define DRI2BufferBackLeft 1
#define DRI2BufferFrontRight 2
#define DRI2BufferBackRight 3
#define DRI2BufferDepth 4
#define DRI2BufferStencil 5
#define DRI2BufferAccum 6
#define DRI2BufferFakeFrontLeft 7
#define DRI2BufferFakeFrontRight 8
#define DRI2DriverDRI 0
#endif

147
lib/libva/va/x11/va_dri3.c Normal file
View file

@ -0,0 +1,147 @@
/*
* Copyright © 2022 Collabora Ltd.
* Copyright (c) 2023 Emil Velikov
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Emil Velikov (emil.velikov@collabora.com)
*/
#include "sysdeps.h"
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/dri3.h>
#include <X11/Xlib-xcb.h>
#include <xf86drm.h>
#include "va_backend.h"
#include "va_drmcommon.h"
#include "drm/va_drm_utils.h"
static xcb_screen_t *
va_DRI3GetXCBScreen(xcb_connection_t *conn, int screen)
{
xcb_screen_iterator_t iter;
iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
for (; iter.rem; --screen, xcb_screen_next(&iter))
if (screen == 0)
return iter.data;
return NULL;
}
static int
va_isDRI3Connected(VADriverContextP ctx, int *outfd)
{
xcb_connection_t *conn = XGetXCBConnection(ctx->native_dpy);
xcb_screen_t *screen;
xcb_window_t root;
const xcb_query_extension_reply_t *ext;
xcb_dri3_open_cookie_t cookie;
xcb_dri3_open_reply_t *reply;
int fd;
char *render_node;
if (!conn)
return -1;
screen = va_DRI3GetXCBScreen(conn, ctx->x11_screen);
if (!screen)
return -1;
root = screen->root;
xcb_prefetch_extension_data(conn, &xcb_dri3_id);
ext = xcb_get_extension_data(conn, &xcb_dri3_id);
if (!ext || !ext->present)
return -1;
/* We don't require any of the ancy stuff, so there's no point in checking
* the version.
*/
cookie = xcb_dri3_open(conn, root, 0 /* provider */);
reply = xcb_dri3_open_reply(conn, cookie, NULL /* error */);
if (!reply || reply->nfd != 1) {
free(reply);
return -1;
}
fd = xcb_dri3_open_reply_fds(conn, reply)[0];
free(reply);
/* The server can give us primary or a render node.
* In case of the former we need to swap it for the latter.
*/
switch (drmGetNodeTypeFromFd(fd)) {
case DRM_NODE_PRIMARY:
render_node = drmGetRenderDeviceNameFromFd(fd);
close(fd);
if (!render_node)
return -1;
fd = open(render_node, O_RDWR | O_CLOEXEC);
free(render_node);
if (fd == -1)
return -1;
break;
case DRM_NODE_RENDER:
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
break;
default:
close(fd);
return -1;
}
*outfd = fd;
return 0;
}
VAStatus va_DRI3_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
)
{
VADriverContextP const ctx = pDisplayContext->pDriverContext;
struct drm_state * const drm_state = ctx->drm_state;
int fd = -1;
if (va_isDRI3Connected(ctx, &fd) && fd != -1)
return VA_STATUS_ERROR_UNKNOWN;
drm_state->fd = fd;
drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
return VA_DRM_GetDriverNames(ctx, drivers, num_drivers);
}

View file

@ -0,0 +1,46 @@
/*
* Copyright © 2022 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL 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 PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Authors:
* Emil Velikov (emil.velikov@collabora.com)
*/
#ifndef _VA_DRI3_H_
#define _VA_DRI3_H_
#include "sysdeps.h"
#include "va_backend.h"
DLL_HIDDEN
VAStatus va_DRI3_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
);
#endif

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2012 Intel Corporation. All Rights Reserved.
*
* 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 PRECISION INSIGHT 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 "va_dricommon.h"
// X error trap
static int x11_error_code = 0;
static int (*old_error_handler)(Display *, XErrorEvent *);
static int
error_handler(Display *dpy, XErrorEvent *error)
{
x11_error_code = error->error_code;
return 0;
}
static void
x11_trap_errors(void)
{
x11_error_code = 0;
old_error_handler = XSetErrorHandler(error_handler);
}
static int
x11_untrap_errors(void)
{
XSetErrorHandler(old_error_handler);
return x11_error_code;
}
static int
is_window(Display *dpy, Drawable drawable)
{
XWindowAttributes wattr;
x11_trap_errors();
XGetWindowAttributes(dpy, drawable, &wattr);
return x11_untrap_errors() == 0;
}
static struct dri_drawable *
do_drawable_hash(VADriverContextP ctx, XID drawable)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
int index = drawable % DRAWABLE_HASH_SZ;
struct dri_drawable *dri_drawable = dri_state->drawable_hash[index];
while (dri_drawable) {
if (dri_drawable->x_drawable == drawable)
return dri_drawable;
dri_drawable = dri_drawable->next;
}
if (dri_state->createDrawable) {
dri_drawable = dri_state->createDrawable(ctx, drawable);
}
if (dri_drawable) {
dri_drawable->x_drawable = drawable;
dri_drawable->is_window = is_window(ctx->native_dpy, drawable);
dri_drawable->next = dri_state->drawable_hash[index];
dri_state->drawable_hash[index] = dri_drawable;
}
return dri_drawable;
}
void
va_dri_free_drawable(VADriverContextP ctx, struct dri_drawable* dri_drawable)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
int i = 0;
while (i < DRAWABLE_HASH_SZ) {
if (dri_drawable == dri_state->drawable_hash[i]) {
dri_state->destroyDrawable(ctx, dri_drawable);
dri_state->drawable_hash[i] = NULL;
return;
}
i++;
}
}
void
va_dri_free_drawable_hashtable(VADriverContextP ctx)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
int i;
struct dri_drawable *dri_drawable, *prev;
for (i = 0; i < DRAWABLE_HASH_SZ; i++) {
dri_drawable = dri_state->drawable_hash[i];
while (dri_drawable) {
prev = dri_drawable;
dri_drawable = prev->next;
dri_state->destroyDrawable(ctx, prev);
}
dri_state->drawable_hash[i] = NULL;
}
}
struct dri_drawable *
va_dri_get_drawable(VADriverContextP ctx, XID drawable)
{
return do_drawable_hash(ctx, drawable);
}
void
va_dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
dri_state->swapBuffer(ctx, dri_drawable);
}
union dri_buffer *
va_dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{
struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
return dri_state->getRenderingBuffer(ctx, dri_drawable);
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2012 Intel Corporation. All Rights Reserved.
*
* 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 PRECISION INSIGHT 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 _VA_DRICOMMON_H_
#define _VA_DRICOMMON_H_
#include <X11/Xlib.h>
#include <xf86drm.h>
#include <drm.h>
#include <va/va_backend.h>
#include <va/va_drmcommon.h>
enum {
/* Compatibility. Do not use for newly-written code. */
VA_NONE = VA_DRM_AUTH_NONE,
VA_DRI1 = VA_DRM_AUTH_DRI1,
VA_DRI2 = VA_DRM_AUTH_DRI2,
VA_DUMMY = VA_DRM_AUTH_CUSTOM
};
union dri_buffer {
struct {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
/** \brief Reserved bytes for future use, must be zero */
unsigned int va_reserved[8];
} dri2;
};
struct dri_drawable {
XID x_drawable;
int is_window;
int x;
int y;
unsigned int width;
unsigned int height;
struct dri_drawable *next;
};
#define DRAWABLE_HASH_SZ 32
struct dri_state {
struct drm_state base;
struct dri_drawable *drawable_hash[DRAWABLE_HASH_SZ];
struct dri_drawable *(*createDrawable)(VADriverContextP ctx, XID x_drawable);
void (*destroyDrawable)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
void (*swapBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
union dri_buffer *(*getRenderingBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
void (*close)(VADriverContextP ctx);
/** \brief Reserved bytes for future use, must be zero */
unsigned long va_reserved[16];
};
Bool va_isDRI2Connected(VADriverContextP ctx, char **driver_name);
void va_dri_free_drawable(VADriverContextP ctx, struct dri_drawable* dri_drawable);
void va_dri_free_drawable_hashtable(VADriverContextP ctx);
struct dri_drawable *va_dri_get_drawable(VADriverContextP ctx, XID drawable);
void va_dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable);
union dri_buffer *va_dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable);
#endif /* _VA_DRICOMMON_H_ */

256
lib/libva/va/x11/va_fglrx.c Normal file
View file

@ -0,0 +1,256 @@
/*
* Copyright (C) 2010 Splitted-Desktop Systems. All Rights Reserved.
*
* 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 PRECISION INSIGHT 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 "sysdeps.h"
#ifdef HAVE_FGLRX
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <X11/Xlib.h>
#include "va_fglrx.h"
#define ADL_OK 0
#define ADL_MAX_PATH 256
/*
* Based on public AMD Display Library (ADL) SDK:
* <http://developer.amd.com/gpu/adlsdk/Pages/default.aspx>
*/
typedef struct AdapterInfo {
int iSize;
int iAdapterIndex;
char strUDID[ADL_MAX_PATH];
int iBusNumber;
int iDeviceNumber;
int iFunctionNumber;
int iVendorID;
char strAdapterName[ADL_MAX_PATH];
char strDisplayName[ADL_MAX_PATH];
int iPresent;
int iXScreenNum;
int iDrvIndex;
char strXScreenConfigName[ADL_MAX_PATH];
} AdapterInfo, *LPAdapterInfo;
typedef struct XScreenInfo {
int iXScreenNum;
char strXScreenConfigName[ADL_MAX_PATH];
} XScreenInfo, *LPXScreenInfo;
typedef void *(*ADL_MAIN_MALLOC_CALLBACK)(int);
typedef int (*ADL_MAIN_CONTROL_CREATE)(ADL_MAIN_MALLOC_CALLBACK, int);
typedef int (*ADL_MAIN_CONTROL_DESTROY)(void);
typedef int (*ADL_ADAPTER_NUMBEROFADAPTERS_GET)(int *);
typedef int (*ADL_ADAPTER_ADAPTERINFO_GET)(LPAdapterInfo, int);
typedef int (*ADL_ADAPTER_XSCREENINFO_GET)(LPXScreenInfo, int);
static void *ADL_Main_Memory_Alloc(int iSize)
{
return malloc(iSize);
}
static void ADL_Main_Memory_Free(void *arg)
{
void ** const lpBuffer = arg;
if (lpBuffer && *lpBuffer) {
free(*lpBuffer);
*lpBuffer = NULL;
}
}
static int get_display_name_length(const char *name)
{
const char *m;
if (!name)
return 0;
/* Strip out screen number */
m = strchr(name, ':');
if (m) {
m = strchr(m, '.');
if (m)
return m - name;
}
return strlen(name);
}
static int match_display_name(Display *x11_dpy, const char *display_name)
{
Display *test_dpy;
char *test_dpy_name, *x11_dpy_name;
int test_dpy_namelen, x11_dpy_namelen;
int m;
test_dpy = XOpenDisplay(display_name);
if (!test_dpy)
return 0;
test_dpy_name = XDisplayString(test_dpy);
test_dpy_namelen = get_display_name_length(test_dpy_name);
x11_dpy_name = XDisplayString(x11_dpy);
x11_dpy_namelen = get_display_name_length(x11_dpy_name);
m = (test_dpy_namelen == x11_dpy_namelen &&
(test_dpy_namelen == 0 ||
(test_dpy_namelen > 0 &&
strncmp(test_dpy_name, x11_dpy_name, test_dpy_namelen) == 0)));
XCloseDisplay(test_dpy);
return m;
}
static Bool VA_FGLRXGetClientDriverName(Display *dpy, int screen, char **clientDriverName)
{
ADL_MAIN_CONTROL_CREATE ADL_Main_Control_Create;
ADL_MAIN_CONTROL_DESTROY ADL_Main_Control_Destroy;
ADL_ADAPTER_NUMBEROFADAPTERS_GET ADL_Adapter_NumberOfAdapters_Get;
ADL_ADAPTER_ADAPTERINFO_GET ADL_Adapter_AdapterInfo_Get;
ADL_ADAPTER_XSCREENINFO_GET ADL_Adapter_XScreenInfo_Get;
LPAdapterInfo lpAdapterInfo = NULL;
LPXScreenInfo lpXScreenInfo = NULL;
void *libadl_handle = NULL;
Bool success = False;
int is_adl_initialized = 0;
int i, num_adapters, lpAdapterInfo_size, lpXScreenInfo_size;
libadl_handle = dlopen("libatiadlxx.so", RTLD_LAZY | RTLD_GLOBAL);
if (!libadl_handle)
goto end;
dlerror();
ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE)
dlsym(libadl_handle, "ADL_Main_Control_Create");
if (dlerror())
goto end;
ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY)
dlsym(libadl_handle, "ADL_Main_Control_Destroy");
if (dlerror())
goto end;
ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET)
dlsym(libadl_handle, "ADL_Adapter_NumberOfAdapters_Get");
if (dlerror())
goto end;
ADL_Adapter_AdapterInfo_Get = (ADL_ADAPTER_ADAPTERINFO_GET)
dlsym(libadl_handle, "ADL_Adapter_AdapterInfo_Get");
if (dlerror())
goto end;
ADL_Adapter_XScreenInfo_Get = (ADL_ADAPTER_XSCREENINFO_GET)
dlsym(libadl_handle, "ADL_Adapter_XScreenInfo_Get");
if (dlerror())
goto end;
if (ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 1) != ADL_OK)
goto end;
is_adl_initialized = 1;
if (ADL_Adapter_NumberOfAdapters_Get(&num_adapters) != ADL_OK)
goto end;
if (num_adapters <= 0)
goto end;
lpAdapterInfo_size = num_adapters * sizeof(*lpAdapterInfo);
lpAdapterInfo = ADL_Main_Memory_Alloc(lpAdapterInfo_size);
if (!lpAdapterInfo)
goto end;
memset(lpAdapterInfo, 0, lpAdapterInfo_size);
for (i = 0; i < num_adapters; i++)
lpAdapterInfo[i].iSize = sizeof(lpAdapterInfo[i]);
lpXScreenInfo_size = num_adapters * sizeof(*lpXScreenInfo);
lpXScreenInfo = ADL_Main_Memory_Alloc(lpXScreenInfo_size);
if (!lpXScreenInfo)
goto end;
memset(lpXScreenInfo, 0, lpXScreenInfo_size);
if (ADL_Adapter_AdapterInfo_Get(lpAdapterInfo, lpAdapterInfo_size) != ADL_OK)
goto end;
if (ADL_Adapter_XScreenInfo_Get(lpXScreenInfo, lpXScreenInfo_size) != ADL_OK)
goto end;
for (i = 0; i < num_adapters; i++) {
LPXScreenInfo const lpCurrXScreenInfo = &lpXScreenInfo[i];
LPAdapterInfo const lpCurrAdapterInfo = &lpAdapterInfo[i];
if (!lpCurrAdapterInfo->iPresent)
continue;
#if 0
printf("Adapter %d:\n", i);
printf(" iAdapterIndex: %d\n", lpCurrAdapterInfo->iAdapterIndex);
printf(" strUDID: '%s'\n", lpCurrAdapterInfo->strUDID);
printf(" iBusNumber: %d\n", lpCurrAdapterInfo->iBusNumber);
printf(" iDeviceNumber: %d\n", lpCurrAdapterInfo->iDeviceNumber);
printf(" iFunctionNumber: %d\n", lpCurrAdapterInfo->iFunctionNumber);
printf(" iVendorID: 0x%04x\n", lpCurrAdapterInfo->iVendorID);
printf(" strAdapterName: '%s'\n", lpCurrAdapterInfo->strAdapterName);
printf(" strDisplayName: '%s'\n", lpCurrAdapterInfo->strDisplayName);
printf(" iPresent: %d\n", lpCurrAdapterInfo->iPresent);
printf(" iXScreenNum: %d\n", lpCurrXScreenInfo->iXScreenNum);
#endif
if (screen == lpCurrXScreenInfo->iXScreenNum &&
match_display_name(dpy, lpCurrAdapterInfo->strDisplayName)) {
*clientDriverName = strdup("fglrx");
success = !!(*clientDriverName);
break;
}
}
end:
if (lpXScreenInfo)
ADL_Main_Memory_Free(&lpXScreenInfo);
if (lpAdapterInfo)
ADL_Main_Memory_Free(&lpAdapterInfo);
if (is_adl_initialized)
ADL_Main_Control_Destroy();
if (libadl_handle)
dlclose(libadl_handle);
return success;
}
VAStatus va_FGLRX_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
)
{
VADriverContextP ctx = pDisplayContext->pDriverContext;
if (!VA_FGLRXGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
drivers))
return VA_STATUS_ERROR_UNKNOWN;
*num_drivers = 1;
return VA_STATUS_SUCCESS;
}
#endif

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2010 Splitted-Desktop Systems. All Rights Reserved.
*
* 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 PRECISION INSIGHT 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 VA_FGLRX_H
#define VA_FGLRX_H
#ifdef HAVE_FGLRX
#include <X11/Xlib.h>
#include "va_backend.h"
DLL_HIDDEN
VAStatus va_FGLRX_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
);
#endif
#endif /* VA_FGLRX_H */

View file

@ -0,0 +1,421 @@
/*
* Copyright (c) 2008 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.
*/
#define _GNU_SOURCE 1
#include "sysdeps.h"
#ifdef HAVE_NVCTRL
#include <string.h>
#define NEED_REPLIES
#include <stdlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include "va_nvctrl.h"
#define NV_CONTROL_ERRORS 0
#define NV_CONTROL_EVENTS 5
#define NV_CONTROL_NAME "NV-CONTROL"
#define NV_CTRL_TARGET_TYPE_X_SCREEN 0
#define NV_CTRL_TARGET_TYPE_GPU 1
#define NV_CTRL_TARGET_TYPE_FRAMELOCK 2
#define NV_CTRL_TARGET_TYPE_VCSC 3 /* Visual Computing System */
#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R--G */
#define X_nvCtrlQueryExtension 0
#define X_nvCtrlIsNv 1
#define X_nvCtrlQueryStringAttribute 4
typedef struct {
CARD8 reqType;
CARD8 nvReqType;
CARD16 length B16;
} xnvCtrlQueryExtensionReq;
#define sz_xnvCtrlQueryExtensionReq 4
typedef struct {
BYTE type; /* X_Reply */
CARD8 padb1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD16 major B16;
CARD16 minor B16;
CARD32 padl4 B32;
CARD32 padl5 B32;
CARD32 padl6 B32;
CARD32 padl7 B32;
CARD32 padl8 B32;
} xnvCtrlQueryExtensionReply;
#define sz_xnvCtrlQueryExtensionReply 32
typedef struct {
CARD8 reqType;
CARD8 nvReqType;
CARD16 length B16;
CARD32 screen B32;
} xnvCtrlIsNvReq;
#define sz_xnvCtrlIsNvReq 8
typedef struct {
BYTE type; /* X_Reply */
CARD8 padb1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 isnv B32;
CARD32 padl4 B32;
CARD32 padl5 B32;
CARD32 padl6 B32;
CARD32 padl7 B32;
CARD32 padl8 B32;
} xnvCtrlIsNvReply;
#define sz_xnvCtrlIsNvReply 32
typedef struct {
CARD8 reqType;
CARD8 nvReqType;
CARD16 length B16;
CARD16 target_id B16; /* X screen number or GPU number */
CARD16 target_type B16; /* X screen or GPU */
CARD32 display_mask B32;
CARD32 attribute B32;
} xnvCtrlQueryStringAttributeReq;
#define sz_xnvCtrlQueryStringAttributeReq 16
typedef struct {
BYTE type;
BYTE pad0;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 flags B32;
CARD32 n B32; /* Length of string */
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
} xnvCtrlQueryStringAttributeReply;
#define sz_xnvCtrlQueryStringAttributeReply 32
#define NVCTRL_EXT_NEED_CHECK (XPointer)(~0)
#define NVCTRL_EXT_NEED_NOTHING (XPointer)(0)
#define NVCTRL_EXT_NEED_TARGET_SWAP (XPointer)(1)
static XExtensionInfo _nvctrl_ext_info_data;
static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data;
static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME;
#define XNVCTRLCheckExtension(dpy,i,val) \
XextCheckExtension (dpy, i, nvctrl_extension_name, val)
#define XNVCTRLSimpleCheckExtension(dpy,i) \
XextSimpleCheckExtension (dpy, i, nvctrl_extension_name)
static XEXT_GENERATE_CLOSE_DISPLAY(close_display, nvctrl_ext_info)
static /* const */ XExtensionHooks nvctrl_extension_hooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
close_display, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
static XEXT_GENERATE_FIND_DISPLAY(find_display, nvctrl_ext_info,
nvctrl_extension_name,
&nvctrl_extension_hooks,
NV_CONTROL_EVENTS, NVCTRL_EXT_NEED_CHECK)
static Bool XNVCTRLQueryVersion(Display *dpy, int *major, int *minor);
/*
* NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id
* fields in reversed order. In order to talk to one of these servers,
* we need to swap these fields.
*/
static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info,
int *target_type, int *target_id)
{
/* Find out what the server's NV-CONTROL version is and
* setup for swapping if we need to.
*/
if (info->data == NVCTRL_EXT_NEED_CHECK) {
int major, minor;
if (XNVCTRLQueryVersion(dpy, &major, &minor)) {
if (major == 1 &&
(minor == 8 || minor == 9)) {
info->data = NVCTRL_EXT_NEED_TARGET_SWAP;
} else {
info->data = NVCTRL_EXT_NEED_NOTHING;
}
} else {
info->data = NVCTRL_EXT_NEED_NOTHING;
}
}
/* We need to swap the target_type and target_id */
if (info->data == NVCTRL_EXT_NEED_TARGET_SWAP) {
int tmp;
tmp = *target_type;
*target_type = *target_id;
*target_id = tmp;
}
}
static Bool XNVCTRLQueryExtension(
Display *dpy,
int *event_basep,
int *error_basep
)
{
XExtDisplayInfo *info = find_display(dpy);
if (XextHasExtension(info)) {
if (event_basep) *event_basep = info->codes->first_event;
if (error_basep) *error_basep = info->codes->first_error;
return True;
} else {
return False;
}
}
static Bool XNVCTRLQueryVersion(
Display *dpy,
int *major,
int *minor
)
{
XExtDisplayInfo *info = find_display(dpy);
xnvCtrlQueryExtensionReply rep;
xnvCtrlQueryExtensionReq *req;
if (!XextHasExtension(info))
return False;
XNVCTRLCheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(nvCtrlQueryExtension, req);
req->reqType = info->codes->major_opcode;
req->nvReqType = X_nvCtrlQueryExtension;
if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
if (major) *major = rep.major;
if (minor) *minor = rep.minor;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
static Bool XNVCTRLIsNvScreen(
Display *dpy,
int screen
)
{
XExtDisplayInfo *info = find_display(dpy);
xnvCtrlIsNvReply rep;
xnvCtrlIsNvReq *req;
Bool isnv;
if (!XextHasExtension(info))
return False;
XNVCTRLCheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(nvCtrlIsNv, req);
req->reqType = info->codes->major_opcode;
req->nvReqType = X_nvCtrlIsNv;
req->screen = screen;
if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
isnv = rep.isnv;
UnlockDisplay(dpy);
SyncHandle();
return isnv;
}
static Bool XNVCTRLQueryTargetStringAttribute(
Display *dpy,
int target_type,
int target_id,
unsigned int display_mask,
unsigned int attribute,
char **ptr
)
{
XExtDisplayInfo *info = find_display(dpy);
xnvCtrlQueryStringAttributeReply rep;
xnvCtrlQueryStringAttributeReq *req;
Bool exists;
int length, numbytes, slop;
if (!ptr) return False;
if (!XextHasExtension(info))
return False;
XNVCTRLCheckExtension(dpy, info, False);
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
LockDisplay(dpy);
GetReq(nvCtrlQueryStringAttribute, req);
req->reqType = info->codes->major_opcode;
req->nvReqType = X_nvCtrlQueryStringAttribute;
req->target_type = target_type;
req->target_id = target_id;
req->display_mask = display_mask;
req->attribute = attribute;
if (!_XReply(dpy, (xReply *) &rep, 0, False)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
length = rep.length;
numbytes = rep.n;
slop = numbytes & 3;
*ptr = (char *) Xmalloc(numbytes);
if (! *ptr) {
_XEatData(dpy, length);
UnlockDisplay(dpy);
SyncHandle();
return False;
} else {
_XRead(dpy, (char *) *ptr, numbytes);
if (slop) _XEatData(dpy, 4 - slop);
}
exists = rep.flags;
UnlockDisplay(dpy);
SyncHandle();
return exists;
}
static Bool XNVCTRLQueryStringAttribute(
Display *dpy,
int screen,
unsigned int display_mask,
unsigned int attribute,
char **ptr
)
{
return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
screen, display_mask,
attribute, ptr);
}
static Bool VA_NVCTRLQueryDirectRenderingCapable(Display *dpy, int screen,
Bool *isCapable)
{
int event_base;
int error_base;
if (isCapable)
*isCapable = False;
if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base))
return False;
if (isCapable && XNVCTRLIsNvScreen(dpy, screen))
*isCapable = True;
return True;
}
static Bool VA_NVCTRLGetClientDriverName(Display *dpy, int screen,
char **clientDriverName)
{
int ddxDriverMajorVersion, ddxDriverMinorVersion, ddxDriverPatchVersion;
char *nvidia_driver_version = NULL;
if (!XNVCTRLQueryStringAttribute(dpy, screen, 0, NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &nvidia_driver_version))
return False;
char *end, *str = nvidia_driver_version;
unsigned long v = strtoul(str, &end, 10);
if (end && end != str) {
ddxDriverMajorVersion = v;
if (*(str = end) == '.') {
v = strtoul(str + 1, &end, 10);
if (end && end != str && (*end == '.' || *end == '\0')) {
ddxDriverMinorVersion = v;
if (*(str = end) == '.') {
v = strtoul(str + 1, &end, 10);
if (end && end != str && *end == '\0') {
ddxDriverPatchVersion = v;
}
}
}
}
}
Xfree(nvidia_driver_version);
(void) ddxDriverMajorVersion;
(void) ddxDriverMinorVersion;
(void) ddxDriverPatchVersion;
*clientDriverName = strdup("nvidia");
return True;
}
VAStatus va_NVCTRL_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
)
{
VADriverContextP ctx = pDisplayContext->pDriverContext;
int direct_capable;
if (!VA_NVCTRLQueryDirectRenderingCapable(ctx->native_dpy, ctx->x11_screen,
&direct_capable) || !direct_capable)
return VA_STATUS_ERROR_UNKNOWN;
if (!VA_NVCTRLGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
drivers))
return VA_STATUS_ERROR_UNKNOWN;
*num_drivers = 1;
return VA_STATUS_SUCCESS;
}
#endif

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2008 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.
*/
#ifndef VA_NVCTRLLIB_H
#define VA_NVCTRLLIB_H
#ifdef HAVE_NVCTRL
#include <X11/Xlib.h>
#include "va_backend.h"
DLL_HIDDEN
VAStatus va_NVCTRL_GetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers,
unsigned *num_drivers
);
#endif
#endif /* VA_NVCTRLLIB_H */

187
lib/libva/va/x11/va_x11.c Normal file
View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2007 Intel Corporation. All Rights Reserved.
* Copyright (c) 2023 Emil Velikov
*
* 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 PRECISION INSIGHT 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.
*/
#define _GNU_SOURCE 1
#include "sysdeps.h"
#include "va.h"
#include "va_backend.h"
#include "va_internal.h"
#include "va_trace.h"
#include "va_x11.h"
#include "va_dri2.h"
#include "va_dri2_priv.h"
#include "va_dri3.h"
#include "va_dricommon.h"
#include "va_nvctrl.h"
#include "va_fglrx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static void va_DisplayContextDestroy(
VADisplayContextP pDisplayContext
)
{
VADriverContextP ctx;
struct dri_state *dri_state;
if (pDisplayContext == NULL)
return;
ctx = pDisplayContext->pDriverContext;
dri_state = ctx->drm_state;
if (dri_state && dri_state->close)
dri_state->close(ctx);
if (dri_state && dri_state->base.fd != -1)
close(dri_state->base.fd);
free(pDisplayContext->pDriverContext->drm_state);
free(pDisplayContext->pDriverContext);
free(pDisplayContext);
}
static VAStatus va_DisplayContextGetDriverNames(
VADisplayContextP pDisplayContext,
char **drivers, unsigned *num_drivers
)
{
VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
if (!getenv("LIBVA_DRI3_DISABLE"))
vaStatus = va_DRI3_GetDriverNames(pDisplayContext, drivers, num_drivers);
if (vaStatus != VA_STATUS_SUCCESS)
vaStatus = va_DRI2_GetDriverNames(pDisplayContext, drivers, num_drivers);
#ifdef HAVE_NVCTRL
if (vaStatus != VA_STATUS_SUCCESS)
vaStatus = va_NVCTRL_GetDriverNames(pDisplayContext, drivers, num_drivers);
#endif
#ifdef HAVE_FGLRX
if (vaStatus != VA_STATUS_SUCCESS)
vaStatus = va_FGLRX_GetDriverNames(pDisplayContext, drivers, num_drivers);
#endif
return vaStatus;
}
VADisplay vaGetDisplay(
Display *native_dpy /* implementation specific */
)
{
VADisplayContextP pDisplayContext;
VADriverContextP pDriverContext;
struct dri_state *dri_state;
if (!native_dpy)
return NULL;
pDisplayContext = va_newDisplayContext();
if (!pDisplayContext)
return NULL;
pDisplayContext->vaDestroy = va_DisplayContextDestroy;
pDisplayContext->vaGetDriverNames = va_DisplayContextGetDriverNames;
pDriverContext = va_newDriverContext(pDisplayContext);
if (!pDriverContext) {
free(pDisplayContext);
return NULL;
}
pDriverContext->native_dpy = (void *)native_dpy;
pDriverContext->x11_screen = XDefaultScreen(native_dpy);
pDriverContext->display_type = VA_DISPLAY_X11;
dri_state = calloc(1, sizeof(*dri_state));
if (!dri_state) {
free(pDisplayContext);
free(pDriverContext);
return NULL;
}
dri_state->base.fd = -1;
dri_state->base.auth_type = VA_NONE;
pDriverContext->drm_state = dri_state;
return (VADisplay)pDisplayContext;
}
void va_TracePutSurface(
VADisplay dpy,
VASurfaceID surface,
void *draw, /* the target Drawable */
short srcx,
short srcy,
unsigned short srcw,
unsigned short srch,
short destx,
short desty,
unsigned short destw,
unsigned short desth,
VARectangle *cliprects, /* client supplied clip list */
unsigned int number_cliprects, /* number of clip rects in the clip list */
unsigned int flags /* de-interlacing flags */
);
VAStatus vaPutSurface(
VADisplay dpy,
VASurfaceID surface,
Drawable draw, /* X Drawable */
short srcx,
short srcy,
unsigned short srcw,
unsigned short srch,
short destx,
short desty,
unsigned short destw,
unsigned short desth,
VARectangle *cliprects, /* client supplied clip list */
unsigned int number_cliprects, /* number of clip rects in the clip list */
unsigned int flags /* de-interlacing flags */
)
{
VADriverContextP ctx;
VAStatus vaStatus = VA_STATUS_SUCCESS;
CHECK_DISPLAY(dpy);
ctx = CTX(dpy);
VA_TRACE_LOG(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
destx, desty, destw, desth,
cliprects, number_cliprects, flags);
vaStatus = ctx->vtable->vaPutSurface(ctx, surface, (void *)draw, srcx, srcy, srcw, srch,
destx, desty, destw, desth,
cliprects, number_cliprects, flags);
VA_TRACE_RET(dpy, vaStatus);
return vaStatus;
}