[PATCH 5/9] etnaviv: create optional 2d pipe in screen

Lucas Stach l.stach at pengutronix.de
Mon Jul 9 16:02:36 UTC 2018


The 2D pipe is useful to implement fast planar and interleaved YUV buffer
imports. Not all systems have a 2D capable core, so this is strictly
optional.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 src/gallium/drivers/etnaviv/etnaviv_context.c |  6 ++
 src/gallium/drivers/etnaviv/etnaviv_context.h |  1 +
 src/gallium/drivers/etnaviv/etnaviv_screen.c  | 68 +++++++++++++++++++
 src/gallium/drivers/etnaviv/etnaviv_screen.h  |  6 ++
 4 files changed, 81 insertions(+)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index 3038d210e109..96cf2f3b59a8 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -72,6 +72,9 @@ etna_context_destroy(struct pipe_context *pctx)
    if (ctx->stream)
       etna_cmd_stream_del(ctx->stream);
 
+   if (ctx->stream2d)
+      etna_cmd_stream_del(ctx->stream2d);
+
    slab_destroy_child(&ctx->transfer_pool);
 
    if (ctx->in_fence_fd != -1)
@@ -431,6 +434,9 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    if (ctx->stream == NULL)
       goto fail;
 
+   if (screen->pipe2d)
+      ctx->stream2d = etna_cmd_stream_new(screen->pipe2d, 0x1000, NULL, NULL);
+
    /* context ctxate setup */
    ctx->specs = screen->specs;
    ctx->screen = screen;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h
index 584caa77080b..ef2752c61456 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.h
@@ -109,6 +109,7 @@ struct etna_context {
    struct etna_specs specs;
    struct etna_screen *screen;
    struct etna_cmd_stream *stream;
+   struct etna_cmd_stream *stream2d;
 
    /* which state objects need to be re-emit'd: */
    enum {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
index 04c7a873de65..2c975084f08f 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
@@ -90,6 +90,12 @@ etna_screen_destroy(struct pipe_screen *pscreen)
    if (screen->gpu)
       etna_gpu_del(screen->gpu);
 
+   if (screen->pipe2d)
+      etna_pipe_del(screen->pipe2d);
+
+   if (screen->gpu2d)
+      etna_gpu_del(screen->gpu2d);
+
    if (screen->ro)
       FREE(screen->ro);
 
@@ -877,6 +883,66 @@ etna_screen_bo_from_handle(struct pipe_screen *pscreen,
    return bo;
 }
 
+static void etna_screen_init_2d(struct etna_screen *screen)
+{
+   struct etna_gpu *gpu2d = NULL;
+   uint64_t val;
+   int ret, i;
+
+   /* If the current GPU is a combined 2d/3D core, use it as 2D engine */
+   if (screen->features[0] & chipFeatures_PIPE_2D)
+      gpu2d = screen->gpu;
+
+   /* otherwise search for a 2D capable core */
+   if (!gpu2d) {
+      for (i = 0;; i++) {
+         gpu2d = etna_gpu_new(screen->dev, i);
+         if (!gpu2d)
+            return;
+
+         ret = etna_gpu_get_param(gpu2d, ETNA_GPU_FEATURES_0, &val);
+         if (!ret && (val & chipFeatures_PIPE_2D)) {
+            screen->gpu2d = gpu2d;
+            break;
+         }
+
+         etna_gpu_del(gpu2d);
+      }
+   }
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_0, &val))
+      return;
+   screen->features2d[0] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_1, &val))
+      return;
+   screen->features2d[1] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_2, &val))
+      return;
+   screen->features2d[2] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_3, &val))
+      return;
+   screen->features2d[3] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_4, &val))
+      return;
+   screen->features2d[4] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_5, &val))
+      return;
+   screen->features2d[5] = val;
+
+   if (etna_gpu_get_param(screen->gpu2d, ETNA_GPU_FEATURES_6, &val))
+      return;
+   screen->features2d[6] = val;
+
+   screen->pipe2d = etna_pipe_new(gpu2d, ETNA_PIPE_2D);
+   if (!screen->pipe2d)
+      DBG("could not create 2d pipe");
+}
+
 struct pipe_screen *
 etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
                    struct renderonly *ro)
@@ -970,6 +1036,8 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
    }
    screen->features[6] = val;
 
+   etna_screen_init_2d(screen);
+
    if (!etna_get_specs(screen))
       goto fail;
 
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.h b/src/gallium/drivers/etnaviv/etnaviv_screen.h
index bffd4b6ef94a..f529d337ea1d 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.h
@@ -58,6 +58,9 @@ enum viv_features_word {
 #define VIV_FEATURE(screen, word, feature) \
    ((screen->features[viv_ ## word] & (word ## _ ## feature)) != 0)
 
+#define VIV_2D_FEATURE(screen, word, feature) \
+   ((screen->features2d[viv_ ## word] & (word ## _ ## feature)) != 0)
+
 struct etna_screen {
    struct pipe_screen base;
 
@@ -66,7 +69,9 @@ struct etna_screen {
 
    struct etna_device *dev;
    struct etna_gpu *gpu;
+   struct etna_gpu *gpu2d;
    struct etna_pipe *pipe;
+   struct etna_pipe *pipe2d;
    struct etna_perfmon *perfmon;
    struct renderonly *ro;
 
@@ -76,6 +81,7 @@ struct etna_screen {
    uint32_t model;
    uint32_t revision;
    uint32_t features[VIV_FEATURES_WORD_COUNT];
+   uint32_t features2d[VIV_FEATURES_WORD_COUNT];
 
    struct etna_specs specs;
 
-- 
2.18.0



More information about the etnaviv mailing list