backport some code from mesa current (and 7.5) so that the dri2 protocol

is correctly handled. without fixes to mesa and the ddx, the so-called
backwards compat goop that was added just plain does not work and ends
up with rendering bullshit.
This commit is contained in:
oga 2009-08-06 15:50:02 +00:00
parent 11a94b33b4
commit 9997d7a073
13 changed files with 506 additions and 70 deletions

View File

@ -78,6 +78,7 @@ typedef struct __DRIswrastExtensionRec __DRIswrastExtension;
typedef struct __DRIbufferRec __DRIbuffer;
typedef struct __DRIdri2ExtensionRec __DRIdri2Extension;
typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension;
typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
/*@}*/
@ -245,6 +246,16 @@ struct __DRItexBufferExtensionRec {
__DRIdrawable *pDraw);
};
/**
* Used by drivers that implement DRI2
*/
#define __DRI2_FLUSH "DRI2_Flush"
#define __DRI2_FLUSH_VERSION 1
struct __DRI2flushExtensionRec {
__DRIextension base;
void (*flush)(__DRIdrawable *drawable);
};
/**
* XML document describing the configuration options supported by the
@ -626,6 +637,7 @@ struct __DRIswrastExtensionRec {
#define __DRI_BUFFER_ACCUM 6
#define __DRI_BUFFER_FAKE_FRONT_LEFT 7
#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8
#define __DRI_BUFFER_DEPTH_STENCIL 9 /**< Only available with DRI2 1.1 */
struct __DRIbufferRec {
unsigned int attachment;
@ -636,7 +648,7 @@ struct __DRIbufferRec {
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
#define __DRI_DRI2_LOADER_VERSION 2
#define __DRI_DRI2_LOADER_VERSION 3
struct __DRIdri2LoaderExtensionRec {
__DRIextension base;
@ -657,6 +669,31 @@ struct __DRIdri2LoaderExtensionRec {
* into __DRIdri2ExtensionRec::createNewDrawable
*/
void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
/**
* Get list of buffers from the server
*
* Gets a list of buffer for the specified set of attachments. Unlike
* \c ::getBuffers, this function takes a list of attachments paired with
* opaque \c unsigned \c int value describing the format of the buffer.
* It is the responsibility of the caller to know what the service that
* allocates the buffers will expect to receive for the format.
*
* \param driDrawable Drawable whose buffers are being queried.
* \param width Output where the width of the buffers is stored.
* \param height Output where the height of the buffers is stored.
* \param attachments List of pairs of attachment ID and opaque format
* requested for the drawable.
* \param count Number of attachment / format pairs stored in
* \c attachments.
* \param loaderPrivate Loader's private data that was previously passed
* into __DRIdri2ExtensionRec::createNewDrawable.
*/
__DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate);
};
/**

View File

@ -39,6 +39,16 @@
#include "xf86drm.h"
#include "dri2.h"
/* Allow the build to work with an older versions of dri2proto.h and
* dri2tokens.h.
*/
#if DRI2_MINOR < 1
#undef DRI2_MINOR
#define DRI2_MINOR 1
#define X_DRI2GetBuffersWithFormat 7
#endif
static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
@ -276,6 +286,66 @@ DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
return buffers;
}
DRI2Buffer *DRI2GetBuffersWithFormat(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 * 2), req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2GetBuffersWithFormat;
req->drawable = drawable;
req->count = count;
p = (CARD32 *) &req[1];
for (i = 0; i < (count * 2); i++)
p[i] = attachments[i];
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return NULL;
}
*width = rep.width;
*height = rep.height;
*outCount = rep.count;
buffers = Xmalloc(rep.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();
return buffers;
}
void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
{

View File

@ -63,6 +63,16 @@ DRI2GetBuffers(Display *dpy, XID drawable,
unsigned int *attachments, int count,
int *outCount);
/**
* \note
* This function is only supported with DRI2 version 1.1 or later.
*/
extern DRI2Buffer *
DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount);
extern void
DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);

View File

