DRI2: Drop sarea, implement swap buffers in the X server.

This commit is contained in:
Kristian Høgsberg 2008-08-13 11:46:25 -04:00
parent 7a2ab6d055
commit f56b569e9a
19 changed files with 448 additions and 641 deletions

View File

@ -75,6 +75,10 @@ typedef struct __DRItexOffsetExtensionRec __DRItexOffsetExtension;
typedef struct __DRItexBufferExtensionRec __DRItexBufferExtension;
typedef struct __DRIlegacyExtensionRec __DRIlegacyExtension;
typedef struct __DRIswrastExtensionRec __DRIswrastExtension;
typedef struct __DRIbufferRec __DRIbuffer;
typedef struct __DRIdri2ExtensionRec __DRIdri2Extension;
typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension;
/*@}*/
@ -343,29 +347,6 @@ struct __DRIdamageExtensionRec {
void *loaderPrivate);
};
/**
* DRI2 Loader extension. This extension describes the basic
* functionality the loader needs to provide for the DRI driver.
*/
#define __DRI_LOADER "DRI_Loader"
#define __DRI_LOADER_VERSION 1
struct __DRIloaderExtensionRec {
__DRIextension base;
/**
* Ping the windowing system to get it to reemit info for the
* specified drawable in the DRI2 event buffer.
*
* \param draw the drawable for which to request info
* \param tail the new event buffer tail pointer
*/
void (*reemitDrawableInfo)(__DRIdrawable *draw, unsigned int *tail,
void *loaderPrivate);
void (*postDamage)(__DRIdrawable *draw, struct drm_clip_rect *rects,
int num_rects, void *loaderPrivate);
};
#define __DRI_SWRAST_IMAGE_OP_DRAW 1
#define __DRI_SWRAST_IMAGE_OP_CLEAR 2
#define __DRI_SWRAST_IMAGE_OP_SWAP 3
@ -633,4 +614,60 @@ struct __DRIswrastExtensionRec {
void *loaderPrivate);
};
/**
* DRI2 Loader extension.
*/
#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
struct __DRIbufferRec {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
#define __DRI_DRI2_LOADER_VERSION 1
struct __DRIdri2LoaderExtensionRec {
__DRIextension base;
__DRIbuffer *(*getBuffers)(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate);
};
/**
* This extension provides alternative screen, drawable and context
* constructors for DRI2.
*/
#define __DRI_DRI2 "DRI_DRI2"
#define __DRI_DRI2_VERSION 1
struct __DRIdri2ExtensionRec {
__DRIextension base;
__DRIscreen *(*createNewScreen)(int screen, int fd,
const __DRIextension **extensions,
const __DRIconfig ***driver_configs,
void *loaderPrivate);
__DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
const __DRIconfig *config,
void *loaderPrivate);
__DRIcontext *(*createNewContext)(__DRIscreen *screen,
const __DRIconfig *config,
__DRIcontext *shared,
void *loaderPrivate);
};
#endif

View File

@ -1,134 +0,0 @@
/*
* Copyright 2007 Red Hat, Inc
* 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
* on 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
* THE COPYRIGHT HOLDERS AND/OR THEIR 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 DRI_SAREA_H
#define DRI_SAREA_H
#include <drm.h>
/* The DRI2 SAREA holds a list of self-describing blocks. Each block
* is 8 byte aligned and has a common 32-bit header word. The upper
* 16 bits describe the type of the block and the lower 16 bits the
* size. DRI2 only defines a couple of blocks and allows drivers to
* define driver specific blocks using type codes from 0x8000 and up.
* The type code 0x0000 defines the end of the sarea. */
#define DRI2_SAREA_BLOCK_HEADER(type, size) (((type) << 16) | (size))
#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16)
#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff)
#define DRI2_SAREA_BLOCK_NEXT(p) \
((void *) ((unsigned char *) (p) + \
DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p)))
#define DRI2_SAREA_BLOCK_END 0x0000
#define DRI2_SAREA_BLOCK_LOCK 0x0001
#define DRI2_SAREA_BLOCK_EVENT_BUFFER 0x0002
/* Chipset specific blocks start at 0x8000, 0xffff is reserved. */
typedef struct __DRILock __DRILock;
typedef struct __DRIEventBuffer __DRIEventBuffer;
typedef struct __DRIDrawableBuffer __DRIDrawableBuffer;
typedef struct __DRIDrawableConfigEvent __DRIDrawableConfigEvent;
typedef struct __DRIBufferAttachEvent __DRIBufferAttachEvent;
struct __DRILock {
unsigned int block_header;
drm_hw_lock_t lock;
/* We use this with DRM_CAS to allocate lock IDs for the real lock.*/
unsigned int next_id;
};
struct __DRIEventBuffer {
unsigned int block_header;
unsigned int head; /* last valid event */
unsigned int prealloc; /* event currently being written */
unsigned int size; /* size of data */
unsigned char data[0];
};
enum {
/* the four standard color buffers */
DRI_DRAWABLE_BUFFER_FRONT_LEFT = 0,
DRI_DRAWABLE_BUFFER_BACK_LEFT = 1,
DRI_DRAWABLE_BUFFER_FRONT_RIGHT = 2,
DRI_DRAWABLE_BUFFER_BACK_RIGHT = 3,
/* optional aux buffer */
DRI_DRAWABLE_BUFFER_AUX0 = 4,
DRI_DRAWABLE_BUFFER_AUX1 = 5,
DRI_DRAWABLE_BUFFER_AUX2 = 6,
DRI_DRAWABLE_BUFFER_AUX3 = 7,
DRI_DRAWABLE_BUFFER_DEPTH = 8,
DRI_DRAWABLE_BUFFER_STENCIL = 9,
DRI_DRAWABLE_BUFFER_ACCUM = 10,
/* generic renderbuffers */
DRI_DRAWABLE_BUFFER_COLOR0 = 11,
DRI_DRAWABLE_BUFFER_COLOR1 = 12,
DRI_DRAWABLE_BUFFER_COLOR2 = 13,
DRI_DRAWABLE_BUFFER_COLOR3 = 14,
DRI_DRAWABLE_BUFFER_COLOR4 = 15,
DRI_DRAWABLE_BUFFER_COLOR5 = 16,
DRI_DRAWABLE_BUFFER_COLOR6 = 17,
DRI_DRAWABLE_BUFFER_COLOR7 = 18,
DRI_DRAWABLE_BUFFER_COUNT = 19
};
struct __DRIDrawableBuffer {
unsigned int attachment;
unsigned int handle;
unsigned int pitch;
unsigned short cpp;
/* Upper 8 bits are driver specific, lower 8 bits generic. The
* bits can inidicate buffer properties such as tiled, swizzled etc. */
unsigned short flags;
};
#define DRI2_EVENT_HEADER(type, size) (((type) << 16) | (size))
#define DRI2_EVENT_TYPE(b) ((b) >> 16)
#define DRI2_EVENT_SIZE(b) ((b) & 0xffff)
#define DRI2_EVENT_PAD 0x0000
#define DRI2_EVENT_DRAWABLE_CONFIG 0x0001
#define DRI2_EVENT_BUFFER_ATTACH 0x0002
struct __DRIDrawableConfigEvent {
unsigned int event_header;
unsigned int drawable;
short x;
short y;
unsigned int width;
unsigned int height;
unsigned int num_rects;
struct drm_clip_rect rects[0];
};
struct __DRIBufferAttachEvent {
unsigned int event_header;
unsigned int drawable;
__DRIDrawableBuffer buffer;
};
#endif /* DRI_SAREA_H */

