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