struct drisw_context
{
- __GLXDRIcontext base;
+ struct glx_context base;
__DRIcontext *driContext;
- __GLXscreenConfigs *psc;
+
};
struct drisw_screen
{
- __GLXscreenConfigs base;
+ struct glx_screen base;
__DRIscreen *driScreen;
__GLXDRIscreen vtable;
const __DRIcoreExtension *core;
const __DRIswrastExtension *swrast;
+ const __DRItexBufferExtension *texBuffer;
+
+ const __DRIconfig **driver_configs;
+
void *driver;
};
32, /* bitmap_pad */
0); /* bytes_per_line */
+ /**
+ * swrast does not handle 24-bit depth with 24 bpp, so let X do the
+ * the conversion for us.
+ */
+ if (pdp->ximage->bits_per_pixel == 24)
+ pdp->ximage->bits_per_pixel = 32;
+
return True;
}
Drawable drawable;
Window root;
- Status stat;
unsigned uw, uh, bw, depth;
drawable = pdraw->xDrawable;
- stat = XGetGeometry(dpy, drawable, &root,
- x, y, &uw, &uh, &bw, &depth);
+ XGetGeometry(dpy, drawable, &root, x, y, &uw, &uh, &bw, &depth);
*w = uw;
*h = uh;
}
*/
static void
-driDestroyContext(__GLXDRIcontext *context,
- __GLXscreenConfigs *base, Display *dpy)
+drisw_destroy_context(struct glx_context *context)
{
struct drisw_context *pcp = (struct drisw_context *) context;
- struct drisw_screen *psc = (struct drisw_screen *) base;
+ struct drisw_screen *psc = (struct drisw_screen *) context->psc;
+
+ driReleaseDrawables(&pcp->base);
+
+ if (context->extensions)
+ XFree((char *) context->extensions);
(*psc->core->destroyContext) (pcp->driContext);
Xfree(pcp);
}
-static Bool
-driBindContext(__GLXDRIcontext * context,
- __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
+static int
+drisw_bind_context(struct glx_context *context, struct glx_context *old,
+ GLXDrawable draw, GLXDrawable read)
{
struct drisw_context *pcp = (struct drisw_context *) context;
- struct drisw_screen *psc = (struct drisw_screen *) pcp->psc;
- struct drisw_drawable *pdr = (struct drisw_drawable *) draw;
- struct drisw_drawable *prd = (struct drisw_drawable *) read;
+ struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
+ struct drisw_drawable *pdraw, *pread;
+
+ pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw);
+ pread = (struct drisw_drawable *) driFetchDrawable(context, read);
+
+ driReleaseDrawables(&pcp->base);
- return (*psc->core->bindContext) (pcp->driContext,
- pdr->driDrawable, prd->driDrawable);
+ if (pdraw == NULL || pread == NULL)
+ return GLXBadDrawable;
+
+ if ((*psc->core->bindContext) (pcp->driContext,
+ pdraw->driDrawable, pread->driDrawable))
+ return Success;
+
+ return GLXBadContext;
}
static void
-driUnbindContext(__GLXDRIcontext * context)
+drisw_unbind_context(struct glx_context *context, struct glx_context *new)
{
struct drisw_context *pcp = (struct drisw_context *) context;
- struct drisw_screen *psc = (struct drisw_screen *) pcp->psc;
+ struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
(*psc->core->unbindContext) (pcp->driContext);
}
-static __GLXDRIcontext *
-driCreateContext(__GLXscreenConfigs *base,
- const __GLcontextModes *mode,
- GLXContext gc, GLXContext shareList, int renderType)
+static void
+drisw_bind_tex_image(Display * dpy,
+ GLXDrawable drawable,
+ int buffer, const int *attrib_list)
+{
+ struct glx_context *gc = __glXGetCurrentContext();
+ struct drisw_context *pcp = (struct drisw_context *) gc;
+ __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
+ struct drisw_drawable *pdraw = (struct drisw_drawable *) base;
+ struct drisw_screen *psc;
+
+ __glXInitialize(dpy);
+
+ if (pdraw != NULL) {
+ psc = (struct drisw_screen *) base->psc;
+
+ if (!psc->texBuffer)
+ return;
+
+ if (psc->texBuffer->base.version >= 2 &&
+ psc->texBuffer->setTexBuffer2 != NULL) {
+ (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->base.textureFormat,
+ pdraw->driDrawable);
+ }
+ else {
+ (*psc->texBuffer->setTexBuffer) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+}
+
+static void
+drisw_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+{
+#if __DRI_TEX_BUFFER_VERSION >= 3
+ struct glx_context *gc = __glXGetCurrentContext();
+ struct dri2_context *pcp = (struct dri2_context *) gc;
+ __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
+ struct glx_display *dpyPriv = __glXInitialize(dpy);
+ struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
+ struct dri2_screen *psc;
+
+ if (pdraw != NULL) {
+ psc = (struct dri2_screen *) base->psc;
+
+ if (!psc->texBuffer)
+ return;
+
+ if (psc->texBuffer->base.version >= 3 &&
+ psc->texBuffer->releaseTexBuffer != NULL) {
+ (*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
+ pdraw->base.textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+#endif
+}
+
+static const struct glx_context_vtable drisw_context_vtable = {
+ drisw_destroy_context,
+ drisw_bind_context,
+ drisw_unbind_context,
+ NULL,
+ NULL,
+ DRI_glXUseXFont,
+ drisw_bind_tex_image,
+ drisw_release_tex_image,
+ NULL, /* get_proc_address */
+};
+
+static struct glx_context *
+drisw_create_context(struct glx_screen *base,
+ struct glx_config *config_base,
+ struct glx_context *shareList, int renderType)
{
struct drisw_context *pcp, *pcp_shared;
- __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
struct drisw_screen *psc = (struct drisw_screen *) base;
__DRIcontext *shared = NULL;
return NULL;
if (shareList) {
- pcp_shared = (struct drisw_context *) shareList->driContext;
+ /* If the shareList context is not a DRISW context, we cannot possibly
+ * create a DRISW context that shares it.
+ */
+ if (shareList->vtable->destroy != drisw_destroy_context) {
+ return NULL;
+ }
+
+ pcp_shared = (struct drisw_context *) shareList;
shared = pcp_shared->driContext;
}
if (pcp == NULL)
return NULL;
- pcp->psc = &psc->base;
+ memset(pcp, 0, sizeof *pcp);
+ if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
+ Xfree(pcp);
+ return NULL;
+ }
+
pcp->driContext =
(*psc->core->createNewContext) (psc->driScreen,
config->driConfig, shared, pcp);
return NULL;
}
- pcp->base.destroyContext = driDestroyContext;
- pcp->base.bindContext = driBindContext;
- pcp->base.unbindContext = driUnbindContext;
+ pcp->base.vtable = &drisw_context_vtable;
return &pcp->base;
}
static void
-driDestroyDrawable(__GLXDRIdrawable * pdraw)
+driswDestroyDrawable(__GLXDRIdrawable * pdraw)
{
struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
}
static __GLXDRIdrawable *
-driCreateDrawable(__GLXscreenConfigs *base, XID xDrawable,
- GLXDrawable drawable, const __GLcontextModes * modes)
+driswCreateDrawable(struct glx_screen *base, XID xDrawable,
+ GLXDrawable drawable, struct glx_config *modes)
{
struct drisw_drawable *pdp;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
const __DRIswrastExtension *swrast = psc->swrast;
- /* Old dri can't handle GLX 1.3+ drawable constructors. */
- if (xDrawable != drawable)
- return NULL;
-
pdp = Xmalloc(sizeof(*pdp));
if (!pdp)
return NULL;
+ memset(pdp, 0, sizeof *pdp);
pdp->base.xDrawable = xDrawable;
pdp->base.drawable = drawable;
pdp->base.psc = &psc->base;
return NULL;
}
- pdp->base.destroyDrawable = driDestroyDrawable;
+ pdp->base.destroyDrawable = driswDestroyDrawable;
return &pdp->base;
}
static int64_t
-driSwapBuffers(__GLXDRIdrawable * pdraw,
- int64_t target_msc, int64_t divisor, int64_t remainder)
+driswSwapBuffers(__GLXDRIdrawable * pdraw,
+ int64_t target_msc, int64_t divisor, int64_t remainder)
{
struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
}
static void
-driDestroyScreen(__GLXscreenConfigs *base)
+driswDestroyScreen(struct glx_screen *base)
{
struct drisw_screen *psc = (struct drisw_screen *) base;
/* Free the direct rendering per screen data */
(*psc->core->destroyScreen) (psc->driScreen);
+ driDestroyConfigs(psc->driver_configs);
psc->driScreen = NULL;
if (psc->driver)
dlclose(psc->driver);
if (driver == NULL)
driver = driOpenDriver("swrast");
- if (driver == NULL)
- driver = driOpenDriver("swrastg");
-
return driver;
}
-static __GLXscreenConfigs *
-driCreateScreen(int screen, __GLXdisplayPrivate *priv)
+static const struct glx_screen_vtable drisw_screen_vtable = {
+ drisw_create_context
+};
+
+static void
+driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
+{
+ int i;
+
+ __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
+
+ /* FIXME: Figure out what other extensions can be ported here from dri2. */
+ for (i = 0; extensions[i]; i++) {
+ if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
+ }
+ }
+}
+
+static struct glx_screen *
+driswCreateScreen(int screen, struct glx_display *priv)
{
__GLXDRIscreen *psp;
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
struct drisw_screen *psc;
+ struct glx_config *configs = NULL, *visuals = NULL;
int i;
psc = Xcalloc(1, sizeof *psc);
return NULL;
memset(psc, 0, sizeof *psc);
- if (!glx_screen_init(&psc->base, screen, priv))
- return NULL;
+ if (!glx_screen_init(&psc->base, screen, priv)) {
+ Xfree(psc);
+ return NULL;
+ }
psc->driver = driOpenSwrast();
if (psc->driver == NULL)
}
extensions = psc->core->getExtensions(psc->driScreen);
- driBindCommonExtensions(&psc->base, extensions);
+ driswBindExtensions(psc, extensions);
+
+ configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+ visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+
+ if (!configs || !visuals)
+ goto handle_error;
- psc->base.configs =
- driConvertConfigs(psc->core, psc->base.configs, driver_configs);
- psc->base.visuals =
- driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+ glx_config_destroy_list(psc->base.configs);
+ psc->base.configs = configs;
+ glx_config_destroy_list(psc->base.visuals);
+ psc->base.visuals = visuals;
- psc->base.driver_configs = driver_configs;
+ psc->driver_configs = driver_configs;
+ psc->base.vtable = &drisw_screen_vtable;
psp = &psc->vtable;
psc->base.driScreen = psp;
- psp->destroyScreen = driDestroyScreen;
- psp->createContext = driCreateContext;
- psp->createDrawable = driCreateDrawable;
- psp->swapBuffers = driSwapBuffers;
- psp->waitX = NULL;
- psp->waitGL = NULL;
+ psp->destroyScreen = driswDestroyScreen;
+ psp->createDrawable = driswCreateDrawable;
+ psp->swapBuffers = driswSwapBuffers;
return &psc->base;
handle_error:
- Xfree(psc);
+ if (configs)
+ glx_config_destroy_list(configs);
+ if (visuals)
+ glx_config_destroy_list(visuals);
+ if (psc->driScreen)
+ psc->core->destroyScreen(psc->driScreen);
+ psc->driScreen = NULL;
if (psc->driver)
dlclose(psc->driver);
+ glx_screen_cleanup(&psc->base);
+ Xfree(psc);
ErrorMessageF("reverting to indirect rendering\n");
/* Called from __glXFreeDisplayPrivate.
*/
static void
-driDestroyDisplay(__GLXDRIdisplay * dpy)
+driswDestroyDisplay(__GLXDRIdisplay * dpy)
{
Xfree(dpy);
}
if (pdpyp == NULL)
return NULL;
- pdpyp->base.destroyDisplay = driDestroyDisplay;
- pdpyp->base.createScreen = driCreateScreen;
+ pdpyp->base.destroyDisplay = driswDestroyDisplay;
+ pdpyp->base.createScreen = driswCreateScreen;
return &pdpyp->base;
}