v3dv: create a helper to start a new frame
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
parent
d902e68732
commit
a904b6f082
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue