summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXuelian Bai <xuelian.bai@samsung.com>2019-01-31 01:48:07 +0800
committerXuelian Bai <xuelian.bai@samsung.com>2019-06-05 18:40:17 +0800
commite3680281fe46c813c52defa00a2de76dace2ead6 (patch)
tree83ec8c90fb1cff36c3a03196e2c9e4b04bbeb8b9
parent92cefc86263ebe05353c3275515be7c5ccbb857e (diff)
downloadlibtbm-vc4-e3680281fe46c813c52defa00a2de76dace2ead6.tar.gz
libtbm-vc4-e3680281fe46c813c52defa00a2de76dace2ead6.tar.bz2
libtbm-vc4-e3680281fe46c813c52defa00a2de76dace2ead6.zip
Add function for tiled format
Change-Id: I3e283a29fca3b8b4800ddb05822f83f73c52350a
-rw-r--r--src/tbm_bufmgr_vc4.c163
1 files changed, 162 insertions, 1 deletions
diff --git a/src/tbm_bufmgr_vc4.c b/src/tbm_bufmgr_vc4.c
index 1b0009b..6dc364b 100644
--- a/src/tbm_bufmgr_vc4.c
+++ b/src/tbm_bufmgr_vc4.c
@@ -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);