diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/common/dri_util.c | 13 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_util.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_context.c | 113 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_mipmap_tree.c | 33 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_mipmap_tree.h | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_screen.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_screen.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.c | 114 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_screen.c | 5 |
11 files changed, 352 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 46a2da4cb59..86cf24cb881 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -78,6 +78,8 @@ setupLoaderExtensions(__DRIscreen *psp, psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0) + psp->image.loader = (__DRIimageLoaderExtension *) extensions[i]; } } @@ -859,3 +861,14 @@ driImageFormatToGLFormat(uint32_t image_format) return MESA_FORMAT_NONE; } } + +/** Image driver interface */ +const __DRIimageDriverExtension driImageDriverExtension = { + .base = { __DRI_IMAGE_DRIVER, __DRI_IMAGE_DRIVER_VERSION }, + + .createNewScreen2 = driCreateNewScreen2, + .createNewDrawable = driCreateNewDrawable, + .createNewContext = driCreateNewContext, + .getAPIMask = driGetAPIMask, + .createContextAttribs = driCreateContextAttribs, +}; diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 7fab3e5f720..79a8564ad51 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -176,6 +176,10 @@ struct __DRIscreenRec { __DRIuseInvalidateExtension *useInvalidate; } dri2; + struct { + __DRIimageLoaderExtension *loader; + } image; + driOptionCache optionInfo; driOptionCache optionCache; @@ -285,4 +289,6 @@ dri2InvalidateDrawable(__DRIdrawable *drawable); extern void driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv); +extern const __DRIimageDriverExtension driImageDriverExtension; + #endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 1568a166485..36188934fca 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -99,6 +99,8 @@ intelGetString(struct gl_context * ctx, GLenum name) } } +#define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer) + static void intel_flush_front(struct gl_context *ctx) { @@ -108,11 +110,10 @@ intel_flush_front(struct gl_context *ctx) __DRIscreen *const screen = intel->intelScreen->driScrnPriv; if (intel->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) { - if (screen->dri2.loader->flushFrontBuffer != NULL && + if (flushFront(screen) && driDrawable && driDrawable->loaderPrivate) { - screen->dri2.loader->flushFrontBuffer(driDrawable, - driDrawable->loaderPrivate); + flushFront(screen)(driDrawable, driDrawable->loaderPrivate); /* We set the dirty bit in intel_prepare_render() if we're * front buffer rendering once we get there. @@ -122,6 +123,9 @@ intel_flush_front(struct gl_context *ctx) } } +static void +intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable); + static unsigned intel_bits_per_pixel(const struct intel_renderbuffer *rb) { @@ -202,7 +206,10 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) if (unlikely(INTEL_DEBUG & DEBUG_DRI)) fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); - intel_update_dri2_buffers(intel, drawable); + if (screen->image.loader) + intel_update_image_buffers(intel, drawable); + else + intel_update_dri2_buffers(intel, drawable); driUpdateFramebufferSize(&intel->ctx, drawable); } @@ -811,3 +818,101 @@ intel_process_dri2_buffer(struct intel_context *intel, region); intel_region_release(®ion); } + +/** + * \brief Query DRI Image loader to obtain a DRIdrawable's buffers. + * + * To determine which DRI buffers to request, examine the renderbuffers + * attached to the drawable's framebuffer. Then request the buffers with + * dri3 + * + * This is called from intel_update_renderbuffers(). + * + * \param drawable Drawable whose buffers are queried. + * \param buffers [out] List of buffers returned by DRI2 query. + * \param buffer_count [out] Number of buffers returned. + * + * \see intel_update_renderbuffers() + */ + +static void +intel_update_image_buffer(struct intel_context *intel, + __DRIdrawable *drawable, + struct intel_renderbuffer *rb, + __DRIimage *buffer, + enum __DRIimageBufferMask buffer_type) +{ + struct intel_region *region = buffer->region; + + if (!rb || !region) + return; + + unsigned num_samples = rb->Base.Base.NumSamples; + + if (rb->mt && + rb->mt->region && + rb->mt->region == region) + return; + + intel_miptree_release(&rb->mt); + rb->mt = intel_miptree_create_for_image_buffer(intel, + buffer_type, + intel_rb_format(rb), + num_samples, + region); +} + + +static void +intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable) +{ + struct gl_framebuffer *fb = drawable->driverPrivate; + __DRIscreen *screen = intel->intelScreen->driScrnPriv; + struct intel_renderbuffer *front_rb; + struct intel_renderbuffer *back_rb; + struct __DRIimageList images; + unsigned int format; + uint32_t buffer_mask = 0; + + front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); + back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); + + if (back_rb) + format = intel_rb_format(back_rb); + else if (front_rb) + format = intel_rb_format(front_rb); + else + return; + + if ((intel->is_front_buffer_rendering || intel->is_front_buffer_reading || !back_rb) && front_rb) + buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; + + if (back_rb) + buffer_mask |= __DRI_IMAGE_BUFFER_BACK; + + (*screen->image.loader->getBuffers) (drawable, + driGLFormatToImageFormat(format), + &drawable->dri2.stamp, + drawable->loaderPrivate, + buffer_mask, + &images); + + if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { + drawable->w = images.front->width; + drawable->h = images.front->height; + intel_update_image_buffer(intel, + drawable, + front_rb, + images.front, + __DRI_IMAGE_BUFFER_FRONT); + } + if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { + drawable->w = images.back->width; + drawable->h = images.back->height; + intel_update_image_buffer(intel, + drawable, + back_rb, + images.back, + __DRI_IMAGE_BUFFER_BACK); + } +} diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c index 8432b6dc53f..66a7a92dc05 100644 --- a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c @@ -322,6 +322,39 @@ intel_miptree_create_for_dri2_buffer(struct intel_context *intel, return mt; } +/** + * For a singlesample image buffer, this simply wraps the given region with a miptree. + * + * For a multisample image buffer, this wraps the given region with + * a singlesample miptree, then creates a multisample miptree into which the + * singlesample miptree is embedded as a child. + */ +struct intel_mipmap_tree* +intel_miptree_create_for_image_buffer(struct intel_context *intel, + enum __DRIimageBufferMask buffer_type, + gl_format format, + uint32_t num_samples, + struct intel_region *region) +{ + struct intel_mipmap_tree *mt = NULL; + + /* Only the front and back buffers, which are color buffers, are allocated + * through the image loader. + */ + assert(_mesa_get_format_base_format(format) == GL_RGB || + _mesa_get_format_base_format(format) == GL_RGBA); + + mt = intel_miptree_create_for_bo(intel, + region->bo, + format, + 0, + region->width, + region->height, + region->pitch, + region->tiling); + return mt; +} + struct intel_mipmap_tree* intel_miptree_create_for_renderbuffer(struct intel_context *intel, gl_format format, diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h index 1142af60bb7..35cad6dfcc6 100644 --- a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h @@ -32,6 +32,7 @@ #include "intel_screen.h" #include "intel_regions.h" +#include "GL/internal/dri_interface.h" #ifdef __cplusplus extern "C" { @@ -258,6 +259,13 @@ intel_miptree_create_for_dri2_buffer(struct intel_context *intel, gl_format format, struct intel_region *region); +struct intel_mipmap_tree* +intel_miptree_create_for_image_buffer(struct intel_context *intel, + enum __DRIimageBufferMask buffer_type, + gl_format format, + uint32_t num_samples, + struct intel_region *region); + /** * Create a miptree appropriate as the storage for a non-texture renderbuffer. * The miptree has the following properties: diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index d93bd9be59e..2c309ed4a16 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -1258,6 +1258,7 @@ static const struct __DRIDriverVtableExtensionRec i915_vtable = { /* This is the table of extensions that the loader will dlsym() for. */ static const __DRIextension *i915_driver_extensions[] = { &driCoreExtension.base, + &driImageDriverExtension.base, &driDRI2Extension.base, &i915_vtable.base, &i915_config_options.base, diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h index 4ae259cccdf..faa4c205d36 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.h +++ b/src/mesa/drivers/dri/i915/intel_screen.h @@ -155,6 +155,7 @@ struct intel_screen #define intel_fbo_init old_intel_fbo_init #define intel_get_rb_region old_intel_get_rb_region #define intel_renderbuffer_set_draw_offset old_intel_renderbuffer_set_draw_offset +#define intel_miptree_create_for_image_buffer old_intel_miptree_create_for_image_buffer extern void intelDestroyContext(__DRIcontext * driContextPriv); diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index f9623bb2a7d..a33e993f281 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -162,6 +162,8 @@ intelInvalidateState(struct gl_context * ctx, GLuint new_state) brw->NewGLState |= new_state; } +#define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer) + static void intel_flush_front(struct gl_context *ctx) { @@ -171,8 +173,7 @@ intel_flush_front(struct gl_context *ctx) __DRIscreen *const screen = brw->intelScreen->driScrnPriv; if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) { - if (screen->dri2.loader->flushFrontBuffer != NULL && - driDrawable && + if (flushFront(screen) && driDrawable && driDrawable->loaderPrivate) { /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT. @@ -185,8 +186,7 @@ intel_flush_front(struct gl_context *ctx) intel_resolve_for_dri2_flush(brw, driDrawable); intel_batchbuffer_flush(brw); - screen->dri2.loader->flushFrontBuffer(driDrawable, - driDrawable->loaderPrivate); + flushFront(screen)(driDrawable, driDrawable->loaderPrivate); /* We set the dirty bit in intel_prepare_render() if we're * front buffer rendering once we get there. @@ -1029,6 +1029,9 @@ intel_process_dri2_buffer(struct brw_context *brw, const char *buffer_name); static void +intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable); + +static void intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable) { struct gl_framebuffer *fb = drawable->driverPrivate; @@ -1088,6 +1091,7 @@ void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) { struct brw_context *brw = context->driverPrivate; + __DRIscreen *screen = brw->intelScreen->driScrnPriv; /* Set this up front, so that in case our buffers get invalidated * while we're getting new buffers, we don't clobber the stamp and @@ -1097,7 +1101,10 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) if (unlikely(INTEL_DEBUG & DEBUG_DRI)) fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); - intel_update_dri2_buffers(brw, drawable); + if (screen->image.loader) + intel_update_image_buffers(brw, drawable); + else + intel_update_dri2_buffers(brw, drawable); driUpdateFramebufferSize(&brw->ctx, drawable); } @@ -1303,3 +1310,100 @@ intel_process_dri2_buffer(struct brw_context *brw, region); intel_region_release(®ion); } + +/** + * \brief Query DRI image loader to obtain a DRIdrawable's buffers. + * + * To determine which DRI buffers to request, examine the renderbuffers + * attached to the drawable's framebuffer. Then request the buffers from + * the image loader + * + * This is called from intel_update_renderbuffers(). + * + * \param drawable Drawable whose buffers are queried. + * \param buffers [out] List of buffers returned by DRI2 query. + * \param buffer_count [out] Number of buffers returned. + * + * \see intel_update_renderbuffers() + */ + +static void +intel_update_image_buffer(struct brw_context *intel, + __DRIdrawable *drawable, + struct intel_renderbuffer *rb, + __DRIimage *buffer, + enum __DRIimageBufferMask buffer_type) +{ + struct intel_region *region = buffer->region; + + if (!rb || !region) + return; + + unsigned num_samples = rb->Base.Base.NumSamples; + + if (rb->mt && + rb->mt->region && + rb->mt->region == region) + return; + + intel_miptree_release(&rb->mt); + rb->mt = intel_miptree_create_for_image_buffer(intel, + buffer_type, + intel_rb_format(rb), + num_samples, + region); +} + +static void +intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable) +{ + struct gl_framebuffer *fb = drawable->driverPrivate; + __DRIscreen *screen = brw->intelScreen->driScrnPriv; + struct intel_renderbuffer *front_rb; + struct intel_renderbuffer *back_rb; + struct __DRIimageList images; + unsigned int format; + uint32_t buffer_mask = 0; + + front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); + back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); + + if (back_rb) + format = intel_rb_format(back_rb); + else if (front_rb) + format = intel_rb_format(front_rb); + else + return; + + if ((brw->is_front_buffer_rendering || brw->is_front_buffer_reading || !back_rb) && front_rb) + buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; + + if (back_rb) + buffer_mask |= __DRI_IMAGE_BUFFER_BACK; + + (*screen->image.loader->getBuffers) (drawable, + driGLFormatToImageFormat(format), + &drawable->dri2.stamp, + drawable->loaderPrivate, + buffer_mask, + &images); + + if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { + drawable->w = images.front->width; + drawable->h = images.front->height; + intel_update_image_buffer(brw, + drawable, + front_rb, + images.front, + __DRI_IMAGE_BUFFER_FRONT); + } + if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { + drawable->w = images.back->width; + drawable->h = images.back->height; + intel_update_image_buffer(brw, + drawable, + back_rb, + images.back, + __DRI_IMAGE_BUFFER_BACK); + } +} diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index f690ac1aca1..3f5608601ec 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -726,6 +726,67 @@ intel_miptree_create_for_dri2_buffer(struct brw_context *brw, return multisample_mt; } +/** + * For a singlesample image buffer, this simply wraps the given region with a miptree. + * + * For a multisample image buffer, this wraps the given region with + * a singlesample miptree, then creates a multisample miptree into which the + * singlesample miptree is embedded as a child. + */ +struct intel_mipmap_tree* +intel_miptree_create_for_image_buffer(struct brw_context *intel, + enum __DRIimageBufferMask buffer_type, + gl_format format, + uint32_t num_samples, + struct intel_region *region) +{ + struct intel_mipmap_tree *singlesample_mt = NULL; + struct intel_mipmap_tree *multisample_mt = NULL; + + /* Only the front and back buffers, which are color buffers, are allocated + * through the image loader. + */ + assert(_mesa_get_format_base_format(format) == GL_RGB || + _mesa_get_format_base_format(format) == GL_RGBA); + + singlesample_mt = intel_miptree_create_for_bo(intel, + region->bo, + format, + 0, + region->width, + region->height, + region->pitch, + region->tiling); + if (!singlesample_mt) + return NULL; + + intel_region_reference(&singlesample_mt->region, region); + + if (num_samples == 0) + return singlesample_mt; + + multisample_mt = intel_miptree_create_for_renderbuffer(intel, + format, + region->width, + region->height, + num_samples); + if (!multisample_mt) { + intel_miptree_release(&singlesample_mt); + return NULL; + } + + multisample_mt->singlesample_mt = singlesample_mt; + multisample_mt->need_downsample = false; + + intel_region_reference(&multisample_mt->region, region); + + if (intel->is_front_buffer_rendering && buffer_type == __DRI_IMAGE_BUFFER_FRONT) { + intel_miptree_upsample(intel, multisample_mt); + } + + return multisample_mt; +} + struct intel_mipmap_tree* intel_miptree_create_for_renderbuffer(struct brw_context *brw, gl_format format, diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index d7181255edb..8777a8c605c 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -32,6 +32,7 @@ #include "intel_regions.h" #include "intel_resolve_map.h" +#include <GL/internal/dri_interface.h> #ifdef __cplusplus extern "C" { @@ -529,6 +530,13 @@ intel_miptree_create_for_dri2_buffer(struct brw_context *brw, uint32_t num_samples, struct intel_region *region); +struct intel_mipmap_tree* +intel_miptree_create_for_image_buffer(struct brw_context *intel, + enum __DRIimageBufferMask buffer_type, + gl_format format, + uint32_t num_samples, + struct intel_region *region); + /** * Create a miptree appropriate as the storage for a non-texture renderbuffer. * The miptree has the following properties: diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 099cabfb9d0..e39d6545970 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -1264,7 +1264,8 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) { struct intel_screen *intelScreen; - if (psp->dri2.loader->base.version <= 2 || + if (psp->image.loader) { + } else if (psp->dri2.loader->base.version <= 2 || psp->dri2.loader->getBuffersWithFormat == NULL) { fprintf(stderr, "\nERROR! DRI2 loader with getBuffersWithFormat() " @@ -1352,7 +1353,6 @@ intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) free(intelBuffer); } - static const struct __DriverAPIRec brw_driver_api = { .InitScreen = intelInitScreen2, .DestroyScreen = intelDestroyScreen, @@ -1373,6 +1373,7 @@ static const struct __DRIDriverVtableExtensionRec brw_vtable = { static const __DRIextension *brw_driver_extensions[] = { &driCoreExtension.base, + &driImageDriverExtension.base, &driDRI2Extension.base, &brw_vtable.base, &brw_config_options.base, |