aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/drivers/dri
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/drivers/dri')
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c26
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.h8
-rw-r--r--mesalib/src/mesa/drivers/dri/common/megadriver_stub.c126
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c39
4 files changed, 193 insertions, 6 deletions
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index 0bce77ea9..d64821112 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -438,16 +438,19 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
return NULL;
}
- struct gl_context *ctx = context->driverPrivate;
+ *error = __DRI_CTX_ERROR_SUCCESS;
+ return context;
+}
+
+void
+driContextSetFlags(struct gl_context *ctx, uint32_t flags)
+{
if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) {
ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
ctx->Debug.DebugOutput = GL_TRUE;
}
-
- *error = __DRI_CTX_ERROR_SUCCESS;
- return context;
}
static __DRIcontext *
@@ -873,3 +876,18 @@ const __DRIimageDriverExtension driImageDriverExtension = {
.getAPIMask = driGetAPIMask,
.createContextAttribs = driCreateContextAttribs,
};
+
+/* swrast copy sub buffer entrypoint. */
+static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y,
+ int w, int h)
+{
+ assert(pdp->driScreenPriv->swrast_loader);
+
+ pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h);
+}
+
+/* for swrast only */
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
+ { __DRI_COPY_SUB_BUFFER, 1 },
+ .copySubBuffer = driCopySubBuffer,
+};
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h
index 79a8564ad..a79a4ed7a 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.h
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h
@@ -66,7 +66,7 @@ extern const __DRIcoreExtension driCoreExtension;
extern const __DRIswrastExtension driSWRastExtension;
extern const __DRIdri2Extension driDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
-
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
/**
* Driver callback functions.
*
@@ -115,6 +115,9 @@ struct __DriverAPIRec {
int width, int height);
void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer);
+
+ void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y,
+ int w, int h);
};
extern const struct __DriverAPIRec driDriverAPI;
@@ -289,6 +292,9 @@ dri2InvalidateDrawable(__DRIdrawable *drawable);
extern void
driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv);
+extern void
+driContextSetFlags(struct gl_context *ctx, uint32_t flags);
+
extern const __DRIimageDriverExtension driImageDriverExtension;
#endif /* _DRI_UTIL_H_ */
diff --git a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
index 6bf5d7327..a8217703d 100644
--- a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
+++ b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
@@ -23,6 +23,132 @@
#include <stdio.h>
#include "dri_util.h"
+#include <dlfcn.h>
+#include "main/macros.h"
+
+/* We need GNU extensions to dlfcn.h in order to provide backward
+ * compatibility for the older DRI driver loader mechanism. (dladdr,
+ * Dl_info, and RTLD_DEFAULT are only defined when _GNU_SOURCE is
+ * defined.)
+ */
+#ifdef _GNU_SOURCE
+
+#define MEGADRIVER_STUB_MAX_EXTENSIONS 10
+#define LIB_PATH_SUFFIX "_dri.so"
+#define LIB_PATH_SUFFIX_LENGTH (sizeof(LIB_PATH_SUFFIX)-1)
+
+/* This is the table of extensions that the loader will dlsym() for.
+ *
+ * Initially it is empty for the megadriver stub, but the library
+ * constructor may initialize it based on the name of the library that
+ * is being loaded.
+ */
+PUBLIC const __DRIextension *
+__driDriverExtensions[MEGADRIVER_STUB_MAX_EXTENSIONS] = {
+ NULL
+};
+
+/**
+ * This is a constructor function for the megadriver dynamic library.
+ *
+ * When the driver is dlopen'ed, this function will run. It will
+ * search for the name of the foo_dri.so file that was opened using
+ * the dladdr function.
+ *
+ * After finding foo's name, it will call __driDriverGetExtensions_foo
+ * and use the return to update __driDriverExtensions to enable
+ * compatibility with older DRI driver loaders.
+ */
+__attribute__((constructor)) static void
+megadriver_stub_init(void)
+{
+ Dl_info info;
+ char *driver_name;
+ size_t name_len;
+ char *get_extensions_name;
+ const __DRIextension **(*get_extensions)(void);
+ const __DRIextension **extensions;
+ int i;
+
+ /* Call dladdr on __driDriverExtensions. We are really
+ * interested in the returned info.dli_fname so we can
+ * figure out the path name of the library being loaded.
+ */
+ i = dladdr((void*) __driDriverExtensions, &info);
+ if (i == 0)
+ return;
+
+ /* Search for the last '/' character in the path. */
+ driver_name = strrchr(info.dli_fname, '/');
+ if (driver_name != NULL) {
+ /* Skip '/' character */
+ driver_name++;
+ } else {
+ /* Try using the start of the path */
+ driver_name = (char*) info.dli_fname;
+ }
+
+ /* Make sure the path ends with _dri.so */
+ name_len = strlen(driver_name);
+ i = name_len - LIB_PATH_SUFFIX_LENGTH;
+ if (i < 0 || strcmp(driver_name + i, LIB_PATH_SUFFIX) != 0)
+ return;
+
+ /* Duplicate the string so we can modify it.
+ * So far we've been using info.dli_fname.
+ */
+ driver_name = strdup(driver_name);
+ if (!driver_name)
+ return;
+
+ /* The path ends with _dri.so. Chop this part of the
+ * string off. Then we'll have the driver's final name.
+ */
+ driver_name[i] = '\0';
+
+ i = asprintf(&get_extensions_name, "%s_%s",
+ __DRI_DRIVER_GET_EXTENSIONS, driver_name);
+ free(driver_name);
+ if (i == -1)
+ return;
+
+ /* dlsym to get the driver's get extensions function. We
+ * don't have the dlopen handle, so we have to use
+ * RTLD_DEFAULT. It seems unlikely that the symbol will
+ * be found in another library, but this isn't optimal.
+ */
+ get_extensions = dlsym(RTLD_DEFAULT, get_extensions_name);
+ free(get_extensions_name);
+ if (!get_extensions)
+ return;
+
+ /* Use the newer DRI loader entrypoint to find extensions.
+ * We will then expose these extensions via the older
+ * __driDriverExtensions symbol.
+ */
+ extensions = get_extensions();
+
+ /* Copy the extensions into the __driDriverExtensions array
+ * we declared.
+ */
+ for (i = 0; i < ARRAY_SIZE(__driDriverExtensions); i++) {
+ __driDriverExtensions[i] = extensions[i];
+ if (extensions[i] == NULL)
+ break;
+ }
+
+ /* If the driver had more extensions than we reserved, then
+ * bail out.
+ */
+ if (i == ARRAY_SIZE(__driDriverExtensions)) {
+ __driDriverExtensions[0] = NULL;
+ fprintf(stderr, "Megadriver stub did not reserve enough extension "
+ "slots.\n");
+ return;
+ }
+}
+
+#endif /* _GNU_SOURCE */
static const
__DRIconfig **stub_error_init_screen(__DRIscreen *psp)
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 73dc5c4c0..79a27408f 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -402,7 +402,7 @@ swrast_map_renderbuffer(struct gl_context *ctx,
stride = w * cpp;
xrb->Base.Buffer = malloc(h * stride);
- sPriv->swrast_loader->getImage(dPriv, x, y, w, h,
+ sPriv->swrast_loader->getImage(dPriv, x, rb->Height - y - h, w, h,
(char *) xrb->Base.Buffer,
dPriv->loaderPrivate);
@@ -705,6 +705,8 @@ dri_create_context(gl_api api,
goto context_fail;
}
+ driContextSetFlags(mesaCtx, flags);
+
/* do bounds checking to prevent segfaults and server crashes! */
mesaCtx->Const.CheckArrayBounds = GL_TRUE;
@@ -820,6 +822,39 @@ dri_unbind_context(__DRIcontext * cPriv)
return GL_TRUE;
}
+static void
+dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
+ int w, int h)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ void *data;
+ int iy;
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct gl_framebuffer *fb;
+ struct dri_swrast_renderbuffer *frontrb, *backrb;
+
+ TRACE;
+
+ fb = &drawable->Base;
+
+ frontrb =
+ dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ backrb =
+ dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+ /* check for signle-buffered */
+ if (backrb == NULL)
+ return;
+
+ iy = frontrb->Base.Base.Height - y - h;
+ data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8));
+ sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+ x, iy, w, h,
+ frontrb->pitch,
+ data,
+ dPriv->loaderPrivate);
+}
+
static const struct __DriverAPIRec swrast_driver_api = {
.InitScreen = dri_init_screen,
@@ -831,6 +866,7 @@ static const struct __DriverAPIRec swrast_driver_api = {
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+ .CopySubBuffer = dri_copy_sub_buffer,
};
static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
@@ -841,6 +877,7 @@ static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
static const __DRIextension *swrast_driver_extensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
+ &driCopySubBufferExtension.base,
&swrast_vtable.base,
NULL
};