0116-drm-vc4-Add-support-for-MSAA-rendering.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. From c682c50a4564b43a43791dc03d0aa7c8848b2564 Mon Sep 17 00:00:00 2001
  2. From: Eric Anholt <eric@anholt.net>
  3. Date: Fri, 17 Jul 2015 13:15:50 -0700
  4. Subject: [PATCH] drm/vc4: Add support for MSAA rendering.
  5. For MSAA, you set a bit in the binner that halves the size of tiles in
  6. each direction, so you can pack 4 samples per pixel in the tile
  7. buffer. During rendering, you can load and store raw tile buffer
  8. contents (to save the per-sample MSAA contents), or you can load/store
  9. resolved tile buffer contents (loads spam the pixel value to all 4
  10. samples, and stores either average the 4 color samples, or store the
  11. first sample for Z/S).
  12. Signed-off-by: Eric Anholt <eric@anholt.net>
  13. ---
  14. drivers/gpu/drm/vc4/vc4_packet.h | 23 ++-
  15. drivers/gpu/drm/vc4/vc4_render_cl.c | 274 ++++++++++++++++++++++++++++++------
  16. drivers/gpu/drm/vc4/vc4_validate.c | 5 +-
  17. include/uapi/drm/vc4_drm.h | 11 +-
  18. 4 files changed, 258 insertions(+), 55 deletions(-)
  19. --- a/drivers/gpu/drm/vc4/vc4_packet.h
  20. +++ b/drivers/gpu/drm/vc4/vc4_packet.h
  21. @@ -123,6 +123,11 @@ enum vc4_packet {
  22. #define VC4_PACKET_TILE_COORDINATES_SIZE 3
  23. #define VC4_PACKET_GEM_HANDLES_SIZE 9
  24. +/* Number of multisamples supported. */
  25. +#define VC4_MAX_SAMPLES 4
  26. +/* Size of a full resolution color or Z tile buffer load/store. */
  27. +#define VC4_TILE_BUFFER_SIZE (64 * 64 * 4)
  28. +
  29. /** @{
  30. * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and
  31. * VC4_PACKET_TILE_RENDERING_MODE_CONFIG.
  32. @@ -137,10 +142,20 @@ enum vc4_packet {
  33. * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and
  34. * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER.
  35. */
  36. -#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3)
  37. -#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2)
  38. -#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1)
  39. -#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0)
  40. +#define VC4_LOADSTORE_FULL_RES_EOF BIT(3)
  41. +#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2)
  42. +#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1)
  43. +#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0)
  44. +
  45. +/** @{
  46. + *
  47. + * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and
  48. + * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER.
  49. + */
  50. +#define VC4_LOADSTORE_FULL_RES_EOF BIT(3)
  51. +#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2)
  52. +#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1)
  53. +#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0)
  54. /** @{
  55. *
  56. --- a/drivers/gpu/drm/vc4/vc4_render_cl.c
  57. +++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
  58. @@ -37,9 +37,11 @@
  59. struct vc4_rcl_setup {
  60. struct drm_gem_cma_object *color_read;
  61. - struct drm_gem_cma_object *color_ms_write;
  62. + struct drm_gem_cma_object *color_write;
  63. struct drm_gem_cma_object *zs_read;
  64. struct drm_gem_cma_object *zs_write;
  65. + struct drm_gem_cma_object *msaa_color_write;
  66. + struct drm_gem_cma_object *msaa_zs_write;
  67. struct drm_gem_cma_object *rcl;
  68. u32 next_offset;
  69. @@ -82,6 +84,22 @@ static void vc4_store_before_load(struct
  70. }
  71. /*
  72. + * Calculates the physical address of the start of a tile in a RCL surface.
  73. + *
  74. + * Unlike the other load/store packets,
  75. + * VC4_PACKET_LOAD/STORE_FULL_RES_TILE_BUFFER don't look at the tile
  76. + * coordinates packet, and instead just store to the address given.
  77. + */
  78. +static uint32_t vc4_full_res_offset(struct vc4_exec_info *exec,
  79. + struct drm_gem_cma_object *bo,
  80. + struct drm_vc4_submit_rcl_surface *surf,
  81. + uint8_t x, uint8_t y)
  82. +{
  83. + return bo->paddr + surf->offset + VC4_TILE_BUFFER_SIZE *
  84. + (DIV_ROUND_UP(exec->args->width, 32) * y + x);
  85. +}
  86. +
  87. +/*
  88. * Emits a PACKET_TILE_COORDINATES if one isn't already pending.
  89. *
  90. * The tile coordinates packet triggers a pending load if there is one, are
  91. @@ -108,22 +126,41 @@ static void emit_tile(struct vc4_exec_in
  92. * may be outstanding at a time.
  93. */
  94. if (setup->color_read) {
  95. - rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
  96. - rcl_u16(setup, args->color_read.bits);
  97. - rcl_u32(setup,
  98. - setup->color_read->paddr + args->color_read.offset);
  99. + if (args->color_read.flags &
  100. + VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  101. + rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
  102. + rcl_u32(setup,
  103. + vc4_full_res_offset(exec, setup->color_read,
  104. + &args->color_read, x, y) |
  105. + VC4_LOADSTORE_FULL_RES_DISABLE_ZS);
  106. + } else {
  107. + rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
  108. + rcl_u16(setup, args->color_read.bits);
  109. + rcl_u32(setup, setup->color_read->paddr +
  110. + args->color_read.offset);
  111. + }
  112. }
  113. if (setup->zs_read) {
  114. - if (setup->color_read) {
  115. - /* Exec previous load. */
  116. - vc4_tile_coordinates(setup, x, y);
  117. - vc4_store_before_load(setup);
  118. + if (args->zs_read.flags &
  119. + VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  120. + rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
  121. + rcl_u32(setup,
  122. + vc4_full_res_offset(exec, setup->zs_read,
  123. + &args->zs_read, x, y) |
  124. + VC4_LOADSTORE_FULL_RES_DISABLE_COLOR);
  125. + } else {
  126. + if (setup->color_read) {
  127. + /* Exec previous load. */
  128. + vc4_tile_coordinates(setup, x, y);
  129. + vc4_store_before_load(setup);
  130. + }
  131. +
  132. + rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
  133. + rcl_u16(setup, args->zs_read.bits);
  134. + rcl_u32(setup, setup->zs_read->paddr +
  135. + args->zs_read.offset);
  136. }
  137. -
  138. - rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
  139. - rcl_u16(setup, args->zs_read.bits);
  140. - rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset);
  141. }
  142. /* Clipping depends on tile coordinates having been
  143. @@ -144,20 +181,60 @@ static void emit_tile(struct vc4_exec_in
  144. (y * exec->bin_tiles_x + x) * 32));
  145. }
  146. + if (setup->msaa_color_write) {
  147. + bool last_tile_write = (!setup->msaa_zs_write &&
  148. + !setup->zs_write &&
  149. + !setup->color_write);
  150. + uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_ZS;
  151. +
  152. + if (!last_tile_write)
  153. + bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
  154. + else if (last)
  155. + bits |= VC4_LOADSTORE_FULL_RES_EOF;
  156. + rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
  157. + rcl_u32(setup,
  158. + vc4_full_res_offset(exec, setup->msaa_color_write,
  159. + &args->msaa_color_write, x, y) |
  160. + bits);
  161. + }
  162. +
  163. + if (setup->msaa_zs_write) {
  164. + bool last_tile_write = (!setup->zs_write &&
  165. + !setup->color_write);
  166. + uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_COLOR;
  167. +
  168. + if (setup->msaa_color_write)
  169. + vc4_tile_coordinates(setup, x, y);
  170. + if (!last_tile_write)
  171. + bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
  172. + else if (last)
  173. + bits |= VC4_LOADSTORE_FULL_RES_EOF;
  174. + rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
  175. + rcl_u32(setup,
  176. + vc4_full_res_offset(exec, setup->msaa_zs_write,
  177. + &args->msaa_zs_write, x, y) |
  178. + bits);
  179. + }
  180. +
  181. if (setup->zs_write) {
  182. + bool last_tile_write = !setup->color_write;
  183. +
  184. + if (setup->msaa_color_write || setup->msaa_zs_write)
  185. + vc4_tile_coordinates(setup, x, y);
  186. +
  187. rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
  188. rcl_u16(setup, args->zs_write.bits |
  189. - (setup->color_ms_write ?
  190. - VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0));
  191. + (last_tile_write ?
  192. + 0 : VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR));
  193. rcl_u32(setup,
  194. (setup->zs_write->paddr + args->zs_write.offset) |
  195. - ((last && !setup->color_ms_write) ?
  196. + ((last && last_tile_write) ?
  197. VC4_LOADSTORE_TILE_BUFFER_EOF : 0));
  198. }
  199. - if (setup->color_ms_write) {
  200. - if (setup->zs_write) {
  201. - /* Reset after previous store */
  202. + if (setup->color_write) {
  203. + if (setup->msaa_color_write || setup->msaa_zs_write ||
  204. + setup->zs_write) {
  205. vc4_tile_coordinates(setup, x, y);
  206. }
  207. @@ -192,14 +269,26 @@ static int vc4_create_rcl_bo(struct drm_
  208. }
  209. if (setup->color_read) {
  210. - loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE);
  211. + if (args->color_read.flags &
  212. + VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  213. + loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
  214. + } else {
  215. + loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
  216. + }
  217. }
  218. if (setup->zs_read) {
  219. - if (setup->color_read) {
  220. - loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
  221. - loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
  222. + if (args->zs_read.flags &
  223. + VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  224. + loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
  225. + } else {
  226. + if (setup->color_read &&
  227. + !(args->color_read.flags &
  228. + VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES)) {
  229. + loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
  230. + loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
  231. + }
  232. + loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
  233. }
  234. - loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
  235. }
  236. if (has_bin) {
  237. @@ -207,13 +296,23 @@ static int vc4_create_rcl_bo(struct drm_
  238. loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE;
  239. }
  240. + if (setup->msaa_color_write)
  241. + loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
  242. + if (setup->msaa_zs_write)
  243. + loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
  244. +
  245. if (setup->zs_write)
  246. loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
  247. - if (setup->color_ms_write) {
  248. - if (setup->zs_write)
  249. - loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
  250. + if (setup->color_write)
  251. loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE;
  252. - }
  253. +
  254. + /* We need a VC4_PACKET_TILE_COORDINATES in between each store. */
  255. + loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE *
  256. + ((setup->msaa_color_write != NULL) +
  257. + (setup->msaa_zs_write != NULL) +
  258. + (setup->color_write != NULL) +
  259. + (setup->zs_write != NULL) - 1);
  260. +
  261. size += xtiles * ytiles * loop_body_size;
  262. setup->rcl = &vc4_bo_create(dev, size, true)->base;
  263. @@ -224,13 +323,12 @@ static int vc4_create_rcl_bo(struct drm_
  264. rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
  265. rcl_u32(setup,
  266. - (setup->color_ms_write ?
  267. - (setup->color_ms_write->paddr +
  268. - args->color_ms_write.offset) :
  269. + (setup->color_write ? (setup->color_write->paddr +
  270. + args->color_write.offset) :
  271. 0));
  272. rcl_u16(setup, args->width);
  273. rcl_u16(setup, args->height);
  274. - rcl_u16(setup, args->color_ms_write.bits);
  275. + rcl_u16(setup, args->color_write.bits);
  276. /* The tile buffer gets cleared when the previous tile is stored. If
  277. * the clear values changed between frames, then the tile buffer has
  278. @@ -267,6 +365,56 @@ static int vc4_create_rcl_bo(struct drm_
  279. return 0;
  280. }
  281. +static int vc4_full_res_bounds_check(struct vc4_exec_info *exec,
  282. + struct drm_gem_cma_object *obj,
  283. + struct drm_vc4_submit_rcl_surface *surf)
  284. +{
  285. + struct drm_vc4_submit_cl *args = exec->args;
  286. + u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32);
  287. +
  288. + if (surf->offset > obj->base.size) {
  289. + DRM_ERROR("surface offset %d > BO size %zd\n",
  290. + surf->offset, obj->base.size);
  291. + return -EINVAL;
  292. + }
  293. +
  294. + if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE <
  295. + render_tiles_stride * args->max_y_tile + args->max_x_tile) {
  296. + DRM_ERROR("MSAA tile %d, %d out of bounds "
  297. + "(bo size %zd, offset %d).\n",
  298. + args->max_x_tile, args->max_y_tile,
  299. + obj->base.size,
  300. + surf->offset);
  301. + return -EINVAL;
  302. + }
  303. +
  304. + return 0;
  305. +}
  306. +
  307. +static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
  308. + struct drm_gem_cma_object **obj,
  309. + struct drm_vc4_submit_rcl_surface *surf)
  310. +{
  311. + if (surf->flags != 0 || surf->bits != 0) {
  312. + DRM_ERROR("MSAA surface had nonzero flags/bits\n");
  313. + return -EINVAL;
  314. + }
  315. +
  316. + if (surf->hindex == ~0)
  317. + return 0;
  318. +
  319. + *obj = vc4_use_bo(exec, surf->hindex);
  320. + if (!*obj)
  321. + return -EINVAL;
  322. +
  323. + if (surf->offset & 0xf) {
  324. + DRM_ERROR("MSAA write must be 16b aligned.\n");
  325. + return -EINVAL;
  326. + }
  327. +
  328. + return vc4_full_res_bounds_check(exec, *obj, surf);
  329. +}
  330. +
  331. static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
  332. struct drm_gem_cma_object **obj,
  333. struct drm_vc4_submit_rcl_surface *surf)
  334. @@ -278,9 +426,10 @@ static int vc4_rcl_surface_setup(struct
  335. uint8_t format = VC4_GET_FIELD(surf->bits,
  336. VC4_LOADSTORE_TILE_BUFFER_FORMAT);
  337. int cpp;
  338. + int ret;
  339. - if (surf->pad != 0) {
  340. - DRM_ERROR("Padding unset\n");
  341. + if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  342. + DRM_ERROR("Extra flags set\n");
  343. return -EINVAL;
  344. }
  345. @@ -290,6 +439,25 @@ static int vc4_rcl_surface_setup(struct
  346. if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj))
  347. return -EINVAL;
  348. + if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
  349. + if (surf == &exec->args->zs_write) {
  350. + DRM_ERROR("general zs write may not be a full-res.\n");
  351. + return -EINVAL;
  352. + }
  353. +
  354. + if (surf->bits != 0) {
  355. + DRM_ERROR("load/store general bits set with "
  356. + "full res load/store.\n");
  357. + return -EINVAL;
  358. + }
  359. +
  360. + ret = vc4_full_res_bounds_check(exec, *obj, surf);
  361. + if (!ret)
  362. + return ret;
  363. +
  364. + return 0;
  365. + }
  366. +
  367. if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
  368. VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
  369. VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
  370. @@ -341,9 +509,10 @@ static int vc4_rcl_surface_setup(struct
  371. }
  372. static int
  373. -vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec,
  374. - struct drm_gem_cma_object **obj,
  375. - struct drm_vc4_submit_rcl_surface *surf)
  376. +vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
  377. + struct vc4_rcl_setup *setup,
  378. + struct drm_gem_cma_object **obj,
  379. + struct drm_vc4_submit_rcl_surface *surf)
  380. {
  381. uint8_t tiling = VC4_GET_FIELD(surf->bits,
  382. VC4_RENDER_CONFIG_MEMORY_FORMAT);
  383. @@ -351,13 +520,15 @@ vc4_rcl_ms_surface_setup(struct vc4_exec
  384. VC4_RENDER_CONFIG_FORMAT);
  385. int cpp;
  386. - if (surf->pad != 0) {
  387. - DRM_ERROR("Padding unset\n");
  388. + if (surf->flags != 0) {
  389. + DRM_ERROR("No flags supported on render config.\n");
  390. return -EINVAL;
  391. }
  392. if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK |
  393. - VC4_RENDER_CONFIG_FORMAT_MASK)) {
  394. + VC4_RENDER_CONFIG_FORMAT_MASK |
  395. + VC4_RENDER_CONFIG_MS_MODE_4X |
  396. + VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) {
  397. DRM_ERROR("Unknown bits in render config: 0x%04x\n",
  398. surf->bits);
  399. return -EINVAL;
  400. @@ -413,18 +584,20 @@ int vc4_get_rcl(struct drm_device *dev,
  401. if (has_bin &&
  402. (args->max_x_tile > exec->bin_tiles_x ||
  403. args->max_y_tile > exec->bin_tiles_y)) {
  404. - DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n",
  405. + DRM_ERROR("Render tiles (%d,%d) outside of bin config "
  406. + "(%d,%d)\n",
  407. args->max_x_tile, args->max_y_tile,
  408. exec->bin_tiles_x, exec->bin_tiles_y);
  409. return -EINVAL;
  410. }
  411. - ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
  412. + ret = vc4_rcl_render_config_surface_setup(exec, &setup,
  413. + &setup.color_write,
  414. + &args->color_write);
  415. if (ret)
  416. return ret;
  417. - ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write,
  418. - &args->color_ms_write);
  419. + ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
  420. if (ret)
  421. return ret;
  422. @@ -436,10 +609,21 @@ int vc4_get_rcl(struct drm_device *dev,
  423. if (ret)
  424. return ret;
  425. + ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_color_write,
  426. + &args->msaa_color_write);
  427. + if (ret)
  428. + return ret;
  429. +
  430. + ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_zs_write,
  431. + &args->msaa_zs_write);
  432. + if (ret)
  433. + return ret;
  434. +
  435. /* We shouldn't even have the job submitted to us if there's no
  436. * surface to write out.
  437. */
  438. - if (!setup.color_ms_write && !setup.zs_write) {
  439. + if (!setup.color_write && !setup.zs_write &&
  440. + !setup.msaa_color_write && !setup.msaa_zs_write) {
  441. DRM_ERROR("RCL requires color or Z/S write\n");
  442. return -EINVAL;
  443. }
  444. --- a/drivers/gpu/drm/vc4/vc4_validate.c
  445. +++ b/drivers/gpu/drm/vc4/vc4_validate.c
  446. @@ -400,9 +400,8 @@ validate_tile_binning_config(VALIDATE_AR
  447. }
  448. if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
  449. - VC4_BIN_CONFIG_TILE_BUFFER_64BIT |
  450. - VC4_BIN_CONFIG_MS_MODE_4X)) {
  451. - DRM_ERROR("unsupported bining config flags 0x%02x\n", flags);
  452. + VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) {
  453. + DRM_ERROR("unsupported binning config flags 0x%02x\n", flags);
  454. return -EINVAL;
  455. }
  456. --- a/include/uapi/drm/vc4_drm.h
  457. +++ b/include/uapi/drm/vc4_drm.h
  458. @@ -46,10 +46,13 @@ struct drm_vc4_submit_rcl_surface {
  459. uint32_t hindex; /* Handle index, or ~0 if not present. */
  460. uint32_t offset; /* Offset to start of buffer. */
  461. /*
  462. - * Bits for either render config (color_ms_write) or load/store packet.
  463. + * Bits for either render config (color_write) or load/store packet.
  464. + * Bits should all be 0 for MSAA load/stores.
  465. */
  466. uint16_t bits;
  467. - uint16_t pad;
  468. +
  469. +#define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0)
  470. + uint16_t flags;
  471. };
  472. /**
  473. @@ -128,9 +131,11 @@ struct drm_vc4_submit_cl {
  474. uint8_t max_x_tile;
  475. uint8_t max_y_tile;
  476. struct drm_vc4_submit_rcl_surface color_read;
  477. - struct drm_vc4_submit_rcl_surface color_ms_write;
  478. + struct drm_vc4_submit_rcl_surface color_write;
  479. struct drm_vc4_submit_rcl_surface zs_read;
  480. struct drm_vc4_submit_rcl_surface zs_write;
  481. + struct drm_vc4_submit_rcl_surface msaa_color_write;
  482. + struct drm_vc4_submit_rcl_surface msaa_zs_write;
  483. uint32_t clear_color[2];
  484. uint32_t clear_z;
  485. uint8_t clear_s;