@ -47,6 +47,9 @@
#include "dri2.h"
#include "dri_common.h"
#undef DRI2_MINOR
#define DRI2_MINOR 1
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
@ -77,6 +80,8 @@ struct __GLXDRIdrawablePrivateRec {
int have_fake_front;
};
static void dri2WaitX(__GLXDRIdrawable *pdraw);
static void dri2DestroyContext(__GLXDRIcontext *context,
__GLXscreenConfigs *psc, Display *dpy)
{
@ -202,10 +207,21 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
xrect.width = width;
xrect.height = height;
#ifdef __DRI2_FLUSH
if (pdraw->psc->f)
(*pdraw->psc->f->flush)(pdraw->driDrawable);
#endif
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
/* should get a fence ID back from here at some point */
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
/* Refresh the fake front (if present) after we just damaged the real
* front.
*/
dri2WaitX(pdraw);
}
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
@ -230,6 +246,11 @@ static void dri2WaitX(__GLXDRIdrawable *pdraw)
xrect.width = priv->width;
xrect.height = priv->height;
#ifdef __DRI2_FLUSH
if (pdraw->psc->f)
(*pdraw->psc->f->flush)(pdraw->driDrawable);
#endif
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
@ -250,6 +271,11 @@ static void dri2WaitGL(__GLXDRIdrawable *pdraw)
xrect.width = priv->width;
xrect.height = priv->height;
#ifdef __DRI2_FLUSH
if (pdraw->psc->f)
(*pdraw->psc->f->flush)(pdraw->driDrawable);
#endif
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
@ -273,30 +299,25 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
psc->__driScreen = NULL;
}
static __DRIbuffer *
dri2GetBuffers(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate)
/**
* Process list of buffer received from the server
*
* Processes the list of buffers received in a reply from the server to either
* \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
*/
static void
process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers,
unsigned count)
{
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
DRI2Buffer *buffers;
int i;
buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
width, height, attachments, count, out_count);
if (buffers == NULL)
return NULL;
pdraw->width = *width;
pdraw->height = *height;
pdraw->bufferCount = *out_count;
pdraw->bufferCount = count;
pdraw->have_fake_front = 0;
pdraw->have_back = 0;
/* This assumes the DRI2 buffer attachment tokens matches the
* __DRIbuffer tokens. */
for (i = 0; i < *out_count; i++) {
for (i = 0; i < count; i++) {
pdraw->buffers[i].attachment = buffers[i].attachment;
pdraw->buffers[i].name = buffers[i].name;
pdraw->buffers[i].pitch = buffers[i].pitch;
@ -308,6 +329,51 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
pdraw->have_back = 1;
}
}
static __DRIbuffer *
dri2GetBuffers(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
DRI2Buffer *buffers;
buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
width, height, attachments, count, out_count);
if (buffers == NULL)
return NULL;
pdraw->width = *width;
pdraw->height = *height;
process_buffers(pdraw, buffers, *out_count);
Xfree(buffers);
return pdraw->buffers;
}
static __DRIbuffer *
dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
DRI2Buffer *buffers;
buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
pdraw->base.xDrawable,
width, height, attachments,
count, out_count);
if (buffers == NULL)
return NULL;
pdraw->width = *width;
pdraw->height = *height;
process_buffers(pdraw, buffers, *out_count);
Xfree(buffers);
return pdraw->buffers;
@ -316,7 +382,15 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
{ __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
dri2GetBuffers,
dri2FlushFrontBuffer
dri2FlushFrontBuffer,
dri2GetBuffersWithFormat,
};
static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
{ __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
dri2GetBuffers,
dri2FlushFrontBuffer,
NULL,
};
static const __DRIextension *loader_extensions[] = {
@ -325,11 +399,19 @@ static const __DRIextension *loader_extensions[] = {
NULL
};
static const __DRIextension *loader_extensions_old[] = {
&dri2LoaderExtension_old.base,
&systemTimeExtension.base,
NULL
};
static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv)
{
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
priv->dri2Display;
__GLXDRIscreen *psp;
char *driverName, *deviceName;
drm_magic_t magic;
@ -347,8 +429,10 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
return NULL;
psc->driver = driOpenDriver(driverName);
if (psc->driver == NULL)
if (psc->driver == NULL) {
ErrorMessageF("driver pointer missing\n");
goto handle_error;
}
extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
@ -374,15 +458,26 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
return NULL;
}
if (drmGetMagic(psc->fd, &magic))
if (drmGetMagic(psc->fd, &magic)) {
ErrorMessageF("failed to get magic\n");
return NULL;
}
if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic))
if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
ErrorMessageF("failed to authenticate magic %d\n", magic);
return NULL;
}
/* If the server does not support the protocol for
* DRI2GetBuffersWithFormat, don't supply that interface to the driver.
*/
psc->__driScreen =
psc->dri2->createNewScreen(screen, psc->fd,
loader_extensions, &driver_configs, psc);
psc->dri2->createNewScreen(screen, psc->fd,
((pdp->driMinor < 1)
? loader_extensions_old
: loader_extensions),
&driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
return NULL;

View File

@ -345,7 +345,9 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
#endif
#ifdef __DRI_SWAP_CONTROL
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
/* No DRI2 support for swap_control at the moment, since SwapBuffers
* is done by the X server */
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
psc->swapControl = (__DRIswapControlExtension *) extensions[i];
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
@ -392,6 +394,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
}
#endif
#ifdef __DRI2_FLUSH
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
psc->f = (__DRI2flushExtension *) extensions[i];
/* internal driver extension, no GL extension exposed */
}
#endif
/* Ignore unknown extensions */
}
}

