blob: 35c45eb17d1bc395f84ff80382fa791d67d5499d [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
Binu R S8d705182020-07-20 10:36:53 +053047struct modifier_support_t {
48 const uint64_t *order;
49 uint32_t count;
50};
51
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080052struct i915_device {
Gurchetan Singh68af9c22017-01-18 13:48:11 -080053 uint32_t gen;
54 int32_t has_llc;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -070055 int32_t has_hw_protection;
Binu R S8d705182020-07-20 10:36:53 +053056 struct modifier_support_t modifier;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080057 int device_id;
58 bool is_adlp;
Stéphane Marchesin25a26062014-09-12 16:18:59 -070059};
60
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080061static void i915_info_from_device_id(struct i915_device *i915)
Stéphane Marchesin25a26062014-09-12 16:18:59 -070062{
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080063 const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
64 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 };
Nicholas Bishopa2047242021-10-29 12:42:33 -040065 const uint16_t gen4_ids[] = { 0x29A2, 0x2992, 0x2982, 0x2972, 0x2A02, 0x2A12, 0x2A42,
66 0x2E02, 0x2E12, 0x2E22, 0x2E32, 0x2E42, 0x2E92 };
67 const uint16_t gen5_ids[] = { 0x0042, 0x0046 };
68 const uint16_t gen6_ids[] = { 0x0102, 0x0112, 0x0122, 0x0106, 0x0116, 0x0126, 0x010A };
69 const uint16_t gen7_ids[] = {
70 0x0152, 0x0162, 0x0156, 0x0166, 0x015a, 0x016a, 0x0402, 0x0412, 0x0422,
71 0x0406, 0x0416, 0x0426, 0x040A, 0x041A, 0x042A, 0x040B, 0x041B, 0x042B,
72 0x040E, 0x041E, 0x042E, 0x0C02, 0x0C12, 0x0C22, 0x0C06, 0x0C16, 0x0C26,
73 0x0C0A, 0x0C1A, 0x0C2A, 0x0C0B, 0x0C1B, 0x0C2B, 0x0C0E, 0x0C1E, 0x0C2E,
74 0x0A02, 0x0A12, 0x0A22, 0x0A06, 0x0A16, 0x0A26, 0x0A0A, 0x0A1A, 0x0A2A,
75 0x0A0B, 0x0A1B, 0x0A2B, 0x0A0E, 0x0A1E, 0x0A2E, 0x0D02, 0x0D12, 0x0D22,
76 0x0D06, 0x0D16, 0x0D26, 0x0D0A, 0x0D1A, 0x0D2A, 0x0D0B, 0x0D1B, 0x0D2B,
77 0x0D0E, 0x0D1E, 0x0D2E, 0x0F31, 0x0F32, 0x0F33, 0x0157, 0x0155
78 };
79 const uint16_t gen8_ids[] = { 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x1602, 0x1606,
80 0x160A, 0x160B, 0x160D, 0x160E, 0x1612, 0x1616,
81 0x161A, 0x161B, 0x161D, 0x161E, 0x1622, 0x1626,
82 0x162A, 0x162B, 0x162D, 0x162E };
83 const uint16_t gen9_ids[] = {
84 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913, 0x1915, 0x1916, 0x1917,
85 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, 0x1923, 0x1926, 0x1927, 0x192A, 0x192B,
86 0x192D, 0x1932, 0x193A, 0x193B, 0x193D, 0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85,
87 0x3184, 0x3185, 0x5902, 0x5906, 0x590A, 0x5908, 0x590B, 0x590E, 0x5913, 0x5915,
88 0x5917, 0x5912, 0x5916, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, 0x5923, 0x5926,
89 0x5927, 0x593B, 0x591C, 0x87C0, 0x87CA, 0x3E90, 0x3E93, 0x3E99, 0x3E9C, 0x3E91,
90 0x3E92, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3E94, 0x3EA9, 0x3EA5, 0x3EA6, 0x3EA7,
91 0x3EA8, 0x3EA1, 0x3EA4, 0x3EA0, 0x3EA3, 0x3EA2, 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4,
92 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5,
93 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, 0x9BE6, 0x9BF6
94 };
95 const uint16_t gen11_ids[] = { 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A56, 0x8A57,
96 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A71,
97 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571, 0x4E51,
98 0x4E55, 0x4E57, 0x4E61, 0x4E71 };
99 const uint16_t gen12_ids[] = {
100 0x4c8a, 0x4c8b, 0x4c8c, 0x4c90, 0x4c9a, 0x4680, 0x4681, 0x4682, 0x4683, 0x4688,
101 0x4689, 0x4690, 0x4691, 0x4692, 0x4693, 0x4698, 0x4699, 0x4626, 0x4628, 0x462a,
102 0x46a0, 0x46a1, 0x46a2, 0x46a3, 0x46a6, 0x46a8, 0x46aa, 0x46b0, 0x46b1, 0x46b2,
103 0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68,
104 0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908
105 };
Drew Davenport862d36f2021-06-09 19:54:04 -0600106 const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8,
107 0x46AA, 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1,
Sudarshan S69ccacd2022-02-18 07:31:46 +0530108 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3,
109 0x46D0, 0x46D1, 0x46D2 };
Stéphane Marchesina39dfde2014-09-15 15:38:25 -0700110 unsigned i;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800111 i915->gen = 4;
112 i915->is_adlp = false;
113
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800114 for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800115 if (gen3_ids[i] == i915->device_id)
116 i915->gen = 3;
117
Nicholas Bishopa2047242021-10-29 12:42:33 -0400118 /* Gen 4 */
119 for (i = 0; i < ARRAY_SIZE(gen4_ids); i++)
120 if (gen4_ids[i] == i915->device_id)
121 i915->gen = 4;
122
123 /* Gen 5 */
124 for (i = 0; i < ARRAY_SIZE(gen5_ids); i++)
125 if (gen5_ids[i] == i915->device_id)
126 i915->gen = 5;
127
128 /* Gen 6 */
129 for (i = 0; i < ARRAY_SIZE(gen6_ids); i++)
130 if (gen6_ids[i] == i915->device_id)
131 i915->gen = 6;
132
133 /* Gen 7 */
134 for (i = 0; i < ARRAY_SIZE(gen7_ids); i++)
135 if (gen7_ids[i] == i915->device_id)
136 i915->gen = 7;
137
138 /* Gen 8 */
139 for (i = 0; i < ARRAY_SIZE(gen8_ids); i++)
140 if (gen8_ids[i] == i915->device_id)
141 i915->gen = 8;
142
143 /* Gen 9 */
144 for (i = 0; i < ARRAY_SIZE(gen9_ids); i++)
145 if (gen9_ids[i] == i915->device_id)
146 i915->gen = 9;
147
Binu R S8d705182020-07-20 10:36:53 +0530148 /* Gen 11 */
149 for (i = 0; i < ARRAY_SIZE(gen11_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800150 if (gen11_ids[i] == i915->device_id)
151 i915->gen = 11;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700152
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700153 /* Gen 12 */
154 for (i = 0; i < ARRAY_SIZE(gen12_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800155 if (gen12_ids[i] == i915->device_id)
156 i915->gen = 12;
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700157
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800158 for (i = 0; i < ARRAY_SIZE(adlp_ids); i++)
159 if (adlp_ids[i] == i915->device_id) {
160 i915->is_adlp = true;
161 i915->gen = 12;
162 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700163}
164
Binu R S8d705182020-07-20 10:36:53 +0530165static void i915_get_modifier_order(struct i915_device *i915)
166{
Vipin Ananda0af3092020-06-17 10:53:02 +0530167 if (i915->gen == 12) {
168 i915->modifier.order = gen12_modifier_order;
169 i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
Cooper Chiouc8c61d32021-10-27 12:18:30 +0800170 }
171 else if (i915->gen == 11) {
172 i915->modifier.order = gen11_modifier_order;
173 i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
Vipin Ananda0af3092020-06-17 10:53:02 +0530174 } else {
175 i915->modifier.order = gen_modifier_order;
176 i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
177 }
Binu R S8d705182020-07-20 10:36:53 +0530178}
179
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000180static uint64_t unset_flags(uint64_t current_flags, uint64_t mask)
Kristian H. Kristensen9c3fb322018-04-11 15:55:13 -0700181{
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000182 uint64_t value = current_flags & ~mask;
183 return value;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800184}
185
186static int i915_add_combinations(struct driver *drv)
187{
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700188 struct i915_device *i915 = drv->priv;
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700189
Miguel Casasda47b7d2021-04-15 21:46:33 -0400190 const uint64_t scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT;
191 const uint64_t render = BO_USE_RENDER_MASK;
192 const uint64_t texture_only = BO_USE_TEXTURE_MASK;
Jeffrey Kardatzkedba19872020-12-04 16:58:28 -0800193 // HW protected buffers also need to be scanned out.
Miguel Casasda47b7d2021-04-15 21:46:33 -0400194 const uint64_t hw_protected =
195 i915->has_hw_protection ? (BO_USE_PROTECTED | BO_USE_SCANOUT) : 0;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700196
Miguel Casasabeadde2021-04-16 14:49:18 -0400197 const uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN |
198 BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY |
199 BO_USE_SW_WRITE_RARELY;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800200
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700201 struct format_metadata metadata_linear = { .tiling = I915_TILING_NONE,
202 .priority = 1,
203 .modifier = DRM_FORMAT_MOD_LINEAR };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800204
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000205 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400206 &metadata_linear, scanout_and_render);
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800207
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700208 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_linear,
209 render);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700210
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700211 drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats),
212 &metadata_linear, texture_only);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000213
214 drv_modify_linear_combinations(drv);
Hirokazu Hondafd8b8ab2020-06-16 15:28:56 +0900215
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900216 /* NV12 format for camera, display, decoding and encoding. */
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000217 /* IPU3 camera ISP supports only NV12 output. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400218 drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata_linear,
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900219 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700220 BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
221 hw_protected);
Hirokazu Honda3b8d4d02019-07-31 16:35:52 +0900222
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700223 /* Android CTS tests require this. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400224 drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata_linear, BO_USE_SW_MASK);
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700225
Tomasz Figad30c0a52017-07-05 17:50:18 +0900226 /*
227 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
David Stevens49518142020-06-15 13:48:48 +0900228 * from camera and input/output from hardware decoder/encoder.
Tomasz Figad30c0a52017-07-05 17:50:18 +0900229 */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400230 drv_modify_combination(drv, DRM_FORMAT_R8, &metadata_linear,
David Stevens49518142020-06-15 13:48:48 +0900231 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
232 BO_USE_HW_VIDEO_ENCODER);
Tomasz Figad30c0a52017-07-05 17:50:18 +0900233
Miguel Casasda47b7d2021-04-15 21:46:33 -0400234 const uint64_t render_not_linear = unset_flags(render, linear_mask);
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400235 const uint64_t scanout_and_render_not_linear = render_not_linear | BO_USE_SCANOUT;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800236
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700237 struct format_metadata metadata_x_tiled = { .tiling = I915_TILING_X,
238 .priority = 2,
239 .modifier = I915_FORMAT_MOD_X_TILED };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800240
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700241 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_x_tiled,
242 render_not_linear);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000243 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasda47b7d2021-04-15 21:46:33 -0400244 &metadata_x_tiled, scanout_and_render_not_linear);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700245
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700246 struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
247 .priority = 3,
248 .modifier = I915_FORMAT_MOD_Y_TILED };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800249
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000250/* Support y-tiled NV12 and P010 for libva */
251#ifdef I915_SCANOUT_Y_TILED
Miguel Casas231913e2021-04-06 19:17:25 -0400252 const uint64_t nv12_usage =
Jeffrey Kardatzkedba19872020-12-04 16:58:28 -0800253 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
Miguel Casas231913e2021-04-06 19:17:25 -0400254 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
255 (i915->gen >= 11 ? BO_USE_SCANOUT : 0);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000256#else
Miguel Casas231913e2021-04-06 19:17:25 -0400257 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
258 const uint64_t p010_usage = nv12_usage;
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000259#endif
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400260 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
261 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
Jeffrey Kardatzkedba19872020-12-04 16:58:28 -0800262
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700263 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_y_tiled,
264 render_not_linear);
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400265
266 // Y-tiled scanout isn't available on old platforms so we add
267 // |scanout_render_formats| without that USE flag.
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000268 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400269 &metadata_y_tiled, render_not_linear);
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800270 return 0;
271}
272
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800273static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
274 uint32_t *aligned_height)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700275{
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700276 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700277 uint32_t horizontal_alignment;
278 uint32_t vertical_alignment;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700279
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700280 switch (tiling) {
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700281 default:
282 case I915_TILING_NONE:
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700283 /*
284 * The Intel GPU doesn't need any alignment in linear mode,
285 * but libva requires the allocation stride to be aligned to
286 * 16 bytes and height to 4 rows. Further, we round up the
287 * horizontal alignment so that row start on a cache line (64
288 * bytes).
289 */
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800290#ifdef LINEAR_ALIGN_256
291 /*
292 * If we want to import these buffers to amdgpu they need to
293 * their match LINEAR_ALIGNED requirement of 256 byte alignement.
294 */
295 horizontal_alignment = 256;
296#else
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700297 horizontal_alignment = 64;
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800298#endif
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700299 vertical_alignment = 4;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700300 break;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800301
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700302 case I915_TILING_X:
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700303 horizontal_alignment = 512;
304 vertical_alignment = 8;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700305 break;
306
307 case I915_TILING_Y:
Yiwei Zhang17fa1a82022-02-04 00:39:06 +0000308 if (i915->gen == 3) {
Chad Versace0f9bd722022-01-20 11:36:02 -0800309 horizontal_alignment = 512;
310 vertical_alignment = 8;
Yiwei Zhang17fa1a82022-02-04 00:39:06 +0000311 } else {
312 horizontal_alignment = 128;
313 vertical_alignment = 32;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700314 }
315 break;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700316 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800317
David Stevens793675a2019-09-25 11:17:48 +0900318 *aligned_height = ALIGN(*aligned_height, vertical_alignment);
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700319 if (i915->gen > 3) {
320 *stride = ALIGN(*stride, horizontal_alignment);
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800321 } else {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700322 while (*stride > horizontal_alignment)
323 horizontal_alignment <<= 1;
324
325 *stride = horizontal_alignment;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800326 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800327
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700328 if (i915->gen <= 3 && *stride > 8192)
329 return -EINVAL;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800330
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700331 return 0;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700332}
333
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800334static void i915_clflush(void *start, size_t size)
335{
336 void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
337 void *end = (void *)((uintptr_t)start + size);
338
339 __builtin_ia32_mfence();
340 while (p < end) {
341 __builtin_ia32_clflush(p);
342 p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
343 }
344}
345
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800346static int i915_init(struct driver *drv)
347{
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800348 int ret;
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800349 struct i915_device *i915;
Gurchetan Singh99644382020-10-07 15:28:11 -0700350 drm_i915_getparam_t get_param = { 0 };
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800351
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800352 i915 = calloc(1, sizeof(*i915));
353 if (!i915)
354 return -ENOMEM;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800355
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800356 get_param.param = I915_PARAM_CHIPSET_ID;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800357 get_param.value = &(i915->device_id);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800358 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
359 if (ret) {
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700360 drv_log("Failed to get I915_PARAM_CHIPSET_ID\n");
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800361 free(i915);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800362 return -EINVAL;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800363 }
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800364 /* must call before i915->gen is used anywhere else */
365 i915_info_from_device_id(i915);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800366
Binu R S8d705182020-07-20 10:36:53 +0530367 i915_get_modifier_order(i915);
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800368
369 memset(&get_param, 0, sizeof(get_param));
370 get_param.param = I915_PARAM_HAS_LLC;
371 get_param.value = &i915->has_llc;
372 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
373 if (ret) {
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700374 drv_log("Failed to get I915_PARAM_HAS_LLC\n");
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800375 free(i915);
376 return -EINVAL;
377 }
378
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700379 if (i915->gen >= 12)
380 i915->has_hw_protection = 1;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800381
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700382 drv->priv = i915;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800383 return i915_add_combinations(drv);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800384}
385
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700386/*
387 * Returns true if the height of a buffer of the given format should be aligned
388 * to the largest coded unit (LCU) assuming that it will be used for video. This
389 * is based on gmmlib's GmmIsYUVFormatLCUAligned().
390 */
Drew Davenport862d36f2021-06-09 19:54:04 -0600391static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
392 const struct i915_device *i915)
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700393{
394 switch (format) {
395 case DRM_FORMAT_NV12:
396 case DRM_FORMAT_P010:
397 case DRM_FORMAT_P016:
398 return (i915->gen == 11 || i915->gen == 12) && plane == 1;
399 }
400 return false;
401}
402
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700403static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
404{
405 uint32_t offset;
406 size_t plane;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800407 int ret, pagesize;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700408 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700409
410 offset = 0;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800411 pagesize = getpagesize();
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700412
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700413 for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
414 uint32_t stride = drv_stride_from_format(format, width, plane);
415 uint32_t plane_height = drv_height_from_format(format, height, plane);
416
Gurchetan Singh298b7572019-09-19 09:55:18 -0700417 if (bo->meta.tiling != I915_TILING_NONE)
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800418 assert(IS_ALIGNED(offset, pagesize));
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700419
Gurchetan Singh298b7572019-09-19 09:55:18 -0700420 ret = i915_align_dimensions(bo, bo->meta.tiling, &stride, &plane_height);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700421 if (ret)
422 return ret;
423
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700424 if (i915_format_needs_LCU_alignment(format, plane, i915)) {
425 /*
426 * Align the height of the V plane for certain formats to the
427 * largest coded unit (assuming that this BO may be used for video)
428 * to be consistent with gmmlib.
429 */
430 plane_height = ALIGN(plane_height, 64);
431 }
432
Gurchetan Singh298b7572019-09-19 09:55:18 -0700433 bo->meta.strides[plane] = stride;
434 bo->meta.sizes[plane] = stride * plane_height;
435 bo->meta.offsets[plane] = offset;
436 offset += bo->meta.sizes[plane];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700437 }
438
Gurchetan Singh298b7572019-09-19 09:55:18 -0700439 bo->meta.total_size = ALIGN(offset, pagesize);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700440
441 return 0;
442}
443
Robert Mader96058f92022-04-05 12:15:11 +0200444static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format,
445 uint64_t modifier)
446{
447 size_t num_planes = drv_num_planes_from_format(format);
448 if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
449 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
450 assert(num_planes == 1);
451 return 2;
452 }
453
454 return num_planes;
455}
456
David Stevens26fe6822020-03-09 12:23:42 +0000457static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
458 uint64_t use_flags, const uint64_t *modifiers, uint32_t count)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700459{
David Stevens26fe6822020-03-09 12:23:42 +0000460 uint64_t modifier;
Sean Paula9d3f772020-05-19 10:17:07 -0400461 struct i915_device *i915 = bo->drv->priv;
Abhishek Kumard39fe4e2020-10-09 16:08:01 +0530462 bool huge_bo = (i915->gen < 11) && (width > 4096);
David Stevens26fe6822020-03-09 12:23:42 +0000463
464 if (modifiers) {
465 modifier =
Binu R S8d705182020-07-20 10:36:53 +0530466 drv_pick_modifier(modifiers, count, i915->modifier.order, i915->modifier.count);
David Stevens26fe6822020-03-09 12:23:42 +0000467 } else {
468 struct combination *combo = drv_get_combination(bo->drv, format, use_flags);
469 if (!combo)
470 return -EINVAL;
471 modifier = combo->metadata.modifier;
472 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700473
Sean Paula9d3f772020-05-19 10:17:07 -0400474 /*
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530475 * i915 only supports linear/x-tiled above 4096 wide on Gen9/Gen10 GPU.
476 * VAAPI decode in NV12 Y tiled format so skip modifier change for NV12/P010 huge bo.
Sean Paula9d3f772020-05-19 10:17:07 -0400477 */
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530478 if (huge_bo && format != DRM_FORMAT_NV12 && format != DRM_FORMAT_P010 &&
479 modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) {
Sean Paula9d3f772020-05-19 10:17:07 -0400480 uint32_t i;
481 for (i = 0; modifiers && i < count; i++) {
482 if (modifiers[i] == I915_FORMAT_MOD_X_TILED)
483 break;
484 }
485 if (i == count)
486 modifier = DRM_FORMAT_MOD_LINEAR;
487 else
488 modifier = I915_FORMAT_MOD_X_TILED;
489 }
490
Pilar Molina Lopez28cf2f12020-11-12 18:19:42 -0500491 /*
492 * Skip I915_FORMAT_MOD_Y_TILED_CCS modifier if compression is disabled
493 * Pick y tiled modifier if it has been passed in, otherwise use linear
494 */
495 if (!bo->drv->compression && modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
496 uint32_t i;
497 for (i = 0; modifiers && i < count; i++) {
498 if (modifiers[i] == I915_FORMAT_MOD_Y_TILED)
499 break;
500 }
501 if (i == count)
502 modifier = DRM_FORMAT_MOD_LINEAR;
503 else
504 modifier = I915_FORMAT_MOD_Y_TILED;
505 }
506
Nicholas Bishopa2047242021-10-29 12:42:33 -0400507 /* Prevent gen 8 and earlier from trying to use a tiling modifier */
508 if (i915->gen <= 8 && format == DRM_FORMAT_ARGB8888) {
509 modifier = DRM_FORMAT_MOD_LINEAR;
510 }
511
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700512 switch (modifier) {
513 case DRM_FORMAT_MOD_LINEAR:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700514 bo->meta.tiling = I915_TILING_NONE;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700515 break;
516 case I915_FORMAT_MOD_X_TILED:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700517 bo->meta.tiling = I915_TILING_X;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700518 break;
519 case I915_FORMAT_MOD_Y_TILED:
Mark Yacoubc9565642020-02-07 11:02:22 -0500520 case I915_FORMAT_MOD_Y_TILED_CCS:
Vipin Ananda0af3092020-06-17 10:53:02 +0530521 /* For now support only I915_TILING_Y as this works with all
522 * IPs(render/media/display)
523 */
524 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700525 bo->meta.tiling = I915_TILING_Y;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700526 break;
527 }
Owen Linbbb69fd2017-06-05 14:33:08 +0800528
Gurchetan Singh52155b42021-01-27 17:55:17 -0800529 bo->meta.format_modifier = modifier;
Kristian H. Kristensen2b8f89e2018-02-07 16:10:06 -0800530
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700531 if (format == DRM_FORMAT_YVU420_ANDROID) {
532 /*
533 * We only need to be able to use this as a linear texture,
534 * which doesn't put any HW restrictions on how we lay it
535 * out. The Android format does require the stride to be a
536 * multiple of 16 and expects the Cr and Cb stride to be
537 * ALIGN(Y_stride / 2, 16), which we can make happen by
538 * aligning to 32 bytes here.
539 */
540 uint32_t stride = ALIGN(width, 32);
541 drv_bo_from_format(bo, stride, height, format);
Mark Yacoubc9565642020-02-07 11:02:22 -0500542 } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
543 /*
544 * For compressed surfaces, we need a color control surface
545 * (CCS). Color compression is only supported for Y tiled
546 * surfaces, and for each 32x16 tiles in the main surface we
547 * need a tile in the control surface. Y tiles are 128 bytes
548 * wide and 32 lines tall and we use that to first compute the
549 * width and height in tiles of the main surface. stride and
550 * height are already multiples of 128 and 32, respectively:
551 */
552 uint32_t stride = drv_stride_from_format(format, width, 0);
553 uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128);
554 uint32_t height_in_tiles = DIV_ROUND_UP(height, 32);
555 uint32_t size = width_in_tiles * height_in_tiles * 4096;
556 uint32_t offset = 0;
557
558 bo->meta.strides[0] = width_in_tiles * 128;
559 bo->meta.sizes[0] = size;
560 bo->meta.offsets[0] = offset;
561 offset += size;
562
563 /*
564 * Now, compute the width and height in tiles of the control
565 * surface by dividing and rounding up.
566 */
567 uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32);
568 uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16);
569 uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096;
570
571 /*
572 * With stride and height aligned to y tiles, offset is
573 * already a multiple of 4096, which is the required alignment
574 * of the CCS.
575 */
576 bo->meta.strides[1] = ccs_width_in_tiles * 128;
577 bo->meta.sizes[1] = ccs_size;
578 bo->meta.offsets[1] = offset;
579 offset += ccs_size;
580
Robert Mader96058f92022-04-05 12:15:11 +0200581 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Mark Yacoubc9565642020-02-07 11:02:22 -0500582 bo->meta.total_size = offset;
Vipin Ananda0af3092020-06-17 10:53:02 +0530583 } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
584
585 /*
586 * considering only 128 byte compression and one cache line of
587 * aux buffer(64B) contains compression status of 4-Y tiles.
588 * Which is 4 * (128B * 32L).
589 * line stride(bytes) is 4 * 128B
590 * and tile stride(lines) is 32L
591 */
592 uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
593
594 height = ALIGN(drv_height_from_format(format, height, 0), 32);
595
596 if (i915->is_adlp && (stride > 1)) {
597 stride = 1 << (32 - __builtin_clz(stride - 1));
598 height = ALIGN(drv_height_from_format(format, height, 0), 128);
599 }
600
601 bo->meta.strides[0] = stride;
602 /* size calculation and alignment are 64KB aligned
603 * size as per spec
604 */
605 bo->meta.sizes[0] = ALIGN(stride * height, 65536);
606 bo->meta.offsets[0] = 0;
607
608 /* Aux buffer is linear and page aligned. It is placed after
609 * other planes and aligned to main buffer stride.
610 */
611 bo->meta.strides[1] = bo->meta.strides[0] / 8;
612 /* Aligned to page size */
613 bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
614 bo->meta.offsets[1] = bo->meta.sizes[0];
615 /* Total number of planes & sizes */
Robert Mader96058f92022-04-05 12:15:11 +0200616 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Vipin Ananda0af3092020-06-17 10:53:02 +0530617 bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700618 } else {
619 i915_bo_from_format(bo, width, height, format);
620 }
David Stevens26fe6822020-03-09 12:23:42 +0000621 return 0;
622}
623
624static int i915_bo_create_from_metadata(struct bo *bo)
625{
626 int ret;
627 size_t plane;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700628 uint32_t gem_handle;
Gurchetan Singh99644382020-10-07 15:28:11 -0700629 struct drm_i915_gem_set_tiling gem_set_tiling = { 0 };
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700630 struct i915_device *i915 = bo->drv->priv;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800631
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700632 if (i915->has_hw_protection && (bo->meta.use_flags & BO_USE_PROTECTED)) {
Juston Lief852e02021-08-02 11:02:45 -0700633 struct drm_i915_gem_create_ext_protected_content protected_content = {
634 .base = { .name = I915_GEM_CREATE_EXT_PROTECTED_CONTENT },
635 .flags = 0,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700636 };
637
638 struct drm_i915_gem_create_ext create_ext = {
639 .size = bo->meta.total_size,
Juston Lief852e02021-08-02 11:02:45 -0700640 .extensions = (uintptr_t)&protected_content,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700641 };
642
643 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
644 if (ret) {
Juston Lief852e02021-08-02 11:02:45 -0700645 drv_log("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
646 create_ext.size, ret);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700647 return -errno;
648 }
649
650 gem_handle = create_ext.handle;
651 } else {
652 struct drm_i915_gem_create gem_create = { 0 };
653 gem_create.size = bo->meta.total_size;
654 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
655 if (ret) {
656 drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
657 return -errno;
658 }
659
660 gem_handle = gem_create.handle;
Ilja H. Friedelf9d2ab72015-04-09 14:08:36 -0700661 }
Gurchetan Singh83dc4fb2016-07-19 15:52:33 -0700662
Gurchetan Singh298b7572019-09-19 09:55:18 -0700663 for (plane = 0; plane < bo->meta.num_planes; plane++)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700664 bo->handles[plane].u32 = gem_handle;
Daniel Nicoara1de26dc2014-09-25 18:53:19 -0400665
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800666 gem_set_tiling.handle = bo->handles[0].u32;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700667 gem_set_tiling.tiling_mode = bo->meta.tiling;
668 gem_set_tiling.stride = bo->meta.strides[0];
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700669
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800670 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
671 if (ret) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700672 struct drm_gem_close gem_close = { 0 };
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800673 gem_close.handle = bo->handles[0].u32;
674 drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800675
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700676 drv_log("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700677 return -errno;
678 }
679
680 return 0;
681}
682
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800683static void i915_close(struct driver *drv)
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800684{
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800685 free(drv->priv);
686 drv->priv = NULL;
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800687}
688
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800689static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
690{
691 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700692 struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800693
Robert Mader96058f92022-04-05 12:15:11 +0200694 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, data->format,
695 data->format_modifier);
696
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800697 ret = drv_prime_bo_import(bo, data);
698 if (ret)
699 return ret;
700
701 /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800702 gem_get_tiling.handle = bo->handles[0].u32;
703
704 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
705 if (ret) {
Joe Kniss9e5d12a2017-06-29 11:54:22 -0700706 drv_gem_bo_destroy(bo);
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700707 drv_log("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800708 return ret;
709 }
710
Gurchetan Singh298b7572019-09-19 09:55:18 -0700711 bo->meta.tiling = gem_get_tiling.tiling_mode;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800712 return 0;
713}
714
Gurchetan Singhee43c302017-11-14 18:20:27 -0800715static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
Gurchetan Singhef920532016-08-12 16:38:25 -0700716{
717 int ret;
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000718 void *addr = MAP_FAILED;
Gurchetan Singhef920532016-08-12 16:38:25 -0700719
Gurchetan Singh52155b42021-01-27 17:55:17 -0800720 if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS)
Mark Yacoubc9565642020-02-07 11:02:22 -0500721 return MAP_FAILED;
722
Vipin Ananda0af3092020-06-17 10:53:02 +0530723 if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS)
724 return MAP_FAILED;
725
Gurchetan Singh298b7572019-09-19 09:55:18 -0700726 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700727 struct drm_i915_gem_mmap gem_map = { 0 };
Tomasz Figa39eb9512018-11-01 00:45:31 +0900728 /* TODO(b/118799155): We don't seem to have a good way to
729 * detect the use cases for which WC mapping is really needed.
730 * The current heuristic seems overly coarse and may be slowing
731 * down some other use cases unnecessarily.
732 *
733 * For now, care must be taken not to use WC mappings for
734 * Renderscript and camera use cases, as they're
735 * performance-sensitive. */
Gurchetan Singh298b7572019-09-19 09:55:18 -0700736 if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
737 !(bo->meta.use_flags &
Tomasz Figa39eb9512018-11-01 00:45:31 +0900738 (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
Gurchetan Singh5af20232017-09-19 15:10:58 -0700739 gem_map.flags = I915_MMAP_WC;
740
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800741 gem_map.handle = bo->handles[0].u32;
742 gem_map.offset = 0;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700743 gem_map.size = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800744
745 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000746 /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
747 * file and returns a user space address directly, ie,
748 * doesn't go through mmap. If we try that on a
749 * dma-buf that doesn't have a shm file, i915.ko
750 * returns ENXIO. Fall through to
751 * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
752 * will mmap on the drm fd instead. */
753 if (ret == 0)
754 addr = (void *)(uintptr_t)gem_map.addr_ptr;
755 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800756
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000757 if (addr == MAP_FAILED) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700758 struct drm_i915_gem_mmap_gtt gem_map = { 0 };
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800759
760 gem_map.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800761 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
762 if (ret) {
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700763 drv_log("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800764 return MAP_FAILED;
765 }
766
Gurchetan Singh298b7572019-09-19 09:55:18 -0700767 addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED,
768 bo->drv->fd, gem_map.offset);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800769 }
770
771 if (addr == MAP_FAILED) {
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700772 drv_log("i915 GEM mmap failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800773 return addr;
774 }
775
Gurchetan Singh298b7572019-09-19 09:55:18 -0700776 vma->length = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800777 return addr;
778}
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700779
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700780static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700781{
782 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700783 struct drm_i915_gem_set_domain set_domain = { 0 };
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700784
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700785 set_domain.handle = bo->handles[0].u32;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700786 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700787 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700788 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700789 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
790 } else {
791 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700792 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700793 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
794 }
795
796 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
797 if (ret) {
Alistair Strachan0cfaaa52018-03-19 14:03:23 -0700798 drv_log("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700799 return ret;
800 }
801
802 return 0;
803}
804
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700805static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800806{
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800807 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700808 if (!i915->has_llc && bo->meta.tiling == I915_TILING_NONE)
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700809 i915_clflush(mapping->vma->addr, mapping->vma->length);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800810
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700811 return 0;
Gurchetan Singhef920532016-08-12 16:38:25 -0700812}
813
Gurchetan Singh3e9d3832017-10-31 10:36:25 -0700814const struct backend backend_i915 = {
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700815 .name = "i915",
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700816 .init = i915_init,
817 .close = i915_close,
David Stevens26fe6822020-03-09 12:23:42 +0000818 .bo_compute_metadata = i915_bo_compute_metadata,
819 .bo_create_from_metadata = i915_bo_create_from_metadata,
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800820 .bo_destroy = drv_gem_bo_destroy,
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800821 .bo_import = i915_bo_import,
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700822 .bo_map = i915_bo_map,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700823 .bo_unmap = drv_bo_munmap,
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700824 .bo_invalidate = i915_bo_invalidate,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700825 .bo_flush = i915_bo_flush,
Yiwei Zhangb8ad7b82021-10-01 17:55:14 +0000826 .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
Robert Mader96058f92022-04-05 12:15:11 +0200827 .num_planes_from_modifier = i915_num_planes_from_modifier,
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700828};
829
830#endif