0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include "uapi/drm/vc4_drm.h"
0039 #include "vc4_drv.h"
0040 #include "vc4_packet.h"
0041
0042 struct vc4_rcl_setup {
0043 struct drm_gem_cma_object *color_read;
0044 struct drm_gem_cma_object *color_write;
0045 struct drm_gem_cma_object *zs_read;
0046 struct drm_gem_cma_object *zs_write;
0047 struct drm_gem_cma_object *msaa_color_write;
0048 struct drm_gem_cma_object *msaa_zs_write;
0049
0050 struct drm_gem_cma_object *rcl;
0051 u32 next_offset;
0052
0053 u32 next_write_bo_index;
0054 };
0055
0056 static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val)
0057 {
0058 *(u8 *)(setup->rcl->vaddr + setup->next_offset) = val;
0059 setup->next_offset += 1;
0060 }
0061
0062 static inline void rcl_u16(struct vc4_rcl_setup *setup, u16 val)
0063 {
0064 *(u16 *)(setup->rcl->vaddr + setup->next_offset) = val;
0065 setup->next_offset += 2;
0066 }
0067
0068 static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val)
0069 {
0070 *(u32 *)(setup->rcl->vaddr + setup->next_offset) = val;
0071 setup->next_offset += 4;
0072 }
0073
0074
0075
0076
0077
0078
0079
0080 static void vc4_store_before_load(struct vc4_rcl_setup *setup)
0081 {
0082 rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
0083 rcl_u16(setup,
0084 VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_NONE,
0085 VC4_LOADSTORE_TILE_BUFFER_BUFFER) |
0086 VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR |
0087 VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR |
0088 VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR);
0089 rcl_u32(setup, 0);
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099 static uint32_t vc4_full_res_offset(struct vc4_exec_info *exec,
0100 struct drm_gem_cma_object *bo,
0101 struct drm_vc4_submit_rcl_surface *surf,
0102 uint8_t x, uint8_t y)
0103 {
0104 return bo->paddr + surf->offset + VC4_TILE_BUFFER_SIZE *
0105 (DIV_ROUND_UP(exec->args->width, 32) * y + x);
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115 static void vc4_tile_coordinates(struct vc4_rcl_setup *setup,
0116 uint32_t x, uint32_t y)
0117 {
0118 rcl_u8(setup, VC4_PACKET_TILE_COORDINATES);
0119 rcl_u8(setup, x);
0120 rcl_u8(setup, y);
0121 }
0122
0123 static void emit_tile(struct vc4_exec_info *exec,
0124 struct vc4_rcl_setup *setup,
0125 uint8_t x, uint8_t y, bool first, bool last)
0126 {
0127 struct drm_vc4_submit_cl *args = exec->args;
0128 bool has_bin = args->bin_cl_size != 0;
0129
0130
0131
0132
0133
0134 if (setup->color_read) {
0135 if (args->color_read.flags &
0136 VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0137 rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
0138 rcl_u32(setup,
0139 vc4_full_res_offset(exec, setup->color_read,
0140 &args->color_read, x, y) |
0141 VC4_LOADSTORE_FULL_RES_DISABLE_ZS);
0142 } else {
0143 rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
0144 rcl_u16(setup, args->color_read.bits);
0145 rcl_u32(setup, setup->color_read->paddr +
0146 args->color_read.offset);
0147 }
0148 }
0149
0150 if (setup->zs_read) {
0151 if (setup->color_read) {
0152
0153 vc4_tile_coordinates(setup, x, y);
0154 vc4_store_before_load(setup);
0155 }
0156
0157 if (args->zs_read.flags &
0158 VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0159 rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER);
0160 rcl_u32(setup,
0161 vc4_full_res_offset(exec, setup->zs_read,
0162 &args->zs_read, x, y) |
0163 VC4_LOADSTORE_FULL_RES_DISABLE_COLOR);
0164 } else {
0165 rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL);
0166 rcl_u16(setup, args->zs_read.bits);
0167 rcl_u32(setup, setup->zs_read->paddr +
0168 args->zs_read.offset);
0169 }
0170 }
0171
0172
0173
0174
0175 vc4_tile_coordinates(setup, x, y);
0176
0177
0178
0179
0180 if (first && has_bin)
0181 rcl_u8(setup, VC4_PACKET_WAIT_ON_SEMAPHORE);
0182
0183 if (has_bin) {
0184 rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST);
0185 rcl_u32(setup, (exec->tile_alloc_offset +
0186 (y * exec->bin_tiles_x + x) * 32));
0187 }
0188
0189 if (setup->msaa_color_write) {
0190 bool last_tile_write = (!setup->msaa_zs_write &&
0191 !setup->zs_write &&
0192 !setup->color_write);
0193 uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_ZS;
0194
0195 if (!last_tile_write)
0196 bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
0197 else if (last)
0198 bits |= VC4_LOADSTORE_FULL_RES_EOF;
0199 rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
0200 rcl_u32(setup,
0201 vc4_full_res_offset(exec, setup->msaa_color_write,
0202 &args->msaa_color_write, x, y) |
0203 bits);
0204 }
0205
0206 if (setup->msaa_zs_write) {
0207 bool last_tile_write = (!setup->zs_write &&
0208 !setup->color_write);
0209 uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_COLOR;
0210
0211 if (setup->msaa_color_write)
0212 vc4_tile_coordinates(setup, x, y);
0213 if (!last_tile_write)
0214 bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL;
0215 else if (last)
0216 bits |= VC4_LOADSTORE_FULL_RES_EOF;
0217 rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER);
0218 rcl_u32(setup,
0219 vc4_full_res_offset(exec, setup->msaa_zs_write,
0220 &args->msaa_zs_write, x, y) |
0221 bits);
0222 }
0223
0224 if (setup->zs_write) {
0225 bool last_tile_write = !setup->color_write;
0226
0227 if (setup->msaa_color_write || setup->msaa_zs_write)
0228 vc4_tile_coordinates(setup, x, y);
0229
0230 rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
0231 rcl_u16(setup, args->zs_write.bits |
0232 (last_tile_write ?
0233 0 : VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR));
0234 rcl_u32(setup,
0235 (setup->zs_write->paddr + args->zs_write.offset) |
0236 ((last && last_tile_write) ?
0237 VC4_LOADSTORE_TILE_BUFFER_EOF : 0));
0238 }
0239
0240 if (setup->color_write) {
0241 if (setup->msaa_color_write || setup->msaa_zs_write ||
0242 setup->zs_write) {
0243 vc4_tile_coordinates(setup, x, y);
0244 }
0245
0246 if (last)
0247 rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF);
0248 else
0249 rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER);
0250 }
0251 }
0252
0253 static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
0254 struct vc4_rcl_setup *setup)
0255 {
0256 struct drm_vc4_submit_cl *args = exec->args;
0257 bool has_bin = args->bin_cl_size != 0;
0258 uint8_t min_x_tile = args->min_x_tile;
0259 uint8_t min_y_tile = args->min_y_tile;
0260 uint8_t max_x_tile = args->max_x_tile;
0261 uint8_t max_y_tile = args->max_y_tile;
0262 uint8_t xtiles = max_x_tile - min_x_tile + 1;
0263 uint8_t ytiles = max_y_tile - min_y_tile + 1;
0264 uint8_t xi, yi;
0265 uint32_t size, loop_body_size;
0266 bool positive_x = true;
0267 bool positive_y = true;
0268
0269 if (args->flags & VC4_SUBMIT_CL_FIXED_RCL_ORDER) {
0270 if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X))
0271 positive_x = false;
0272 if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y))
0273 positive_y = false;
0274 }
0275
0276 size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
0277 loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE;
0278
0279 if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) {
0280 size += VC4_PACKET_CLEAR_COLORS_SIZE +
0281 VC4_PACKET_TILE_COORDINATES_SIZE +
0282 VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
0283 }
0284
0285 if (setup->color_read) {
0286 if (args->color_read.flags &
0287 VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0288 loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
0289 } else {
0290 loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
0291 }
0292 }
0293 if (setup->zs_read) {
0294 if (setup->color_read) {
0295 loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE;
0296 loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
0297 }
0298
0299 if (args->zs_read.flags &
0300 VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0301 loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE;
0302 } else {
0303 loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE;
0304 }
0305 }
0306
0307 if (has_bin) {
0308 size += VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE;
0309 loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE;
0310 }
0311
0312 if (setup->msaa_color_write)
0313 loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
0314 if (setup->msaa_zs_write)
0315 loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE;
0316
0317 if (setup->zs_write)
0318 loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE;
0319 if (setup->color_write)
0320 loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE;
0321
0322
0323 loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE *
0324 ((setup->msaa_color_write != NULL) +
0325 (setup->msaa_zs_write != NULL) +
0326 (setup->color_write != NULL) +
0327 (setup->zs_write != NULL) - 1);
0328
0329 size += xtiles * ytiles * loop_body_size;
0330
0331 setup->rcl = &vc4_bo_create(dev, size, true, VC4_BO_TYPE_RCL)->base;
0332 if (IS_ERR(setup->rcl))
0333 return PTR_ERR(setup->rcl);
0334 list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head,
0335 &exec->unref_list);
0336
0337
0338
0339
0340
0341
0342 if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) {
0343 rcl_u8(setup, VC4_PACKET_CLEAR_COLORS);
0344 rcl_u32(setup, args->clear_color[0]);
0345 rcl_u32(setup, args->clear_color[1]);
0346 rcl_u32(setup, args->clear_z);
0347 rcl_u8(setup, args->clear_s);
0348
0349 vc4_tile_coordinates(setup, 0, 0);
0350
0351 rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL);
0352 rcl_u16(setup, VC4_LOADSTORE_TILE_BUFFER_NONE);
0353 rcl_u32(setup, 0);
0354 }
0355
0356 rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
0357 rcl_u32(setup,
0358 (setup->color_write ? (setup->color_write->paddr +
0359 args->color_write.offset) :
0360 0));
0361 rcl_u16(setup, args->width);
0362 rcl_u16(setup, args->height);
0363 rcl_u16(setup, args->color_write.bits);
0364
0365 for (yi = 0; yi < ytiles; yi++) {
0366 int y = positive_y ? min_y_tile + yi : max_y_tile - yi;
0367 for (xi = 0; xi < xtiles; xi++) {
0368 int x = positive_x ? min_x_tile + xi : max_x_tile - xi;
0369 bool first = (xi == 0 && yi == 0);
0370 bool last = (xi == xtiles - 1 && yi == ytiles - 1);
0371
0372 emit_tile(exec, setup, x, y, first, last);
0373 }
0374 }
0375
0376 BUG_ON(setup->next_offset != size);
0377 exec->ct1ca = setup->rcl->paddr;
0378 exec->ct1ea = setup->rcl->paddr + setup->next_offset;
0379
0380 return 0;
0381 }
0382
0383 static int vc4_full_res_bounds_check(struct vc4_exec_info *exec,
0384 struct drm_gem_cma_object *obj,
0385 struct drm_vc4_submit_rcl_surface *surf)
0386 {
0387 struct drm_vc4_submit_cl *args = exec->args;
0388 u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32);
0389
0390 if (surf->offset > obj->base.size) {
0391 DRM_DEBUG("surface offset %d > BO size %zd\n",
0392 surf->offset, obj->base.size);
0393 return -EINVAL;
0394 }
0395
0396 if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE <
0397 render_tiles_stride * args->max_y_tile + args->max_x_tile) {
0398 DRM_DEBUG("MSAA tile %d, %d out of bounds "
0399 "(bo size %zd, offset %d).\n",
0400 args->max_x_tile, args->max_y_tile,
0401 obj->base.size,
0402 surf->offset);
0403 return -EINVAL;
0404 }
0405
0406 return 0;
0407 }
0408
0409 static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
0410 struct drm_gem_cma_object **obj,
0411 struct drm_vc4_submit_rcl_surface *surf)
0412 {
0413 if (surf->flags != 0 || surf->bits != 0) {
0414 DRM_DEBUG("MSAA surface had nonzero flags/bits\n");
0415 return -EINVAL;
0416 }
0417
0418 if (surf->hindex == ~0)
0419 return 0;
0420
0421 *obj = vc4_use_bo(exec, surf->hindex);
0422 if (!*obj)
0423 return -EINVAL;
0424
0425 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
0426
0427 if (surf->offset & 0xf) {
0428 DRM_DEBUG("MSAA write must be 16b aligned.\n");
0429 return -EINVAL;
0430 }
0431
0432 return vc4_full_res_bounds_check(exec, *obj, surf);
0433 }
0434
0435 static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
0436 struct drm_gem_cma_object **obj,
0437 struct drm_vc4_submit_rcl_surface *surf,
0438 bool is_write)
0439 {
0440 uint8_t tiling = VC4_GET_FIELD(surf->bits,
0441 VC4_LOADSTORE_TILE_BUFFER_TILING);
0442 uint8_t buffer = VC4_GET_FIELD(surf->bits,
0443 VC4_LOADSTORE_TILE_BUFFER_BUFFER);
0444 uint8_t format = VC4_GET_FIELD(surf->bits,
0445 VC4_LOADSTORE_TILE_BUFFER_FORMAT);
0446 int cpp;
0447 int ret;
0448
0449 if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0450 DRM_DEBUG("Extra flags set\n");
0451 return -EINVAL;
0452 }
0453
0454 if (surf->hindex == ~0)
0455 return 0;
0456
0457 *obj = vc4_use_bo(exec, surf->hindex);
0458 if (!*obj)
0459 return -EINVAL;
0460
0461 if (is_write)
0462 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
0463
0464 if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
0465 if (surf == &exec->args->zs_write) {
0466 DRM_DEBUG("general zs write may not be a full-res.\n");
0467 return -EINVAL;
0468 }
0469
0470 if (surf->bits != 0) {
0471 DRM_DEBUG("load/store general bits set with "
0472 "full res load/store.\n");
0473 return -EINVAL;
0474 }
0475
0476 ret = vc4_full_res_bounds_check(exec, *obj, surf);
0477 if (ret)
0478 return ret;
0479
0480 return 0;
0481 }
0482
0483 if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
0484 VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
0485 VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
0486 DRM_DEBUG("Unknown bits in load/store: 0x%04x\n",
0487 surf->bits);
0488 return -EINVAL;
0489 }
0490
0491 if (tiling > VC4_TILING_FORMAT_LT) {
0492 DRM_DEBUG("Bad tiling format\n");
0493 return -EINVAL;
0494 }
0495
0496 if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) {
0497 if (format != 0) {
0498 DRM_DEBUG("No color format should be set for ZS\n");
0499 return -EINVAL;
0500 }
0501 cpp = 4;
0502 } else if (buffer == VC4_LOADSTORE_TILE_BUFFER_COLOR) {
0503 switch (format) {
0504 case VC4_LOADSTORE_TILE_BUFFER_BGR565:
0505 case VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER:
0506 cpp = 2;
0507 break;
0508 case VC4_LOADSTORE_TILE_BUFFER_RGBA8888:
0509 cpp = 4;
0510 break;
0511 default:
0512 DRM_DEBUG("Bad tile buffer format\n");
0513 return -EINVAL;
0514 }
0515 } else {
0516 DRM_DEBUG("Bad load/store buffer %d.\n", buffer);
0517 return -EINVAL;
0518 }
0519
0520 if (surf->offset & 0xf) {
0521 DRM_DEBUG("load/store buffer must be 16b aligned.\n");
0522 return -EINVAL;
0523 }
0524
0525 if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling,
0526 exec->args->width, exec->args->height, cpp)) {
0527 return -EINVAL;
0528 }
0529
0530 return 0;
0531 }
0532
0533 static int
0534 vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
0535 struct vc4_rcl_setup *setup,
0536 struct drm_gem_cma_object **obj,
0537 struct drm_vc4_submit_rcl_surface *surf)
0538 {
0539 uint8_t tiling = VC4_GET_FIELD(surf->bits,
0540 VC4_RENDER_CONFIG_MEMORY_FORMAT);
0541 uint8_t format = VC4_GET_FIELD(surf->bits,
0542 VC4_RENDER_CONFIG_FORMAT);
0543 int cpp;
0544
0545 if (surf->flags != 0) {
0546 DRM_DEBUG("No flags supported on render config.\n");
0547 return -EINVAL;
0548 }
0549
0550 if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK |
0551 VC4_RENDER_CONFIG_FORMAT_MASK |
0552 VC4_RENDER_CONFIG_MS_MODE_4X |
0553 VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) {
0554 DRM_DEBUG("Unknown bits in render config: 0x%04x\n",
0555 surf->bits);
0556 return -EINVAL;
0557 }
0558
0559 if (surf->hindex == ~0)
0560 return 0;
0561
0562 *obj = vc4_use_bo(exec, surf->hindex);
0563 if (!*obj)
0564 return -EINVAL;
0565
0566 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
0567
0568 if (tiling > VC4_TILING_FORMAT_LT) {
0569 DRM_DEBUG("Bad tiling format\n");
0570 return -EINVAL;
0571 }
0572
0573 switch (format) {
0574 case VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED:
0575 case VC4_RENDER_CONFIG_FORMAT_BGR565:
0576 cpp = 2;
0577 break;
0578 case VC4_RENDER_CONFIG_FORMAT_RGBA8888:
0579 cpp = 4;
0580 break;
0581 default:
0582 DRM_DEBUG("Bad tile buffer format\n");
0583 return -EINVAL;
0584 }
0585
0586 if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling,
0587 exec->args->width, exec->args->height, cpp)) {
0588 return -EINVAL;
0589 }
0590
0591 return 0;
0592 }
0593
0594 int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
0595 {
0596 struct vc4_dev *vc4 = to_vc4_dev(dev);
0597 struct vc4_rcl_setup setup = {0};
0598 struct drm_vc4_submit_cl *args = exec->args;
0599 bool has_bin = args->bin_cl_size != 0;
0600 int ret;
0601
0602 if (WARN_ON_ONCE(vc4->is_vc5))
0603 return -ENODEV;
0604
0605 if (args->min_x_tile > args->max_x_tile ||
0606 args->min_y_tile > args->max_y_tile) {
0607 DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n",
0608 args->min_x_tile, args->min_y_tile,
0609 args->max_x_tile, args->max_y_tile);
0610 return -EINVAL;
0611 }
0612
0613 if (has_bin &&
0614 (args->max_x_tile > exec->bin_tiles_x ||
0615 args->max_y_tile > exec->bin_tiles_y)) {
0616 DRM_DEBUG("Render tiles (%d,%d) outside of bin config "
0617 "(%d,%d)\n",
0618 args->max_x_tile, args->max_y_tile,
0619 exec->bin_tiles_x, exec->bin_tiles_y);
0620 return -EINVAL;
0621 }
0622
0623 ret = vc4_rcl_render_config_surface_setup(exec, &setup,
0624 &setup.color_write,
0625 &args->color_write);
0626 if (ret)
0627 return ret;
0628
0629 ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read,
0630 false);
0631 if (ret)
0632 return ret;
0633
0634 ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read,
0635 false);
0636 if (ret)
0637 return ret;
0638
0639 ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write,
0640 true);
0641 if (ret)
0642 return ret;
0643
0644 ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_color_write,
0645 &args->msaa_color_write);
0646 if (ret)
0647 return ret;
0648
0649 ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_zs_write,
0650 &args->msaa_zs_write);
0651 if (ret)
0652 return ret;
0653
0654
0655
0656
0657 if (!setup.color_write && !setup.zs_write &&
0658 !setup.msaa_color_write && !setup.msaa_zs_write) {
0659 DRM_DEBUG("RCL requires color or Z/S write\n");
0660 return -EINVAL;
0661 }
0662
0663 return vc4_create_rcl_bo(dev, exec, &setup);
0664 }