diff options
Diffstat (limited to 'mesalib/src/mesa/drivers/dri')
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/dri_util.c | 26 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/dri_util.h | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/megadriver_stub.c | 126 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/swrast/swrast.c | 39 |
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 }; |