[Mesa-dev] [PATCH 6/6] st/dri: implement createImageFromRenderbuffer(2)

Nicolai Hähnle nhaehnle at gmail.com
Fri Oct 6 20:16:08 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Tested with dEQP-EGL tests.
---
 src/gallium/state_trackers/dri/dri2.c        |  8 +++-
 src/gallium/state_trackers/dri/dri_helpers.c | 65 +++++++++++++++++++++++++---
 src/gallium/state_trackers/dri/dri_helpers.h |  5 +++
 src/mesa/state_tracker/st_cb_fbo.h           |  5 +++
 4 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 86721747878..324e357c358 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -1554,38 +1554,44 @@ dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data)
 static int
 dri2_get_capabilities(__DRIscreen *_screen)
 {
    struct dri_screen *screen = dri_screen(_screen);
 
    return (screen->can_share_buffer ? __DRI_IMAGE_CAP_GLOBAL_NAMES : 0);
 }
 
 /* The extension is modified during runtime if DRI_PRIME is detected */
 static __DRIimageExtension dri2ImageExtension = {
-    .base = { __DRI_IMAGE, 15 },
+    .base = { __DRI_IMAGE, 17 },
 
     .createImageFromName          = dri2_create_image_from_name,
     .createImageFromRenderbuffer  = dri2_create_image_from_renderbuffer,
     .destroyImage                 = dri2_destroy_image,
     .createImage                  = dri2_create_image,
     .queryImage                   = dri2_query_image,
     .dupImage                     = dri2_dup_image,
     .validateUsage                = dri2_validate_usage,
     .createImageFromNames         = dri2_from_names,
     .fromPlanar                   = dri2_from_planar,
     .createImageFromTexture       = dri2_create_from_texture,
     .createImageFromFds           = NULL,
     .createImageFromDmaBufs       = NULL,
     .blitImage                    = dri2_blit_image,
     .getCapabilities              = dri2_get_capabilities,
     .mapImage                     = dri2_map_image,
     .unmapImage                   = dri2_unmap_image,
+    .createImageWithModifiers     = NULL,
+    .createImageFromDmaBufs2      = NULL,
+    .queryDmaBufFormats           = NULL,
+    .queryDmaBufModifiers         = NULL,
+    .queryDmaBufFormatModifierAttribs = NULL,
+    .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2,
 };
 
 static const __DRIrobustnessExtension dri2Robustness = {
    .base = { __DRI2_ROBUSTNESS, 1 }
 };
 
 static int
 dri2_interop_query_device_info(__DRIcontext *_ctx,
                                struct mesa_glinterop_device_info *out)
 {
diff --git a/src/gallium/state_trackers/dri/dri_helpers.c b/src/gallium/state_trackers/dri/dri_helpers.c
index 07c4086310d..06309d8f0ce 100644
--- a/src/gallium/state_trackers/dri/dri_helpers.c
+++ b/src/gallium/state_trackers/dri/dri_helpers.c
@@ -18,20 +18,21 @@
  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dlfcn.h>
 #include "util/u_memory.h"
 #include "pipe/p_screen.h"
 #include "state_tracker/st_texture.h"
 #include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_fbo.h"
 #include "main/texobj.h"
 
 #include "dri_helpers.h"
 
 static bool
 dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
 {
    return screen->opencl_dri_event_add_ref &&
           screen->opencl_dri_event_release &&
           screen->opencl_dri_event_wait &&
@@ -239,30 +240,82 @@ dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
    if (!loader->lookupEGLImage)
       return NULL;
 
    img = loader->lookupEGLImage(screen->sPriv,
 				handle, screen->sPriv->loaderPrivate);
 
    return img;
 }
 
 __DRIimage *
-dri2_create_image_from_renderbuffer(__DRIcontext *context,
-				    int renderbuffer, void *loaderPrivate)
+dri2_create_image_from_renderbuffer2(__DRIcontext *context,
+				     int renderbuffer, void *loaderPrivate,
+                                     unsigned *error)
 {
-   struct dri_context *ctx = dri_context(context);
+   struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx;
+   struct gl_renderbuffer *rb;
+   struct pipe_resource *tex;
+   __DRIimage *img;
+
+   /* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5
+    * specification says:
+    *
+    *   "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a
+    *    renderbuffer object, or if buffer is the name of a multisampled
+    *    renderbuffer object, the error EGL_BAD_PARAMETER is generated."
+    *
+    *   "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*,
+    *    EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the
+    *    default GL texture object (0) for the corresponding GL target, the
+    *    error EGL_BAD_PARAMETER is generated."
+    *   (rely on _mesa_lookup_renderbuffer returning NULL in this case)
+    */
+   rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+   if (!rb || rb->NumSamples > 0) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      return NULL;
+   }
+
+   tex = st_get_renderbuffer_resource(rb);
+   if (!tex) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      return NULL;
+   }
+
+   img = CALLOC_STRUCT(__DRIimageRec);
+   if (!img) {
+      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+      return NULL;
+   }
 
