diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 06cb653..b1979ac 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -175,7 +175,7 @@ cros_gralloc_driver::cros_gralloc_driver() if (!drv_render_) { drv_loge("Failed to create driver for the 1st device\n"); close(node_fd[0]); - } + } switch (availabe_node) { // only have one render node, is GVT-d/BM/VirtIO case 1: @@ -753,7 +753,7 @@ uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint6 uint32_t resolved_format; uint64_t resolved_use_flags; struct driver *drv = drv_render_; - + drv_resolve_format_and_use_flags(drv, drm_format, use_flags, &resolved_format, &resolved_use_flags); diff --git a/drv.c b/drv.c index c7eeaae..347c3b7 100644 --- a/drv.c +++ b/drv.c @@ -743,11 +743,11 @@ uint32_t drv_resolved_common_drm_format(uint32_t format) case DRM_FORMAT_FLEX_YCbCr_420_888: case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: ret = DRM_FORMAT_NV12; - drv_loge("drv_resolved_common_drm_format: DRM_FORMAT_NV12"); + drv_logi("drv_resolved_common_drm_format: DRM_FORMAT_NV12"); break; case DRM_FORMAT_YVU420_ANDROID: ret = DRM_FORMAT_YVU420; - drv_loge("drv_resolved_common_drm_format: DRM_FORMAT_YVU420"); + drv_logi("drv_resolved_common_drm_format: DRM_FORMAT_YVU420"); break; default: break; diff --git a/drv.h b/drv.h index ac435dc..f786594 100644 --- a/drv.h +++ b/drv.h @@ -146,6 +146,7 @@ struct vma { uint32_t map_flags; int32_t refcount; uint32_t map_strides[DRV_MAX_PLANES]; + bool cpu; void *priv; }; diff --git a/drv_helpers.c b/drv_helpers.c index 6fca864..b36447e 100644 --- a/drv_helpers.c +++ b/drv_helpers.c @@ -522,6 +522,10 @@ void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags) int drv_bo_munmap(struct bo *bo, struct vma *vma) { + if (vma->cpu) { + free(vma->addr); + vma->addr = NULL; + } return munmap(vma->addr, vma->length); } @@ -614,6 +618,45 @@ bool drv_has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier) return false; } +const u_int16_t ytile_width = 16; +const u_int16_t ytile_heigth = 32; +void one_ytile_to_linear(char *src, char *dst, u_int16_t x, u_int16_t y, u_int16_t width, u_int16_t height, uint32_t offset) +{ + // x and y follow linear + u_int32_t count = x + y * width/ytile_width; + + for (int j = 0; j < ytile_width * ytile_heigth; j += ytile_width) { + memcpy(dst + offset + width * ytile_heigth * y + width * j / ytile_width + x * ytile_width, + src + offset + j + ytile_width * ytile_heigth * count, ytile_width); + } +} + +void * ytiled_to_linear(struct bo_metadata meta, void * src) +{ + void* dst = malloc(meta.total_size); + if (NULL == dst) return NULL; + + memset(dst, 0, meta.total_size); + + u_int16_t height = meta.sizes[0] / meta.strides[0]; + // Y + u_int16_t y_hcount = height / ytile_heigth + (height % ytile_heigth != 0); + for (u_int16_t x = 0; x < meta.strides[0]/ytile_width; x++) { + for (u_int16_t y = 0; y < y_hcount; y++) { + one_ytile_to_linear(src, dst, x, y, meta.strides[0], height, 0); + } + } + // UV + u_int16_t uv_hcount = (height/ytile_heigth/2) + (height % (ytile_heigth*2) != 0); + for (u_int16_t x = 0; x < meta.strides[0]/ytile_width; x++) { + for (u_int16_t y = 0; y < uv_hcount; y++) { + one_ytile_to_linear(src, dst, x, y, meta.strides[0], height/2, meta.sizes[0]); + } + } + + return dst; +} + void drv_resolve_format_and_use_flags_helper(struct driver *drv, uint32_t format, uint64_t use_flags, uint32_t *out_format, uint64_t *out_use_flags) diff --git a/drv_helpers.h b/drv_helpers.h index 0ea9ba9..9794d37 100644 --- a/drv_helpers.h +++ b/drv_helpers.h @@ -10,7 +10,9 @@ #include #include "drv.h" +#include "drv_priv.h" #include "drv_array_helpers.h" +#include #ifndef PAGE_SIZE #define PAGE_SIZE 0x1000 @@ -50,4 +52,7 @@ void drv_resolve_format_and_use_flags_helper(struct driver *drv, uint32_t format uint64_t use_flags, uint32_t *out_format, uint64_t *out_use_flags); +void one_ytile_to_linear(char *src, char *dst, u_int16_t x, u_int16_t y, + u_int16_t width, u_int16_t height, uint32_t offset); +void *ytiled_to_linear(struct bo_metadata meta, void * src); #endif diff --git a/gbm.c b/gbm.c index 8dffb14..410a1b2 100644 --- a/gbm.c +++ b/gbm.c @@ -63,7 +63,7 @@ PUBLIC struct gbm_device *gbm_create_device(int fd) } drv_init(gbm->drv, 0); - + return gbm; } diff --git a/i915.c b/i915.c index 4b7595b..44e3457 100644 --- a/i915.c +++ b/i915.c @@ -434,7 +434,7 @@ static int i915_add_combinations(struct driver *drv) if (i915_has_tile4(i915)) { struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4, .priority = 3, - .modifier = I915_FORMAT_MOD_4_TILED }; + .modifier = I915_FORMAT_MOD_4_TILED }; /* Support tile4 NV12 and P010 for libva */ #ifdef I915_SCANOUT_4_TILED const uint64_t nv12_usage = @@ -751,7 +751,7 @@ static int i915_init(struct driver *drv) if (!i915_bo_query_prelim_meminfo(drv, i915)) { i915_bo_query_meminfo(drv, i915); } else { - drv_loge("drv: kernel supports prelim\n"); + drv_logi("drv: kernel supports prelim\n"); } #define FORCE_MEM_PROP "sys.icr.gralloc.force_mem" char prop[PROPERTY_VALUE_MAX]; @@ -759,7 +759,7 @@ static int i915_init(struct driver *drv) property_get(FORCE_MEM_PROP, prop, "local") > 0 && !strcmp(prop, "local"); if (i915->force_mem_local) { - drv_loge("Force to use local memory"); + drv_logi("Force to use local memory"); } memset(&get_param, 0, sizeof(get_param)); @@ -789,9 +789,9 @@ static int i915_init(struct driver *drv) uint64_t width = 0, height = 0; if (drmGetCap(drv->fd, DRM_CAP_CURSOR_WIDTH, &width)) { - drv_loge("cannot get cursor width. \n"); + drv_logi("cannot get cursor width. \n"); } else if (drmGetCap(drv->fd, DRM_CAP_CURSOR_HEIGHT, &height)) { - drv_loge("cannot get cursor height. \n"); + drv_logi("cannot get cursor height. \n"); } if (!width) @@ -1082,7 +1082,7 @@ static int i915_bo_create_from_metadata(struct bo *bo) struct i915_device *i915 = bo->drv->priv; int64_t use_flags = bo->meta.use_flags; bool local = is_need_local(use_flags); - + if (local && i915->has_local_mem) { if (!is_prelim_kernel) { /* All new BOs we get from the kernel are zeroed, so we don't need to @@ -1255,6 +1255,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags) int ret; void *addr = MAP_FAILED; struct i915_device *i915 = bo->drv->priv; + vma->cpu = false; if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) || (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) || @@ -1298,12 +1299,26 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags) return MAP_FAILED; } - drv_loge("%s : %d : handle = %x, size = %zd, mmpa_arg.offset = %llx", __func__, + drv_logi("%s : %d : handle = %x, size = %zd, mmpa_arg.offset = %llx", __func__, __LINE__, mmap_arg.handle, bo->meta.total_size, mmap_arg.offset); /* And map it */ addr = mmap(0, bo->meta.total_size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->drv->fd, mmap_arg.offset); + + // TODO: GEM_MMAP_OFFSET cannot convert ytiled to linear, we have to convert it manually. + // Other formats(e.g. I915_TILING_X) should also be converted. + if ((bo->meta.use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) && + (bo->meta.tiling == I915_TILING_Y)) { + void* tmp_addr = ytiled_to_linear(bo->meta, addr); + + if (NULL != tmp_addr) { + // release original one and replace it with a linear address. + munmap(addr, bo->meta.total_size); + addr = tmp_addr; + vma->cpu = true; + } + } } else if (bo->meta.tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map = { 0 }; /* TODO(b/118799155): We don't seem to have a good way to @@ -1379,7 +1394,7 @@ static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) int ret; struct drm_i915_gem_set_domain set_domain = { 0 }; struct i915_device *i915_dev = (struct i915_device *)bo->drv->priv; - + if (i915_dev->graphics_version != 125) { set_domain.handle = bo->handles[0].u32; if (bo->meta.tiling == I915_TILING_NONE) {