From c643d24cdeaade8d7839691a3113c4d2d17be61e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 29 May 2009 18:07:48 -0400 Subject: [PATCH 01/14] vfb: Fix depth setup. Initialize the depth corresponding to the root window before the pixmap-only depths. Otherwise you end up with the root window depth in the depth list twice, which is mildly confusing for clients and catastrophically confusing for PanoramiXConsolidate(). (cherry picked from commit 45530d16097459a756696e255ab4e72d6e51fbc4) --- hw/vfb/InitOutput.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c index 6bf6a33a1..fd383e1c2 100644 --- a/hw/vfb/InitOutput.c +++ b/hw/vfb/InitOutput.c @@ -862,8 +862,6 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) pbits = vfbAllocateFramebufferMemory(pvfb); if (!pbits) return FALSE; - miSetPixmapDepths (); - switch (pvfb->depth) { case 8: miSetVisualTypesAndMasks (8, @@ -875,20 +873,6 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) (1 << DirectColor)), 8, PseudoColor, 0, 0, 0); break; -#if 0 - /* 12bit PseudoColor with 12bit color resolution - * (to simulate SGI hardware and the 12bit PseudoColor emulation layer) */ - case 12: - miSetVisualTypesAndMasks (12, - ((1 << StaticGray) | - (1 << GrayScale) | - (1 << StaticColor) | - (1 << PseudoColor) | - (1 << TrueColor) | - (1 << DirectColor)), - 12, PseudoColor, 0, 0, 0); - break; -#endif case 15: miSetVisualTypesAndMasks (15, ((1 << TrueColor) | @@ -907,18 +891,10 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) (1 << DirectColor)), 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff); break; -#if 0 - /* 30bit TrueColor (to simulate Sun's XVR-1000/-4000 high quality - * framebuffer series) */ - case 30: - miSetVisualTypesAndMasks (30, - ((1 << TrueColor) | - (1 << DirectColor)), - 10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff); - break; -#endif } - + + miSetPixmapDepths (); + ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height, dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel); #ifdef RENDER From ebca49e0fedcc1c536f1dee7c58cae9903e74fa2 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 21 May 2009 10:20:48 -0400 Subject: [PATCH 02/14] EDID: Be more cautious about finding vendor blocks. Many old monitors zero-fill the detailed descriptors, so check for that to avoid a useless warning like: (WW) RADEON(0): Unknown vendor-specific block 0 (cherry picked from commit a2c5ee36b21c2ee5c0468f1b251e74c1412dbecb) --- hw/xfree86/ddc/interpret_edid.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index c4d896393..191e900d8 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -284,6 +284,8 @@ get_std_timing_section(Uchar *c, struct std_timings *r, } } +static const unsigned char empty_block[18]; + static void get_dt_md_section(Uchar *c, struct edid_version *ver, struct detailed_monitor_section *det_mon) @@ -335,10 +337,10 @@ get_dt_md_section(Uchar *c, struct edid_version *ver, det_mon[i].type = DS_UNKOWN; break; } - if (c[3] <= 0x0F) { + if (c[3] <= 0x0F && memcmp(c, empty_block, sizeof(empty_block))) { det_mon[i].type = DS_VENDOR + c[3]; } - } else { + } else { det_mon[i].type = DT; get_detailed_timing_section(c,&det_mon[i].section.d_timings); } From db61eff891675aeaf2466c3529424de4621005dc Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 22 May 2009 12:01:55 -0400 Subject: [PATCH 03/14] EDID: Add modes from Established Timings III descriptor to mode pool EDID 1.4, section 3.10.3.9 (cherry picked from commit 99e22b86c5f1a3653f3caaf01368a777d2b208d0) --- hw/xfree86/ddc/edid.h | 2 +- hw/xfree86/ddc/interpret_edid.c | 1 + hw/xfree86/modes/xf86EdidModes.c | 87 ++++++++++++++++++++++++++++++-- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index 45caf6ea9..3ca402f57 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -527,7 +527,7 @@ struct detailed_monitor_section { struct whitePoints wp[2]; /* 32 */ /* color management data */ struct cvt_timings cvt[4]; /* 64 */ - /* established timings III */ + Uchar est_iii[6]; /* 6 */ } section; /* max: 80 */ }; diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 191e900d8..310606c7c 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -329,6 +329,7 @@ get_dt_md_section(Uchar *c, struct edid_version *ver, break; case ADD_EST_TIMINGS: det_mon[i].type = DS_EST_III; + memcpy(det_mon[i].section.est_iii, c + 6, 6); break; case ADD_DUMMY: det_mon[i].type = DS_DUMMY; diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 54f2c6570..087f66376 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -628,6 +628,85 @@ DDCModesFromCVT(int scrnIndex, struct cvt_timings *t) } #endif +static const struct { + short w; + short h; + short r; + short rb; +} EstIIIModes[] = { + /* byte 6 */ + { 640, 350, 85, 0 }, + { 640, 400, 85, 0 }, + { 720, 400, 85, 0 }, + { 640, 480, 85, 0 }, + { 848, 480, 60, 0 }, + { 800, 600, 85, 0 }, + { 1024, 768, 85, 0 }, + { 1152, 864, 75, 0 }, + /* byte 7 */ + { 1280, 768, 60, 1 }, + { 1280, 768, 60, 0 }, + { 1280, 768, 75, 0 }, + { 1280, 768, 85, 0 }, + { 1280, 960, 60, 0 }, + { 1280, 960, 85, 0 }, + { 1280, 1024, 60, 0 }, + { 1280, 1024, 85, 0 }, + /* byte 8 */ + { 1360, 768, 60, 0 }, + { 1440, 900, 60, 1 }, + { 1440, 900, 60, 0 }, + { 1440, 900, 75, 0 }, + { 1440, 900, 85, 0 }, + { 1400, 1050, 60, 1 }, + { 1400, 1050, 60, 0 }, + { 1400, 1050, 75, 0 }, + /* byte 9 */ + { 1400, 1050, 85, 0 }, + { 1680, 1050, 60, 1 }, + { 1680, 1050, 60, 0 }, + { 1680, 1050, 75, 0 }, + { 1680, 1050, 85, 0 }, + { 1600, 1200, 60, 0 }, + { 1600, 1200, 65, 0 }, + { 1600, 1200, 70, 0 }, + /* byte 10 */ + { 1600, 1200, 75, 0 }, + { 1600, 1200, 85, 0 }, + { 1792, 1344, 60, 0 }, + { 1792, 1344, 85, 0 }, + { 1856, 1392, 60, 0 }, + { 1856, 1392, 75, 0 }, + { 1920, 1200, 60, 1 }, + { 1920, 1200, 60, 0 }, + /* byte 11 */ + { 1920, 1200, 75, 0 }, + { 1920, 1200, 85, 0 }, + { 1920, 1440, 60, 0 }, + { 1920, 1440, 75, 0 }, +}; + +static DisplayModePtr +DDCModesFromEstIII(unsigned char *est) +{ + DisplayModePtr modes = NULL; + int i, j, m; + + for (i = 0; i < 6; i++) { + for (j = 7; j > 0; j--) { + if (est[i] & (1 << j)) { + m = (i * 8) + (7 - j); + modes = xf86ModesAdd(modes, + FindDMTMode(EstIIIModes[m].w, + EstIIIModes[m].h, + EstIIIModes[m].r, + EstIIIModes[m].rb)); + } + } + } + + return modes; +} /* * This is only valid when the sink claims to be continuous-frequency @@ -798,6 +877,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) for (i = 0; i < DET_TIMINGS; i++) { struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; + Mode = NULL; switch (det_mon->type) { case DT: Mode = DDCModeFromDetailedTiming(scrnIndex, @@ -805,22 +885,23 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) preferred, quirks); preferred = FALSE; - Modes = xf86ModesAdd(Modes, Mode); break; case DS_STD_TIMINGS: Mode = DDCModesFromStandardTiming(det_mon->section.std_t, quirks, timing_level, rb); - Modes = xf86ModesAdd(Modes, Mode); break; #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) case DS_CVT: Mode = DDCModesFromCVT(scrnIndex, det_mon->section.cvt); - Modes = xf86ModesAdd(Modes, Mode); break; #endif + case DS_EST_III: + Mode = DDCModesFromEstIII(det_mon->section.est_iii); + break; default: break; } + Modes = xf86ModesAdd(Modes, Mode); } /* Add established timings */ From 32d250a881341ece8a1f1d78359adc1b265b5174 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 8 Apr 2009 15:44:34 -0700 Subject: [PATCH 04/14] DRI2: Add fake front-buffer to request list for windows If a front-buffer is requested for a window, add the fake front-buffer to the list of requested buffers. Signed-off-by: Ian Romanick (cherry picked from commit aa2928325fe51d94a636dde9c090e8f54a311a12) --- hw/xfree86/dri2/dri2.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 0f2e24b3f..351d02b7b 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -139,6 +139,42 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); DRI2BufferPtr buffers; + unsigned int temp_buf[32]; + unsigned int *temp = temp_buf; + + + /* If the drawable is a window and the front-buffer is requested, silently + * add the fake front-buffer to the list of requested attachments. The + * counting logic in the loop accounts for the case where the client + * requests both the fake and real front-buffer. + */ + if (pDraw->type == DRAWABLE_WINDOW) { + int need_fake_front = 0; + int i; + + if ((count + 1) > 32) { + temp = xalloc((count + 1) * sizeof(temp[0])); + } + + for (i = 0; i < count; i++) { + if (attachments[i] == DRI2BufferFrontLeft) { + need_fake_front++; + } + + if (attachments[i] == DRI2BufferFakeFrontLeft) { + need_fake_front--; + } + + temp[i] = attachments[i]; + } + + if (need_fake_front > 0) { + temp[i] = DRI2BufferFakeFrontLeft; + count++; + attachments = temp; + } + } + if (pPriv->buffers == NULL || pDraw->width != pPriv->width || pDraw->height != pPriv->height) @@ -151,6 +187,10 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, pPriv->height = pDraw->height; } + if (temp != temp_buf) { + xfree(temp); + } + *width = pPriv->width; *height = pPriv->height; *out_count = pPriv->bufferCount; From 73b786f7e7f46d40bf3b039538540c2e25f45947 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 9 Apr 2009 14:31:01 -0700 Subject: [PATCH 05/14] DRI2: Do not send the real front buffer of a window to the client Signed-off-by: Ian Romanick (cherry picked from commit f1a995d1496d73741731e32f475097c44a8da972) --- glx/glxdri2.c | 10 ++++++++++ hw/xfree86/dri2/dri2ext.c | 24 ++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 4544a2c50..4596cc554 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -361,6 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, __GLXDRIdrawable *private = loaderPrivate; DRI2BufferPtr buffers; int i; + int skip = 0; buffers = DRI2GetBuffers(private->base.pDraw, width, height, attachments, count, out_count); @@ -375,6 +376,14 @@ dri2GetBuffers(__DRIdrawable *driDrawable, /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ for (i = 0; i < *out_count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if ((private->base.pDraw->type == DRAWABLE_WINDOW) + && (buffers[i].attachment == DRI2BufferFrontLeft)) { + skip++; + continue; + } + private->buffers[i].attachment = buffers[i].attachment; private->buffers[i].name = buffers[i].name; private->buffers[i].pitch = buffers[i].pitch; @@ -382,6 +391,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, private->buffers[i].flags = buffers[i].flags; } + *out_count -= skip; return private->buffers; } diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 1409777e4..ccc1bbb7f 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -203,6 +203,7 @@ ProcDRI2GetBuffers(ClientPtr client) int i, status, width, height, count; unsigned int *attachments; xDRI2Buffer buffer; + int skip; REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) @@ -212,15 +213,34 @@ ProcDRI2GetBuffers(ClientPtr client) buffers = DRI2GetBuffers(pDrawable, &width, &height, attachments, stuff->count, &count); + skip = 0; + if (pDrawable->type == DRAWABLE_WINDOW) { + for (i = 0; i < count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if (buffers[i].attachment == DRI2BufferFrontLeft) { + skip++; + continue; + } + } + } + rep.type = X_Reply; - rep.length = count * sizeof(xDRI2Buffer) / 4; + rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4; rep.sequenceNumber = client->sequence; rep.width = width; rep.height = height; - rep.count = count; + rep.count = count - skip; WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); for (i = 0; i < count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if ((pDrawable->type == DRAWABLE_WINDOW) + && (buffers[i].attachment == DRI2BufferFrontLeft)) { + continue; + } + buffer.attachment = buffers[i].attachment; buffer.name = buffers[i].name; buffer.pitch = buffers[i].pitch; From d7277296ed7aea7bd41b3489d4ceef750d400206 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 9 Apr 2009 14:38:24 -0700 Subject: [PATCH 06/14] DRI2: Synchronize the contents of the real and fake front-buffers Signed-off-by: Ian Romanick (cherry picked from commit 567cf67959b30432ae30f4851ec17b3a375ab838) --- hw/xfree86/dri2/dri2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 351d02b7b..0b52a0f8c 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -141,6 +141,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, DRI2BufferPtr buffers; unsigned int temp_buf[32]; unsigned int *temp = temp_buf; + int have_fake_front = 0; /* If the drawable is a window and the front-buffer is requested, silently @@ -163,6 +164,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, if (attachments[i] == DRI2BufferFakeFrontLeft) { need_fake_front--; + have_fake_front = 1; } temp[i] = attachments[i]; @@ -171,6 +173,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, if (need_fake_front > 0) { temp[i] = DRI2BufferFakeFrontLeft; count++; + have_fake_front = 1; attachments = temp; } } @@ -195,6 +198,25 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, *height = pPriv->height; *out_count = pPriv->bufferCount; + + /* If the client is getting a fake front-buffer, pre-fill it with the + * contents of the real front-buffer. This ensures correct operation of + * applications that call glXWaitX before calling glDrawBuffer. + */ + if (have_fake_front) { + BoxRec box; + RegionRec region; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pPriv->width; + box.y2 = pPriv->height; + REGION_INIT(pDraw->pScreen, ®ion, &box, 0); + + DRI2CopyRegion(pDraw, ®ion, DRI2BufferFakeFrontLeft, + DRI2BufferFrontLeft); + } + return pPriv->buffers; } From aa13faef2b1464f808e04de9826c6b8b8b91ae89 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 15 Apr 2009 11:13:48 -0700 Subject: [PATCH 07/14] DRI2: Don't leave empty entries in private->buffers This should fix bug #21130. Signed-off-by: Ian Romanick (cherry picked from commit de1e43181bd670877b994db221ad8a04b5d63324) --- glx/glxdri2.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 4596cc554..0daf9aa75 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -361,7 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, __GLXDRIdrawable *private = loaderPrivate; DRI2BufferPtr buffers; int i; - int skip = 0; + int j; buffers = DRI2GetBuffers(private->base.pDraw, width, height, attachments, count, out_count); @@ -375,23 +375,24 @@ dri2GetBuffers(__DRIdrawable *driDrawable, /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ + j = 0; for (i = 0; i < *out_count; i++) { /* Do not send the real front buffer of a window to the client. */ if ((private->base.pDraw->type == DRAWABLE_WINDOW) && (buffers[i].attachment == DRI2BufferFrontLeft)) { - skip++; continue; } - private->buffers[i].attachment = buffers[i].attachment; - private->buffers[i].name = buffers[i].name; - private->buffers[i].pitch = buffers[i].pitch; - private->buffers[i].cpp = buffers[i].cpp; - private->buffers[i].flags = buffers[i].flags; + private->buffers[j].attachment = buffers[i].attachment; + private->buffers[j].name = buffers[i].name; + private->buffers[j].pitch = buffers[i].pitch; + private->buffers[j].cpp = buffers[i].cpp; + private->buffers[j].flags = buffers[i].flags; + j++; } - *out_count -= skip; + *out_count = j; return private->buffers; } From 4cb4c210c365fd40ad314e0707eb38811f240a12 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 16 Apr 2009 12:10:34 -0700 Subject: [PATCH 08/14] DRI2: Add missing front-buffer flush callback. Signed-off-by: Ian Romanick (cherry picked from commit d1e916d29be8b470cbc8cadcf6e83991fdbc5a9f) --- glx/glxdri2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 0daf9aa75..84d2c03d1 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -396,9 +396,17 @@ dri2GetBuffers(__DRIdrawable *driDrawable, return private->buffers; } +static void +dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate) +{ + (void) driDrawable; + __glXDRIdrawableWaitGL((__GLXdrawable *) loaderPrivate); +} + static const __DRIdri2LoaderExtension loaderExtension = { { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, dri2GetBuffers, + dri2FlushFrontBuffer, }; static const __DRIextension *loader_extensions[] = { From 98c3c21735197fbd2c8166c9bdabf055e14c9009 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 24 Apr 2009 12:09:21 -0700 Subject: [PATCH 09/14] DRI2: Add interface for drivers to query DRI2 extension version Signed-off-by: Ian Romanick (cherry picked from commit 28ddfc88d8d547941c7f4713db527a3c2f9ec35a) --- hw/xfree86/dri2/dri2.c | 9 +++++++++ hw/xfree86/dri2/dri2.h | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 0b52a0f8c..80de18f86 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -380,3 +380,12 @@ static XF86ModuleVersionInfo DRI2VersRec = _X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL }; +void +DRI2Version(int *major, int *minor) +{ + if (major != NULL) + *major = DRI2VersRec.majorversion; + + if (minor != NULL) + *minor = DRI2VersRec.minorversion; +} diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 5e7fd65d5..e6c4b97d0 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -100,4 +100,22 @@ int DRI2CopyRegion(DrawablePtr pDraw, unsigned int dest, unsigned int src); +/** + * Determine the major and minor version of the DRI2 extension. + * + * Provides a mechanism to other modules (e.g., 2D drivers) to determine the + * version of the DRI2 extension. While it is possible to peek directly at + * the \c XF86ModuleData from a layered module, such a module will fail to + * load (due to an unresolved symbol) if the DRI2 extension is not loaded. + * + * \param major Location to store the major verion of the DRI2 extension + * \param minor Location to store the minor verion of the DRI2 extension + * + * \note + * This interface was added some time after the initial release of the DRI2 + * module. Layered modules that wish to use this interface must first test + * its existance by calling \c xf86LoaderCheckSymbol. + */ +extern _X_EXPORT void DRI2Version(int *major, int *minor); + #endif From 4fad615d689c61c6c3a000295a1fa755359737cb Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 24 Apr 2009 12:49:19 -0700 Subject: [PATCH 10/14] DRI2: Implement protocol for DRI2GetBuffersWithFormat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change implements the protocol for DRI2GetBuffersWithFormat, but the bulk of the differences are the changes to the extension / driver interface to make this function work. The old CreateBuffers and DeleteBuffers routines are replaced with CreateBuffer and DeleteBuffer (both singular). This allows drivers to allocate buffers for a drawable one at a time. As a result, 3D drivers can now allocate the (fake) front-buffer for a window only when it is needed. Since 3D drivers only ask for the front-buffer on demand, the real front-buffer is always created. This allows CopyRegion impelemenations of SwapBuffers to continue working. As with previous version of this code, if the client asks for the front-buffer for a window, we instead give it the fake front-buffer. Signed-off-by: Ian Romanick Reviewed-by: Kristian Høgsberg --- configure.ac | 2 +- glx/glxdri2.c | 59 +++++++++-- hw/xfree86/dri2/dri2.c | 199 +++++++++++++++++++++++++++----------- hw/xfree86/dri2/dri2.h | 28 +++++- hw/xfree86/dri2/dri2ext.c | 88 ++++++++++++----- 5 files changed, 286 insertions(+), 90 deletions(-) diff --git a/configure.ac b/configure.ac index af4ba4fef..1f0fddddf 100644 --- a/configure.ac +++ b/configure.ac @@ -859,7 +859,7 @@ if test "x$DRI" = xyes; then AC_SUBST(GL_CFLAGS) fi -PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.3], +PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 2.1], [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) case "$DRI2,$HAVE_DRI2PROTO" in yes,no) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 84d2c03d1..c6716703f 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -359,7 +359,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, int *out_count, void *loaderPrivate) { __GLXDRIdrawable *private = loaderPrivate; - DRI2BufferPtr buffers; + DRI2BufferPtr *buffers; int i; int j; @@ -380,15 +380,59 @@ dri2GetBuffers(__DRIdrawable *driDrawable, /* Do not send the real front buffer of a window to the client. */ if ((private->base.pDraw->type == DRAWABLE_WINDOW) - && (buffers[i].attachment == DRI2BufferFrontLeft)) { + && (buffers[i]->attachment == DRI2BufferFrontLeft)) { continue; } - private->buffers[j].attachment = buffers[i].attachment; - private->buffers[j].name = buffers[i].name; - private->buffers[j].pitch = buffers[i].pitch; - private->buffers[j].cpp = buffers[i].cpp; - private->buffers[j].flags = buffers[i].flags; + private->buffers[j].attachment = buffers[i]->attachment; + private->buffers[j].name = buffers[i]->name; + private->buffers[j].pitch = buffers[i]->pitch; + private->buffers[j].cpp = buffers[i]->cpp; + private->buffers[j].flags = buffers[i]->flags; + j++; + } + + *out_count = j; + return private->buffers; +} + +static __DRIbuffer * +dri2GetBuffersWithFormat(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + __GLXDRIdrawable *private = loaderPrivate; + DRI2BufferPtr *buffers; + int i; + int j = 0; + + buffers = DRI2GetBuffersWithFormat(private->base.pDraw, + width, height, attachments, count, + out_count); + if (*out_count > MAX_DRAWABLE_BUFFERS) { + *out_count = 0; + return NULL; + } + + private->width = *width; + private->height = *height; + + /* This assumes the DRI2 buffer attachment tokens matches the + * __DRIbuffer tokens. */ + for (i = 0; i < *out_count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if ((private->base.pDraw->type == DRAWABLE_WINDOW) + && (buffers[i]->attachment == DRI2BufferFrontLeft)) { + continue; + } + + private->buffers[j].attachment = buffers[i]->attachment; + private->buffers[j].name = buffers[i]->name; + private->buffers[j].pitch = buffers[i]->pitch; + private->buffers[j].cpp = buffers[i]->cpp; + private->buffers[j].flags = buffers[i]->flags; j++; } @@ -407,6 +451,7 @@ static const __DRIdri2LoaderExtension loaderExtension = { { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, dri2GetBuffers, dri2FlushFrontBuffer, + dri2GetBuffersWithFormat, }; static const __DRIextension *loader_extensions[] = { diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 80de18f86..9ded048eb 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -53,7 +53,7 @@ typedef struct _DRI2Drawable { unsigned int refCount; int width; int height; - DRI2BufferPtr buffers; + DRI2BufferPtr *buffers; int bufferCount; unsigned int pendingSequence; } DRI2DrawableRec, *DRI2DrawablePtr; @@ -63,8 +63,8 @@ typedef struct _DRI2Screen { const char *deviceName; int fd; unsigned int lastSequence; - DRI2CreateBuffersProcPtr CreateBuffers; - DRI2DestroyBuffersProcPtr DestroyBuffers; + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; DRI2CopyRegionProcPtr CopyRegion; HandleExposuresProcPtr HandleExposures; @@ -132,71 +132,130 @@ DRI2CreateDrawable(DrawablePtr pDraw) return Success; } -DRI2BufferPtr -DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, - unsigned int *attachments, int count, int *out_count) +static int +find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment) +{ + int i; + + if (buffer_list == NULL) { + return -1; + } + + for (i = 0; i < count; i++) { + if ((buffer_list[i] != NULL) + && (buffer_list[i]->attachment == attachment)) { + return i; + } + } + + return -1; +} + +static DRI2BufferPtr +allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds, + DRI2DrawablePtr pPriv, + unsigned int attachment, unsigned int format, + int dimensions_match) +{ + DRI2BufferPtr buffer; + int old_buf; + + old_buf = find_attachment(pPriv->buffers, pPriv->bufferCount, attachment); + + if ((old_buf < 0) + || !dimensions_match + || (pPriv->buffers[old_buf]->format != format)) { + buffer = (*ds->CreateBuffer)(pDraw, attachment, format); + } else { + buffer = pPriv->buffers[old_buf]; + pPriv->buffers[old_buf] = NULL; + } + + return buffer; +} + +static DRI2BufferPtr * +do_get_buffers(DrawablePtr pDraw, int *width, int *height, + unsigned int *attachments, int count, int *out_count, + int has_format) { DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); - DRI2BufferPtr buffers; - unsigned int temp_buf[32]; - unsigned int *temp = temp_buf; + DRI2BufferPtr *buffers; + int need_real_front = 0; + int need_fake_front = 0; int have_fake_front = 0; + int front_format = 0; + const int dimensions_match = (pDraw->width == pPriv->width) + && (pDraw->height == pPriv->height); + int i; - /* If the drawable is a window and the front-buffer is requested, silently - * add the fake front-buffer to the list of requested attachments. The - * counting logic in the loop accounts for the case where the client - * requests both the fake and real front-buffer. - */ - if (pDraw->type == DRAWABLE_WINDOW) { - int need_fake_front = 0; - int i; + buffers = xalloc((count + 1) * sizeof(buffers[0])); - if ((count + 1) > 32) { - temp = xalloc((count + 1) * sizeof(temp[0])); - } + for (i = 0; i < count; i++) { + const unsigned attachment = *(attachments++); + const unsigned format = (has_format) ? *(attachments++) : 0; - for (i = 0; i < count; i++) { - if (attachments[i] == DRI2BufferFrontLeft) { - need_fake_front++; + buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment, + format, dimensions_match); + + + /* If the drawable is a window and the front-buffer is requested, + * silently add the fake front-buffer to the list of requested + * attachments. The counting logic in the loop accounts for the case + * where the client requests both the fake and real front-buffer. + */ + if (pDraw->type == DRAWABLE_WINDOW) { + if (attachment == DRI2BufferBackLeft) { + need_real_front++; + front_format = format; } - if (attachments[i] == DRI2BufferFakeFrontLeft) { + if (attachment == DRI2BufferFrontLeft) { + need_real_front--; + need_fake_front++; + front_format = format; + } + + if (attachment == DRI2BufferFakeFrontLeft) { need_fake_front--; have_fake_front = 1; } - - temp[i] = attachments[i]; - } - - if (need_fake_front > 0) { - temp[i] = DRI2BufferFakeFrontLeft; - count++; - have_fake_front = 1; - attachments = temp; } } - - if (pPriv->buffers == NULL || - pDraw->width != pPriv->width || pDraw->height != pPriv->height) - { - buffers = (*ds->CreateBuffers)(pDraw, attachments, count); - (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); - pPriv->buffers = buffers; - pPriv->bufferCount = count; - pPriv->width = pDraw->width; - pPriv->height = pDraw->height; + if (need_real_front > 0) { + buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv, + DRI2BufferFrontLeft, + front_format, dimensions_match); } - if (temp != temp_buf) { - xfree(temp); + if (need_fake_front > 0) { + buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv, + DRI2BufferFakeFrontLeft, + front_format, dimensions_match); + have_fake_front = 1; } + *out_count = i; + + + if (pPriv->buffers != NULL) { + for (i = 0; i < pPriv->bufferCount; i++) { + if (pPriv->buffers[i] != NULL) { + (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]); + } + } + + xfree(pPriv->buffers); + } + + + pPriv->buffers = buffers; + pPriv->bufferCount = *out_count; *width = pPriv->width; *height = pPriv->height; - *out_count = pPriv->bufferCount; /* If the client is getting a fake front-buffer, pre-fill it with the @@ -220,6 +279,22 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, return pPriv->buffers; } +DRI2BufferPtr * +DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, + unsigned int *attachments, int count, int *out_count) +{ + return do_get_buffers(pDraw, width, height, attachments, count, + out_count, FALSE); +} + +DRI2BufferPtr * +DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height, + unsigned int *attachments, int count, int *out_count) +{ + return do_get_buffers(pDraw, width, height, attachments, count, + out_count, TRUE); +} + int DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, unsigned int dest, unsigned int src) @@ -237,10 +312,10 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, pSrcBuffer = NULL; for (i = 0; i < pPriv->bufferCount; i++) { - if (pPriv->buffers[i].attachment == dest) - pDestBuffer = &pPriv->buffers[i]; - if (pPriv->buffers[i].attachment == src) - pSrcBuffer = &pPriv->buffers[i]; + if (pPriv->buffers[i]->attachment == dest) + pDestBuffer = pPriv->buffers[i]; + if (pPriv->buffers[i]->attachment == src) + pSrcBuffer = pPriv->buffers[i]; } if (pSrcBuffer == NULL || pDestBuffer == NULL) return BadValue; @@ -266,7 +341,16 @@ DRI2DestroyDrawable(DrawablePtr pDraw) if (pPriv->refCount > 0) return; - (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); + if (pPriv->buffers != NULL) { + int i; + + for (i = 0; i < pPriv->bufferCount; i++) { + (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]); + } + + xfree(pPriv->buffers); + } + xfree(pPriv); if (pDraw->type == DRAWABLE_WINDOW) @@ -320,11 +404,18 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (!ds) return FALSE; + if ((info->version < 2) + || (info->CreateBuffer == NULL) + || (info->DestroyBuffer == NULL)) { + return FALSE; + } + + ds->fd = info->fd; ds->driverName = info->driverName; ds->deviceName = info->deviceName; - ds->CreateBuffers = info->CreateBuffers; - ds->DestroyBuffers = info->DestroyBuffers; + ds->CreateBuffer = info->CreateBuffer; + ds->DestroyBuffer = info->DestroyBuffer; ds->CopyRegion = info->CopyRegion; dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); @@ -371,7 +462,7 @@ static XF86ModuleVersionInfo DRI2VersRec = MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, - 1, 0, 0, + 1, 1, 0, ABI_CLASS_EXTENSION, ABI_EXTENSION_VERSION, MOD_CLASS_NONE, diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index e6c4b97d0..c9a0d3f0d 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -41,6 +41,7 @@ typedef struct { unsigned int pitch; unsigned int cpp; unsigned int flags; + unsigned int format; void *driverPrivate; } DRI2BufferRec, *DRI2BufferPtr; @@ -58,8 +59,19 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, unsigned int sequence); +typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, + unsigned int attachment, + unsigned int format); +typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffer); + +/** + * Version of the DRI2InfoRec structure defined in this header + */ +#define DRI2INFOREC_VERSION 2 + typedef struct { - unsigned int version; /* Version of this struct */ + unsigned int version; /**< Version of this struct */ int fd; const char *driverName; const char *deviceName; @@ -69,6 +81,14 @@ typedef struct { DRI2CopyRegionProcPtr CopyRegion; DRI2WaitProcPtr Wait; + /** + * \name Fields added in version 2 of the structure. + */ + /*@{*/ + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + /*@}*/ + } DRI2InfoRec, *DRI2InfoPtr; Bool DRI2ScreenInit(ScreenPtr pScreen, @@ -88,7 +108,7 @@ int DRI2CreateDrawable(DrawablePtr pDraw); void DRI2DestroyDrawable(DrawablePtr pDraw); -DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw, +DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, unsigned int *attachments, @@ -118,4 +138,8 @@ int DRI2CopyRegion(DrawablePtr pDraw, */ extern _X_EXPORT void DRI2Version(int *major, int *minor); +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, + int *width, int *height, unsigned int *attachments, int count, + int *out_count); + #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index ccc1bbb7f..97b96fa98 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -81,7 +81,7 @@ ProcDRI2QueryVersion(ClientPtr client) rep.length = 0; rep.sequenceNumber = client->sequence; rep.majorVersion = 1; - rep.minorVersion = 0; + rep.minorVersion = 1; if (client->swapped) { swaps(&rep.sequenceNumber, n); @@ -193,32 +193,20 @@ ProcDRI2DestroyDrawable(ClientPtr client) return client->noClientException; } -static int -ProcDRI2GetBuffers(ClientPtr client) + +static void +send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, + DRI2BufferPtr *buffers, int count, int width, int height) { - REQUEST(xDRI2GetBuffersReq); xDRI2GetBuffersReply rep; - DrawablePtr pDrawable; - DRI2BufferPtr buffers; - int i, status, width, height, count; - unsigned int *attachments; - xDRI2Buffer buffer; - int skip; + int skip = 0; + int i; - REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); - if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) - return status; - - attachments = (unsigned int *) &stuff[1]; - buffers = DRI2GetBuffers(pDrawable, &width, &height, - attachments, stuff->count, &count); - - skip = 0; if (pDrawable->type == DRAWABLE_WINDOW) { for (i = 0; i < count; i++) { /* Do not send the real front buffer of a window to the client. */ - if (buffers[i].attachment == DRI2BufferFrontLeft) { + if (buffers[i]->attachment == DRI2BufferFrontLeft) { skip++; continue; } @@ -234,20 +222,66 @@ ProcDRI2GetBuffers(ClientPtr client) WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); for (i = 0; i < count; i++) { + xDRI2Buffer buffer; + /* Do not send the real front buffer of a window to the client. */ if ((pDrawable->type == DRAWABLE_WINDOW) - && (buffers[i].attachment == DRI2BufferFrontLeft)) { + && (buffers[i]->attachment == DRI2BufferFrontLeft)) { continue; } - buffer.attachment = buffers[i].attachment; - buffer.name = buffers[i].name; - buffer.pitch = buffers[i].pitch; - buffer.cpp = buffers[i].cpp; - buffer.flags = buffers[i].flags; + buffer.attachment = buffers[i]->attachment; + buffer.name = buffers[i]->name; + buffer.pitch = buffers[i]->pitch; + buffer.cpp = buffers[i]->cpp; + buffer.flags = buffers[i]->flags; WriteToClient(client, sizeof(xDRI2Buffer), &buffer); } +} + + +static int +ProcDRI2GetBuffers(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); + + + send_buffers_reply(client, pDrawable, buffers, count, width, height); + + return client->noClientException; +} + +static int +ProcDRI2GetBuffersWithFormat(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4)); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, + attachments, stuff->count, &count); + + send_buffers_reply(client, pDrawable, buffers, count, width, height); return client->noClientException; } @@ -314,6 +348,8 @@ ProcDRI2Dispatch (ClientPtr client) return ProcDRI2GetBuffers(client); case X_DRI2CopyRegion: return ProcDRI2CopyRegion(client); + case X_DRI2GetBuffersWithFormat: + return ProcDRI2GetBuffersWithFormat(client); default: return BadRequest; } From ec9f1ae32474bc0507a3c66e63bdf2835d467a34 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 27 Apr 2009 15:11:10 -0700 Subject: [PATCH 11/14] DRI2: Force allocation of real-front buffer for non-windows as well For redirected rendering we end up with pixmaps (which the app thinks are windows) that are double buffered. Signed-off-by: Ian Romanick Tested-by: Pierre Willenbrock (cherry picked from commit 0d9d3f3e361f769822caedccf4c2a58cc9930ecc) --- hw/xfree86/dri2/dri2.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 9ded048eb..1d49d7c65 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -206,18 +206,21 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, * attachments. The counting logic in the loop accounts for the case * where the client requests both the fake and real front-buffer. */ - if (pDraw->type == DRAWABLE_WINDOW) { - if (attachment == DRI2BufferBackLeft) { - need_real_front++; - front_format = format; - } + if (attachment == DRI2BufferBackLeft) { + need_real_front++; + front_format = format; + } - if (attachment == DRI2BufferFrontLeft) { - need_real_front--; + if (attachment == DRI2BufferFrontLeft) { + need_real_front--; + front_format = format; + + if (pDraw->type == DRAWABLE_WINDOW) { need_fake_front++; - front_format = format; } + } + if (pDraw->type == DRAWABLE_WINDOW) { if (attachment == DRI2BufferFakeFrontLeft) { need_fake_front--; have_fake_front = 1; From 540d5b87a4e24d85ec46620dfedd7bd7979180ea Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 11 May 2009 22:52:46 +0200 Subject: [PATCH 12/14] DRI2: update DRI2 private drawable width & height according to X drawable (cherry picked from commit f250eea2e90fc50bec5214c2f41132b95edc2c46) --- hw/xfree86/dri2/dri2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 1d49d7c65..385c5e8d4 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -257,6 +257,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height, pPriv->buffers = buffers; pPriv->bufferCount = *out_count; + pPriv->width = pDraw->width; + pPriv->height = pDraw->height; *width = pPriv->width; *height = pPriv->height; From 6be19e8f43086fb4b7fb30a47b89b5f3eed798ef Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 8 Apr 2009 14:54:30 -0700 Subject: [PATCH 13/14] Use a #define instead of a magic number The number of buffers is likely to change in the future, so having this as a define is the right way to go. Signed-off-by: Ian Romanick (cherry picked from commit 03aebed519986c4dd03e02b3b3d4af1f64595ca7) --- glx/glxdri2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/glx/glxdri2.c b/glx/glxdri2.c index c6716703f..f2682d4d9 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -82,6 +82,8 @@ struct __GLXDRIcontext { __DRIcontext *driContext; }; +#define MAX_DRAWABLE_BUFFERS 5 + struct __GLXDRIdrawable { __GLXdrawable base; __DRIdrawable *driDrawable; @@ -90,7 +92,7 @@ struct __GLXDRIdrawable { /* Dimensions as last reported by DRI2GetBuffers. */ int width; int height; - __DRIbuffer buffers[5]; + __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS]; int count; }; @@ -365,7 +367,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, buffers = DRI2GetBuffers(private->base.pDraw, width, height, attachments, count, out_count); - if (*out_count > 5) { + if (*out_count > MAX_DRAWABLE_BUFFERS) { *out_count = 0; return NULL; } From dbac41b624e4aa86a6a184b7ebb52bfdd367bbf0 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 19 Jun 2009 12:42:07 -0400 Subject: [PATCH 14/14] pci: Dump vendor/devices ids in the printed device list (cherry picked from commit eb35402d0a5290e8a73d7d1e92f173294c364cc2) --- hw/xfree86/common/xf86pciBus.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 467a0c397..5b29a1511 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -417,18 +417,16 @@ xf86PciProbe(void) if (xf86IsPrimaryPci(info)) prim = "*"; - xf86Msg( X_PROBED, "PCI:%s(%u@%u:%u:%u) ", prim, info->domain, - info->bus, info->dev, info->func ); + xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim, + info->domain, info->bus, info->dev, info->func, + info->vendor_id, info->device_id, + info->subvendor_id, info->subdevice_id); if (vendorname) xf86ErrorF("%s ", vendorname); - else - xf86ErrorF("unknown vendor (0x%04x) ", info->vendor_id); if (chipname) xf86ErrorF("%s ", chipname); - else - xf86ErrorF("unknown chipset (0x%04x) ", info->device_id); xf86ErrorF("rev %d", info->revision);