Add function for tiled format 43/198843/5
authorXuelian Bai <xuelian.bai@samsung.com>
Wed, 30 Jan 2019 17:48:07 +0000 (01:48 +0800)
committerXuelian Bai <xuelian.bai@samsung.com>
Wed, 5 Jun 2019 10:40:17 +0000 (18:40 +0800)
Change-Id: I3e283a29fca3b8b4800ddb05822f83f73c52350a

src/tbm_bufmgr_vc4.c

index 1b0009b..6dc364b 100644 (file)
@@ -1001,6 +1001,152 @@ tbm_vc4_bufmgr_get_supported_formats(tbm_backend_bufmgr_data *bufmgr_data,
        return TBM_ERROR_NONE;
 }
 
+//#define VC4_TILED_FORMAT 1
+
+#ifdef VC4_TILED_FORMAT
+#include <drm_fourcc.h>
+static inline uint32_t
+vc4_utile_width(int cpp)
+{
+       switch (cpp) {
+       case 1:
+       case 2:
+               return 8;
+       case 4:
+               return 4;
+       case 8:
+               return 2;
+       default:
+               return 4;
+       }
+}
+
+static inline uint32_t
+vc4_utile_height(int cpp)
+{
+       switch (cpp) {
+       case 1:
+               return 8;
+       case 2:
+       case 4:
+       case 8:
+               return 4;
+       default:
+               return 4;
+       }
+}
+
+static inline bool
+vc4_size_is_lt(uint32_t width, uint32_t height, int cpp)
+{
+       return (width <= 4 * vc4_utile_width(cpp) ||
+                               height <= 4 * vc4_utile_height(cpp));
+}
+
+static tbm_backend_bo_data *
+tbm_vc4_bufmgr_alloc_bo_with_tiled_format(tbm_backend_bufmgr_data *bufmgr_data, int width, int height,
+                       int cpp, int format, tbm_bo_memory_type flags, int bo_idx, tbm_error_e *err)
+{
+       tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data;
+       tbm_bo_vc4 bo_vc4;
+       uint32_t utile_w = vc4_utile_width(cpp);
+       uint32_t utile_h = vc4_utile_height(cpp);
+       uint32_t level_width, level_height;
+       int size;
+       uint32_t stride;
+
+
+       level_width = width;
+       level_height = height;
+
+       if (bufmgr_vc4 == NULL) {
+               TBM_ERR("bufmgr_data is null\n");
+               return NULL;
+       }
+
+       if (vc4_size_is_lt(level_width, level_height, cpp)) {
+               level_width = SIZE_ALIGN(level_width, utile_w);
+               level_height = SIZE_ALIGN(level_height, utile_h);
+       } else {
+               level_width = SIZE_ALIGN(level_width,
+                                       4 * 2 * utile_w);
+               level_height = SIZE_ALIGN(level_height,
+                                       4 * 2 * utile_h);
+       }
+
+       stride = level_width * cpp;
+
+       size = level_height * stride;
+       size = SIZE_ALIGN(size, 4096);
+
+
+       bo_vc4 = calloc(1, sizeof(struct _tbm_bo_vc4));
+       if (!bo_vc4) {
+               TBM_ERR("fail to allocate the bo_vc4 private\n");
+               return NULL;
+       }
+       bo_vc4->bufmgr_vc4 = bufmgr_vc4;
+
+       struct drm_vc4_create_bo arg = {0, };
+
+       arg.size = (__u32)size;
+       arg.flags = flags;/*currently no values for the flags,but it may be used in future extension*/
+       if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_VC4_CREATE_BO, &arg)) {
+               TBM_ERR("Cannot create bo_vc4(flag:%x, size:%d)\n", arg.flags,
+                                       (unsigned int)arg.size);
+               free(bo_vc4);
+               return NULL;
+       }
+
+       bo_vc4->fd = bufmgr_vc4->fd;
+       bo_vc4->gem = (unsigned int)arg.handle;
+       bo_vc4->size = size;
+       bo_vc4->flags_tbm = flags;
+       bo_vc4->name = _get_name(bo_vc4->fd, bo_vc4->gem);
+
+       if (!_bo_init_cache_state(bufmgr_vc4, bo_vc4, 0)) {
+               TBM_ERR("fail init cache state(%d)\n", bo_vc4->name);
+               free(bo_vc4);
+               return NULL;
+       }
+
+       pthread_mutex_init(&bo_vc4->mutex, NULL);
+
+       if (bufmgr_vc4->use_dma_fence && !bo_vc4->dmabuf) {
+               struct drm_prime_handle arg = {0, };
+
+               arg.handle = bo_vc4->gem;
+               if (drmIoctl(bo_vc4->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) {
+                       TBM_ERR("Cannot dmabuf=%d\n", bo_vc4->gem);
+                       free(bo_vc4);
+                       return NULL;
+               }
+               bo_vc4->dmabuf = arg.fd;
+       }
+
+       //set modifier
+       uint64_t modifier;
+       modifier = DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED;
+       struct drm_vc4_set_tiling set_tiling = {
+               .handle = bo_vc4->gem,
+               .modifier = modifier,
+       };
+       drmIoctl(bo_vc4->fd, DRM_IOCTL_VC4_SET_TILING, &set_tiling);
+
+
+       /* add bo_vc4 to hash */
+       if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, (void *)bo_vc4) < 0)
+         TBM_ERR("Cannot insert bo_vc4 to Hash(%d)\n", bo_vc4->name);
+
+       TBM_DBG("     bo_vc4:%p, gem:%d(%d), flags:%d(%d), size:%d\n",
+                               bo_vc4,
+                               bo_vc4->gem, bo_vc4->name,
+                               bo_vc4->flags_tbm,
+                               bo_vc4->size);
+
+       return (tbm_backend_bo_data *)bo_vc4;
+}
+#endif
 static tbm_error_e
 tbm_vc4_bufmgr_get_plane_data(tbm_backend_bufmgr_data *bufmgr_data,
                                                        tbm_format format, int plane_idx, int width,
@@ -1061,6 +1207,17 @@ tbm_vc4_bufmgr_get_plane_data(tbm_backend_bufmgr_data *bufmgr_data,
        case TBM_FORMAT_BGRA8888:
                bpp = 32;
                _offset = 0;
+#ifdef VC4_TILED_FORMAT
+               if (vc4_size_is_lt(width, height, 4)) {
+                       width = SIZE_ALIGN(width, vc4_utile_width(4));
+                       height = SIZE_ALIGN(height, vc4_utile_height(4));
+
+               } else {
+                       width = SIZE_ALIGN(width, 32);
+                       uint32_t utile_h = vc4_utile_height(bpp);
+                       height = SIZE_ALIGN(height, 8*utile_h);
+               }
+#endif
                _pitch = SIZE_ALIGN((width * bpp) >> 3, TBM_SURFACE_ALIGNMENT_PITCH_RGB);
                _size = SIZE_ALIGN(_pitch * height, TBM_SURFACE_ALIGNMENT_PLANE);
                _bo_idx = 0;
@@ -2195,7 +2352,11 @@ tbm_vc4_init(tbm_bufmgr bufmgr, tbm_error_e *error)
        bufmgr_func->bufmgr_alloc_bo_with_format = NULL;
        bufmgr_func->bufmgr_import_fd = tbm_vc4_bufmgr_import_fd;
        bufmgr_func->bufmgr_import_key = tbm_vc4_bufmgr_import_key;
-
+#ifdef VC4_TILED_FORMAT
+       bufmgr_func->bufmgr_alloc_bo_with_tiled_format =  tbm_vc4_bufmgr_alloc_bo_with_tiled_format;
+#else
+       bufmgr_func->bufmgr_alloc_bo_with_tiled_format = NULL;
+#endif
        err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func);
        if (err != TBM_ERROR_NONE) {
                TBM_ERR("fail to register bufmgr_func! err(%d)\n", err);