View File

@ -122,7 +122,11 @@ Bool DRI2Connect(Display *dpy, int screen,
return False;
}
*sareaHandle = rep.sareaHandle;
if (rep.driverNameLength == 0 && rep.busIdLength == 0) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
*driverName = Xmalloc(rep.driverNameLength + 1);
if (*driverName == NULL) {
@ -150,7 +154,7 @@ Bool DRI2Connect(Display *dpy, int screen,
UnlockDisplay(dpy);
SyncHandle();
return rep.sareaHandle != 0;
return True;
}
Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic)
@ -179,32 +183,103 @@ Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic)
return rep.authenticated;
}
Bool DRI2CreateDrawable(Display *dpy, XID drawable,
unsigned int *handle, unsigned int *head)
void DRI2CreateDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2CreateDrawableReply rep;
xDRI2CreateDrawableReq *req;
XextCheckExtension (dpy, info, dri2ExtensionName, False);
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2CreateDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2CreateDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
}
DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2GetBuffersReply rep;
xDRI2GetBuffersReq *req;
DRI2Buffer *buffers;
xDRI2Buffer repBuffer;
CARD32 *p;
int i;
XextCheckExtension (dpy, info, dri2ExtensionName, False);
LockDisplay(dpy);
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)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
return NULL;
}
*width = rep.width;
*height = rep.height;
*outCount = rep.count;
buffers = Xmalloc(count * sizeof buffers[0]);
if (buffers == NULL) {
_XEatData(dpy, rep.count * sizeof repBuffer);
UnlockDisplay(dpy);
SyncHandle();
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;
}
UnlockDisplay(dpy);
SyncHandle();
*handle = rep.handle;
*head = rep.head;
return buffers;
}
return True;
void DRI2SwapBuffers(Display *dpy, XID drawable,
int x, int y, int width, int height)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2SwapBuffersReq *req;
xDRI2SwapBuffersReply rep;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2SwapBuffers, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2SwapBuffers;
req->drawable = drawable;
req->x = x;
req->y = y;
req->width = width;
req->height = height;
_XReply(dpy, (xReply *)&rep, 0, xFalse);
UnlockDisplay(dpy);
SyncHandle();
}
void DRI2DestroyDrawable(Display *dpy, XID drawable)
@ -224,29 +299,3 @@ void DRI2DestroyDrawable(Display *dpy, XID drawable)
UnlockDisplay(dpy);
SyncHandle();
}
Bool DRI2ReemitDrawableInfo(Display *dpy, XID drawable, unsigned int *head)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2ReemitDrawableInfoReply rep;
xDRI2ReemitDrawableInfoReq *req;
XextCheckExtension (dpy, info, dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2ReemitDrawableInfo, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2ReemitDrawableInfo;
req->drawable = drawable;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
UnlockDisplay(dpy);
SyncHandle();
*head = rep.head;
return True;
}

View File

@ -33,6 +33,14 @@
#ifndef _DRI2_H_
#define _DRI2_H_
typedef struct {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
} DRI2Buffer;
extern Bool
DRI2QueryExtension(Display *display, int *eventBase, int *errorBase);
extern Bool
@ -42,12 +50,17 @@ DRI2Connect(Display *display, int screen,
char **driverName, char **busId, unsigned int *sareaHandle);
extern Bool
DRI2AuthConnection(Display *display, int screen, drm_magic_t magic);
extern Bool
DRI2CreateDrawable(Display *display, XID drawable,
unsigned int *handle, unsigned int *head);
extern void
DRI2CreateDrawable(Display *display, XID drawable);
extern void
DRI2DestroyDrawable(Display *display, XID handle);
extern Bool
DRI2ReemitDrawableInfo(Display *dpy, XID handle, unsigned int *head);
extern DRI2Buffer *
DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount);
extern void
DRI2SwapBuffers(Display *dpy, XID drawable,
int x, int y, int width, int height);
#endif

