blob: dd3bfacfc5cd75e60393175ffa5099e93b4c71f2 [file] [log] [blame]
Stéphane Marchesin25a26062014-09-12 16:18:59 -07001/*
Daniele Castagna7a755de2016-12-16 17:32:30 -05002 * Copyright 2014 The Chromium OS Authors. All rights reserved.
Stéphane Marchesin25a26062014-09-12 16:18:59 -07003 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Gurchetan Singh46faf6b2016-08-05 14:40:07 -07007#ifdef DRV_I915
Stéphane Marchesin25a26062014-09-12 16:18:59 -07008
Kristian H. Kristensene8778f02018-04-04 14:21:41 -07009#include <assert.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070010#include <errno.h>
Kristian H. Kristensen9c3fb322018-04-11 15:55:13 -070011#include <stdbool.h>
Gurchetan Singhcc015e82017-01-17 16:15:25 -080012#include <stdio.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070013#include <string.h>
Gurchetan Singhef920532016-08-12 16:38:25 -070014#include <sys/mman.h>
Gurchetan Singhcc35e692019-02-28 15:44:54 -080015#include <unistd.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070016#include <xf86drm.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070017
Yiwei Zhangb7a64442021-09-30 05:13:10 +000018#include "drv_helpers.h"
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070019#include "drv_priv.h"
Gurchetan Singh13b00122020-10-07 14:31:20 -070020#include "external/i915_drm.h"
Stéphane Marchesin25a26062014-09-12 16:18:59 -070021#include "util.h"
22
Gurchetan Singh68af9c22017-01-18 13:48:11 -080023#define I915_CACHELINE_SIZE 64
24#define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1)
25
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +000026static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
27 DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888,
28 DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010,
29 DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010,
30 DRM_FORMAT_XRGB8888 };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -080031
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +000032static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F };
33
34static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010,
35 DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
Gurchetan Singh179687e2016-10-28 10:07:35 -070036
Mark Yacoub6e277082020-12-07 16:36:17 -050037static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
38 I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
Binu R S8d705182020-07-20 10:36:53 +053039
Vipin Ananda0af3092020-06-17 10:53:02 +053040static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
41 I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
42 DRM_FORMAT_MOD_LINEAR };
43
Cooper Chiouc8c61d32021-10-27 12:18:30 +080044static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
45 DRM_FORMAT_MOD_LINEAR };
46
Vipin Anand97e07de2022-08-12 04:47:34 +000047static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
48 DRM_FORMAT_MOD_LINEAR};
49
Binu R S8d705182020-07-20 10:36:53 +053050struct modifier_support_t {
51 const uint64_t *order;
52 uint32_t count;
53};
54
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080055struct i915_device {
Ap, Kamal1d54c832022-08-11 16:49:35 +000056 uint32_t graphics_version;
Gurchetan Singh68af9c22017-01-18 13:48:11 -080057 int32_t has_llc;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -070058 int32_t has_hw_protection;
Binu R S8d705182020-07-20 10:36:53 +053059 struct modifier_support_t modifier;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080060 int device_id;
Juston Li89875822022-06-28 10:42:23 -070061 bool is_xelpd;
Ap, Kamal1d54c832022-08-11 16:49:35 +000062 /*TODO : cleanup is_mtl to avoid adding variables for every new platforms */
63 bool is_mtl;
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +000064 int32_t num_fences_avail;
Stéphane Marchesin25a26062014-09-12 16:18:59 -070065};
66
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080067static void i915_info_from_device_id(struct i915_device *i915)
Stéphane Marchesin25a26062014-09-12 16:18:59 -070068{
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080069 const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
70 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 };
Nicholas Bishopa2047242021-10-29 12:42:33 -040071 const uint16_t gen4_ids[] = { 0x29A2, 0x2992, 0x2982, 0x2972, 0x2A02, 0x2A12, 0x2A42,
72 0x2E02, 0x2E12, 0x2E22, 0x2E32, 0x2E42, 0x2E92 };
73 const uint16_t gen5_ids[] = { 0x0042, 0x0046 };
74 const uint16_t gen6_ids[] = { 0x0102, 0x0112, 0x0122, 0x0106, 0x0116, 0x0126, 0x010A };
75 const uint16_t gen7_ids[] = {
76 0x0152, 0x0162, 0x0156, 0x0166, 0x015a, 0x016a, 0x0402, 0x0412, 0x0422,
77 0x0406, 0x0416, 0x0426, 0x040A, 0x041A, 0x042A, 0x040B, 0x041B, 0x042B,
78 0x040E, 0x041E, 0x042E, 0x0C02, 0x0C12, 0x0C22, 0x0C06, 0x0C16, 0x0C26,
79 0x0C0A, 0x0C1A, 0x0C2A, 0x0C0B, 0x0C1B, 0x0C2B, 0x0C0E, 0x0C1E, 0x0C2E,
80 0x0A02, 0x0A12, 0x0A22, 0x0A06, 0x0A16, 0x0A26, 0x0A0A, 0x0A1A, 0x0A2A,
81 0x0A0B, 0x0A1B, 0x0A2B, 0x0A0E, 0x0A1E, 0x0A2E, 0x0D02, 0x0D12, 0x0D22,
82 0x0D06, 0x0D16, 0x0D26, 0x0D0A, 0x0D1A, 0x0D2A, 0x0D0B, 0x0D1B, 0x0D2B,
83 0x0D0E, 0x0D1E, 0x0D2E, 0x0F31, 0x0F32, 0x0F33, 0x0157, 0x0155
84 };
85 const uint16_t gen8_ids[] = { 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x1602, 0x1606,
86 0x160A, 0x160B, 0x160D, 0x160E, 0x1612, 0x1616,
87 0x161A, 0x161B, 0x161D, 0x161E, 0x1622, 0x1626,
88 0x162A, 0x162B, 0x162D, 0x162E };
89 const uint16_t gen9_ids[] = {
90 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913, 0x1915, 0x1916, 0x1917,
91 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, 0x1923, 0x1926, 0x1927, 0x192A, 0x192B,
92 0x192D, 0x1932, 0x193A, 0x193B, 0x193D, 0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85,
93 0x3184, 0x3185, 0x5902, 0x5906, 0x590A, 0x5908, 0x590B, 0x590E, 0x5913, 0x5915,
94 0x5917, 0x5912, 0x5916, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, 0x5923, 0x5926,
95 0x5927, 0x593B, 0x591C, 0x87C0, 0x87CA, 0x3E90, 0x3E93, 0x3E99, 0x3E9C, 0x3E91,
96 0x3E92, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3E94, 0x3EA9, 0x3EA5, 0x3EA6, 0x3EA7,
97 0x3EA8, 0x3EA1, 0x3EA4, 0x3EA0, 0x3EA3, 0x3EA2, 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4,
98 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5,
99 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, 0x9BE6, 0x9BF6
100 };
101 const uint16_t gen11_ids[] = { 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A56, 0x8A57,
102 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A71,
103 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571, 0x4E51,
104 0x4E55, 0x4E57, 0x4E61, 0x4E71 };
105 const uint16_t gen12_ids[] = {
106 0x4c8a, 0x4c8b, 0x4c8c, 0x4c90, 0x4c9a, 0x4680, 0x4681, 0x4682, 0x4683, 0x4688,
107 0x4689, 0x4690, 0x4691, 0x4692, 0x4693, 0x4698, 0x4699, 0x4626, 0x4628, 0x462a,
108 0x46a0, 0x46a1, 0x46a2, 0x46a3, 0x46a6, 0x46a8, 0x46aa, 0x46b0, 0x46b1, 0x46b2,
109 0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68,
110 0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908
111 };
Yiwei Zhang7648f062022-07-13 23:15:22 +0000112 const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA,
113 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, 0x46B2, 0x46B3,
114 0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2 };
Juston Lie18552a2022-06-27 13:32:45 -0700115
116 const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9 };
Ap, Kamal1d54c832022-08-11 16:49:35 +0000117
118 const uint16_t mtl_ids[] = { 0x7D40, 0x7D60, 0x7D45, 0x7D55, 0x7DD5 };
119
Stéphane Marchesina39dfde2014-09-15 15:38:25 -0700120 unsigned i;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000121 i915->graphics_version = 4;
Juston Li89875822022-06-28 10:42:23 -0700122 i915->is_xelpd = false;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000123 i915->is_mtl = false;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800124
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800125 for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800126 if (gen3_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000127 i915->graphics_version = 3;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800128
Nicholas Bishopa2047242021-10-29 12:42:33 -0400129 /* Gen 4 */
130 for (i = 0; i < ARRAY_SIZE(gen4_ids); i++)
131 if (gen4_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000132 i915->graphics_version = 4;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400133
134 /* Gen 5 */
135 for (i = 0; i < ARRAY_SIZE(gen5_ids); i++)
136 if (gen5_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000137 i915->graphics_version = 5;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400138
139 /* Gen 6 */
140 for (i = 0; i < ARRAY_SIZE(gen6_ids); i++)
141 if (gen6_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000142 i915->graphics_version = 6;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400143
144 /* Gen 7 */
145 for (i = 0; i < ARRAY_SIZE(gen7_ids); i++)
146 if (gen7_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000147 i915->graphics_version = 7;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400148
149 /* Gen 8 */
150 for (i = 0; i < ARRAY_SIZE(gen8_ids); i++)
151 if (gen8_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000152 i915->graphics_version = 8;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400153
154 /* Gen 9 */
155 for (i = 0; i < ARRAY_SIZE(gen9_ids); i++)
156 if (gen9_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000157 i915->graphics_version = 9;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400158
Binu R S8d705182020-07-20 10:36:53 +0530159 /* Gen 11 */
160 for (i = 0; i < ARRAY_SIZE(gen11_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800161 if (gen11_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000162 i915->graphics_version = 11;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700163
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700164 /* Gen 12 */
165 for (i = 0; i < ARRAY_SIZE(gen12_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800166 if (gen12_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000167 i915->graphics_version = 12;
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700168
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800169 for (i = 0; i < ARRAY_SIZE(adlp_ids); i++)
170 if (adlp_ids[i] == i915->device_id) {
Juston Li89875822022-06-28 10:42:23 -0700171 i915->is_xelpd = true;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000172 i915->graphics_version = 12;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800173 }
Juston Lie18552a2022-06-27 13:32:45 -0700174
175 for (i = 0; i < ARRAY_SIZE(rplp_ids); i++)
176 if (rplp_ids[i] == i915->device_id) {
177 i915->is_xelpd = true;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000178 i915->graphics_version = 12;
179 }
180
181 for (i = 0; i < ARRAY_SIZE(mtl_ids); i++)
182 if (mtl_ids[i] == i915->device_id) {
183 i915->graphics_version = 12;
184 i915->is_mtl = true;
Juston Lie18552a2022-06-27 13:32:45 -0700185 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700186}
187
Binu R S8d705182020-07-20 10:36:53 +0530188static void i915_get_modifier_order(struct i915_device *i915)
189{
Vipin Anand97e07de2022-08-12 04:47:34 +0000190 if (i915->is_mtl) {
191 i915->modifier.order = xe_lpdp_modifier_order;
192 i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order);
193 } else if (i915->graphics_version == 12) {
Vipin Ananda0af3092020-06-17 10:53:02 +0530194 i915->modifier.order = gen12_modifier_order;
195 i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
Ap, Kamal1d54c832022-08-11 16:49:35 +0000196 } else if (i915->graphics_version == 11) {
Cooper Chiouc8c61d32021-10-27 12:18:30 +0800197 i915->modifier.order = gen11_modifier_order;
198 i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
Vipin Ananda0af3092020-06-17 10:53:02 +0530199 } else {
200 i915->modifier.order = gen_modifier_order;
201 i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
202 }
Binu R S8d705182020-07-20 10:36:53 +0530203}
204
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000205static uint64_t unset_flags(uint64_t current_flags, uint64_t mask)
Kristian H. Kristensen9c3fb322018-04-11 15:55:13 -0700206{
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000207 uint64_t value = current_flags & ~mask;
208 return value;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800209}
210
211static int i915_add_combinations(struct driver *drv)
212{
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700213 struct i915_device *i915 = drv->priv;
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700214
Miguel Casasda47b7d2021-04-15 21:46:33 -0400215 const uint64_t scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT;
216 const uint64_t render = BO_USE_RENDER_MASK;
217 const uint64_t texture_only = BO_USE_TEXTURE_MASK;
Jeffrey Kardatzkedba19872020-12-04 16:58:28 -0800218 // HW protected buffers also need to be scanned out.
Miguel Casasda47b7d2021-04-15 21:46:33 -0400219 const uint64_t hw_protected =
220 i915->has_hw_protection ? (BO_USE_PROTECTED | BO_USE_SCANOUT) : 0;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700221
Miguel Casasabeadde2021-04-16 14:49:18 -0400222 const uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN |
223 BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY |
224 BO_USE_SW_WRITE_RARELY;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800225
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700226 struct format_metadata metadata_linear = { .tiling = I915_TILING_NONE,
227 .priority = 1,
228 .modifier = DRM_FORMAT_MOD_LINEAR };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800229
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000230 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400231 &metadata_linear, scanout_and_render);
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800232
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700233 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_linear,
234 render);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700235
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700236 drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats),
237 &metadata_linear, texture_only);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000238
239 drv_modify_linear_combinations(drv);
Hirokazu Hondafd8b8ab2020-06-16 15:28:56 +0900240
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900241 /* NV12 format for camera, display, decoding and encoding. */
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000242 /* IPU3 camera ISP supports only NV12 output. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400243 drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata_linear,
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900244 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700245 BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
246 hw_protected);
Hirokazu Honda3b8d4d02019-07-31 16:35:52 +0900247
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700248 /* Android CTS tests require this. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400249 drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata_linear, BO_USE_SW_MASK);
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700250
Tomasz Figad30c0a52017-07-05 17:50:18 +0900251 /*
252 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
David Stevens49518142020-06-15 13:48:48 +0900253 * from camera and input/output from hardware decoder/encoder.
Tomasz Figad30c0a52017-07-05 17:50:18 +0900254 */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400255 drv_modify_combination(drv, DRM_FORMAT_R8, &metadata_linear,
David Stevens49518142020-06-15 13:48:48 +0900256 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
Jason Macnak80f664c2022-07-19 16:44:22 -0700257 BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER |
258 BO_USE_SENSOR_DIRECT_DATA);
Tomasz Figad30c0a52017-07-05 17:50:18 +0900259
Miguel Casasda47b7d2021-04-15 21:46:33 -0400260 const uint64_t render_not_linear = unset_flags(render, linear_mask);
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400261 const uint64_t scanout_and_render_not_linear = render_not_linear | BO_USE_SCANOUT;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800262
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700263 struct format_metadata metadata_x_tiled = { .tiling = I915_TILING_X,
264 .priority = 2,
265 .modifier = I915_FORMAT_MOD_X_TILED };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800266
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700267 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_x_tiled,
268 render_not_linear);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000269 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasda47b7d2021-04-15 21:46:33 -0400270 &metadata_x_tiled, scanout_and_render_not_linear);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700271
Vipin Anand97e07de2022-08-12 04:47:34 +0000272 if (i915->is_mtl) {
273 struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4,
274 .priority = 3,
275 .modifier = I915_FORMAT_MOD_4_TILED };
276/* Support tile4 NV12 and P010 for libva */
277#ifdef I915_SCANOUT_4_TILED
278 const uint64_t nv12_usage =
279 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
280 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
281 BO_USE_SCANOUT;
282#else
283 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
284 const uint64_t p010_usage = nv12_usage;
285#endif
286 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_4_tiled, nv12_usage);
287 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_4_tiled, p010_usage);
288 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_4_tiled,
289 render_not_linear);
290 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
291 &metadata_4_tiled, render_not_linear);
292 } else {
293 struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700294 .priority = 3,
295 .modifier = I915_FORMAT_MOD_Y_TILED };
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000296/* Support y-tiled NV12 and P010 for libva */
297#ifdef I915_SCANOUT_Y_TILED
Vipin Anand97e07de2022-08-12 04:47:34 +0000298 const uint64_t nv12_usage =
299 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
300 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
301 (i915->graphics_version >= 11 ? BO_USE_SCANOUT : 0);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000302#else
Vipin Anand97e07de2022-08-12 04:47:34 +0000303 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
304 const uint64_t p010_usage = nv12_usage;
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000305#endif
Vipin Anand97e07de2022-08-12 04:47:34 +0000306 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
307 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
308 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_y_tiled,
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700309 render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000310 /* Y-tiled scanout isn't available on old platforms so we add
311 * |scanout_render_formats| without that USE flag.
312 */
313 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400314 &metadata_y_tiled, render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000315 }
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800316 return 0;
317}
318
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000319static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling, uint32_t *stride,
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800320 uint32_t *aligned_height)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700321{
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700322 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700323 uint32_t horizontal_alignment;
324 uint32_t vertical_alignment;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700325
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700326 switch (tiling) {
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700327 default:
328 case I915_TILING_NONE:
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700329 /*
330 * The Intel GPU doesn't need any alignment in linear mode,
331 * but libva requires the allocation stride to be aligned to
332 * 16 bytes and height to 4 rows. Further, we round up the
333 * horizontal alignment so that row start on a cache line (64
334 * bytes).
335 */
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800336#ifdef LINEAR_ALIGN_256
337 /*
338 * If we want to import these buffers to amdgpu they need to
339 * their match LINEAR_ALIGNED requirement of 256 byte alignement.
340 */
341 horizontal_alignment = 256;
342#else
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700343 horizontal_alignment = 64;
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800344#endif
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000345 /*
346 * For R8 and height=1, we assume the surface will be used as a linear buffer blob
347 * (such as VkBuffer). The hardware allows vertical_alignment=1 only for non-tiled
348 * 1D surfaces, which covers the VkBuffer case. However, if the app uses the surface
349 * as a 2D image with height=1, then this code is buggy. For 2D images, the hardware
350 * requires a vertical_alignment >= 4, and underallocating with vertical_alignment=1
351 * will cause the GPU to read out-of-bounds.
352 *
353 * TODO: add a new DRM_FORMAT_BLOB format for this case, or further tighten up the
354 * constraints with GPU_DATA_BUFFER usage when the guest has migrated to use
355 * virtgpu_cross_domain backend which passes that flag through.
356 */
357 if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
358 vertical_alignment = 1;
359 } else {
360 vertical_alignment = 4;
361 }
362
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700363 break;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800364
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700365 case I915_TILING_X:
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700366 horizontal_alignment = 512;
367 vertical_alignment = 8;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700368 break;
369
370 case I915_TILING_Y:
Vipin Anand97e07de2022-08-12 04:47:34 +0000371 case I915_TILING_4:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000372 if (i915->graphics_version == 3) {
Chad Versace0f9bd722022-01-20 11:36:02 -0800373 horizontal_alignment = 512;
374 vertical_alignment = 8;
Yiwei Zhang17fa1a82022-02-04 00:39:06 +0000375 } else {
376 horizontal_alignment = 128;
377 vertical_alignment = 32;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700378 }
379 break;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700380 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800381
David Stevens793675a2019-09-25 11:17:48 +0900382 *aligned_height = ALIGN(*aligned_height, vertical_alignment);
Ap, Kamal1d54c832022-08-11 16:49:35 +0000383 if (i915->graphics_version > 3) {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700384 *stride = ALIGN(*stride, horizontal_alignment);
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800385 } else {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700386 while (*stride > horizontal_alignment)
387 horizontal_alignment <<= 1;
388
389 *stride = horizontal_alignment;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800390 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800391
Ap, Kamal1d54c832022-08-11 16:49:35 +0000392 if (i915->graphics_version <= 3 && *stride > 8192)
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700393 return -EINVAL;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800394
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700395 return 0;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700396}
397
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800398static void i915_clflush(void *start, size_t size)
399{
400 void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
401 void *end = (void *)((uintptr_t)start + size);
402
403 __builtin_ia32_mfence();
404 while (p < end) {
405 __builtin_ia32_clflush(p);
406 p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
407 }
408}
409
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800410static int i915_init(struct driver *drv)
411{
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800412 int ret;
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800413 struct i915_device *i915;
Gurchetan Singh99644382020-10-07 15:28:11 -0700414 drm_i915_getparam_t get_param = { 0 };
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800415
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800416 i915 = calloc(1, sizeof(*i915));
417 if (!i915)
418 return -ENOMEM;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800419
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800420 get_param.param = I915_PARAM_CHIPSET_ID;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800421 get_param.value = &(i915->device_id);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800422 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
423 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000424 drv_loge("Failed to get I915_PARAM_CHIPSET_ID\n");
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800425 free(i915);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800426 return -EINVAL;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800427 }
Ap, Kamal1d54c832022-08-11 16:49:35 +0000428 /* must call before i915->graphics_version is used anywhere else */
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800429 i915_info_from_device_id(i915);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800430
Binu R S8d705182020-07-20 10:36:53 +0530431 i915_get_modifier_order(i915);
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800432
433 memset(&get_param, 0, sizeof(get_param));
434 get_param.param = I915_PARAM_HAS_LLC;
435 get_param.value = &i915->has_llc;
436 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
437 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000438 drv_loge("Failed to get I915_PARAM_HAS_LLC\n");
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800439 free(i915);
440 return -EINVAL;
441 }
442
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000443 memset(&get_param, 0, sizeof(get_param));
444 get_param.param = I915_PARAM_NUM_FENCES_AVAIL;
445 get_param.value = &i915->num_fences_avail;
446 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
447 if (ret) {
448 drv_loge("Failed to get I915_PARAM_NUM_FENCES_AVAIL\n");
449 return -EINVAL;
450 }
451
Ap, Kamal1d54c832022-08-11 16:49:35 +0000452 if (i915->graphics_version >= 12)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700453 i915->has_hw_protection = 1;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800454
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700455 drv->priv = i915;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800456 return i915_add_combinations(drv);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800457}
458
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700459/*
460 * Returns true if the height of a buffer of the given format should be aligned
461 * to the largest coded unit (LCU) assuming that it will be used for video. This
462 * is based on gmmlib's GmmIsYUVFormatLCUAligned().
463 */
Drew Davenport862d36f2021-06-09 19:54:04 -0600464static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
465 const struct i915_device *i915)
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700466{
467 switch (format) {
468 case DRM_FORMAT_NV12:
469 case DRM_FORMAT_P010:
470 case DRM_FORMAT_P016:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000471 return (i915->graphics_version == 11 || i915->graphics_version == 12) && plane == 1;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700472 }
473 return false;
474}
475
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700476static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
477{
478 uint32_t offset;
479 size_t plane;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800480 int ret, pagesize;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700481 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700482
483 offset = 0;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800484 pagesize = getpagesize();
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700485
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700486 for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
487 uint32_t stride = drv_stride_from_format(format, width, plane);
488 uint32_t plane_height = drv_height_from_format(format, height, plane);
489
Gurchetan Singh298b7572019-09-19 09:55:18 -0700490 if (bo->meta.tiling != I915_TILING_NONE)
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800491 assert(IS_ALIGNED(offset, pagesize));
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700492
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000493 ret = i915_align_dimensions(bo, format, bo->meta.tiling, &stride, &plane_height);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700494 if (ret)
495 return ret;
496
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700497 if (i915_format_needs_LCU_alignment(format, plane, i915)) {
498 /*
499 * Align the height of the V plane for certain formats to the
500 * largest coded unit (assuming that this BO may be used for video)
501 * to be consistent with gmmlib.
502 */
503 plane_height = ALIGN(plane_height, 64);
504 }
505
Gurchetan Singh298b7572019-09-19 09:55:18 -0700506 bo->meta.strides[plane] = stride;
507 bo->meta.sizes[plane] = stride * plane_height;
508 bo->meta.offsets[plane] = offset;
509 offset += bo->meta.sizes[plane];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700510 }
511
Gurchetan Singh298b7572019-09-19 09:55:18 -0700512 bo->meta.total_size = ALIGN(offset, pagesize);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700513
514 return 0;
515}
516
Yiwei Zhang7648f062022-07-13 23:15:22 +0000517static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier)
Robert Mader96058f92022-04-05 12:15:11 +0200518{
519 size_t num_planes = drv_num_planes_from_format(format);
520 if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
521 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
522 assert(num_planes == 1);
523 return 2;
524 }
525
526 return num_planes;
527}
528
David Stevens26fe6822020-03-09 12:23:42 +0000529static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
530 uint64_t use_flags, const uint64_t *modifiers, uint32_t count)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700531{
David Stevens26fe6822020-03-09 12:23:42 +0000532 uint64_t modifier;
Sean Paula9d3f772020-05-19 10:17:07 -0400533 struct i915_device *i915 = bo->drv->priv;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000534 bool huge_bo = (i915->graphics_version < 11) && (width > 4096);
David Stevens26fe6822020-03-09 12:23:42 +0000535
536 if (modifiers) {
537 modifier =
Binu R S8d705182020-07-20 10:36:53 +0530538 drv_pick_modifier(modifiers, count, i915->modifier.order, i915->modifier.count);
David Stevens26fe6822020-03-09 12:23:42 +0000539 } else {
540 struct combination *combo = drv_get_combination(bo->drv, format, use_flags);
541 if (!combo)
542 return -EINVAL;
543 modifier = combo->metadata.modifier;
544 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700545
Sean Paula9d3f772020-05-19 10:17:07 -0400546 /*
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530547 * i915 only supports linear/x-tiled above 4096 wide on Gen9/Gen10 GPU.
548 * VAAPI decode in NV12 Y tiled format so skip modifier change for NV12/P010 huge bo.
Sean Paula9d3f772020-05-19 10:17:07 -0400549 */
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530550 if (huge_bo && format != DRM_FORMAT_NV12 && format != DRM_FORMAT_P010 &&
551 modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) {
Sean Paula9d3f772020-05-19 10:17:07 -0400552 uint32_t i;
553 for (i = 0; modifiers && i < count; i++) {
554 if (modifiers[i] == I915_FORMAT_MOD_X_TILED)
555 break;
556 }
557 if (i == count)
558 modifier = DRM_FORMAT_MOD_LINEAR;
559 else
560 modifier = I915_FORMAT_MOD_X_TILED;
561 }
562
Pilar Molina Lopez28cf2f12020-11-12 18:19:42 -0500563 /*
564 * Skip I915_FORMAT_MOD_Y_TILED_CCS modifier if compression is disabled
565 * Pick y tiled modifier if it has been passed in, otherwise use linear
566 */
567 if (!bo->drv->compression && modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
568 uint32_t i;
569 for (i = 0; modifiers && i < count; i++) {
570 if (modifiers[i] == I915_FORMAT_MOD_Y_TILED)
571 break;
572 }
573 if (i == count)
574 modifier = DRM_FORMAT_MOD_LINEAR;
575 else
576 modifier = I915_FORMAT_MOD_Y_TILED;
577 }
578
Nicholas Bishopa2047242021-10-29 12:42:33 -0400579 /* Prevent gen 8 and earlier from trying to use a tiling modifier */
Ap, Kamal1d54c832022-08-11 16:49:35 +0000580 if (i915->graphics_version <= 8 && format == DRM_FORMAT_ARGB8888) {
Nicholas Bishopa2047242021-10-29 12:42:33 -0400581 modifier = DRM_FORMAT_MOD_LINEAR;
582 }
583
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700584 switch (modifier) {
585 case DRM_FORMAT_MOD_LINEAR:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700586 bo->meta.tiling = I915_TILING_NONE;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700587 break;
588 case I915_FORMAT_MOD_X_TILED:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700589 bo->meta.tiling = I915_TILING_X;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700590 break;
591 case I915_FORMAT_MOD_Y_TILED:
Mark Yacoubc9565642020-02-07 11:02:22 -0500592 case I915_FORMAT_MOD_Y_TILED_CCS:
Vipin Ananda0af3092020-06-17 10:53:02 +0530593 /* For now support only I915_TILING_Y as this works with all
594 * IPs(render/media/display)
595 */
596 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700597 bo->meta.tiling = I915_TILING_Y;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700598 break;
Vipin Anand97e07de2022-08-12 04:47:34 +0000599 case I915_FORMAT_MOD_4_TILED:
600 bo->meta.tiling = I915_TILING_4;
601 break;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700602 }
Owen Linbbb69fd2017-06-05 14:33:08 +0800603
Gurchetan Singh52155b42021-01-27 17:55:17 -0800604 bo->meta.format_modifier = modifier;
Kristian H. Kristensen2b8f89e2018-02-07 16:10:06 -0800605
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700606 if (format == DRM_FORMAT_YVU420_ANDROID) {
607 /*
608 * We only need to be able to use this as a linear texture,
609 * which doesn't put any HW restrictions on how we lay it
610 * out. The Android format does require the stride to be a
611 * multiple of 16 and expects the Cr and Cb stride to be
612 * ALIGN(Y_stride / 2, 16), which we can make happen by
613 * aligning to 32 bytes here.
614 */
615 uint32_t stride = ALIGN(width, 32);
Yiwei Zhang30182072022-11-18 21:03:21 +0000616 return drv_bo_from_format(bo, stride, height, format);
Mark Yacoubc9565642020-02-07 11:02:22 -0500617 } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
618 /*
619 * For compressed surfaces, we need a color control surface
620 * (CCS). Color compression is only supported for Y tiled
621 * surfaces, and for each 32x16 tiles in the main surface we
622 * need a tile in the control surface. Y tiles are 128 bytes
623 * wide and 32 lines tall and we use that to first compute the
624 * width and height in tiles of the main surface. stride and
625 * height are already multiples of 128 and 32, respectively:
626 */
627 uint32_t stride = drv_stride_from_format(format, width, 0);
628 uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128);
629 uint32_t height_in_tiles = DIV_ROUND_UP(height, 32);
630 uint32_t size = width_in_tiles * height_in_tiles * 4096;
631 uint32_t offset = 0;
632
633 bo->meta.strides[0] = width_in_tiles * 128;
634 bo->meta.sizes[0] = size;
635 bo->meta.offsets[0] = offset;
636 offset += size;
637
638 /*
639 * Now, compute the width and height in tiles of the control
640 * surface by dividing and rounding up.
641 */
642 uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32);
643 uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16);
644 uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096;
645
646 /*
647 * With stride and height aligned to y tiles, offset is
648 * already a multiple of 4096, which is the required alignment
649 * of the CCS.
650 */
651 bo->meta.strides[1] = ccs_width_in_tiles * 128;
652 bo->meta.sizes[1] = ccs_size;
653 bo->meta.offsets[1] = offset;
654 offset += ccs_size;
655
Robert Mader96058f92022-04-05 12:15:11 +0200656 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Mark Yacoubc9565642020-02-07 11:02:22 -0500657 bo->meta.total_size = offset;
Vipin Ananda0af3092020-06-17 10:53:02 +0530658 } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
659
660 /*
661 * considering only 128 byte compression and one cache line of
662 * aux buffer(64B) contains compression status of 4-Y tiles.
663 * Which is 4 * (128B * 32L).
664 * line stride(bytes) is 4 * 128B
665 * and tile stride(lines) is 32L
666 */
667 uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
668
669 height = ALIGN(drv_height_from_format(format, height, 0), 32);
670
Juston Li89875822022-06-28 10:42:23 -0700671 if (i915->is_xelpd && (stride > 1)) {
Vipin Ananda0af3092020-06-17 10:53:02 +0530672 stride = 1 << (32 - __builtin_clz(stride - 1));
673 height = ALIGN(drv_height_from_format(format, height, 0), 128);
674 }
675
676 bo->meta.strides[0] = stride;
677 /* size calculation and alignment are 64KB aligned
678 * size as per spec
679 */
680 bo->meta.sizes[0] = ALIGN(stride * height, 65536);
681 bo->meta.offsets[0] = 0;
682
683 /* Aux buffer is linear and page aligned. It is placed after
684 * other planes and aligned to main buffer stride.
685 */
686 bo->meta.strides[1] = bo->meta.strides[0] / 8;
687 /* Aligned to page size */
688 bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
689 bo->meta.offsets[1] = bo->meta.sizes[0];
690 /* Total number of planes & sizes */
Robert Mader96058f92022-04-05 12:15:11 +0200691 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Vipin Ananda0af3092020-06-17 10:53:02 +0530692 bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700693 } else {
Yiwei Zhang30182072022-11-18 21:03:21 +0000694 return i915_bo_from_format(bo, width, height, format);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700695 }
David Stevens26fe6822020-03-09 12:23:42 +0000696 return 0;
697}
698
699static int i915_bo_create_from_metadata(struct bo *bo)
700{
701 int ret;
702 size_t plane;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700703 uint32_t gem_handle;
Gurchetan Singh99644382020-10-07 15:28:11 -0700704 struct drm_i915_gem_set_tiling gem_set_tiling = { 0 };
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700705 struct i915_device *i915 = bo->drv->priv;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800706
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700707 if (i915->has_hw_protection && (bo->meta.use_flags & BO_USE_PROTECTED)) {
Juston Lief852e02021-08-02 11:02:45 -0700708 struct drm_i915_gem_create_ext_protected_content protected_content = {
709 .base = { .name = I915_GEM_CREATE_EXT_PROTECTED_CONTENT },
710 .flags = 0,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700711 };
712
713 struct drm_i915_gem_create_ext create_ext = {
714 .size = bo->meta.total_size,
Juston Lief852e02021-08-02 11:02:45 -0700715 .extensions = (uintptr_t)&protected_content,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700716 };
717
718 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
719 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000720 drv_loge("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
721 create_ext.size, ret);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700722 return -errno;
723 }
724
725 gem_handle = create_ext.handle;
726 } else {
727 struct drm_i915_gem_create gem_create = { 0 };
728 gem_create.size = bo->meta.total_size;
729 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
730 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000731 drv_loge("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700732 return -errno;
733 }
734
735 gem_handle = gem_create.handle;
Ilja H. Friedelf9d2ab72015-04-09 14:08:36 -0700736 }
Gurchetan Singh83dc4fb2016-07-19 15:52:33 -0700737
Gurchetan Singh298b7572019-09-19 09:55:18 -0700738 for (plane = 0; plane < bo->meta.num_planes; plane++)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700739 bo->handles[plane].u32 = gem_handle;
Daniel Nicoara1de26dc2014-09-25 18:53:19 -0400740
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000741 /* Set/Get tiling ioctl not supported based on fence availability
742 Refer : "https://patchwork.freedesktop.org/patch/325343/"
743 */
744 if (i915->num_fences_avail) {
745 gem_set_tiling.handle = bo->handles[0].u32;
746 gem_set_tiling.tiling_mode = bo->meta.tiling;
747 gem_set_tiling.stride = bo->meta.strides[0];
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700748
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000749 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
750 if (ret) {
751 struct drm_gem_close gem_close = { 0 };
752 gem_close.handle = bo->handles[0].u32;
753 drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800754
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000755 drv_loge("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
756 return -errno;
757 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700758 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700759 return 0;
760}
761
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800762static void i915_close(struct driver *drv)
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800763{
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800764 free(drv->priv);
765 drv->priv = NULL;
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800766}
767
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800768static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
769{
770 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700771 struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000772 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800773
Yiwei Zhang7648f062022-07-13 23:15:22 +0000774 bo->meta.num_planes =
775 i915_num_planes_from_modifier(bo->drv, data->format, data->format_modifier);
Robert Mader96058f92022-04-05 12:15:11 +0200776
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800777 ret = drv_prime_bo_import(bo, data);
778 if (ret)
779 return ret;
780
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000781 /* Set/Get tiling ioctl not supported based on fence availability
782 Refer : "https://patchwork.freedesktop.org/patch/325343/"
783 */
784 if (i915->num_fences_avail) {
785 /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
786 gem_get_tiling.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800787
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000788 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
789 if (ret) {
790 drv_gem_bo_destroy(bo);
791 drv_loge("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
792 return ret;
793 }
794 bo->meta.tiling = gem_get_tiling.tiling_mode;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800795 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800796 return 0;
797}
798
Gurchetan Singhee43c302017-11-14 18:20:27 -0800799static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
Gurchetan Singhef920532016-08-12 16:38:25 -0700800{
801 int ret;
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000802 void *addr = MAP_FAILED;
Gurchetan Singhef920532016-08-12 16:38:25 -0700803
Vipin Anand97e07de2022-08-12 04:47:34 +0000804 if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
805 (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
806 (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED))
Vipin Ananda0af3092020-06-17 10:53:02 +0530807 return MAP_FAILED;
808
Gurchetan Singh298b7572019-09-19 09:55:18 -0700809 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700810 struct drm_i915_gem_mmap gem_map = { 0 };
Tomasz Figa39eb9512018-11-01 00:45:31 +0900811 /* TODO(b/118799155): We don't seem to have a good way to
812 * detect the use cases for which WC mapping is really needed.
813 * The current heuristic seems overly coarse and may be slowing
814 * down some other use cases unnecessarily.
815 *
816 * For now, care must be taken not to use WC mappings for
817 * Renderscript and camera use cases, as they're
818 * performance-sensitive. */
Gurchetan Singh298b7572019-09-19 09:55:18 -0700819 if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
820 !(bo->meta.use_flags &
Tomasz Figa39eb9512018-11-01 00:45:31 +0900821 (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
Gurchetan Singh5af20232017-09-19 15:10:58 -0700822 gem_map.flags = I915_MMAP_WC;
823
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800824 gem_map.handle = bo->handles[0].u32;
825 gem_map.offset = 0;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700826 gem_map.size = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800827
828 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000829 /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
830 * file and returns a user space address directly, ie,
831 * doesn't go through mmap. If we try that on a
832 * dma-buf that doesn't have a shm file, i915.ko
833 * returns ENXIO. Fall through to
834 * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
835 * will mmap on the drm fd instead. */
836 if (ret == 0)
837 addr = (void *)(uintptr_t)gem_map.addr_ptr;
838 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800839
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000840 if (addr == MAP_FAILED) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700841 struct drm_i915_gem_mmap_gtt gem_map = { 0 };
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800842
843 gem_map.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800844 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
845 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000846 drv_loge("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800847 return MAP_FAILED;
848 }
849
Gurchetan Singh298b7572019-09-19 09:55:18 -0700850 addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED,
851 bo->drv->fd, gem_map.offset);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800852 }
853
854 if (addr == MAP_FAILED) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000855 drv_loge("i915 GEM mmap failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800856 return addr;
857 }
858
Gurchetan Singh298b7572019-09-19 09:55:18 -0700859 vma->length = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800860 return addr;
861}
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700862
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700863static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700864{
865 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700866 struct drm_i915_gem_set_domain set_domain = { 0 };
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700867
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700868 set_domain.handle = bo->handles[0].u32;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700869 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700870 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700871 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700872 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
873 } else {
874 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700875 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700876 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
877 }
878
879 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
880 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000881 drv_loge("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700882 return ret;
883 }
884
885 return 0;
886}
887
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700888static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800889{
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800890 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700891 if (!i915->has_llc && bo->meta.tiling == I915_TILING_NONE)
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700892 i915_clflush(mapping->vma->addr, mapping->vma->length);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800893
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700894 return 0;
Gurchetan Singhef920532016-08-12 16:38:25 -0700895}
896
Gurchetan Singh3e9d3832017-10-31 10:36:25 -0700897const struct backend backend_i915 = {
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700898 .name = "i915",
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700899 .init = i915_init,
900 .close = i915_close,
David Stevens26fe6822020-03-09 12:23:42 +0000901 .bo_compute_metadata = i915_bo_compute_metadata,
902 .bo_create_from_metadata = i915_bo_create_from_metadata,
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800903 .bo_destroy = drv_gem_bo_destroy,
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800904 .bo_import = i915_bo_import,
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700905 .bo_map = i915_bo_map,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700906 .bo_unmap = drv_bo_munmap,
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700907 .bo_invalidate = i915_bo_invalidate,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700908 .bo_flush = i915_bo_flush,
Yiwei Zhangb8ad7b82021-10-01 17:55:14 +0000909 .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
Robert Mader96058f92022-04-05 12:15:11 +0200910 .num_planes_from_modifier = i915_num_planes_from_modifier,
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700911};
912
913#endif