X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=i915.c;h=e8c49096c00e3c5864daef7749a182e8d2ab0948;hb=310cf97a929fced825454e03e0a9390a204dc2d8;hp=3ed785a0bd0183e8461cc5e4e4543a648e917b3e;hpb=8d88474891dfb726c661849a7d299eb81ed91c7a;p=android-x86%2Fexternal-minigbm.git diff --git a/i915.c b/i915.c index 3ed785a..e8c4909 100644 --- a/i915.c +++ b/i915.c @@ -34,23 +34,53 @@ static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F }; static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint64_t gen_modifier_order[] = { 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_CCS, + I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR }; + +struct modifier_support_t { + const uint64_t *order; + uint32_t count; +}; + struct i915_device { uint32_t gen; int32_t has_llc; + struct modifier_support_t modifier; }; static uint32_t i915_get_gen(int device_id) { const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 }; + const uint16_t gen11_ids[] = { 0x4E71, 0x4E61, 0x4E51, 0x4E55, 0x4E57 }; + unsigned i; for (i = 0; i < ARRAY_SIZE(gen3_ids); i++) if (gen3_ids[i] == device_id) return 3; + /* Gen 11 */ + for (i = 0; i < ARRAY_SIZE(gen11_ids); i++) + if (gen11_ids[i] == device_id) + return 11; return 4; } +static void i915_get_modifier_order(struct i915_device *i915) +{ + if (i915->gen == 11) { + i915->modifier.order = gen11_modifier_order; + i915->modifier.count = ARRAY_SIZE(gen11_modifier_order); + } else { + i915->modifier.order = gen_modifier_order; + i915->modifier.count = ARRAY_SIZE(gen_modifier_order); + } +} + static uint64_t unset_flags(uint64_t current_flags, uint64_t mask) { uint64_t value = current_flags & ~mask; @@ -81,25 +111,23 @@ static int i915_add_combinations(struct driver *drv) texture_only); drv_modify_linear_combinations(drv); - /* - * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the - * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. - */ - drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + + /* NV12 format for camera, display, decoding and encoding. */ /* IPU3 camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT | + BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); /* * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots - * from camera. + * from camera and input/output from hardware decoder/encoder. */ drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER); render = unset_flags(render, linear_mask); scanout_and_render = unset_flags(scanout_and_render, linear_mask); @@ -223,6 +251,7 @@ static int i915_init(struct driver *drv) } i915->gen = i915_get_gen(device_id); + i915_get_modifier_order(i915); memset(&get_param, 0, sizeof(get_param)); get_param.param = I915_PARAM_HAS_LLC; @@ -272,17 +301,13 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags, const uint64_t *modifiers, uint32_t count) { - static const uint64_t modifier_order[] = { - I915_FORMAT_MOD_Y_TILED_CCS, - I915_FORMAT_MOD_Y_TILED, - I915_FORMAT_MOD_X_TILED, - DRM_FORMAT_MOD_LINEAR, - }; uint64_t modifier; + struct i915_device *i915 = bo->drv->priv; + bool huge_bo = (i915->gen <= 11) && (width > 4096); if (modifiers) { modifier = - drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + drv_pick_modifier(modifiers, count, i915->modifier.order, i915->modifier.count); } else { struct combination *combo = drv_get_combination(bo->drv, format, use_flags); if (!combo) @@ -290,6 +315,21 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig modifier = combo->metadata.modifier; } + /* + * i915 only supports linear/x-tiled above 4096 wide + */ + if (huge_bo && modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) { + uint32_t i; + for (i = 0; modifiers && i < count; i++) { + if (modifiers[i] == I915_FORMAT_MOD_X_TILED) + break; + } + if (i == count) + modifier = DRM_FORMAT_MOD_LINEAR; + else + modifier = I915_FORMAT_MOD_X_TILED; + } + switch (modifier) { case DRM_FORMAT_MOD_LINEAR: bo->meta.tiling = I915_TILING_NONE;