-   if (!ctx->st->get_resource_for_egl_image)
+   img->dri_format = driGLFormatToImageFormat(rb->Format);
+   img->loader_private = loaderPrivate;
+
+   if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      free(img);
       return NULL;
+   }
+
+   pipe_resource_reference(&img->texture, tex);
+
+   *error = __DRI_IMAGE_ERROR_SUCCESS;
+   return img;
+}
 
-   /* TODO */
-   return NULL;
+__DRIimage *
+dri2_create_image_from_renderbuffer(__DRIcontext *context,
+				    int renderbuffer, void *loaderPrivate)
+{
+   unsigned error;
+   return dri2_create_image_from_renderbuffer2(context, renderbuffer,
+                                               loaderPrivate, &error);
 }
 
 void
 dri2_destroy_image(__DRIimage *img)
 {
    pipe_resource_reference(&img->texture, NULL);
    FREE(img);
 }
 
 
diff --git a/src/gallium/state_trackers/dri/dri_helpers.h b/src/gallium/state_trackers/dri/dri_helpers.h
index 59d903875d3..76f024fd67c 100644
--- a/src/gallium/state_trackers/dri/dri_helpers.h
+++ b/src/gallium/state_trackers/dri/dri_helpers.h
@@ -28,20 +28,25 @@
 
 extern const __DRI2fenceExtension dri2FenceExtension;
 
 __DRIimage *
 dri2_lookup_egl_image(struct dri_screen *screen, void *handle);
 
 __DRIimage *
 dri2_create_image_from_renderbuffer(__DRIcontext *context,
 				    int renderbuffer, void *loaderPrivate);
 
+__DRIimage *
+dri2_create_image_from_renderbuffer2(__DRIcontext *context,
+				     int renderbuffer, void *loaderPrivate,
+                                     unsigned *error);
+
 void
 dri2_destroy_image(__DRIimage *img);
 
 __DRIimage *
 dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
                          int depth, int level, unsigned *error,
                          void *loaderPrivate);
 #endif
 
 /* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 239bfd95e96..ed68875639d 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -72,20 +72,25 @@ struct st_renderbuffer
    boolean rtt_layered; /**< whether glFramebufferTexture was called */
 };
 
 
 static inline struct st_renderbuffer *
 st_renderbuffer(struct gl_renderbuffer *rb)
 {
    return (struct st_renderbuffer *) rb;
 }
 
+static inline struct pipe_resource *
+st_get_renderbuffer_resource(struct gl_renderbuffer *rb)
+{
+   return st_renderbuffer(rb)->texture;
+}
 
 /**
  * Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer.
  * Return NULL if the struct gl_framebuffer is a user-created framebuffer.
  * We'll only return non-null for window system framebuffers.
  * Note that this function may fail.
  */
 static inline struct st_framebuffer *
 st_ws_framebuffer(struct gl_framebuffer *fb)
 {
-- 
2.11.0



More information about the mesa-dev mailing list