View File

@ -49,6 +49,7 @@
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
struct __GLXDRIdisplayPrivateRec {
__GLXDRIdisplay base;
@ -67,6 +68,13 @@ struct __GLXDRIcontextPrivateRec {
__GLXscreenConfigs *psc;
};
struct __GLXDRIdrawablePrivateRec {
__GLXDRIdrawable base;
__DRIbuffer buffers[5];
int bufferCount;
int width, height;
};
static void dri2DestroyContext(__GLXDRIcontext *context,
__GLXscreenConfigs *psc, Display *dpy)
{
@ -104,7 +112,6 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc,
{
__GLXDRIcontextPrivate *pcp, *pcp_shared;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
const __DRIcoreExtension *core = psc->core;
__DRIcontext *shared = NULL;
if (shareList) {
@ -118,8 +125,8 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc,
pcp->psc = psc;
pcp->driContext =
(*core->createNewContext)(psc->__driScreen,
config->driConfig, shared, pcp);
(*psc->dri2->createNewContext)(psc->__driScreen,
config->driConfig, shared, pcp);
gc->__driContext = pcp->driContext;
if (pcp->driContext == NULL) {
@ -148,45 +155,40 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
GLXDrawable drawable,
const __GLcontextModes *modes)
{
__GLXDRIdrawable *pdraw;
__GLXDRIdrawablePrivate *pdraw;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
unsigned int handle, head;
const __DRIcoreExtension *core = psc->core;
pdraw = Xmalloc(sizeof(*pdraw));
if (!pdraw)
return NULL;
pdraw->destroyDrawable = dri2DestroyDrawable;
pdraw->xDrawable = xDrawable;
pdraw->drawable = drawable;
pdraw->psc = psc;
pdraw->base.destroyDrawable = dri2DestroyDrawable;
pdraw->base.xDrawable = xDrawable;
pdraw->base.drawable = drawable;
pdraw->base.psc = psc;
fprintf(stderr, "calling DRI2CreateDrawable, XID 0x%lx, GLX ID 0x%lx\n",
xDrawable, drawable);
if (!DRI2CreateDrawable(psc->dpy, xDrawable, &handle, &head)) {
Xfree(pdraw);
return NULL;
}
fprintf(stderr, "success, head 0x%x, handle 0x%x\n", head, handle);
DRI2CreateDrawable(psc->dpy, xDrawable);
/* Create a new drawable */
pdraw->driDrawable =
(*core->createNewDrawable)(psc->__driScreen,
config->driConfig,
handle,
head,
pdraw);
pdraw->base.driDrawable =
(*psc->dri2->createNewDrawable)(psc->__driScreen,
config->driConfig, pdraw);
if (!pdraw->driDrawable) {
if (!pdraw->base.driDrawable) {
DRI2DestroyDrawable(psc->dpy, drawable);
Xfree(pdraw);
return NULL;
}
return pdraw;
return &pdraw->base;
}
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable,
0, 0, priv->width, priv->height);
}
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
@ -197,46 +199,39 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
psc->__driScreen = NULL;
}
static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail,
void *loaderPrivate)
static __DRIbuffer *
dri2GetBuffers(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate)
{
__GLXDRIdrawable *pdraw = loaderPrivate;
DRI2ReemitDrawableInfo(pdraw->psc->dpy, pdraw->drawable, tail);
}
static void dri2PostDamage(__DRIdrawable *draw,
struct drm_clip_rect *rects,
int numRects, void *loaderPrivate)
{
XRectangle *xrects;
XserverRegion region;
__GLXDRIdrawable *glxDraw = loaderPrivate;
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
DRI2Buffer *buffers;
int i;
xrects = malloc(sizeof(XRectangle) * numRects);
if (xrects == NULL)
return;
buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
width, height, attachments, count, out_count);
pdraw->width = *width;
pdraw->height = *height;
for (i = 0; i < numRects; i++) {
xrects[i].x = rects[i].x1;
xrects[i].y = rects[i].y1;
xrects[i].width = rects[i].x2 - rects[i].x1;
xrects[i].height = rects[i].y2 - rects[i].y1;
/* This assumes the DRI2 buffer attachment tokens matches the
* __DRIbuffer tokens. */
for (i = 0; i < *out_count; i++) {
pdraw->buffers[i].attachment = buffers[i].attachment;
pdraw->buffers[i].name = buffers[i].name;
pdraw->buffers[i].pitch = buffers[i].pitch;
pdraw->buffers[i].cpp = buffers[i].cpp;
pdraw->buffers[i].flags = buffers[i].flags;
}
region = XFixesCreateRegion(dpy, xrects, numRects);
free(xrects);
XDamageAdd(dpy, glxDraw->xDrawable, region);
XFixesDestroyRegion(dpy, region);
Xfree(buffers);
return pdraw->buffers;
}
static const __DRIloaderExtension dri2LoaderExtension = {
{ __DRI_LOADER, __DRI_LOADER_VERSION },
dri2ReemitDrawableInfo,
dri2PostDamage
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
{ __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
dri2GetBuffers,
};
static const __DRIextension *loader_extensions[] = {
@ -279,10 +274,12 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
psc->core = (__DRIcoreExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
psc->dri2 = (__DRIdri2Extension *) extensions[i];
}
if (psc->core == NULL) {
ErrorMessageF("core dri extension not found\n");
if (psc->core == NULL || psc->dri2 == NULL) {
ErrorMessageF("core dri or dri2 extension not found\n");
goto handle_error;
}
@ -301,7 +298,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
}
psc->__driScreen =
psc->core->createNewScreen(screen, psc->fd, sareaHandle,
psc->dri2->createNewScreen(screen, psc->fd,
loader_extensions, &driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
@ -316,6 +313,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
psp->destroyScreen = dri2DestroyScreen;
psp->createContext = dri2CreateContext;
psp->createDrawable = dri2CreateDrawable;
psp->swapBuffers = dri2SwapBuffers;
Xfree(driverName);
Xfree(busID);

View File

@ -570,6 +570,11 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
return pdraw;
}
static void driSwapBuffers(__GLXDRIdrawable *pdraw)
{
(*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
}
static void driDestroyScreen(__GLXscreenConfigs *psc)
{
/* Free the direct rendering per screen data */
@ -641,6 +646,7 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
psp->swapBuffers = driSwapBuffers;
return psp;
}

View File

@ -123,6 +123,8 @@ struct __GLXDRIscreenRec {
XID drawable,
GLXDrawable glxDrawable,
const __GLcontextModes *modes);
void (*swapBuffers)(__GLXDRIdrawable *pdraw);
};
struct __GLXDRIcontextRec {
@ -141,8 +143,8 @@ struct __GLXDRIdrawableRec {
XID xDrawable;
XID drawable;
__GLXscreenConfigs *psc;
__DRIdrawable *driDrawable;
GLenum textureTarget;
__DRIdrawable *driDrawable;
};
/*
@ -469,6 +471,7 @@ struct __GLXscreenConfigsRec {
const __DRIcoreExtension *core;
const __DRIlegacyExtension *legacy;
const __DRIswrastExtension *swrast;
const __DRIdri2Extension *dri2;
__glxHashTable *drawHash;
Display *dpy;
int scr, fd;

View File

@ -855,7 +855,8 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
if (pdraw != NULL) {
(*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
glFlush();
(*pdraw->psc->driScreen->swapBuffers)(pdraw);
return;
}
#endif

View File

@ -40,8 +40,6 @@ install: dri.pc
$(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal
$(INSTALL) -m 0644 $(TOP)/include/GL/internal/dri_interface.h \
$(DESTDIR)$(INSTALL_INC_DIR)/GL/internal
$(INSTALL) -m 0644 $(TOP)/include/GL/internal/dri_sarea.h \
$(DESTDIR)$(INSTALL_INC_DIR)/GL/internal
$(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
$(INSTALL) -m 0644 dri.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig

View File

@ -152,7 +152,6 @@ static int driUnbindContext(__DRIcontext *pcp)
return GL_TRUE;
}
/**
* This function takes both a read buffer and a draw buffer. This is needed
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
@ -186,10 +185,7 @@ static int driBindContext(__DRIcontext *pcp,
** initialize the drawable information if has not been done before.
*/
if (psp->dri2.enabled) {
__driParseEvents(pcp, pdp);
__driParseEvents(pcp, prp);
} else {
if (!psp->dri2.enabled) {
if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
__driUtilUpdateDrawableInfo(pdp);
@ -279,139 +275,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
}
int
__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
{
__DRIscreenPrivate *psp = pdp->driScreenPriv;
__DRIDrawableConfigEvent *dc, *last_dc;
__DRIBufferAttachEvent *ba, *last_ba;
unsigned int tail, mask, *p, end, total, size, changed;
unsigned char *data;
size_t rect_size;
/* Check for wraparound. */
if (pcp && psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
/* If prealloc overlaps into what we just parsed, the
* server overwrote it and we have to reset our tail
* pointer. */
DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
(*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
pdp->loaderPrivate);
DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
}
total = psp->dri2.buffer->head - pdp->dri2.tail;
mask = psp->dri2.buffer->size - 1;
end = psp->dri2.buffer->head;
data = psp->dri2.buffer->data;
changed = 0;
last_dc = NULL;
last_ba = NULL;
for (tail = pdp->dri2.tail; tail != end; tail += size) {
p = (unsigned int *) (data + (tail & mask));
size = DRI2_EVENT_SIZE(*p);
if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
/* illegal data, bail out. */
fprintf(stderr, "illegal event size\n");
break;
}
switch (DRI2_EVENT_TYPE(*p)) {
case DRI2_EVENT_DRAWABLE_CONFIG:
dc = (__DRIDrawableConfigEvent *) p;
if (dc->drawable == pdp->dri2.drawable_id)
last_dc = dc;
break;
case DRI2_EVENT_BUFFER_ATTACH:
ba = (__DRIBufferAttachEvent *) p;
if (ba->drawable == pdp->dri2.drawable_id &&
ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
last_ba = ba;
break;
}
}
if (last_dc) {
if (pdp->w != last_dc->width || pdp->h != last_dc->height)
changed = 1;
pdp->x = last_dc->x;
pdp->y = last_dc->y;
pdp->w = last_dc->width;
pdp->h = last_dc->height;
pdp->backX = 0;
pdp->backY = 0;
pdp->numBackClipRects = 1;
pdp->pBackClipRects[0].x1 = 0;
pdp->pBackClipRects[0].y1 = 0;
pdp->pBackClipRects[0].x2 = pdp->w;
pdp->pBackClipRects[0].y2 = pdp->h;
pdp->numClipRects = last_dc->num_rects;
_mesa_free(pdp->pClipRects);
rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
pdp->pClipRects = _mesa_malloc(rect_size);
memcpy(pdp->pClipRects, last_dc->rects, rect_size);
}
/* We only care about the most recent drawable config. */
if (last_dc && changed)
(*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
/* Front buffer attachments are special, they typically mean that
* we're rendering to a redirected window (or a child window of a
* redirected window) and that it got resized. Resizing the root
* window on randr events is a special case of this. Other causes
* may be a window transitioning between redirected and
* non-redirected, or a window getting reparented between parents
* with different window pixmaps (eg two redirected windows).
* These events are special in that the X server allocates the
* buffer and that the buffer may be shared by other child
* windows. When our window share the window pixmap with its
* parent, drawable config events doesn't affect the front buffer.
* We only care about the last such event in the buffer; in fact,
* older events will refer to invalid buffer objects.*/
if (last_ba)
(*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
/* If there was a drawable config event in the buffer and it
* changed the size of the window, all buffer auxillary buffer
* attachments prior to that are invalid (as opposed to the front
* buffer case discussed above). In that case we can start
* looking for buffer attachment after the last drawable config
* event. If there is no drawable config event in this batch of
* events, we have to assume that the last batch might have had
* one and process all buffer attach events.*/
if (last_dc && changed)
tail = (unsigned char *) last_dc - data;
else
tail = pdp->dri2.tail;
for ( ; tail != end; tail += size) {
ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
size = DRI2_EVENT_SIZE(ba->event_header);
if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
continue;
if (ba->drawable != pdp->dri2.drawable_id)
continue;
if (last_ba == ba)
continue;
(*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
changed = 1;
}
pdp->dri2.tail = tail;
return changed || last_ba;
}
/*@}*/
/*****************************************************************/
@ -425,12 +288,7 @@ static void driReportDamage(__DRIdrawable *pdp,
__DRIscreen *psp = pdp->driScreenPriv;
/* Check that we actually have the new damage report method */
if (psp->dri2.enabled) {
(*psp->dri2.loader->postDamage)(pdp,
pClipRects,
numClipRects,
pdp->loaderPrivate);
} else if (psp->damage) {
if (psp->damage) {
/* Report the damage. Currently, all our drivers draw
* directly to the front buffer, so we report the damage there
* rather than to the backing storein (if any).
@ -460,9 +318,6 @@ static void driSwapBuffers(__DRIdrawable *dPriv)
if (!dPriv->numClipRects)
return;
if (psp->dri2.enabled)
__driParseEvents(NULL, dPriv);
psp->DriverAPI.SwapBuffers(dPriv);
driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
@ -602,17 +457,17 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
static __DRIdrawable *
dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
unsigned int drawable_id, unsigned int head, void *data)
dri2CreateNewDrawable(__DRIscreen *screen,
const __DRIconfig *config,
void *loaderPrivate)
{
__DRIdrawable *pdraw;
pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
if (!pdraw)
return NULL;
pdraw->dri2.drawable_id = drawable_id;
pdraw->dri2.tail = head;
pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
return pdraw;
@ -723,18 +578,7 @@ static __DRIcontext *
dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
__DRIcontext *shared, void *data)
{
drm_context_t hwContext;
DRM_CAS_RESULT(ret);
/* DRI2 doesn't use kernel with context IDs, we just need an ID that's
* different from the kernel context ID to make drmLock() happy. */
do {
hwContext = screen->dri2.lock->next_id;
DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
} while (ret);
return driCreateNewContext(screen, config, 0, shared, hwContext, data);
return driCreateNewContext(screen, config, 0, shared, 0, data);
}
@ -770,12 +614,7 @@ static void driDestroyScreen(__DRIscreen *psp)
if (psp->DriverAPI.DestroyScreen)
(*psp->DriverAPI.DestroyScreen)(psp);
if (psp->dri2.enabled) {
#ifdef TTM_API
drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
#endif
} else {
if (!psp->dri2.enabled) {
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
(void)drmCloseOnce(psp->fd);
@ -798,8 +637,8 @@ setupLoaderExtensions(__DRIscreen *psp,
psp->damage = (__DRIdamageExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
}
}
@ -895,19 +734,16 @@ driCreateNewScreen(int scrn,
return psp;
}
/**
* DRI2
*/
static __DRIscreen *
dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
dri2CreateNewScreen(int scrn, int fd,
const __DRIextension **extensions,
const __DRIconfig ***driver_configs, void *data)
{
#ifdef TTM_API
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
unsigned int *p;
drmVersionPtr version;
if (driDriverAPI.InitScreen2 == NULL)
@ -932,39 +768,9 @@ dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
psp->myNum = scrn;
psp->dri2.enabled = GL_TRUE;
if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
_mesa_free(psp);
return NULL;
}
if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
_mesa_free(psp);
return NULL;
}
p = psp->dri2.sarea;
while (DRI2_SAREA_BLOCK_TYPE(*p)) {
switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
case DRI2_SAREA_BLOCK_LOCK:
psp->dri2.lock = (__DRILock *) p;
break;
case DRI2_SAREA_BLOCK_EVENT_BUFFER:
psp->dri2.buffer = (__DRIEventBuffer *) p;
break;
}
p = DRI2_SAREA_BLOCK_NEXT(p);
}
psp->lock = (drmLock *) &psp->dri2.lock->lock;
psp->DriverAPI = driDriverAPI;
*driver_configs = driDriverAPI.InitScreen2(psp);
if (*driver_configs == NULL) {
drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
_mesa_free(psp);
return NULL;
}
@ -972,9 +778,6 @@ dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
psp->DriverAPI = driDriverAPI;
return psp;
#else
return NULL;
#endif
}
static const __DRIextension **driGetExtensions(__DRIscreen *psp)
@ -982,36 +785,45 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
return psp->extensions;
}
/** Legacy DRI interface */
const __DRIlegacyExtension driLegacyExtension = {
{ __DRI_LEGACY, __DRI_LEGACY_VERSION },
driCreateNewScreen,
driCreateNewDrawable,
driCreateNewContext
};
/** DRI2 interface */
/** Core interface */
const __DRIcoreExtension driCoreExtension = {
{ __DRI_CORE, __DRI_CORE_VERSION },
dri2CreateNewScreen,
NULL,
driDestroyScreen,
driGetExtensions,
driGetConfigAttrib,
driIndexConfigAttrib,
dri2CreateNewDrawable,
NULL,
driDestroyDrawable,
driSwapBuffers,
dri2CreateNewContext,
NULL,
driCopyContext,
driDestroyContext,
driBindContext,
driUnbindContext
};
/** Legacy DRI interface */
const __DRIlegacyExtension driLegacyExtension = {
{ __DRI_LEGACY, __DRI_LEGACY_VERSION },
driCreateNewScreen,
driCreateNewDrawable,
driCreateNewContext,
};
/** Legacy DRI interface */
const __DRIdri2Extension driDRI2Extension = {
{ __DRI_DRI2, __DRI_DRI2_VERSION },
dri2CreateNewScreen,
dri2CreateNewDrawable,
dri2CreateNewContext,
};
/* This is the table of extensions that the loader will dlsym() for. */
PUBLIC const __DRIextension *__driDriverExtensions[] = {
&driCoreExtension.base,
&driLegacyExtension.base,
&driDRI2Extension.base,
NULL
};

View File

@ -204,16 +204,8 @@ struct __DriverAPIRec {
/* DRI2 Entry points */
/* DRI2 Entry point */
const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
void (*HandleDrawableConfig)(__DRIdrawable *dPriv,
__DRIcontext *pcp,
__DRIDrawableConfigEvent *event);
void (*HandleBufferAttach)(__DRIdrawable *dPriv,
__DRIcontext *pcp,
__DRIBufferAttachEvent *ba);
};
extern const struct __DriverAPIRec driDriverAPI;
@ -369,10 +361,6 @@ struct __DRIdrawableRec {
* GLX_MESA_swap_control.
*/
unsigned int swap_interval;
struct {
unsigned int tail;
unsigned int drawable_id;
} dri2;
};
/**
@ -524,13 +512,7 @@ struct __DRIscreenRec {
/* Flag to indicate that this is a DRI2 screen. Many of the above
* fields will not be valid or initializaed in that case. */
int enabled;
#ifdef TTM_API
drmBO sareaBO;
#endif
void *sarea;
__DRIEventBuffer *buffer;
__DRILock *lock;
__DRIloaderExtension *loader;
__DRIdri2LoaderExtension *loader;
} dri2;
/* The lock actually in use, old sarea or DRI2 */
@ -544,9 +526,6 @@ __driUtilMessage(const char *f, ...);
extern void
__driUtilUpdateDrawableInfo(__DRIdrawable *pdp);
extern int
__driParseEvents(__DRIcontext *psp, __DRIdrawable *pdp);
extern float
driCalculateSwapUsage( __DRIdrawable *dPriv,
int64_t last_swap_ust, int64_t current_ust );

View File

@ -75,15 +75,27 @@ static void brw_set_draw_region( struct intel_context *intel,
GLuint num_regions)
{
struct brw_context *brw = brw_context(&intel->ctx);
struct intel_region *old_depth_region, *old_draw_regions[MAX_DRAW_BUFFERS];
int i;
if (brw->state.depth_region != depth_region)
brw->state.dirty.brw |= BRW_NEW_DEPTH_BUFFER;
for (i = 0; i < brw->state.nr_draw_regions; i++)
intel_region_release(&brw->state.draw_regions[i]);
intel_region_release(&brw->state.depth_region);
for (i = 0; i < brw->state.nr_draw_regions; i++) {
old_draw_regions[i] = brw->state.draw_regions[i];
brw->state.draw_regions[i] = NULL;
}
old_depth_region = brw->state.depth_region;
brw->state.depth_region = NULL;
for (i = 0; i < num_regions; i++)
intel_region_reference(&brw->state.draw_regions[i], draw_regions[i]);
intel_region_reference(&brw->state.depth_region, depth_region);
for (i = 0; i < brw->state.nr_draw_regions; i++)
intel_region_release(&old_draw_regions[i]);
intel_region_release(&old_depth_region);
brw->state.nr_draw_regions = num_regions;
}

View File

@ -618,6 +618,9 @@ intel_wait_flips(struct intel_context *intel)
BUFFER_FRONT_LEFT ? BUFFER_FRONT_LEFT :
BUFFER_BACK_LEFT);
if (intel->intelScreen->driScrnPriv->dri2.enabled)
return;
if (intel_fb->Base.Name == 0 && intel_rb &&
intel_rb->pf_pending == intel_fb->pf_seq) {
GLint pf_planes = intel_fb->pf_planes;

View File

@ -195,6 +195,142 @@ intelGetString(GLcontext * ctx, GLenum name)
}
}
void
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
{
struct intel_framebuffer *intel_fb = drawable->driverPrivate;
struct intel_renderbuffer *rb;
struct intel_region *region, *depth_region;
struct intel_context *intel = context->driverPrivate;
__DRIbuffer *buffers;
__DRIscreen *screen;
int i, count;
unsigned int attachments[10];
uint32_t name;
const char *region_name;
if (INTEL_DEBUG & DEBUG_DRI)
fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
screen = intel->intelScreen->driScrnPriv;
i = 0;
if (intel_fb->color_rb[0])
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
if (intel_fb->color_rb[1])
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
attachments[i++] = __DRI_BUFFER_DEPTH;
if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
attachments[i++] = __DRI_BUFFER_STENCIL;
buffers = (*screen->dri2.loader->getBuffers)(drawable,
&drawable->w,
&drawable->h,
attachments, i,
&count,
drawable->loaderPrivate);
drawable->x = 0;
drawable->y = 0;
drawable->backX = 0;
drawable->backY = 0;
drawable->numClipRects = 1;
drawable->pClipRects[0].x1 = 0;
drawable->pClipRects[0].y1 = 0;
drawable->pClipRects[0].x2 = drawable->w;
drawable->pClipRects[0].y2 = drawable->h;
drawable->numBackClipRects = 1;
drawable->pBackClipRects[0].x1 = 0;
drawable->pBackClipRects[0].y1 = 0;
drawable->pBackClipRects[0].x2 = drawable->w;
drawable->pBackClipRects[0].y2 = drawable->h;
depth_region = NULL;
for (i = 0; i < count; i++) {
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
rb = intel_fb->color_rb[0];
region_name = "dri2 front buffer";
break;
case __DRI_BUFFER_BACK_LEFT:
rb = intel_fb->color_rb[1];
region_name = "dri2 back buffer";
break;
case __DRI_BUFFER_DEPTH:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
region_name = "dri2 depth buffer";
break;
case __DRI_BUFFER_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
region_name = "dri2 stencil buffer";
break;
case __DRI_BUFFER_ACCUM:
default:
fprintf(stderr,
"unhandled buffer attach event, attacment type %d\n",
buffers[i].attachment);
return;
}
if (rb->region) {
intel_bo_flink(rb->region->buffer, &name);
if (name == buffers[i].name)
continue;
}
if (INTEL_DEBUG & DEBUG_DRI)
fprintf(stderr,
"attaching buffer %d, at %d, cpp %d, pitch %d\n",
buffers[i].name, buffers[i].attachment,
buffers[i].cpp, buffers[i].pitch);
if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_region) {
if (INTEL_DEBUG & DEBUG_DRI)
fprintf(stderr, "(reusing depth buffer as stencil)\n");
region = depth_region;
}
else
region = intel_region_alloc_for_handle(intel, buffers[i].cpp,
buffers[i].pitch / buffers[i].cpp,
drawable->h,
buffers[i].name,
region_name);
if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
depth_region = region;
intel_renderbuffer_set_region(rb, region);
intel_region_release(&region);
}
driUpdateFramebufferSize(&intel->ctx, drawable);
}
static void
intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
struct intel_context *intel = intel_context(ctx);
__DRIcontext *driContext = intel->driContext;
if (!driContext->driScreenPriv->dri2.enabled)
return;
intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
if (driContext->driDrawablePriv != driContext->driReadablePriv)
intel_update_renderbuffers(driContext, driContext->driReadablePriv);
ctx->Driver.Viewport = NULL;
intel->driDrawable = driContext->driDrawablePriv;
intelWindowMoved(intel);
intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
ctx->Driver.Viewport = intel_viewport;
}
/**
* Extension strings exported by the intel driver.
*
@ -541,6 +677,7 @@ intelInitDriverFunctions(struct dd_function_table *functions)
functions->Finish = intelFinish;
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
functions->Viewport = intel_viewport;
functions->CopyColorTable = _swrast_CopyColorTable;
functions->CopyColorSubTable = _swrast_CopyColorSubTable;
@ -582,6 +719,7 @@ intelInitContext(struct intel_context *intel,
intel->intelScreen = intelScreen;
intel->driScreen = sPriv;
intel->sarea = saPriv;
intel->driContext = driContextPriv;
/* Dri stuff */
intel->hHWContext = driContextPriv->hHWContext;
@ -784,6 +922,9 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
(struct intel_framebuffer *) driDrawPriv->driverPrivate;
GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
intel_update_renderbuffers(driContextPriv, driDrawPriv);
if (driDrawPriv != driReadPriv)
intel_update_renderbuffers(driContextPriv, driReadPriv);
/* XXX FBO temporary fix-ups! */
/* if the renderbuffers don't have regions, init them from the context */
@ -989,18 +1130,12 @@ void LOCK_HARDWARE( struct intel_context *intel )
intel_fb->vbl_waited = vbl.reply.sequence;
}
DRM_CAS(intel->driHwLock, intel->hHWContext,
(DRM_LOCK_HELD|intel->hHWContext), __ret);
if (!sPriv->dri2.enabled) {
DRM_CAS(intel->driHwLock, intel->hHWContext,
(DRM_LOCK_HELD|intel->hHWContext), __ret);
if (sPriv->dri2.enabled) {
if (__ret)
drmGetLock(intel->driFd, intel->hHWContext, 0);
if (__driParseEvents(dPriv->driContextPriv, dPriv)) {
intelWindowMoved(intel);
intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
}
} else if (__ret) {
intelContendedLock( intel, 0 );
intelContendedLock( intel, 0 );
}
@ -1013,10 +1148,13 @@ void LOCK_HARDWARE( struct intel_context *intel )
*/
void UNLOCK_HARDWARE( struct intel_context *intel )
{
__DRIscreen *sPriv = intel->driScreen;
intel->vtbl.note_unlock( intel );
intel->locked = 0;
DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
if (!sPriv->dri2.enabled)
DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
_glthread_UNLOCK_MUTEX(lockMutex);

View File

@ -257,6 +257,7 @@ struct intel_context
drmLock *driHwLock;
int driFd;
__DRIcontextPrivate *driContext;
__DRIdrawablePrivate *driDrawable;
__DRIdrawablePrivate *driReadDrawable;
__DRIscreenPrivate *driScreen;

View File

@ -145,12 +145,12 @@ intel_region_alloc(struct intel_context *intel,
struct intel_region *
intel_region_alloc_for_handle(struct intel_context *intel,
GLuint cpp, GLuint pitch, GLuint height,
GLuint handle)
GLuint handle, const char *name)
{
struct intel_region *region;
dri_bo *buffer;
buffer = intel_bo_gem_create_from_name(intel->bufmgr, "dri2 region", handle);
buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
region = intel_region_alloc_internal(intel, cpp, pitch, height, buffer);
if (region == NULL)
@ -164,6 +164,9 @@ intel_region_alloc_for_handle(struct intel_context *intel,
void
intel_region_reference(struct intel_region **dst, struct intel_region *src)
{
if (src)
DBG("%s %d\n", __FUNCTION__, src->refcount);
assert(*dst == NULL);
if (src) {
src->refcount++;

View File

@ -76,7 +76,7 @@ struct intel_region *intel_region_alloc(struct intel_context *intel,
struct intel_region *
intel_region_alloc_for_handle(struct intel_context *intel,
GLuint cpp, GLuint pitch, GLuint height,
unsigned int handle);
unsigned int handle, const char *name);
void intel_region_reference(struct intel_region **dst,
struct intel_region *src);

View File

@ -211,102 +211,6 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
intelPrintSAREA(sarea);
}
/**
* DRI2 entrypoint
*/
static void
intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,
__DRIcontextPrivate *pcp,
__DRIDrawableConfigEvent *event)
{
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
struct intel_region *region = NULL;
struct intel_renderbuffer *rb, *depth_rb, *stencil_rb;
struct intel_context *intel = pcp->driverPrivate;
int cpp, pitch;
cpp = intel->ctx.Visual.rgbBits / 8;
pitch = ((cpp * dPriv->w + 63) & ~63) / cpp;
rb = intel_fb->color_rb[1];
if (rb) {
region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
intel_renderbuffer_set_region(rb, region);
}
rb = intel_fb->color_rb[2];
if (rb) {
region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
intel_renderbuffer_set_region(rb, region);
}
depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
if (depth_rb || stencil_rb)
region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
if (depth_rb)
intel_renderbuffer_set_region(depth_rb, region);
if (stencil_rb)
intel_renderbuffer_set_region(stencil_rb, region);
/* FIXME: Tell the X server about the regions we just allocated and
* attached. */
}
/**
* DRI2 entrypoint
*/
static void
intelHandleBufferAttach(__DRIdrawablePrivate *dPriv,
__DRIcontextPrivate *pcp,
__DRIBufferAttachEvent *ba)
{
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
struct intel_renderbuffer *rb;
struct intel_region *region;
struct intel_context *intel = pcp->driverPrivate;
switch (ba->buffer.attachment) {
case DRI_DRAWABLE_BUFFER_FRONT_LEFT:
rb = intel_fb->color_rb[0];
break;
case DRI_DRAWABLE_BUFFER_BACK_LEFT:
rb = intel_fb->color_rb[0];
break;
case DRI_DRAWABLE_BUFFER_DEPTH:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
break;
case DRI_DRAWABLE_BUFFER_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
break;
case DRI_DRAWABLE_BUFFER_ACCUM:
default:
fprintf(stderr, "unhandled buffer attach event, attacment type %d\n",
ba->buffer.attachment);
return;
}
#if 0
/* FIXME: Add this so we can filter out when the X server sends us
* attachment events for the buffers we just allocated. Need to
* get the BO handle for a render buffer. */
if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle)
return;
#endif
region = intel_region_alloc_for_handle(intel, ba->buffer.cpp,
ba->buffer.pitch / ba->buffer.cpp,
dPriv->h,
ba->buffer.handle);
intel_renderbuffer_set_region(rb, region);
}
static const __DRItexOffsetExtension intelTexOffsetExtension = {
{ __DRI_TEX_OFFSET },
intelSetTexOffset,
@ -750,26 +654,12 @@ __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
intelScreen->drmMinor = psp->drm_version.minor;
/* Determine chipset ID? */
/* Determine chipset ID */
if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
&intelScreen->deviceID))
return GL_FALSE;
/* Determine if IRQs are active? */
if (!intel_get_param(psp, I915_PARAM_IRQ_ACTIVE,
&intelScreen->irq_active))
return GL_FALSE;
/* Determine if batchbuffers are allowed */
if (!intel_get_param(psp, I915_PARAM_ALLOW_BATCHBUFFER,
&intelScreen->allow_batchbuffer))
return GL_FALSE;
if (!intelScreen->allow_batchbuffer) {
fprintf(stderr, "batch buffer not allowed\n");
return GL_FALSE;
}
intelScreen->irq_active = 1;
psp->extensions = intelScreenExtensions;
return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1),
@ -792,6 +682,4 @@ const struct __DriverAPIRec driDriverAPI = {
.CopySubBuffer = intelCopySubBuffer,
.InitScreen2 = intelInitScreen2,
.HandleDrawableConfig = intelHandleDrawableConfig,
.HandleBufferAttach = intelHandleBufferAttach,
};

View File

@ -731,7 +731,7 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
if (!intelObj)
return;
__driParseEvents(pDRICtx, dPriv);
intel_update_renderbuffers(pDRICtx, dPriv);
rb = intel_fb->color_rb[0];
type = GL_BGRA;