From 34724bafa46a6f25fd3ddc617ab3b67b2f9f5788 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 22 Jul 2021 14:06:28 +0200 Subject: [PATCH] v3dv: skip processing tiles for layers that are not in the view mask MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If a multiview subpass doesn't use a particular layer then we can ignore that layer completely. Reviewed-by: Alejandro Piñeiro Part-of: --- src/broadcom/vulkan/v3dvx_cmd_buffer.c | 106 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 8f8cf73..4104610 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -630,59 +630,6 @@ cmd_buffer_emit_render_pass_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer, list.address = v3dv_cl_address(job->tile_alloc, tile_alloc_offset); } - if (layer == 0) { - cl_emit(rcl, MULTICORE_RENDERING_SUPERTILE_CFG, config) { - config.number_of_bin_tile_lists = 1; - config.total_frame_width_in_tiles = tiling->draw_tiles_x; - config.total_frame_height_in_tiles = tiling->draw_tiles_y; - - config.supertile_width_in_tiles = tiling->supertile_width; - config.supertile_height_in_tiles = tiling->supertile_height; - - config.total_frame_width_in_supertiles = - tiling->frame_width_in_supertiles; - config.total_frame_height_in_supertiles = - tiling->frame_height_in_supertiles; - } - - /* Start by clearing the tile buffer. */ - cl_emit(rcl, TILE_COORDINATES, coords) { - coords.tile_column_number = 0; - coords.tile_row_number = 0; - } - - /* Emit an initial clear of the tile buffers. This is necessary - * for any buffers that should be cleared (since clearing - * normally happens at the *end* of the generic tile list), but - * it's also nice to clear everything so the first tile doesn't - * inherit any contents from some previous frame. - * - * Also, implement the GFXH-1742 workaround. There's a race in - * the HW between the RCL updating the TLB's internal type/size - * and the spawning of the QPU instances using the TLB's current - * internal type/size. To make sure the QPUs get the right - * state, we need 1 dummy store in between internal type/size - * changes on V3D 3.x, and 2 dummy stores on 4.x. - */ - for (int i = 0; i < 2; i++) { - if (i > 0) - cl_emit(rcl, TILE_COORDINATES, coords); - cl_emit(rcl, END_OF_LOADS, end); - cl_emit(rcl, STORE_TILE_BUFFER_GENERAL, store) { - store.buffer_to_store = NONE; - } - if (i == 0 && cmd_buffer->state.tile_aligned_render_area) { - cl_emit(rcl, CLEAR_TILE_BUFFERS, clear) { - clear.clear_z_stencil_buffer = !job->early_zs_clear; - clear.clear_all_render_targets = true; - } - } - cl_emit(rcl, END_OF_TILE_MARKER, end); - } - - cl_emit(rcl, FLUSH_VCD_CACHE, flush); - } - cmd_buffer_render_pass_emit_per_tile_rcl(cmd_buffer, layer); uint32_t supertile_w_in_pixels = @@ -949,8 +896,59 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer) TILE_ALLOCATION_BLOCK_SIZE_64B; } - /* FIXME: skip layers not in the view mask */ + cl_emit(rcl, MULTICORE_RENDERING_SUPERTILE_CFG, config) { + config.number_of_bin_tile_lists = 1; + config.total_frame_width_in_tiles = tiling->draw_tiles_x; + config.total_frame_height_in_tiles = tiling->draw_tiles_y; + + config.supertile_width_in_tiles = tiling->supertile_width; + config.supertile_height_in_tiles = tiling->supertile_height; + + config.total_frame_width_in_supertiles = + tiling->frame_width_in_supertiles; + config.total_frame_height_in_supertiles = + tiling->frame_height_in_supertiles; + } + + /* Start by clearing the tile buffer. */ + cl_emit(rcl, TILE_COORDINATES, coords) { + coords.tile_column_number = 0; + coords.tile_row_number = 0; + } + + /* Emit an initial clear of the tile buffers. This is necessary + * for any buffers that should be cleared (since clearing + * normally happens at the *end* of the generic tile list), but + * it's also nice to clear everything so the first tile doesn't + * inherit any contents from some previous frame. + * + * Also, implement the GFXH-1742 workaround. There's a race in + * the HW between the RCL updating the TLB's internal type/size + * and the spawning of the QPU instances using the TLB's current + * internal type/size. To make sure the QPUs get the right + * state, we need 1 dummy store in between internal type/size + * changes on V3D 3.x, and 2 dummy stores on 4.x. + */ + for (int i = 0; i < 2; i++) { + if (i > 0) + cl_emit(rcl, TILE_COORDINATES, coords); + cl_emit(rcl, END_OF_LOADS, end); + cl_emit(rcl, STORE_TILE_BUFFER_GENERAL, store) { + store.buffer_to_store = NONE; + } + if (i == 0 && cmd_buffer->state.tile_aligned_render_area) { + cl_emit(rcl, CLEAR_TILE_BUFFERS, clear) { + clear.clear_z_stencil_buffer = !job->early_zs_clear; + clear.clear_all_render_targets = true; + } + } + cl_emit(rcl, END_OF_TILE_MARKER, end); + } + + cl_emit(rcl, FLUSH_VCD_CACHE, flush); + for (int layer = 0; layer < MAX2(1, fb_layers); layer++) { + if (subpass->view_mask == 0 || (subpass->view_mask & (1u << layer))) cmd_buffer_emit_render_pass_layer_rcl(cmd_buffer, layer); } -- 2.7.4