summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2015-04-14 09:00:17 +0300
committerTapani Pälli <tapani.palli@intel.com>2015-04-16 13:16:40 +0300
commit8316f6019884d1f76b186d7c02c6e9ecd151be5d (patch)
treeb2d3c279c040ecb9d2fa2b6a5285f864fa727501
parentf78b2c432f31a18794b9f62f0a0cfb8eca256151 (diff)
egl: EGL_EXT_image_flush_external WIPEGL_EXT_image_flush_external
*WARNING* this extension exists only as a draft, work in progress. Patch includes: - adding extension to extension string - validation of function arguments - new api functions for EGL - providing stub driver funcs for dri2 driver - adding new attribute to eglCreateImage - ExplicitFlush property for EGLImage - __DRI_IMAGE_USE_FLUSH_EXTERNAL use flag - extend createImage API to pass use flag - extend DRI image interface with 2 new functions and add entrypoints for them to i965 driver - allow creation of aux buffers in case client has set use_flush_external true (to be split later as multiple patches) Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
-rw-r--r--include/GL/internal/dri_interface.h15
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c49
-rw-r--r--src/egl/drivers/dri2/platform_x11.c1
-rw-r--r--src/egl/main/eglapi.c108
-rw-r--r--src/egl/main/eglapi.h6
-rw-r--r--src/egl/main/egldisplay.h2
-rw-r--r--src/egl/main/eglfallbacks.c3
-rw-r--r--src/egl/main/eglimage.c10
-rw-r--r--src/egl/main/eglimage.h3
-rw-r--r--src/gallium/state_trackers/dri/dri2.c5
-rw-r--r--src/mesa/drivers/dri/i965/intel_fbo.c8
-rw-r--r--src/mesa/drivers/dri/i965/intel_image.h13
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c18
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.h4
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c61
-rw-r--r--src/mesa/drivers/dri/i965/intel_tex_image.c8
16 files changed, 290 insertions, 24 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index eb7da23f7ba..a682344f58e 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1006,7 +1006,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 11
+#define __DRI_IMAGE_VERSION 12
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1038,7 +1038,7 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_USE_SCANOUT 0x0002
#define __DRI_IMAGE_USE_CURSOR 0x0004 /* Depricated */
#define __DRI_IMAGE_USE_LINEAR 0x0008
-
+#define __DRI_IMAGE_USE_FLUSH_EXTERNAL 0x0009 /* Since version xxx */
/**
* Four CC formats that matches with WL_DRM_FORMAT_* from wayland_drm.h
@@ -1162,6 +1162,7 @@ struct __DRIimageExtensionRec {
__DRIimage *(*createImageFromRenderbuffer)(__DRIcontext *context,
int renderbuffer,
+ unsigned use,
void *loaderPrivate);
void (*destroyImage)(__DRIimage *image);
@@ -1227,6 +1228,7 @@ struct __DRIimageExtensionRec {
int depth,
int level,
unsigned *error,
+ unsigned use,
void *loaderPrivate);
/**
* Like createImageFromNames, but takes a prime fd instead.
@@ -1279,6 +1281,15 @@ struct __DRIimageExtensionRec {
* \since 10
*/
int (*getCapabilities)(__DRIscreen *screen);
+
+ /**
+ * API between EGL and GL driver for EGL_EXT_image_flush_external
+ * (TODO - figure out the the actual arguments required)
+ *
+ * \since xxx
+ */
+ GLboolean (*flushImageExternal)(__DRIcontext *ctx, __DRIimage *image);
+ GLboolean (*invalidateImageExternal)(__DRIcontext *ctx, __DRIimage *image);
};
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index a428f284ae7..0f9ab7391cd 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1328,16 +1328,25 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
GLuint renderbuffer = (GLuint) (uintptr_t) buffer;
+ _EGLImageAttribs attrs;
__DRIimage *dri_image;
+ unsigned dri_use = 0;
if (renderbuffer == 0) {
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
}
+ if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS)
+ return EGL_NO_IMAGE_KHR;
+
+ if (attrs.ExplicitFlush)
+ dri_use |= __DRI_IMAGE_USE_FLUSH_EXTERNAL;
+
dri_image =
dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context,
- renderbuffer, NULL);
+ renderbuffer, dri_use,
+ NULL);
return dri2_create_image_from_dri(disp, dri_image);
}
@@ -1462,6 +1471,36 @@ dri2_get_sync_values_chromium(_EGLDisplay *dpy, _EGLSurface *surf,
}
/**
+ * TODO - where to query if external device requires a resolve? We should
+ * not have only vendor specific but a SoC specific solution here.
+ */
+static EGLBoolean
+dri2_image_flush_external(_EGLDisplay *dpy, _EGLImage *img,
+ const EGLAttribKHR *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+ return dri2_dpy->image->flushImageExternal(dri2_ctx->dri_context,
+ dri2_img->dri_image);
+}
+
+static EGLBoolean
+dri2_image_invalidate_external(_EGLDisplay *dpy, _EGLImage *img,
+ const EGLAttribKHR *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+ return dri2_dpy->image->invalidateImageExternal(dri2_ctx->dri_context,
+ dri2_img->dri_image);
+}
+
+/**
* Set the error code after a call to
* dri2_egl_image::dri_image::createImageFromTexture.
*/
@@ -1509,6 +1548,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
GLuint depth;
GLenum gl_target;
unsigned error;
+ unsigned dri_use = 0;
if (texture == 0) {
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
@@ -1553,6 +1593,9 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
return EGL_NO_IMAGE_KHR;
}
+ if (attrs.ExplicitFlush)
+ dri_use |= __DRI_IMAGE_USE_FLUSH_EXTERNAL;
+
dri2_img->dri_image =
dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context,
gl_target,
@@ -1560,6 +1603,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
depth,
attrs.GLTextureLevel,
&error,
+ dri_use,
dri2_img);
dri2_create_image_khr_texture_error(error);
@@ -2284,6 +2328,9 @@ _eglBuiltInDriverDRI2(const char *args)
#endif
dri2_drv->base.API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
+ dri2_drv->base.API.ImageFlushExternalEXT = dri2_image_flush_external;
+ dri2_drv->base.API.ImageInvalidateExternalEXT = dri2_image_invalidate_external;
+
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index ddb3b54e843..db28bb00f9b 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -1302,6 +1302,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
disp->Extensions.NV_post_sub_buffer = EGL_TRUE;
disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
+ disp->Extensions.EXT_image_flush_external = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index ea2ee734a21..d9243686fee 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -425,6 +425,8 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(NV_post_sub_buffer);
_EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
+
+ _EGL_CHECK_EXTENSION(EXT_image_flush_external);
#undef _EGL_CHECK_EXTENSION
}
@@ -1148,6 +1150,18 @@ eglGetError(void)
return e;
}
+/**
+ * Forward declarations for functions not yet in EGL headers.
+ */
+EGLBoolean
+eglImageFlushExternalEXT(EGLDisplay dpy,
+ EGLImageKHR image,
+ const EGLAttribKHR *attrib_list);
+
+EGLBoolean
+eglImageInvalidateExternalEXT(EGLDisplay dpy,
+ EGLImageKHR image,
+ const EGLAttribKHR *attrib_list);
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
@@ -1245,6 +1259,8 @@ eglGetProcAddress(const char *procname)
{ "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
{ "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
#endif
+ { "eglImageFlushExternalEXT", (_EGLProc) eglImageFlushExternalEXT },
+ { "eglImageInvalidateExternalEXT", (_EGLProc) eglImageInvalidateExternalEXT },
{ NULL, NULL }
};
EGLint i;
@@ -1933,6 +1949,98 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
+/* TODO - to be removed when we have real enum values in place. */
+enum flush_external_args
+{
+ EGL_IMAGE_EXTERNAL_DISPLAY_EXT = 42,
+ EGL_IMAGE_EXTERNAL_VIDEO_ENCODER_EXT,
+ EGL_IMAGE_EXTERNAL_VIDEO_DECODER_EXT,
+ EGL_IMAGE_EXTERNAL_CAMERA_EXT,
+ EGL_IMAGE_EXTERNAL_CPU_EXT,
+ EGL_IMAGE_EXTERNAL_TARGET_EXT,
+ EGL_IMAGE_EXTERNAL_SOURCE_EXT,
+};
+
+static EGLBoolean
+validate_flush_external_attribs(const EGLAttribKHR *attrib_list,
+ const EGLAttribKHR func_attrib)
+{
+ for (const EGLAttribKHR *attr = attrib_list; *attr != EGL_NONE; attr += 2) {
+
+ /* Must be EXTERNAL_SOURCE or EXTERNAL_TARGET */
+ if (attr[0] != func_attrib)
+ return EGL_FALSE;
+
+ switch (attr[1]) {
+ case EGL_IMAGE_EXTERNAL_DISPLAY_EXT:
+ case EGL_IMAGE_EXTERNAL_VIDEO_ENCODER_EXT:
+ if (func_attrib != EGL_IMAGE_EXTERNAL_TARGET_EXT)
+ return EGL_FALSE;
+ break;
+ case EGL_IMAGE_EXTERNAL_VIDEO_DECODER_EXT:
+ case EGL_IMAGE_EXTERNAL_CAMERA_EXT:
+ if (func_attrib != EGL_IMAGE_EXTERNAL_SOURCE_EXT)
+ return EGL_FALSE;
+ break;
+ case EGL_IMAGE_EXTERNAL_CPU_EXT:
+ break;
+ default:
+ return EGL_FALSE;
+ }
+ }
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY
+eglImageFlushExternalEXT(EGLDisplay dpy, EGLImageKHR image,
+ const EGLAttribKHR *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ _EGLImage *img;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ img = _eglLookupImage(image, disp);
+
+ if (!img)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ if (!validate_flush_external_attribs(attrib_list,
+ EGL_IMAGE_EXTERNAL_TARGET_EXT))
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.ImageFlushExternalEXT(disp, img, attrib_list);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+EGLBoolean EGLAPIENTRY
+eglImageInvalidateExternalEXT(EGLDisplay dpy, EGLImageKHR image,
+ const EGLAttribKHR *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ _EGLImage *img;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ img = _eglLookupImage(image, disp);
+
+ if (!img)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ if (!validate_flush_external_attribs(attrib_list,
+ EGL_IMAGE_EXTERNAL_SOURCE_EXT))
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.ImageInvalidateExternalEXT(disp, img, attrib_list);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
#ifdef EGL_MESA_image_dma_buf_export
EGLBoolean EGLAPIENTRY
eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index eb5f58e6fa9..6c2da597af4 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -145,6 +145,9 @@ typedef EGLBoolean (*ExportDMABUFImageQueryMESA_t)(_EGLDriver *drv, _EGLDisplay
typedef EGLBoolean (*ExportDMABUFImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *fds, EGLint *strides, EGLint *offsets);
#endif
+typedef EGLBoolean (*ImageFlushExternalEXT_t) (_EGLDisplay *dpy, _EGLImage *image, const EGLAttribKHR *attrib_list);
+typedef EGLBoolean (*ImageInvalidateExternalEXT_t) (_EGLDisplay *dpy, _EGLImage *image, const EGLAttribKHR *attrib_list);
+
/**
* The API dispatcher jumps through these functions
*/
@@ -236,6 +239,9 @@ struct _egl_api
ExportDMABUFImageQueryMESA_t ExportDMABUFImageQueryMESA;
ExportDMABUFImageMESA_t ExportDMABUFImageMESA;
#endif
+
+ ImageFlushExternalEXT_t ImageFlushExternalEXT;
+ ImageInvalidateExternalEXT_t ImageInvalidateExternalEXT;
};
#endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 4a1fb4ab15c..dc424ac3ff3 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -125,6 +125,8 @@ struct _egl_extensions
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean MESA_image_dma_buf_export;
+
+ EGLBoolean EXT_image_flush_external;
};
diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c
index c108ca7687c..42ae5b1eb44 100644
--- a/src/egl/main/eglfallbacks.c
+++ b/src/egl/main/eglfallbacks.c
@@ -123,4 +123,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
drv->API.ExportDMABUFImageQueryMESA = NULL;
drv->API.ExportDMABUFImageMESA = NULL;
#endif
+
+ drv->API.ImageFlushExternalEXT = (ImageFlushExternalEXT_t) _eglReturnFalse;
+ drv->API.ImageInvalidateExternalEXT = (ImageInvalidateExternalEXT_t) _eglReturnFalse;
}
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 818b5975cd2..634475b9267 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -33,6 +33,7 @@
#include "eglimage.h"
#include "egllog.h"
+#define EGL_IMAGE_EXTERNAL_FLUSH_EXT 42
/**
* Parse the list of image attributes and return the proper error code.
@@ -169,6 +170,15 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
}
break;
+ /* EGL_EXT_image_flush_external */
+ case EGL_IMAGE_EXTERNAL_FLUSH_EXT:
+ if (val != EGL_FALSE && val != EGL_TRUE) {
+ err = EGL_BAD_ATTRIBUTE;
+ } else {
+ attrs->ExplicitFlush = val;
+ }
+ break;
+
default:
/* unknown attrs are ignored */
break;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 50a87a18890..d479fa76b74 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -69,6 +69,9 @@ struct _egl_image_attribs
struct _egl_image_attrib_int DMABufSampleRangeHint;
struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
struct _egl_image_attrib_int DMABufChromaVerticalSiting;
+
+ /* EGL_EXT_image_flush_external */
+ EGLBoolean ExplicitFlush;
};
/**
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index f8f4ecf36d7..47f2a525790 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -804,7 +804,8 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
static __DRIimage *
dri2_create_image_from_renderbuffer(__DRIcontext *context,
- int renderbuffer, void *loaderPrivate)
+ int renderbuffer, unsigned use,
+ void *loaderPrivate)
{
struct dri_context *ctx = dri_context(context);
@@ -1030,7 +1031,7 @@ dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate)
static __DRIimage *
dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
- int depth, int level, unsigned *error,
+ int depth, int level, unsigned *error, unsigned use,
void *loaderPrivate)
{
__DRIimage *img;
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c
index aebed723f75..ef98439f285 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -377,10 +377,8 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
irb = intel_renderbuffer(rb);
intel_miptree_release(&irb->mt);
- /* Disable creation of the miptree's aux buffers because the driver exposes
- * no EGL API to manage them. That is, there is no API for resolving the aux
- * buffer's content to the main buffer nor for invalidating the aux buffer's
- * content.
+ /* Disable creation of the miptree's aux buffers in case client has not set
+ * EGL_IMAGE_EXTERNAL_FLUSH_EXT attribute.
*/
irb->mt = intel_miptree_create_for_bo(brw,
image->bo,
@@ -390,7 +388,7 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
image->height,
1,
image->pitch,
- true /*disable_aux_buffers*/);
+ !image->use_flush_external);
if (!irb->mt)
return;
diff --git a/src/mesa/drivers/dri/i965/intel_image.h b/src/mesa/drivers/dri/i965/intel_image.h
index a82cf3b3bd1..f97175651fb 100644
--- a/src/mesa/drivers/dri/i965/intel_image.h
+++ b/src/mesa/drivers/dri/i965/intel_image.h
@@ -82,6 +82,19 @@ struct __DRIimageRec {
uint32_t offsets[3];
struct intel_image_format *planar_format;
+ /**
+ * EXT_image_flush_external
+ *
+ * Boolean value indicates that client is responsible to handle
+ * coherency of EGL access to the EGLImage using EXT_image_flush_external
+ * extension flush|invalidate entrypoints.
+ *
+ * If image was created from a texture or renderbuffer, mt will
+ * point to the mipmap tree so that we can resolve/invalidate it.
+ */
+ bool use_flush_external;
+ struct intel_mipmap_tree *mt;
+
/* particular miptree level */
GLuint width;
GLuint height;
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 9e311f06f45..04e956eb8cf 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -1323,6 +1323,17 @@ intel_miptree_copy_teximage(struct brw_context *brw,
intel_obj->needs_validate = true;
}
+void
+intel_miptree_clear_mcs(struct brw_context *brw,
+ struct intel_mipmap_tree *mt)
+{
+ /* Note: clear value for MCS buffers is all 1's, so we memset to 0xff. */
+ void *data = intel_miptree_map_raw(brw, mt->mcs_mt);
+ memset(data, 0xff, mt->mcs_mt->total_height * mt->mcs_mt->pitch);
+ intel_miptree_unmap_raw(brw, mt->mcs_mt);
+ mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
+}
+
static bool
intel_miptree_alloc_mcs(struct brw_context *brw,
struct intel_mipmap_tree *mt,
@@ -1380,13 +1391,8 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
*
* Since we don't use the MCS buffer for any purpose other than rendering,
* it makes sense to just clear it immediately upon allocation.
- *
- * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
*/
- void *data = intel_miptree_map_raw(brw, mt->mcs_mt);
- memset(data, 0xff, mt->mcs_mt->total_height * mt->mcs_mt->pitch);
- intel_miptree_unmap_raw(brw, mt->mcs_mt);
- mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
+ intel_miptree_clear_mcs(brw, mt);
return mt->mcs_mt;
}
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 07960592e2b..e38ef94e023 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -644,6 +644,10 @@ bool
intel_miptree_wants_hiz_buffer(struct brw_context *brw,
struct intel_mipmap_tree *mt);
+void
+intel_miptree_clear_mcs(struct brw_context *brw,
+ struct intel_mipmap_tree *mt);
+
/**
* \brief Allocate the miptree's embedded HiZ miptree.
* \see intel_mipmap_tree:hiz_mt
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 5a9207af330..9ccc4a0c4f8 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -394,7 +394,8 @@ intel_create_image_from_name(__DRIscreen *screen,
static __DRIimage *
intel_create_image_from_renderbuffer(__DRIcontext *context,
- int renderbuffer, void *loaderPrivate)
+ int renderbuffer, unsigned use,
+ void *loaderPrivate)
{
__DRIimage *image;
struct brw_context *brw = context->driverPrivate;
@@ -414,12 +415,16 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
if (image == NULL)
return NULL;
+ if (use & __DRI_IMAGE_USE_FLUSH_EXTERNAL)
+ image->use_flush_external = true;
+
image->internal_format = rb->InternalFormat;
image->format = rb->Format;
image->offset = 0;
image->data = loaderPrivate;
drm_intel_bo_unreference(image->bo);
image->bo = irb->mt->bo;
+ intel_miptree_reference(&image->mt, irb->mt);
drm_intel_bo_reference(irb->mt->bo);
image->width = rb->Width;
image->height = rb->Height;
@@ -436,6 +441,7 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
unsigned texture, int zoffset,
int level,
unsigned *error,
+ unsigned use,
void *loaderPrivate)
{
__DRIimage *image;
@@ -475,11 +481,15 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
return NULL;
}
+ if (use & __DRI_IMAGE_USE_FLUSH_EXTERNAL)
+ image->use_flush_external = true;
+
image->internal_format = obj->Image[face][level]->InternalFormat;
image->format = obj->Image[face][level]->TexFormat;
image->data = loaderPrivate;
intel_setup_image_from_mipmap_tree(brw, image, iobj->mt, level, zoffset);
image->dri_format = driGLFormatToImageFormat(image->format);
+ intel_miptree_reference(&image->mt, iobj->mt);
image->has_depthstencil = iobj->mt->stencil_mt? true : false;
if (image->dri_format == MESA_FORMAT_NONE) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
@@ -494,6 +504,7 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
static void
intel_destroy_image(__DRIimage *image)
{
+ intel_miptree_release(&image->mt);
drm_intel_bo_unreference(image->bo);
free(image);
}
@@ -802,8 +813,50 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
return image;
}
+/**
+ * External device wants to use the buffer, resolve MCS.
+ */
+static GLboolean
+intel_flush_image_external(__DRIcontext *ctx, __DRIimage *image)
+{
+ struct brw_context *brw = ctx->driverPrivate;
+
+ /* Attempt to flush EGLImage that was created without having
+ * a miptree pointer available. Should we throw an error here?
+ */
+ if (!image->mt)
+ return GL_FALSE;
+
+ intel_miptree_resolve_color(brw, image->mt);
+
+ return GL_TRUE;
+}
+
+/**
+ * Buffer was modified outside of GL by external device, invalidate MCS.
+ */
+static GLboolean
+intel_invalidate_image_external(__DRIcontext *ctx, __DRIimage *image)
+{
+ struct brw_context *brw = ctx->driverPrivate;
+
+ /* Attempt to invalidate EGLImage that was created without having
+ * a miptree pointer available. Should we throw an error here?
+ */
+ if (!image->mt)
+ return GL_FALSE;
+
+ /* No auxillary buffer. */
+ if (!image->mt->mcs_mt)
+ return GL_TRUE;
+
+ intel_miptree_clear_mcs(brw, image->mt);
+
+ return GL_TRUE;
+}
+
static const __DRIimageExtension intelImageExtension = {
- .base = { __DRI_IMAGE, 11 },
+ .base = { __DRI_IMAGE, 12 },
.createImageFromName = intel_create_image_from_name,
.createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
@@ -818,7 +871,9 @@ static const __DRIimageExtension intelImageExtension = {
.createImageFromFds = intel_create_image_from_fds,
.createImageFromDmaBufs = intel_create_image_from_dma_bufs,
.blitImage = NULL,
- .getCapabilities = NULL
+ .getCapabilities = NULL,
+ .flushImageExternal = intel_flush_image_external,
+ .invalidateImageExternal = intel_invalidate_image_external,
};
static int
diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c
index 7952ee5ad88..73d811c65ee 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c
@@ -338,10 +338,8 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
return;
}
- /* Disable creation of the texture's aux buffers because the driver exposes
- * no EGL API to manage them. That is, there is no API for resolving the aux
- * buffer's content to the main buffer nor for invalidating the aux buffer's
- * content.
+ /* Disable creation of the miptree's aux buffers in case client has not set
+ * EGL_IMAGE_EXTERNAL_FLUSH_EXT attribute.
*/
intel_set_texture_image_bo(ctx, texImage, image->bo,
target, image->internal_format,
@@ -349,7 +347,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
image->width, image->height,
image->pitch,
image->tile_x, image->tile_y,
- true /*disable_aux_buffers*/);
+ !image->use_flush_external);
}
/**