summaryrefslogtreecommitdiff
path: root/gralloc4/src
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 /gralloc4/src
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
Diffstat (limited to 'gralloc4/src')
-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
3 files changed, 68 insertions, 10 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);