summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <spyffe@google.com>2021-04-23 15:57:18 -0700
committerSean Callanan <spyffe@google.com>2021-05-11 14:39:31 -0700
commitc33cf706f22de15b77096beb1d01df842c4f1db5 (patch)
treed59a2bda9a1ff2236b74b54614bd1fd1ef595b25
parentb3c940a9d7497ba2e1d784a38998028e1ed09e74 (diff)
downloadgchips-c33cf706f22de15b77096beb1d01df842c4f1db5.tar.gz
gralloc4: align buffers for the GPU to 64 bytes
The camera requires 64-byte stride alignment for a variety of formats. Set this alignment if GPU usage is detected. Test: Boot, use viewfinder Bug: 185836979 Bug: 185065640 Bug: 184793812 Change-Id: I96a5abf5465fb583d5f3393dece431d3b60a2cdb
-rw-r--r--gralloc4/src/core/format_info.cpp6
-rw-r--r--gralloc4/src/core/format_info.h4
-rw-r--r--gralloc4/src/core/mali_gralloc_bufferallocation.cpp68
-rw-r--r--include/exynos_format.h25
-rw-r--r--libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp21
5 files changed, 94 insertions, 30 deletions
diff --git a/gralloc4/src/core/format_info.cpp b/gralloc4/src/core/format_info.cpp
index fedb9ff..1a8c92e 100644
--- a/gralloc4/src/core/format_info.cpp
+++ b/gralloc4/src/core/format_info.cpp
@@ -438,12 +438,6 @@ void get_format_dataspace(uint32_t base_format,
}
-bool is_power2(uint8_t n)
-{
- return ((n & (n-1)) == 0);
-}
-
-
bool sanitize_formats(void)
{
bool fail = false;
diff --git a/gralloc4/src/core/format_info.h b/gralloc4/src/core/format_info.h
index 9882187..ad2db6d 100644
--- a/gralloc4/src/core/format_info.h
+++ b/gralloc4/src/core/format_info.h
@@ -39,6 +39,10 @@ typedef struct
uint16_t height;
} rect_t;
+constexpr bool is_power2(uint8_t n)
+{
+ return ((n & (n-1)) == 0);
+}
/*
* Pixel format information.
diff --git a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp
index d0f2410..7defdde 100644
--- a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp
+++ b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp
@@ -41,6 +41,9 @@
#define YUV_BYTE_ALIGN_DEFAULT 16
#define RGB_BYTE_ALIGN_DEFAULT 64
+/* IP-specific align values */
+#define GPU_BYTE_ALIGN_DEFAULT 64
+
/* Always CPU align for Exynos */
#define CAN_SKIP_CPU_ALIGN 0
@@ -486,6 +489,11 @@ static uint64_t update_usage_for_BO(uint64_t usage) {
return usage;
}
+static void align_plane_stride(plane_info_t *plane_info, int plane, const format_info_t format, uint32_t stride_align)
+{
+ plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride * format.tile_size, stride_align) / format.tile_size;
+ plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane];
+}
/*
* Calculate allocation size.
@@ -509,6 +517,7 @@ static void calc_allocation_size(const int width,
const format_info_t format,
const bool has_cpu_usage,
const bool has_hw_usage,
+ const bool has_gpu_usage,
int * const pixel_stride,
uint64_t * const size,
plane_info_t plane_info[MAX_PLANES])
@@ -557,11 +566,27 @@ static void calc_allocation_size(const int width,
uint16_t hw_align = 0;
if (has_hw_usage)
{
+ static_assert(is_power2(YUV_BYTE_ALIGN_DEFAULT),
+ "YUV_BYTE_ALIGN_DEFAULT is not a power of 2");
+ static_assert(is_power2(RGB_BYTE_ALIGN_DEFAULT),
+ "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
+
hw_align = format.is_yuv ?
YUV_BYTE_ALIGN_DEFAULT :
(format.is_rgb ? RGB_BYTE_ALIGN_DEFAULT : 0);
}
+ if (has_gpu_usage)
+ {
+ static_assert(is_power2(GPU_BYTE_ALIGN_DEFAULT),
+ "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
+
+ /*
+ * The GPU requires stricter alignment on YUV and raw formats.
+ */
+ hw_align = std::max(hw_align, static_cast<uint16_t>(GPU_BYTE_ALIGN_DEFAULT));
+ }
+
uint32_t cpu_align = 0;
#if CAN_SKIP_CPU_ALIGN == 1
@@ -579,8 +604,7 @@ static void calc_allocation_size(const int width,
uint32_t stride_align = lcm(hw_align, cpu_align);
if (stride_align)
{
- plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride * format.tile_size, stride_align) / format.tile_size;
- plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane];
+ align_plane_stride(plane_info, plane, format, stride_align);
}
#if REALIGN_YV12 == 1
@@ -719,7 +743,8 @@ static bool validate_format(const format_info_t * const format,
}
static int prepare_descriptor_exynos_formats(
- buffer_descriptor_t *bufDescriptor)
+ buffer_descriptor_t *bufDescriptor,
+ format_info_t format_info)
{
int fd_count = 1;
int w = bufDescriptor->width;
@@ -865,6 +890,40 @@ static int prepare_descriptor_exynos_formats(
plane_info_t *plane = bufDescriptor->plane_info;
+ if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER))
+ {
+ if (is_sbwc_format(format))
+ {
+ MALI_GRALLOC_LOGE("using SBWC format (%s %" PRIx64 ") with GPU is invalid",
+ format_name(bufDescriptor->alloc_format),
+ bufDescriptor->alloc_format);
+ return -1;
+ }
+ else
+ {
+ /*
+ * The GPU requires stricter alignment on YUV formats.
+ */
+ for (int pidx = 0; pidx < plane_count; ++pidx)
+ {
+ if (plane[pidx].size == plane[pidx].byte_stride * plane[pidx].alloc_height)
+ {
+ align_plane_stride(plane, pidx, format_info, GPU_BYTE_ALIGN_DEFAULT);
+ plane[pidx].size = plane[pidx].byte_stride * plane[pidx].alloc_height;
+ }
+ else
+ {
+ MALI_GRALLOC_LOGE("buffer with format (%s %" PRIx64
+ ") has size %" PRIu64
+ " != byte_stride %" PRIu32 " * alloc_height %" PRIu32,
+ format_name(bufDescriptor->alloc_format),
+ bufDescriptor->alloc_format,
+ plane[pidx].size, plane[pidx].byte_stride, plane[pidx].alloc_height);
+ }
+ }
+ }
+ }
+
for (int fidx = 0; fidx < fd_count; fidx++)
{
uint64_t size = 0;
@@ -945,7 +1004,7 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto
if (is_exynos_format(bufDescriptor->alloc_format))
{
- prepare_descriptor_exynos_formats(bufDescriptor);
+ prepare_descriptor_exynos_formats(bufDescriptor, formats[format_idx]);
}
else
{
@@ -967,6 +1026,7 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto
formats[format_idx],
usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
+ usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER),
&bufDescriptor->pixel_stride,
&bufDescriptor->alloc_sizes[0],
bufDescriptor->plane_info);
diff --git a/include/exynos_format.h b/include/exynos_format.h
index 773e58b..6e4807e 100644
--- a/include/exynos_format.h
+++ b/include/exynos_format.h
@@ -105,6 +105,31 @@ enum {
HAL_PIXEL_FORMAT_GOOGLE_MAX,
};
+static inline int is_sbwc_format(uint32_t format)
+{
+ switch (format) {
+ default:
+ return 0;
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
+ case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
+ return 1;
+ }
+}
+
/* for backward compatibility */
#define HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M
#define HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M
diff --git a/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp b/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp
index 8893ec1..3305004 100644
--- a/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp
+++ b/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp
@@ -98,26 +98,7 @@ int VendorGraphicBufferMeta::is_sbwc(buffer_handle_t buffer_hnd_p)
{
const private_handle_t *hnd = static_cast<const private_handle_t *>(buffer_hnd_p);
- switch (static_cast<uint32_t>(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK)) {
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
- return true;
- }
- return false;
+ return is_sbwc_format(static_cast<uint32_t>(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK));
}
#define GRALLOC_META_GETTER(__type__, __name__, __member__) \