diff options
author | Tapani Pälli <tapani.palli@intel.com> | 2015-04-14 09:00:17 +0300 |
---|---|---|
committer | Tapani Pälli <tapani.palli@intel.com> | 2015-04-16 13:16:40 +0300 |
commit | 8316f6019884d1f76b186d7c02c6e9ecd151be5d (patch) | |
tree | b2d3c279c040ecb9d2fa2b6a5285f864fa727501 | |
parent | f78b2c432f31a18794b9f62f0a0cfb8eca256151 (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.h | 15 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 49 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11.c | 1 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 108 | ||||
-rw-r--r-- | src/egl/main/eglapi.h | 6 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 2 | ||||
-rw-r--r-- | src/egl/main/eglfallbacks.c | 3 | ||||
-rw-r--r-- | src/egl/main/eglimage.c | 10 | ||||
-rw-r--r-- | src/egl/main/eglimage.h | 3 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri2.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_fbo.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_image.h | 13 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_screen.c | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_tex_image.c | 8 |
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); } /** |