summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c13
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h6
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c113
-rw-r--r--src/mesa/drivers/dri/i915/intel_mipmap_tree.c33
-rw-r--r--src/mesa/drivers/dri/i915/intel_mipmap_tree.h8
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c1
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c114
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c61
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.h8
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c5
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(&region);
}
+
+/**
+ * \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(&region);
}
+
+/**
+ * \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,