View File

@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "glxclient.h"
#include "glcontextmodes.h"
#include "xf86dri.h"
#include "dri2.h"
#include "sarea.h"
#include <dlfcn.h>
#include <sys/types.h>
@ -75,32 +76,45 @@ struct __GLXDRIcontextPrivateRec {
*/
static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
{
int directCapable;
Bool b;
int driverMajor, driverMinor, driverPatch;
int directCapable;
Bool b;
int event, error;
int driverMajor, driverMinor, driverPatch;
*driverName = NULL;
*driverName = NULL;
if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
return False;
}
if (!directCapable) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
return False;
}
if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */
if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
return False;
}
if (!directCapable) {
ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
return False;
}
b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
&driverPatch, driverName);
if (!b) {
ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
return False;
}
b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
&driverPatch, driverName);
if (!b) {
ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
return False;
}
InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
driverMajor, driverMinor, driverPatch, *driverName, scrNum);
InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
driverMajor, driverMinor, driverPatch, *driverName, scrNum);
return True;
return True;
} else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */
char *dev;
Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
if (ret)
Xfree(dev);
return ret;
}
return False;
}
/*
@ -291,6 +305,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
drm_handle_t hFB;
int junk;
const __DRIconfig **driver_configs;
__GLcontextModes *visual;
/* DRI protocol version. */
dri_version.major = driDpy->driMajor;
@ -403,6 +418,28 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
/* Visuals with depth != screen depth are subject to automatic compositing
* in the X server, so DRI1 can't render to them properly. Mark them as
* non-conformant to prevent apps from picking them up accidentally.
*/
for (visual = psc->visuals; visual; visual = visual->next) {
XVisualInfo template;
XVisualInfo *visuals;
int num_visuals;
long mask;
template.visualid = visual->visualID;
mask = VisualIDMask;
visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
if (visuals) {
if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
XFree(visuals);
}
}
return psp;
handle_error:

View File

@ -401,10 +401,14 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
free(driver_configs);
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
psp->swapBuffers = driSwapBuffers;
psp->waitX = NULL;
psp->waitGL = NULL;
return psp;

View File

