From a904b6f082f1495d6ee6ac962201af922019981f Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Fri, 10 Jan 2020 12:26:14 +0100 Subject: [PATCH] v3dv: create a helper to start a new frame Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 157 ++++++++++++++------------ src/broadcom/vulkan/v3dv_meta_copy.c | 55 +-------- src/broadcom/vulkan/v3dv_private.h | 3 + 3 files changed, 88 insertions(+), 127 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 1378cef4149..0f4c21440fc 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -162,8 +162,8 @@ cmd_buffer_destroy(struct v3dv_cmd_buffer *cmd_buffer) vk_free(&cmd_buffer->pool->alloc, cmd_buffer); } -static void -emit_binning_flush(struct v3dv_job *job) +void +v3dv_job_emit_binning_flush(struct v3dv_job *job) { assert(job); v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(FLUSH)); @@ -243,6 +243,83 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer) return true; } +void +v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer, + const struct v3dv_framebuffer *framebuffer) +{ + struct v3dv_job *job = cmd_buffer->state.job; + assert(job); + + v3dv_cl_ensure_space_with_branch(&job->bcl, 256); + + /* The PTB will request the tile alloc initial size per tile at start + * of tile binning. + */ + uint32_t tile_alloc_size = 64 * framebuffer->layers * + framebuffer->draw_tiles_x * + framebuffer->draw_tiles_y; + + /* The PTB allocates in aligned 4k chunks after the initial setup. */ + tile_alloc_size = align(tile_alloc_size, 4096); + + /* Include the first two chunk allocations that the PTB does so that + * we definitely clear the OOM condition before triggering one (the HW + * won't trigger OOM during the first allocations). + */ + tile_alloc_size += 8192; + + /* For performance, allocate some extra initial memory after the PTB's + * minimal allocations, so that we hopefully don't have to block the + * GPU on the kernel handling an OOM signal. + */ + tile_alloc_size += 512 * 1024; + + job->tile_alloc = v3dv_bo_alloc(cmd_buffer->device, tile_alloc_size); + v3dv_job_add_bo(job, job->tile_alloc); + + const uint32_t tsda_per_tile_size = 256; + const uint32_t tile_state_size = framebuffer->layers * + framebuffer->draw_tiles_x * + framebuffer->draw_tiles_y * + tsda_per_tile_size; + job->tile_state = v3dv_bo_alloc(cmd_buffer->device, tile_state_size); + v3dv_job_add_bo(job, job->tile_state); + + /* This must go before the binning mode configuration. It is + * required for layered framebuffers to work. + */ + cl_emit(&job->bcl, NUMBER_OF_LAYERS, config) { + config.number_of_layers = framebuffer->layers; + } + + cl_emit(&job->bcl, TILE_BINNING_MODE_CFG, config) { + config.width_in_pixels = framebuffer->width; + config.height_in_pixels = framebuffer->height; + config.number_of_render_targets = MAX2(framebuffer->attachment_count, 1); + config.multisample_mode_4x = false; /* FIXME */ + config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp; + } + + /* There's definitely nothing in the VCD cache we want. */ + cl_emit(&job->bcl, FLUSH_VCD_CACHE, bin); + + /* Disable any leftover OQ state from another job. */ + cl_emit(&job->bcl, OCCLUSION_QUERY_COUNTER, counter); + + /* "Binning mode lists must have a Start Tile Binning item (6) after + * any prefix state data before the binning list proper starts." + */ + cl_emit(&job->bcl, START_TILE_BINNING, bin); +} + +static void +cmd_buffer_end_render_pass_frame(struct v3dv_cmd_buffer *cmd_buffer) +{ + assert(cmd_buffer->state.job); + emit_rcl(cmd_buffer); + v3dv_job_emit_binning_flush(cmd_buffer->state.job); +} + void v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer) { @@ -256,10 +333,8 @@ v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer) * the RCL should have been emitted by the time we got here. */ assert(v3dv_cl_offset(&job->rcl) != 0 || cmd_buffer->state.pass); - if (cmd_buffer->state.pass) { - emit_rcl(cmd_buffer); - emit_binning_flush(job); - } + if (cmd_buffer->state.pass) + cmd_buffer_end_render_pass_frame(cmd_buffer); list_addtail(&job->list_link, &cmd_buffer->submit_jobs); cmd_buffer->state.job = NULL; @@ -1087,74 +1162,8 @@ subpass_start(struct v3dv_cmd_buffer *cmd_buffer) struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer); /* If we are starting a new job we need to setup binning. */ - if (job->first_subpass == state->subpass_idx) { - const struct v3dv_framebuffer *framebuffer = - cmd_buffer->state.framebuffer; - - v3dv_cl_ensure_space_with_branch(&job->bcl, 256); - - /* The PTB will request the tile alloc initial size per tile at start - * of tile binning. - */ - const uint32_t fb_layers = 1; /* FIXME */ - uint32_t tile_alloc_size = 64 * MAX2(fb_layers, 1) * - framebuffer->draw_tiles_x * - framebuffer->draw_tiles_y; - - /* The PTB allocates in aligned 4k chunks after the initial setup. */ - tile_alloc_size = align(tile_alloc_size, 4096); - - /* Include the first two chunk allocations that the PTB does so that - * we definitely clear the OOM condition before triggering one (the HW - * won't trigger OOM during the first allocations). - */ - tile_alloc_size += 8192; - - /* For performance, allocate some extra initial memory after the PTB's - * minimal allocations, so that we hopefully don't have to block the - * GPU on the kernel handling an OOM signal. - */ - tile_alloc_size += 512 * 1024; - - job->tile_alloc = v3dv_bo_alloc(cmd_buffer->device, tile_alloc_size); - v3dv_job_add_bo(job, job->tile_alloc); - - const uint32_t tsda_per_tile_size = 256; - const uint32_t tile_state_size = MAX2(fb_layers, 1) * - framebuffer->draw_tiles_x * - framebuffer->draw_tiles_y * - tsda_per_tile_size; - job->tile_state = v3dv_bo_alloc(cmd_buffer->device, tile_state_size); - v3dv_job_add_bo(job, job->tile_state); - - /* This must go before the binning mode configuration. It is - * required for layered framebuffers to work. - */ - if (fb_layers > 0) { - cl_emit(&job->bcl, NUMBER_OF_LAYERS, config) { - config.number_of_layers = fb_layers; - } - } - - cl_emit(&job->bcl, TILE_BINNING_MODE_CFG, config) { - config.width_in_pixels = framebuffer->width; - config.height_in_pixels = framebuffer->height; - config.number_of_render_targets = MAX2(framebuffer->attachment_count, 1); - config.multisample_mode_4x = false; /* FIXME */ - config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp; - } - - /* There's definitely nothing in the VCD cache we want. */ - cl_emit(&job->bcl, FLUSH_VCD_CACHE, bin); - - /* Disable any leftover OQ state from another job. */ - cl_emit(&job->bcl, OCCLUSION_QUERY_COUNTER, counter); - - /* "Binning mode lists must have a Start Tile Binning item (6) after - * any prefix state data before the binning list proper starts." - */ - cl_emit(&job->bcl, START_TILE_BINNING, bin); - } + if (job->first_subpass == state->subpass_idx) + v3dv_cmd_buffer_start_frame(cmd_buffer, cmd_buffer->state.framebuffer); /* If we don't have a scissor or viewport defined let's just use the render * area as clip_window, as that would be required for a clear in any diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index e2d38253a1f..c3adab8a020 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -269,41 +269,6 @@ emit_copy_image_to_buffer_rcl(struct v3dv_job *job, cl_emit(rcl, END_OF_RENDERING, end); } -static void -emit_copy_image_to_buffer_bcl(struct v3dv_job *job, - struct v3dv_framebuffer *framebuffer, - const VkBufferImageCopy *region) -{ - v3dv_cl_ensure_space_with_branch(&job->bcl, 256); - - cl_emit(&job->bcl, NUMBER_OF_LAYERS, config) { - config.number_of_layers = framebuffer->layers; - } - - cl_emit(&job->bcl, TILE_BINNING_MODE_CFG, config) { - config.width_in_pixels = framebuffer->width; - config.height_in_pixels = framebuffer->height; - config.number_of_render_targets = 1; - config.multisample_mode_4x = false; /* FIXME */ - config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp; - } - - cl_emit(&job->bcl, FLUSH_VCD_CACHE, bin); - - cl_emit(&job->bcl, OCCLUSION_QUERY_COUNTER, counter); - - cl_emit(&job->bcl, START_TILE_BINNING, bin); - - cl_emit(&job->bcl, CLIP_WINDOW, clip) { - clip.clip_window_left_pixel_coordinate = region->imageOffset.x; - clip.clip_window_bottom_pixel_coordinate = region->imageOffset.y; - clip.clip_window_width_in_pixels = region->imageExtent.width; - clip.clip_window_height_in_pixels = region->imageExtent.height; - } - - cl_emit(&job->bcl, FLUSH, flush); -} - /* Sets framebuffer dimensions and computes tile size parameters based on the * maximum internal bpp provided. */ @@ -361,25 +326,9 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer, setup_framebuffer_params(&framebuffer, image, num_layers, internal_bpp); struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer); + v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer); - uint32_t tile_alloc_size = 64 * num_layers * - framebuffer.draw_tiles_x * - framebuffer.draw_tiles_y; - tile_alloc_size = align(tile_alloc_size, 4096); - tile_alloc_size += 8192; - tile_alloc_size += 512 * 1024; - job->tile_alloc = v3dv_bo_alloc(cmd_buffer->device, tile_alloc_size); - v3dv_job_add_bo(job, job->tile_alloc); - - const uint32_t tsda_per_tile_size = 256; - const uint32_t tile_state_size = num_layers * - framebuffer.draw_tiles_x * - framebuffer.draw_tiles_y * - tsda_per_tile_size; - job->tile_state = v3dv_bo_alloc(cmd_buffer->device, tile_state_size); - v3dv_job_add_bo(job, job->tile_state); - - emit_copy_image_to_buffer_bcl(job, &framebuffer, region); + v3dv_job_emit_binning_flush(job); emit_copy_image_to_buffer_rcl(job, buffer, image, &framebuffer, internal_type, region); diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 9fce92bf077..32400b96b30 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -469,6 +469,7 @@ struct v3dv_job { }; void v3dv_job_add_bo(struct v3dv_job *job, struct v3dv_bo *bo); +void v3dv_job_emit_binning_flush(struct v3dv_job *job); struct v3dv_cmd_buffer_state { const struct v3dv_render_pass *pass; @@ -510,6 +511,8 @@ struct v3dv_cmd_buffer { struct v3dv_job *v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer); void v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer); +void v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer, + const struct v3dv_framebuffer *framebuffer); struct v3dv_shader_module { unsigned char sha1[20];