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));
}
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)
{
struct v3dv_job *job = cmd_buffer->state.job;
* 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;
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
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.
*/
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);