@ -519,6 +519,10 @@ struct __GLXscreenConfigsRec {
const __DRItexBufferExtension *texBuffer;
#endif
#ifdef __DRI2_FLUSH
const __DRI2flushExtension *f;
#endif
#endif
/**

View File

@ -332,8 +332,19 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
{
if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
struct intel_context *const intel = intel_context(ctx);
const GLboolean was_front_buffer_rendering =
intel->is_front_buffer_rendering;
intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT)
|| (mode == GL_FRONT);
/* If we weren't front-buffer rendering before but we are now, make sure
* that the front-buffer has actually been allocated.
*/
if (!was_front_buffer_rendering && intel->is_front_buffer_rendering) {
intel_update_renderbuffers(intel->driContext,
intel->driContext->driDrawablePriv);
}
}
intel_draw_buffer(ctx, ctx->DrawBuffer);
@ -343,6 +354,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
static void
intelReadBuffer(GLcontext * ctx, GLenum mode)
{
if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
struct intel_context *const intel = intel_context(ctx);
const GLboolean was_front_buffer_reading =
intel->is_front_buffer_reading;
intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
|| (mode == GL_FRONT);
/* If we weren't front-buffer reading before but we are now, make sure
* that the front-buffer has actually been allocated.
*/
if (!was_front_buffer_reading && intel->is_front_buffer_reading) {
intel_update_renderbuffers(intel->driContext,
intel->driContext->driDrawablePriv);
}
}
if (ctx->ReadBuffer == ctx->DrawBuffer) {
/* This will update FBO completeness status.
* A framebuffer will be incomplete if the GL_READ_BUFFER setting

View File

@ -25,12 +25,12 @@
*
**************************************************************************/
#include "main/glheader.h"
#include "main/context.h"
#include "main/matrix.h"
#include "main/simple_list.h"
#include "main/extensions.h"
#include "main/arrayobj.h"
#include "main/framebuffer.h"
#include "main/imports.h"
#include "main/points.h"
@ -66,6 +66,7 @@
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
#ifndef INTEL_DEBUG
int INTEL_DEBUG = (0);
#endif
@ -100,6 +101,9 @@ int INTEL_DEBUG = (0);
#define DRIVER_DATE "20090418 2009Q1"
#define DRIVER_DATE_GEM "GEM " DRIVER_DATE
static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush);
static const GLubyte *
intelGetString(GLcontext * ctx, GLenum name)
{
@ -203,6 +207,24 @@ intelGetString(GLcontext * ctx, GLenum name)
}
}
static unsigned
intel_bits_per_pixel(const struct intel_renderbuffer *rb)
{
switch (rb->Base._ActualFormat) {
case GL_RGB5:
case GL_DEPTH_COMPONENT16:
return 16;
case GL_RGB8:
case GL_RGBA8:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH24_STENCIL8_EXT:
case GL_STENCIL_INDEX8_EXT:
return 32;
default:
return 0;
}
}
void
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
{
@ -210,7 +232,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
struct intel_renderbuffer *rb;
struct intel_region *region, *depth_region;
struct intel_context *intel = context->driverPrivate;
__DRIbuffer *buffers;
__DRIbuffer *buffers = NULL;
__DRIscreen *screen;
int i, count;
unsigned int attachments[10];
@ -222,22 +244,65 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *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;
if (screen->dri2.loader
&& (screen->dri2.loader->base.version > 2)
&& (screen->dri2.loader->getBuffersWithFormat != NULL)) {
struct intel_renderbuffer *depth_rb;
struct intel_renderbuffer *stencil_rb;
buffers = (*screen->dri2.loader->getBuffers)(drawable,
&drawable->w,
&drawable->h,
attachments, i,
&count,
drawable->loaderPrivate);
i = 0;
if ((intel->is_front_buffer_rendering ||
intel->is_front_buffer_reading ||
!intel_fb->color_rb[1])
&& intel_fb->color_rb[0]) {
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
}
if (intel_fb->color_rb[1]) {
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]);
}
depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
if ((depth_rb != NULL) && (stencil_rb != NULL)) {
attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
attachments[i++] = intel_bits_per_pixel(depth_rb);
} else if (depth_rb != NULL) {
attachments[i++] = __DRI_BUFFER_DEPTH;
attachments[i++] = intel_bits_per_pixel(depth_rb);
} else if (stencil_rb != NULL) {
attachments[i++] = __DRI_BUFFER_STENCIL;
attachments[i++] = intel_bits_per_pixel(stencil_rb);
}
buffers =
(*screen->dri2.loader->getBuffersWithFormat)(drawable,
&drawable->w,
&drawable->h,
attachments, i / 2,
&count,
drawable->loaderPrivate);
} else if (screen->dri2.loader) {
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);
}
if (buffers == NULL)
return;
@ -280,6 +345,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
region_name = "dri2 depth buffer";
break;
case __DRI_BUFFER_DEPTH_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
region_name = "dri2 depth / stencil buffer";
break;
case __DRI_BUFFER_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
region_name = "dri2 stencil buffer";
@ -326,6 +396,23 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
intel_renderbuffer_set_region(rb, region);
intel_region_release(&region);
if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
if (rb != NULL) {
struct intel_region *stencil_region = NULL;
if (rb->region) {
dri_bo_flink(rb->region->buffer, &name);
if (name == buffers[i].name)
continue;
}
intel_region_reference(&stencil_region, region);
intel_renderbuffer_set_region(rb, stencil_region);
intel_region_release(&stencil_region);
}
}
}
driUpdateFramebufferSize(&intel->ctx, drawable);
@ -534,8 +621,8 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
__DRIscreen *const screen = intel->intelScreen->driScrnPriv;
if (screen->dri2.loader
&& (screen->dri2.loader->base.version >= 2)
if (screen->dri2.loader &&
(screen->dri2.loader->base.version >= 2)
&& (screen->dri2.loader->flushFrontBuffer != NULL)) {
(*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
intel->driDrawable->loaderPrivate);
@ -578,7 +665,7 @@ intelFinish(GLcontext * ctx)
irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
if (irb->region)
if (irb && irb->region)
dri_bo_wait_rendering(irb->region->buffer);
}
if (fb->_DepthBuffer) {
@ -704,6 +791,13 @@ intelInitContext(struct intel_context *intel,
_mesa_init_point(ctx);
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
if (IS_965(intelScreen->deviceID)) {
if (MAX_WIDTH > 8192)
ctx->Const.MaxRenderbufferSize = 8192;
} else {
if (MAX_WIDTH > 2048)
ctx->Const.MaxRenderbufferSize = 2048;
}
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext(ctx);
@ -821,13 +915,50 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb_bo = NULL;
if (release_texture_heaps) {
/* This share group is about to go away, free our private
* texture object data.
/* Nothing is currently done here to free texture heaps;
* but we're not using the texture heap utilities, so I
* rather think we shouldn't. I've taken a look, and can't
* find any private texture data hanging around anywhere, but
* I'm not yet certain there isn't any at all...
*/
if (INTEL_DEBUG & DEBUG_TEXTURE)
/* if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "do something to free texture heaps\n");
*/
}
/* XXX In intelMakeCurrent() below, the context's static regions are
* referenced inside the frame buffer; it's listed as a hack,
* with a comment of "XXX FBO temporary fix-ups!", but
* as long as it's there, we should release the regions here.
* The do/while loop around the block is used to allow the
* "continue" statements inside the block to exit the block,
* to avoid many layers of "if" constructs.
*/
do {
__DRIdrawablePrivate * driDrawPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb;
struct intel_renderbuffer *irbDepth, *irbStencil;
if (!driDrawPriv) {
/* We're already detached from the drawable; exit this block. */
continue;
}
intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate;
if (!intel_fb) {
/* The frame buffer is already gone; exit this block. */
continue;
}
irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
/* Usually, the stencil buffer is the same as the depth buffer;
* but they're handled separately in MakeCurrent, so we'll
* handle them separately here.
*/
if (irbStencil && irbStencil->region == intel->depth_region) {
intel_renderbuffer_set_region(irbStencil, NULL);
}
} while (0);
intel_region_release(&intel->front_region);
intel_region_release(&intel->back_region);
intel_region_release(&intel->depth_region);

View File

@ -282,6 +282,14 @@ struct intel_context
* easily.
*/
GLboolean is_front_buffer_rendering;
/**
* Track whether front-buffer is the current read target.
*
* This is closely associated with is_front_buffer_rendering, but may
* be set separately. The DRI2 fake front buffer must be referenced
* either way.
*/
GLboolean is_front_buffer_reading;
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */

View File

@ -688,12 +688,15 @@ intel_set_span_functions(struct intel_context *intel,
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
uint32_t tiling;
#ifndef __OpenBSD__ /* openbsd uses fenced gtt writes for tiles p{read,write} */
/* If in GEM mode, we need to do the tile address swizzling ourselves,
* instead of the fence registers handling it.
*/
if (intel->ttm)
tiling = irb->region->tiling;
else
#endif
tiling = I915_TILING_NONE;
if (rb->_ActualFormat == GL_RGB5) {

View File

@ -1,2 +1,2 @@
major=9
minor=0
minor=1