diff options
-rw-r--r-- | OWNERS | 2 | ||||
-rw-r--r-- | common.mk | 2 | ||||
-rw-r--r-- | cros_gralloc/aidl/Allocator.h | 2 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_driver.cc | 10 | ||||
-rw-r--r-- | cros_gralloc/cros_gralloc_driver.h | 5 | ||||
-rw-r--r-- | cros_gralloc/gralloc0/gralloc0.cc | 2 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Allocator.h | 4 | ||||
-rw-r--r-- | cros_gralloc/gralloc4/CrosGralloc4Mapper.h | 4 | ||||
-rw-r--r-- | cros_gralloc/mapper_stablec/Mapper.cpp | 4 | ||||
-rw-r--r-- | drv.c | 9 | ||||
-rw-r--r-- | i915.c | 135 |
11 files changed, 131 insertions, 48 deletions
@@ -13,7 +13,7 @@ zzyiwei@chromium.org # just reference for backend specific reviews per-file amdgpu.c = basni@chromium.org, ddavenport@chromium.org -per-file i915.c = chadversary@chromium.org, hoegsberg@chromium.org +per-file i915.c = chadversary@chromium.org, linyaa@google.com, hoegsberg@chromium.org per-file mediatek.c = fshao@chromium.org, hsinyi@chromium.org, tzungbi@chromium.org per-file msm.c = robdclark@chromium.org, hoegsberg@chromium.org per-file rockchip.c = tfiga@chromium.org @@ -314,7 +314,7 @@ COMMON_CFLAGS-clang := -fvisibility=hidden -ggdb COMMON_CFLAGS := -Wall -Werror -fno-strict-aliasing $(SSP_CFLAGS) -O1 -Wformat=2 CXXFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CXXDRIVER)) CFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CDRIVER)) -CPPFLAGS += -D_FORTIFY_SOURCE=2 +CPPFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 # Disable exceptions based on the CXXEXCEPTIONS setting. ifeq ($(CXXEXCEPTIONS),0) diff --git a/cros_gralloc/aidl/Allocator.h b/cros_gralloc/aidl/Allocator.h index 5c12308..ea11eaf 100644 --- a/cros_gralloc/aidl/Allocator.h +++ b/cros_gralloc/aidl/Allocator.h @@ -49,7 +49,7 @@ class Allocator : public BnAllocator { void releaseBufferAndHandle(native_handle_t* handle); - cros_gralloc_driver* mDriver = nullptr; + std::shared_ptr<cros_gralloc_driver> mDriver; }; } // namespace aidl::android::hardware::graphics::allocator::impl diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index e8adf42..550f75a 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -77,16 +77,18 @@ int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserv return reserved_region_fd; } -cros_gralloc_driver *cros_gralloc_driver::get_instance() +std::shared_ptr<cros_gralloc_driver> cros_gralloc_driver::get_instance() { - static cros_gralloc_driver s_instance; + static std::shared_ptr<cros_gralloc_driver> s_instance = []() { + return std::shared_ptr<cros_gralloc_driver>(new cros_gralloc_driver()); + }(); - if (!s_instance.is_initialized()) { + if (!s_instance->is_initialized()) { ALOGE("Failed to initialize driver."); return nullptr; } - return &s_instance; + return s_instance; } static struct driver *init_try_node(int idx, char const *str) diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index 2189c33..1f96178 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -22,7 +22,9 @@ class cros_gralloc_driver { public: - static cros_gralloc_driver *get_instance(); + ~cros_gralloc_driver(); + + static std::shared_ptr<cros_gralloc_driver> get_instance(); bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor); int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor, native_handle_t **out_handle); @@ -53,7 +55,6 @@ class cros_gralloc_driver private: cros_gralloc_driver(); - ~cros_gralloc_driver(); bool is_initialized(); cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd); bool diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index d04d87e..5487128 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -15,7 +15,7 @@ struct gralloc0_module { gralloc_module_t base; std::unique_ptr<alloc_device_t> alloc; - cros_gralloc_driver *driver; + std::shared_ptr<cros_gralloc_driver> driver; bool initialized; std::mutex initialization_mutex; }; diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h index 9c1c783..db7294f 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h @@ -7,6 +7,8 @@ #include <android/hardware/graphics/allocator/4.0/IAllocator.h> #include <android/hardware/graphics/mapper/4.0/IMapper.h> +#include <memory> + #include "cros_gralloc/cros_gralloc_driver.h" #include "cros_gralloc/cros_gralloc_helpers.h" #include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" @@ -30,5 +32,5 @@ class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_ description, uint32_t* outStride, android::hardware::hidl_handle* outHandle); - cros_gralloc_driver* mDriver = nullptr; + std::shared_ptr<cros_gralloc_driver> mDriver; }; diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h index 1734feb..e4422e2 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h @@ -6,6 +6,8 @@ #include <android/hardware/graphics/mapper/4.0/IMapper.h> +#include <memory> + #include "cros_gralloc/cros_gralloc_driver.h" #include "cros_gralloc/cros_gralloc_handle.h" #include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" @@ -97,7 +99,7 @@ class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMa int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat, uint64_t bufferUsage, uint32_t* outDrmFormat); - cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance(); + std::shared_ptr<cros_gralloc_driver> mDriver = cros_gralloc_driver::get_instance(); }; extern "C" android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* name); diff --git a/cros_gralloc/mapper_stablec/Mapper.cpp b/cros_gralloc/mapper_stablec/Mapper.cpp index 6c4ac86..c28d7f9 100644 --- a/cros_gralloc/mapper_stablec/Mapper.cpp +++ b/cros_gralloc/mapper_stablec/Mapper.cpp @@ -15,6 +15,8 @@ #include <cutils/native_handle.h> #include <gralloctypes/Gralloc4.h> +#include <memory> + #include "cros_gralloc/cros_gralloc_driver.h" #include "cros_gralloc/cros_gralloc_handle.h" #include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h" @@ -54,7 +56,7 @@ static bool isStandardMetadata(AIMapper_MetadataType metadataType) { class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl { private: - cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance(); + std::shared_ptr<cros_gralloc_driver> mDriver = cros_gralloc_driver::get_instance(); public: explicit CrosGrallocMapperV5() = default; @@ -753,13 +753,8 @@ void drv_log_prefix(enum drv_log_level level, const char *prefix, const char *fi }; __android_log_vprint(prio, buf, format, args); #else - if (level == DRV_LOGE) { - fprintf(stderr, "%s ", buf); - vfprintf(stderr, format, args); - } else { - fprintf(stdout, "%s ", buf); - vfprintf(stdout, format, args); - } + fprintf(stderr, "%s ", buf); + vfprintf(stderr, format, args); #endif va_end(args); } @@ -37,9 +37,16 @@ static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR }; -static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, - I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, - DRM_FORMAT_MOD_LINEAR }; +static const uint64_t gen12_modifier_order_without_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR }; + +static const uint64_t gen12_modifier_order_with_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, + I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR }; static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR }; @@ -63,6 +70,7 @@ struct i915_device { bool is_mtl; int32_t num_fences_avail; bool has_mmap_offset; + bool is_media_compression_enabled; }; static void i915_info_from_device_id(struct i915_device *i915) @@ -192,8 +200,13 @@ static void i915_get_modifier_order(struct i915_device *i915) i915->modifier.order = xe_lpdp_modifier_order; i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order); } else if (i915->graphics_version == 12) { - i915->modifier.order = gen12_modifier_order; - i915->modifier.count = ARRAY_SIZE(gen12_modifier_order); + if (i915->is_media_compression_enabled) { + i915->modifier.order = gen12_modifier_order_with_mc; + i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_with_mc); + } else { + i915->modifier.order = gen12_modifier_order_without_mc; + i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_without_mc); + } } else if (i915->graphics_version == 11) { i915->modifier.order = gen11_modifier_order; i915->modifier.count = ARRAY_SIZE(gen11_modifier_order); @@ -295,9 +308,14 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(scanout_render_formats), &metadata_4_tiled, scanout_and_render_not_linear); } else { - struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y, - .priority = 3, - .modifier = I915_FORMAT_MOD_Y_TILED }; + struct format_metadata metadata_y_tiled = { + .tiling = I915_TILING_Y, + .priority = 3, + .modifier = + (i915->graphics_version == 12 && i915->is_media_compression_enabled) + ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS + : I915_FORMAT_MOD_Y_TILED + }; /* Support y-tiled NV12 and P010 for libva */ #ifdef I915_SCANOUT_Y_TILED const uint64_t nv12_usage = @@ -311,6 +329,11 @@ static int i915_add_combinations(struct driver *drv) #endif drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage); drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage); + + /* Don't allocate media compressed buffers for formats other than NV12 + * and P010. + */ + metadata_y_tiled.modifier = I915_FORMAT_MOD_Y_TILED; drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_y_tiled, render_not_linear); /* Y-tiled scanout isn't available on old platforms so we add @@ -349,7 +372,12 @@ static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling #else horizontal_alignment = 64; #endif + /* + * For hardware video encoding buffers, we want to align to the size of a + * macroblock, because otherwise we will end up encoding uninitialized data. + * This can result in substantial quality degradations, especially on lower + * resolution videos, because this uninitialized data may be high entropy. * For R8 and height=1, we assume the surface will be used as a linear buffer blob * (such as VkBuffer). The hardware allows vertical_alignment=1 only for non-tiled * 1D surfaces, which covers the VkBuffer case. However, if the app uses the surface @@ -361,7 +389,9 @@ static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling * constraints with GPU_DATA_BUFFER usage when the guest has migrated to use * virtgpu_cross_domain backend which passes that flag through. */ - if (format == DRM_FORMAT_R8 && *aligned_height == 1) { + if (bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) { + vertical_alignment = 8; + } else if (format == DRM_FORMAT_R8 && *aligned_height == 1) { vertical_alignment = 1; } else { vertical_alignment = 4; @@ -429,6 +459,17 @@ static int i915_init(struct driver *drv) if (!i915) return -ENOMEM; + const char *enable_intel_media_compression_env_var = + getenv("ENABLE_INTEL_MEDIA_COMPRESSION"); + if (enable_intel_media_compression_env_var == NULL) { + drv_logd("Failed to get ENABLE_INTEL_MEDIA_COMPRESSION"); + i915->is_media_compression_enabled = false; + } else { + i915->is_media_compression_enabled = + (drv->compression) && + (strcmp(enable_intel_media_compression_env_var, "1") == 0); + } + get_param.param = I915_PARAM_CHIPSET_ID; get_param.value = &(i915->device_id); ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param); @@ -546,6 +587,13 @@ static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format, modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) { assert(num_planes == 1); return 2; + } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) { + assert(drv); + struct i915_device *i915 = drv->priv; + assert(i915 && i915->is_media_compression_enabled); + + assert(num_planes == 2); + return 4; } return num_planes; @@ -606,6 +654,9 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig modifier = DRM_FORMAT_MOD_LINEAR; } + assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || + i915->is_media_compression_enabled); + switch (modifier) { case DRM_FORMAT_MOD_LINEAR: bo->meta.tiling = I915_TILING_NONE; @@ -619,6 +670,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig * IPs(render/media/display) */ case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: bo->meta.tiling = I915_TILING_Y; break; case I915_FORMAT_MOD_4_TILED: @@ -680,8 +732,17 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier); bo->meta.total_size = offset; - } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) { + } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) { + assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || + i915->is_media_compression_enabled); + assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || + (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010)); + assert(drv_num_planes_from_format(format) > 0); + uint32_t offset = 0; + size_t plane = 0; + size_t a_plane = 0; /* * considering only 128 byte compression and one cache line of * aux buffer(64B) contains compression status of 4-Y tiles. @@ -689,32 +750,49 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig * line stride(bytes) is 4 * 128B * and tile stride(lines) is 32L */ - uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512); + for (plane = 0; plane < drv_num_planes_from_format(format); plane++) { + uint32_t stride = ALIGN(drv_stride_from_format(format, width, plane), 512); - height = ALIGN(drv_height_from_format(format, height, 0), 32); + const uint32_t plane_height = drv_height_from_format(format, height, plane); + uint32_t aligned_height = ALIGN(plane_height, 32); - if (i915->is_xelpd && (stride > 1)) { - stride = 1 << (32 - __builtin_clz(stride - 1)); - height = ALIGN(drv_height_from_format(format, height, 0), 128); - } + if (i915->is_xelpd && (stride > 1)) { + stride = 1 << (32 - __builtin_clz(stride - 1)); + aligned_height = ALIGN(plane_height, 128); + } - bo->meta.strides[0] = stride; - /* size calculation and alignment are 64KB aligned - * size as per spec - */ - bo->meta.sizes[0] = ALIGN(stride * height, 65536); - bo->meta.offsets[0] = 0; + bo->meta.strides[plane] = stride; + /* size calculation & alignment are 64KB aligned + * size as per spec + */ + bo->meta.sizes[plane] = ALIGN(stride * aligned_height, 512 * 128); + bo->meta.offsets[plane] = offset; + /* next buffer offset */ + offset += bo->meta.sizes[plane]; + } /* Aux buffer is linear and page aligned. It is placed after * other planes and aligned to main buffer stride. */ - bo->meta.strides[1] = bo->meta.strides[0] / 8; - /* Aligned to page size */ - bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize()); - bo->meta.offsets[1] = bo->meta.sizes[0]; + for (a_plane = 0; a_plane < plane; a_plane++) { + /* Every 64 bytes in the aux plane contain compression information for a + * sub-row of 4 Y tiles of the corresponding main plane, so the pitch in + * bytes of the aux plane should be the pitch of the main plane in units of + * 4 tiles multiplied by 64 (or equivalently, the pitch of the main plane in + * bytes divided by 8). + */ + bo->meta.strides[plane + a_plane] = bo->meta.strides[a_plane] / 8; + /* Aligned to page size */ + bo->meta.sizes[plane + a_plane] = + ALIGN(bo->meta.sizes[a_plane] / 256, 4 * 1024); + bo->meta.offsets[plane + a_plane] = offset; + + /* next buffer offset */ + offset += bo->meta.sizes[plane + a_plane]; + } /* Total number of planes & sizes */ - bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier); - bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1]; + bo->meta.num_planes = plane + a_plane; + bo->meta.total_size = offset; } else { return i915_bo_from_format(bo, width, height, format); } @@ -827,6 +905,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags) if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) || (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) || + (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) || (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED)) return MAP_FAILED; |