diff options
author | Keith Packard <[email protected]> | 2013-11-04 18:09:51 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2013-11-07 19:08:09 -0800 |
commit | 442442026eb241f05f2b7c03da304e0be047a7da (patch) | |
tree | 004956fd32cda29d0d0c8cf7edb5581ef0a7681a /src/mesa/drivers/dri/i915 | |
parent | 1f085ba18fb11ca7d378bb2b4423702b1c823786 (diff) |
dri: add __DRIimageLoaderExtension and __DRIimageDriverExtension
These provide an interface between the driver and the loader to allocate
color buffers through the DRIimage extension interface rather than through a
loader-specific extension (as is used by DRI2, for instance).
The driver uses the loader 'getBuffers' interface to allocate color buffers.
The loader uses the createNewScreen2, createNewDrawable, createNewContext,
getAPIMask and createContextAttribs APIS (mostly shared with DRI2).
This interface will work with the DRI3 loader, and should also work with GBM
and other loaders so that drivers need not be customized for each new loader
interface, as long as they provide this image interface.
v2: Fix build of i915 and i965 together (by anholt)
Signed-off-by: Keith Packard <[email protected]>
Reviewed-by: Kristian Høgsberg <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i915')
-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 |
5 files changed, 152 insertions, 4 deletions
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); |