blob: 4a33151431b2e4c88ff07ba2b032d593d37094af [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,
Yiwei Zhangcd1339f2023-01-03 20:06:17 +000048 DRM_FORMAT_MOD_LINEAR };
Vipin Anand97e07de2022-08-12 04:47:34 +000049
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,
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000274 .priority = 3,
275 .modifier = I915_FORMAT_MOD_4_TILED };
Vipin Anand97e07de2022-08-12 04:47:34 +0000276/* Support tile4 NV12 and P010 for libva */
277#ifdef I915_SCANOUT_4_TILED
278 const uint64_t nv12_usage =
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000279 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
280 const uint64_t p010_usage =
281 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected | BO_USE_SCANOUT;
Vipin Anand97e07de2022-08-12 04:47:34 +0000282#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);
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000288 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
289 &metadata_4_tiled, render_not_linear);
290 drv_add_combinations(drv, scanout_render_formats,
291 ARRAY_SIZE(scanout_render_formats), &metadata_4_tiled,
292 render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000293 } else {
294 struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000295 .priority = 3,
296 .modifier = I915_FORMAT_MOD_Y_TILED };
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000297/* Support y-tiled NV12 and P010 for libva */
298#ifdef I915_SCANOUT_Y_TILED
Vipin Anand97e07de2022-08-12 04:47:34 +0000299 const uint64_t nv12_usage =
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000300 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
301 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER |
302 hw_protected |
303 (i915->graphics_version >= 11 ? BO_USE_SCANOUT : 0);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000304#else
Vipin Anand97e07de2022-08-12 04:47:34 +0000305 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
306 const uint64_t p010_usage = nv12_usage;
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000307#endif
Vipin Anand97e07de2022-08-12 04:47:34 +0000308 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
309 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000310 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
311 &metadata_y_tiled, render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000312 /* Y-tiled scanout isn't available on old platforms so we add
313 * |scanout_render_formats| without that USE flag.
314 */
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000315 drv_add_combinations(drv, scanout_render_formats,
316 ARRAY_SIZE(scanout_render_formats), &metadata_y_tiled,
317 render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000318 }
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800319 return 0;
320}
321
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000322static int i915_align_dimensions(struct bo *bo, uint32_t format, uint32_t tiling, uint32_t *stride,
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800323 uint32_t *aligned_height)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700324{
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700325 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700326 uint32_t horizontal_alignment;
327 uint32_t vertical_alignment;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700328
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700329 switch (tiling) {
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700330 default:
331 case I915_TILING_NONE:
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700332 /*
333 * The Intel GPU doesn't need any alignment in linear mode,
334 * but libva requires the allocation stride to be aligned to
335 * 16 bytes and height to 4 rows. Further, we round up the
336 * horizontal alignment so that row start on a cache line (64
337 * bytes).
338 */
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800339#ifdef LINEAR_ALIGN_256
340 /*
341 * If we want to import these buffers to amdgpu they need to
342 * their match LINEAR_ALIGNED requirement of 256 byte alignement.
343 */
344 horizontal_alignment = 256;
345#else
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700346 horizontal_alignment = 64;
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800347#endif
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000348 /*
349 * For R8 and height=1, we assume the surface will be used as a linear buffer blob
350 * (such as VkBuffer). The hardware allows vertical_alignment=1 only for non-tiled
351 * 1D surfaces, which covers the VkBuffer case. However, if the app uses the surface
352 * as a 2D image with height=1, then this code is buggy. For 2D images, the hardware
353 * requires a vertical_alignment >= 4, and underallocating with vertical_alignment=1
354 * will cause the GPU to read out-of-bounds.
355 *
356 * TODO: add a new DRM_FORMAT_BLOB format for this case, or further tighten up the
357 * constraints with GPU_DATA_BUFFER usage when the guest has migrated to use
358 * virtgpu_cross_domain backend which passes that flag through.
359 */
360 if (format == DRM_FORMAT_R8 && *aligned_height == 1) {
361 vertical_alignment = 1;
362 } else {
363 vertical_alignment = 4;
364 }
365
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700366 break;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800367
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700368 case I915_TILING_X:
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700369 horizontal_alignment = 512;
370 vertical_alignment = 8;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700371 break;
372
373 case I915_TILING_Y:
Vipin Anand97e07de2022-08-12 04:47:34 +0000374 case I915_TILING_4:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000375 if (i915->graphics_version == 3) {
Chad Versace0f9bd722022-01-20 11:36:02 -0800376 horizontal_alignment = 512;
377 vertical_alignment = 8;
Yiwei Zhang17fa1a82022-02-04 00:39:06 +0000378 } else {
379 horizontal_alignment = 128;
380 vertical_alignment = 32;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700381 }
382 break;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700383 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800384
David Stevens793675a2019-09-25 11:17:48 +0900385 *aligned_height = ALIGN(*aligned_height, vertical_alignment);
Ap, Kamal1d54c832022-08-11 16:49:35 +0000386 if (i915->graphics_version > 3) {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700387 *stride = ALIGN(*stride, horizontal_alignment);
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800388 } else {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700389 while (*stride > horizontal_alignment)
390 horizontal_alignment <<= 1;
391
392 *stride = horizontal_alignment;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800393 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800394
Ap, Kamal1d54c832022-08-11 16:49:35 +0000395 if (i915->graphics_version <= 3 && *stride > 8192)
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700396 return -EINVAL;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800397
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700398 return 0;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700399}
400
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800401static void i915_clflush(void *start, size_t size)
402{
403 void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
404 void *end = (void *)((uintptr_t)start + size);
405
406 __builtin_ia32_mfence();
407 while (p < end) {
408 __builtin_ia32_clflush(p);
409 p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
410 }
411}
412
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800413static int i915_init(struct driver *drv)
414{
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800415 int ret;
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800416 struct i915_device *i915;
Gurchetan Singh99644382020-10-07 15:28:11 -0700417 drm_i915_getparam_t get_param = { 0 };
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800418
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800419 i915 = calloc(1, sizeof(*i915));
420 if (!i915)
421 return -ENOMEM;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800422
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800423 get_param.param = I915_PARAM_CHIPSET_ID;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800424 get_param.value = &(i915->device_id);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800425 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
426 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000427 drv_loge("Failed to get I915_PARAM_CHIPSET_ID\n");
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800428 free(i915);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800429 return -EINVAL;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800430 }
Ap, Kamal1d54c832022-08-11 16:49:35 +0000431 /* must call before i915->graphics_version is used anywhere else */
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800432 i915_info_from_device_id(i915);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800433
Binu R S8d705182020-07-20 10:36:53 +0530434 i915_get_modifier_order(i915);
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800435
436 memset(&get_param, 0, sizeof(get_param));
437 get_param.param = I915_PARAM_HAS_LLC;
438 get_param.value = &i915->has_llc;
439 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
440 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000441 drv_loge("Failed to get I915_PARAM_HAS_LLC\n");
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800442 free(i915);
443 return -EINVAL;
444 }
445
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000446 memset(&get_param, 0, sizeof(get_param));
447 get_param.param = I915_PARAM_NUM_FENCES_AVAIL;
448 get_param.value = &i915->num_fences_avail;
449 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
450 if (ret) {
451 drv_loge("Failed to get I915_PARAM_NUM_FENCES_AVAIL\n");
452 return -EINVAL;
453 }
454
Ap, Kamal1d54c832022-08-11 16:49:35 +0000455 if (i915->graphics_version >= 12)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700456 i915->has_hw_protection = 1;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800457
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700458 drv->priv = i915;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800459 return i915_add_combinations(drv);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800460}
461
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700462/*
463 * Returns true if the height of a buffer of the given format should be aligned
464 * to the largest coded unit (LCU) assuming that it will be used for video. This
465 * is based on gmmlib's GmmIsYUVFormatLCUAligned().
466 */
Drew Davenport862d36f2021-06-09 19:54:04 -0600467static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
468 const struct i915_device *i915)
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700469{
470 switch (format) {
471 case DRM_FORMAT_NV12:
472 case DRM_FORMAT_P010:
473 case DRM_FORMAT_P016:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000474 return (i915->graphics_version == 11 || i915->graphics_version == 12) && plane == 1;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700475 }
476 return false;
477}
478
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700479static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
480{
481 uint32_t offset;
482 size_t plane;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800483 int ret, pagesize;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700484 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700485
486 offset = 0;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800487 pagesize = getpagesize();
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700488
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700489 for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
490 uint32_t stride = drv_stride_from_format(format, width, plane);
491 uint32_t plane_height = drv_height_from_format(format, height, plane);
492
Gurchetan Singh298b7572019-09-19 09:55:18 -0700493 if (bo->meta.tiling != I915_TILING_NONE)
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800494 assert(IS_ALIGNED(offset, pagesize));
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700495
Yiwei Zhangeccb7f82022-11-18 04:17:02 +0000496 ret = i915_align_dimensions(bo, format, bo->meta.tiling, &stride, &plane_height);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700497 if (ret)
498 return ret;
499
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700500 if (i915_format_needs_LCU_alignment(format, plane, i915)) {
501 /*
502 * Align the height of the V plane for certain formats to the
503 * largest coded unit (assuming that this BO may be used for video)
504 * to be consistent with gmmlib.
505 */
506 plane_height = ALIGN(plane_height, 64);
507 }
508
Gurchetan Singh298b7572019-09-19 09:55:18 -0700509 bo->meta.strides[plane] = stride;
510 bo->meta.sizes[plane] = stride * plane_height;
511 bo->meta.offsets[plane] = offset;
512 offset += bo->meta.sizes[plane];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700513 }
514
Gurchetan Singh298b7572019-09-19 09:55:18 -0700515 bo->meta.total_size = ALIGN(offset, pagesize);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700516
517 return 0;
518}
519
Yiwei Zhang7648f062022-07-13 23:15:22 +0000520static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier)
Robert Mader96058f92022-04-05 12:15:11 +0200521{
522 size_t num_planes = drv_num_planes_from_format(format);
523 if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
524 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
525 assert(num_planes == 1);
526 return 2;
527 }
528
529 return num_planes;
530}
531
David Stevens26fe6822020-03-09 12:23:42 +0000532static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
533 uint64_t use_flags, const uint64_t *modifiers, uint32_t count)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700534{
David Stevens26fe6822020-03-09 12:23:42 +0000535 uint64_t modifier;
Sean Paula9d3f772020-05-19 10:17:07 -0400536 struct i915_device *i915 = bo->drv->priv;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000537 bool huge_bo = (i915->graphics_version < 11) && (width > 4096);
David Stevens26fe6822020-03-09 12:23:42 +0000538
539 if (modifiers) {
540 modifier =
Binu R S8d705182020-07-20 10:36:53 +0530541 drv_pick_modifier(modifiers, count, i915->modifier.order, i915->modifier.count);
David Stevens26fe6822020-03-09 12:23:42 +0000542 } else {
543 struct combination *combo = drv_get_combination(bo->drv, format, use_flags);
544 if (!combo)
545 return -EINVAL;
546 modifier = combo->metadata.modifier;
547 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700548
Sean Paula9d3f772020-05-19 10:17:07 -0400549 /*
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530550 * i915 only supports linear/x-tiled above 4096 wide on Gen9/Gen10 GPU.
551 * VAAPI decode in NV12 Y tiled format so skip modifier change for NV12/P010 huge bo.
Sean Paula9d3f772020-05-19 10:17:07 -0400552 */
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530553 if (huge_bo && format != DRM_FORMAT_NV12 && format != DRM_FORMAT_P010 &&
554 modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) {
Sean Paula9d3f772020-05-19 10:17:07 -0400555 uint32_t i;
556 for (i = 0; modifiers && i < count; i++) {
557 if (modifiers[i] == I915_FORMAT_MOD_X_TILED)
558 break;
559 }
560 if (i == count)
561 modifier = DRM_FORMAT_MOD_LINEAR;
562 else
563 modifier = I915_FORMAT_MOD_X_TILED;
564 }
565
Pilar Molina Lopez28cf2f12020-11-12 18:19:42 -0500566 /*
567 * Skip I915_FORMAT_MOD_Y_TILED_CCS modifier if compression is disabled
568 * Pick y tiled modifier if it has been passed in, otherwise use linear
569 */
570 if (!bo->drv->compression && modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
571 uint32_t i;
572 for (i = 0; modifiers && i < count; i++) {
573 if (modifiers[i] == I915_FORMAT_MOD_Y_TILED)
574 break;
575 }
576 if (i == count)
577 modifier = DRM_FORMAT_MOD_LINEAR;
578 else
579 modifier = I915_FORMAT_MOD_Y_TILED;
580 }
581
Nicholas Bishopa2047242021-10-29 12:42:33 -0400582 /* Prevent gen 8 and earlier from trying to use a tiling modifier */
Ap, Kamal1d54c832022-08-11 16:49:35 +0000583 if (i915->graphics_version <= 8 && format == DRM_FORMAT_ARGB8888) {
Nicholas Bishopa2047242021-10-29 12:42:33 -0400584 modifier = DRM_FORMAT_MOD_LINEAR;
585 }
586
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700587 switch (modifier) {
588 case DRM_FORMAT_MOD_LINEAR:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700589 bo->meta.tiling = I915_TILING_NONE;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700590 break;
591 case I915_FORMAT_MOD_X_TILED:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700592 bo->meta.tiling = I915_TILING_X;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700593 break;
594 case I915_FORMAT_MOD_Y_TILED:
Mark Yacoubc9565642020-02-07 11:02:22 -0500595 case I915_FORMAT_MOD_Y_TILED_CCS:
Vipin Ananda0af3092020-06-17 10:53:02 +0530596 /* For now support only I915_TILING_Y as this works with all
597 * IPs(render/media/display)
598 */
599 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700600 bo->meta.tiling = I915_TILING_Y;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700601 break;
Vipin Anand97e07de2022-08-12 04:47:34 +0000602 case I915_FORMAT_MOD_4_TILED:
603 bo->meta.tiling = I915_TILING_4;
604 break;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700605 }
Owen Linbbb69fd2017-06-05 14:33:08 +0800606
Gurchetan Singh52155b42021-01-27 17:55:17 -0800607 bo->meta.format_modifier = modifier;
Kristian H. Kristensen2b8f89e2018-02-07 16:10:06 -0800608
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700609 if (format == DRM_FORMAT_YVU420_ANDROID) {
610 /*
611 * We only need to be able to use this as a linear texture,
612 * which doesn't put any HW restrictions on how we lay it
613 * out. The Android format does require the stride to be a
614 * multiple of 16 and expects the Cr and Cb stride to be
615 * ALIGN(Y_stride / 2, 16), which we can make happen by
616 * aligning to 32 bytes here.
617 */
618 uint32_t stride = ALIGN(width, 32);
Yiwei Zhang30182072022-11-18 21:03:21 +0000619 return drv_bo_from_format(bo, stride, height, format);
Mark Yacoubc9565642020-02-07 11:02:22 -0500620 } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
621 /*
622 * For compressed surfaces, we need a color control surface
623 * (CCS). Color compression is only supported for Y tiled
624 * surfaces, and for each 32x16 tiles in the main surface we
625 * need a tile in the control surface. Y tiles are 128 bytes
626 * wide and 32 lines tall and we use that to first compute the
627 * width and height in tiles of the main surface. stride and
628 * height are already multiples of 128 and 32, respectively:
629 */
630 uint32_t stride = drv_stride_from_format(format, width, 0);
631 uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128);
632 uint32_t height_in_tiles = DIV_ROUND_UP(height, 32);
633 uint32_t size = width_in_tiles * height_in_tiles * 4096;
634 uint32_t offset = 0;
635
636 bo->meta.strides[0] = width_in_tiles * 128;
637 bo->meta.sizes[0] = size;
638 bo->meta.offsets[0] = offset;
639 offset += size;
640
641 /*
642 * Now, compute the width and height in tiles of the control
643 * surface by dividing and rounding up.
644 */
645 uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32);
646 uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16);
647 uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096;
648
649 /*
650 * With stride and height aligned to y tiles, offset is
651 * already a multiple of 4096, which is the required alignment
652 * of the CCS.
653 */
654 bo->meta.strides[1] = ccs_width_in_tiles * 128;
655 bo->meta.sizes[1] = ccs_size;
656 bo->meta.offsets[1] = offset;
657 offset += ccs_size;
658
Robert Mader96058f92022-04-05 12:15:11 +0200659 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Mark Yacoubc9565642020-02-07 11:02:22 -0500660 bo->meta.total_size = offset;
Vipin Ananda0af3092020-06-17 10:53:02 +0530661 } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
662
663 /*
664 * considering only 128 byte compression and one cache line of
665 * aux buffer(64B) contains compression status of 4-Y tiles.
666 * Which is 4 * (128B * 32L).
667 * line stride(bytes) is 4 * 128B
668 * and tile stride(lines) is 32L
669 */
670 uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
671
672 height = ALIGN(drv_height_from_format(format, height, 0), 32);
673
Juston Li89875822022-06-28 10:42:23 -0700674 if (i915->is_xelpd && (stride > 1)) {
Vipin Ananda0af3092020-06-17 10:53:02 +0530675 stride = 1 << (32 - __builtin_clz(stride - 1));
676 height = ALIGN(drv_height_from_format(format, height, 0), 128);
677 }
678
679 bo->meta.strides[0] = stride;
680 /* size calculation and alignment are 64KB aligned
681 * size as per spec
682 */
683 bo->meta.sizes[0] = ALIGN(stride * height, 65536);
684 bo->meta.offsets[0] = 0;
685
686 /* Aux buffer is linear and page aligned. It is placed after
687 * other planes and aligned to main buffer stride.
688 */
689 bo->meta.strides[1] = bo->meta.strides[0] / 8;
690 /* Aligned to page size */
691 bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
692 bo->meta.offsets[1] = bo->meta.sizes[0];
693 /* Total number of planes & sizes */
Robert Mader96058f92022-04-05 12:15:11 +0200694 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Vipin Ananda0af3092020-06-17 10:53:02 +0530695 bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700696 } else {
Yiwei Zhang30182072022-11-18 21:03:21 +0000697 return i915_bo_from_format(bo, width, height, format);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700698 }
David Stevens26fe6822020-03-09 12:23:42 +0000699 return 0;
700}
701
702static int i915_bo_create_from_metadata(struct bo *bo)
703{
704 int ret;
705 size_t plane;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700706 uint32_t gem_handle;
Gurchetan Singh99644382020-10-07 15:28:11 -0700707 struct drm_i915_gem_set_tiling gem_set_tiling = { 0 };
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700708 struct i915_device *i915 = bo->drv->priv;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800709
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700710 if (i915->has_hw_protection && (bo->meta.use_flags & BO_USE_PROTECTED)) {
Juston Lief852e02021-08-02 11:02:45 -0700711 struct drm_i915_gem_create_ext_protected_content protected_content = {
712 .base = { .name = I915_GEM_CREATE_EXT_PROTECTED_CONTENT },
713 .flags = 0,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700714 };
715
716 struct drm_i915_gem_create_ext create_ext = {
717 .size = bo->meta.total_size,
Juston Lief852e02021-08-02 11:02:45 -0700718 .extensions = (uintptr_t)&protected_content,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700719 };
720
721 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
722 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000723 drv_loge("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
724 create_ext.size, ret);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700725 return -errno;
726 }
727
728 gem_handle = create_ext.handle;
729 } else {
730 struct drm_i915_gem_create gem_create = { 0 };
731 gem_create.size = bo->meta.total_size;
732 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
733 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000734 drv_loge("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700735 return -errno;
736 }
737
738 gem_handle = gem_create.handle;
Ilja H. Friedelf9d2ab72015-04-09 14:08:36 -0700739 }
Gurchetan Singh83dc4fb2016-07-19 15:52:33 -0700740
Gurchetan Singh298b7572019-09-19 09:55:18 -0700741 for (plane = 0; plane < bo->meta.num_planes; plane++)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700742 bo->handles[plane].u32 = gem_handle;
Daniel Nicoara1de26dc2014-09-25 18:53:19 -0400743
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000744 /* Set/Get tiling ioctl not supported based on fence availability
745 Refer : "https://patchwork.freedesktop.org/patch/325343/"
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000746 */
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000747 if (i915->num_fences_avail) {
748 gem_set_tiling.handle = bo->handles[0].u32;
749 gem_set_tiling.tiling_mode = bo->meta.tiling;
750 gem_set_tiling.stride = bo->meta.strides[0];
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700751
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000752 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
753 if (ret) {
754 struct drm_gem_close gem_close = { 0 };
755 gem_close.handle = bo->handles[0].u32;
756 drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800757
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000758 drv_loge("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
759 return -errno;
760 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700761 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700762 return 0;
763}
764
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800765static void i915_close(struct driver *drv)
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800766{
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800767 free(drv->priv);
768 drv->priv = NULL;
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800769}
770
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800771static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
772{
773 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700774 struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000775 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800776
Yiwei Zhang7648f062022-07-13 23:15:22 +0000777 bo->meta.num_planes =
778 i915_num_planes_from_modifier(bo->drv, data->format, data->format_modifier);
Robert Mader96058f92022-04-05 12:15:11 +0200779
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800780 ret = drv_prime_bo_import(bo, data);
781 if (ret)
782 return ret;
783
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000784 /* Set/Get tiling ioctl not supported based on fence availability
785 Refer : "https://patchwork.freedesktop.org/patch/325343/"
Yiwei Zhangcd1339f2023-01-03 20:06:17 +0000786 */
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000787 if (i915->num_fences_avail) {
788 /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
789 gem_get_tiling.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800790
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000791 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
792 if (ret) {
793 drv_gem_bo_destroy(bo);
794 drv_loge("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
795 return ret;
796 }
797 bo->meta.tiling = gem_get_tiling.tiling_mode;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800798 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800799 return 0;
800}
801
Gurchetan Singhee43c302017-11-14 18:20:27 -0800802static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
Gurchetan Singhef920532016-08-12 16:38:25 -0700803{
804 int ret;
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000805 void *addr = MAP_FAILED;
Gurchetan Singhef920532016-08-12 16:38:25 -0700806
Vipin Anand97e07de2022-08-12 04:47:34 +0000807 if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
808 (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
809 (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED))
Vipin Ananda0af3092020-06-17 10:53:02 +0530810 return MAP_FAILED;
811
Gurchetan Singh298b7572019-09-19 09:55:18 -0700812 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700813 struct drm_i915_gem_mmap gem_map = { 0 };
Tomasz Figa39eb9512018-11-01 00:45:31 +0900814 /* TODO(b/118799155): We don't seem to have a good way to
815 * detect the use cases for which WC mapping is really needed.
816 * The current heuristic seems overly coarse and may be slowing
817 * down some other use cases unnecessarily.
818 *
819 * For now, care must be taken not to use WC mappings for
820 * Renderscript and camera use cases, as they're
821 * performance-sensitive. */
Gurchetan Singh298b7572019-09-19 09:55:18 -0700822 if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
823 !(bo->meta.use_flags &
Tomasz Figa39eb9512018-11-01 00:45:31 +0900824 (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
Gurchetan Singh5af20232017-09-19 15:10:58 -0700825 gem_map.flags = I915_MMAP_WC;
826
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800827 gem_map.handle = bo->handles[0].u32;
828 gem_map.offset = 0;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700829 gem_map.size = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800830
831 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000832 /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
833 * file and returns a user space address directly, ie,
834 * doesn't go through mmap. If we try that on a
835 * dma-buf that doesn't have a shm file, i915.ko
836 * returns ENXIO. Fall through to
837 * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
838 * will mmap on the drm fd instead. */
839 if (ret == 0)
840 addr = (void *)(uintptr_t)gem_map.addr_ptr;
841 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800842
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000843 if (addr == MAP_FAILED) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700844 struct drm_i915_gem_mmap_gtt gem_map = { 0 };
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800845
846 gem_map.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800847 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
848 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000849 drv_loge("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800850 return MAP_FAILED;
851 }
852
Gurchetan Singh298b7572019-09-19 09:55:18 -0700853 addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED,
854 bo->drv->fd, gem_map.offset);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800855 }
856
857 if (addr == MAP_FAILED) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000858 drv_loge("i915 GEM mmap failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800859 return addr;
860 }
861
Gurchetan Singh298b7572019-09-19 09:55:18 -0700862 vma->length = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800863 return addr;
864}
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700865
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700866static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700867{
868 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700869 struct drm_i915_gem_set_domain set_domain = { 0 };
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700870
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700871 set_domain.handle = bo->handles[0].u32;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700872 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700873 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700874 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700875 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
876 } else {
877 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700878 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700879 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
880 }
881
882 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
883 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000884 drv_loge("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700885 return ret;
886 }
887
888 return 0;
889}
890
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700891static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800892{
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800893 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700894 if (!i915->has_llc && bo->meta.tiling == I915_TILING_NONE)
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700895 i915_clflush(mapping->vma->addr, mapping->vma->length);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800896
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700897 return 0;
Gurchetan Singhef920532016-08-12 16:38:25 -0700898}
899
Gurchetan Singh3e9d3832017-10-31 10:36:25 -0700900const struct backend backend_i915 = {
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700901 .name = "i915",
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700902 .init = i915_init,
903 .close = i915_close,
David Stevens26fe6822020-03-09 12:23:42 +0000904 .bo_compute_metadata = i915_bo_compute_metadata,
905 .bo_create_from_metadata = i915_bo_create_from_metadata,
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800906 .bo_destroy = drv_gem_bo_destroy,
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800907 .bo_import = i915_bo_import,
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700908 .bo_map = i915_bo_map,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700909 .bo_unmap = drv_bo_munmap,
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700910 .bo_invalidate = i915_bo_invalidate,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700911 .bo_flush = i915_bo_flush,
Yiwei Zhangb8ad7b82021-10-01 17:55:14 +0000912 .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
Robert Mader96058f92022-04-05 12:15:11 +0200913 .num_planes_from_modifier = i915_num_planes_from_modifier,
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700914};
915
916#endif