v3dv: rewrite frame tiling setup

So far we have been getting away with computing frame tiling information for
the framebuffer object, but that is not correct, since different subpasses
may access different subsets of the framebuffer, with each requiring a
different configuration because the number of render targets and the maximum
bpp can change for each subpass.

This adds a v3dv_frame_tiling struct to keep the frame tiling information and
rewrites the code to compute this for every new job we start.

Fixes a bunch of tests in dEQP-VK.pipeline.render_to_image.*

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-03-02 17:21:26 +01:00 committed by Marge Bot
parent 44cda4dbfe
commit 2a3fa914d4
5 changed files with 204 additions and 109 deletions

View File

@ -295,19 +295,24 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer)
void
v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer,
const struct v3dv_framebuffer *framebuffer)
const struct v3dv_framebuffer *framebuffer,
const struct v3dv_frame_tiling *tiling,
int32_t num_render_targets)
{
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
/* Copy the frame tiling spec into the job */
memcpy(&job->frame_tiling, tiling, sizeof(struct v3dv_frame_tiling));
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;
tiling->draw_tiles_x *
tiling->draw_tiles_y;
/* The PTB allocates in aligned 4k chunks after the initial setup. */
tile_alloc_size = align(tile_alloc_size, 4096);
@ -330,8 +335,8 @@ v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer,
const uint32_t tsda_per_tile_size = 256;
const uint32_t tile_state_size = framebuffer->layers *
framebuffer->draw_tiles_x *
framebuffer->draw_tiles_y *
tiling->draw_tiles_x *
tiling->draw_tiles_y *
tsda_per_tile_size;
job->tile_state = v3dv_bo_alloc(cmd_buffer->device, tile_state_size, "TSDA");
v3dv_job_add_bo(job, job->tile_state);
@ -343,13 +348,15 @@ v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer,
config.number_of_layers = framebuffer->layers;
}
if (num_render_targets == -1)
num_render_targets = framebuffer->color_attachment_count;
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->color_attachment_count, 1);
config.number_of_render_targets = MAX2(num_render_targets, 1);
config.multisample_mode_4x = false; /* FIXME */
config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
config.maximum_bpp_of_all_render_targets = tiling->internal_bpp;
}
/* There's definitely nothing in the VCD cache we want. */
@ -1119,7 +1126,6 @@ cmd_buffer_emit_render_pass_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t layer)
{
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
struct v3dv_job *job = cmd_buffer->state.job;
struct v3dv_cl *rcl = &job->rcl;
@ -1127,24 +1133,25 @@ cmd_buffer_emit_render_pass_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
/* If doing multicore binning, we would need to initialize each
* core's tile list here.
*/
const struct v3dv_frame_tiling *tiling = &job->frame_tiling;
const uint32_t tile_alloc_offset =
64 * layer * framebuffer->draw_tiles_x * framebuffer->draw_tiles_y;
64 * layer * tiling->draw_tiles_x * tiling->draw_tiles_y;
cl_emit(rcl, MULTICORE_RENDERING_TILE_LIST_SET_BASE, list) {
list.address = v3dv_cl_address(job->tile_alloc, tile_alloc_offset);
}
cl_emit(rcl, MULTICORE_RENDERING_SUPERTILE_CFG, config) {
config.number_of_bin_tile_lists = 1;
config.total_frame_width_in_tiles = framebuffer->draw_tiles_x;
config.total_frame_height_in_tiles = framebuffer->draw_tiles_y;
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 = framebuffer->supertile_width;
config.supertile_height_in_tiles = framebuffer->supertile_height;
config.supertile_width_in_tiles = tiling->supertile_width;
config.supertile_height_in_tiles = tiling->supertile_height;
config.total_frame_width_in_supertiles =
framebuffer->frame_width_in_supertiles;
tiling->frame_width_in_supertiles;
config.total_frame_height_in_supertiles =
framebuffer->frame_height_in_supertiles;
tiling->frame_height_in_supertiles;
}
/* Start by clearing the tile buffer. */
@ -1187,9 +1194,9 @@ cmd_buffer_emit_render_pass_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
cmd_buffer_render_pass_emit_per_tile_rcl(cmd_buffer, layer);
uint32_t supertile_w_in_pixels =
framebuffer->tile_width * framebuffer->supertile_width;
tiling->tile_width * tiling->supertile_width;
uint32_t supertile_h_in_pixels =
framebuffer->tile_height * framebuffer->supertile_height;
tiling->tile_height * tiling->supertile_height;
const uint32_t min_x_supertile =
state->render_area.offset.x / supertile_w_in_pixels;
const uint32_t min_y_supertile =
@ -1241,6 +1248,8 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
const struct v3dv_frame_tiling *tiling = &job->frame_tiling;
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
const uint32_t fb_layers = framebuffer->layers;
@ -1266,7 +1275,7 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer)
config.image_height_pixels = framebuffer->height;
config.number_of_render_targets = MAX2(subpass->color_count, 1);
config.multisample_mode_4x = false; /* FIXME */
config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
config.maximum_bpp_of_all_render_targets = tiling->internal_bpp;
if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
const struct v3dv_image_view *iview =
@ -1398,14 +1407,27 @@ subpass_start(struct v3dv_cmd_buffer *cmd_buffer, uint32_t subpass_idx)
* change the command buffer state for the new job until we are done creating
* the new job.
*/
struct v3dv_job *job =
v3dv_cmd_buffer_start_job(cmd_buffer, subpass_idx);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, subpass_idx);
state->subpass_idx = subpass_idx;
/* If we are starting a new job we need to setup binning. */
if (job->first_subpass == state->subpass_idx)
v3dv_cmd_buffer_start_frame(cmd_buffer, cmd_buffer->state.framebuffer);
if (job->first_subpass == state->subpass_idx) {
const struct v3dv_subpass *subpass =
&state->pass->subpasses[state->subpass_idx];
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
const uint8_t internal_bpp =
v3dv_framebuffer_compute_internal_bpp(framebuffer, subpass);
struct v3dv_frame_tiling frame_tiling;
v3dv_framebuffer_compute_tiling_params(framebuffer, subpass, internal_bpp,
&frame_tiling);
v3dv_cmd_buffer_start_frame(cmd_buffer, framebuffer, &frame_tiling,
subpass->color_count);
}
/* 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

View File

@ -1659,11 +1659,33 @@ v3dv_DestroyBuffer(VkDevice _device,
vk_free2(&device->alloc, pAllocator, buffer);
}
static void
compute_internal_bpp_from_attachments(struct v3dv_framebuffer *framebuffer)
uint8_t
v3dv_framebuffer_compute_internal_bpp(const struct v3dv_framebuffer *framebuffer,
const struct v3dv_subpass *subpass)
{
STATIC_ASSERT(RENDER_TARGET_MAXIMUM_32BPP == 0);
uint8_t max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
if (subpass) {
for (uint32_t i = 0; i < subpass->color_count; i++) {
uint32_t att_idx = subpass->color_attachments[i].attachment;
if (att_idx == VK_ATTACHMENT_UNUSED)
continue;
const struct v3dv_image_view *att = framebuffer->attachments[i];
assert(att);
if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
max_bpp = MAX2(max_bpp, att->internal_bpp);
}
return max_bpp;
}
/* If we are not in a render pass then we assume that all framebuffer
* attachments are used.
*/
assert(framebuffer->attachment_count <= 4);
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
const struct v3dv_image_view *att = framebuffer->attachments[i];
assert(att);
@ -1671,11 +1693,15 @@ compute_internal_bpp_from_attachments(struct v3dv_framebuffer *framebuffer)
if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
max_bpp = MAX2(max_bpp, att->internal_bpp);
}
framebuffer->internal_bpp = max_bpp;
return max_bpp;
}
void
v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer)
v3dv_framebuffer_compute_tiling_params(const struct v3dv_framebuffer *framebuffer,
const struct v3dv_subpass *subpass,
uint8_t internal_bpp,
struct v3dv_frame_tiling *tiling)
{
static const uint8_t tile_sizes[] = {
64, 64,
@ -1689,40 +1715,44 @@ v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer)
/* FIXME: MSAA */
if (framebuffer->color_attachment_count > 2)
const uint32_t color_attachment_count =
subpass ? subpass->color_count : framebuffer->color_attachment_count;
if (color_attachment_count > 2)
tile_size_index += 2;
else if (framebuffer->color_attachment_count > 1)
else if (color_attachment_count > 1)
tile_size_index += 1;
tile_size_index += framebuffer->internal_bpp;
tiling->internal_bpp = internal_bpp;
tile_size_index += tiling->internal_bpp;
assert(tile_size_index < ARRAY_SIZE(tile_sizes));
framebuffer->tile_width = tile_sizes[tile_size_index * 2];
framebuffer->tile_height = tile_sizes[tile_size_index * 2 + 1];
tiling->tile_width = tile_sizes[tile_size_index * 2];
tiling->tile_height = tile_sizes[tile_size_index * 2 + 1];
framebuffer->draw_tiles_x =
DIV_ROUND_UP(framebuffer->width, framebuffer->tile_width);
framebuffer->draw_tiles_y =
DIV_ROUND_UP(framebuffer->height, framebuffer->tile_height);
tiling->draw_tiles_x =
DIV_ROUND_UP(framebuffer->width, tiling->tile_width);
tiling->draw_tiles_y =
DIV_ROUND_UP(framebuffer->height, tiling->tile_height);
/* Size up our supertiles until we get under the limit */
const uint32_t max_supertiles = 256;
framebuffer->supertile_width = 1;
framebuffer->supertile_height = 1;
tiling->supertile_width = 1;
tiling->supertile_height = 1;
for (;;) {
framebuffer->frame_width_in_supertiles =
DIV_ROUND_UP(framebuffer->draw_tiles_x, framebuffer->supertile_width);
framebuffer->frame_height_in_supertiles =
DIV_ROUND_UP(framebuffer->draw_tiles_y, framebuffer->supertile_height);
const uint32_t num_supertiles = framebuffer->frame_width_in_supertiles *
framebuffer->frame_height_in_supertiles;
tiling->frame_width_in_supertiles =
DIV_ROUND_UP(tiling->draw_tiles_x, tiling->supertile_width);
tiling->frame_height_in_supertiles =
DIV_ROUND_UP(tiling->draw_tiles_y, tiling->supertile_height);
const uint32_t num_supertiles = tiling->frame_width_in_supertiles *
tiling->frame_height_in_supertiles;
if (num_supertiles < max_supertiles)
break;
if (framebuffer->supertile_width < framebuffer->supertile_height)
framebuffer->supertile_width++;
if (tiling->supertile_width < tiling->supertile_height)
tiling->supertile_width++;
else
framebuffer->supertile_height++;
tiling->supertile_height++;
}
}
@ -1756,9 +1786,6 @@ v3dv_CreateFramebuffer(VkDevice _device,
framebuffer->color_attachment_count++;
}
compute_internal_bpp_from_attachments(framebuffer);
v3dv_framebuffer_compute_tiling_params(framebuffer);
*pFramebuffer = v3dv_framebuffer_to_handle(framebuffer);
return VK_SUCCESS;

View File

@ -168,24 +168,26 @@ emit_tlb_clear_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
struct v3dv_job *job = cmd_buffer->state.job;
struct v3dv_cl *rcl = &job->rcl;
const struct v3dv_frame_tiling *tiling = &job->frame_tiling;
const uint32_t tile_alloc_offset =
64 * layer * framebuffer->draw_tiles_x * framebuffer->draw_tiles_y;
64 * layer * tiling->draw_tiles_x * tiling->draw_tiles_y;
cl_emit(rcl, MULTICORE_RENDERING_TILE_LIST_SET_BASE, list) {
list.address = v3dv_cl_address(job->tile_alloc, tile_alloc_offset);
}
cl_emit(rcl, MULTICORE_RENDERING_SUPERTILE_CFG, config) {
config.number_of_bin_tile_lists = 1;
config.total_frame_width_in_tiles = framebuffer->draw_tiles_x;
config.total_frame_height_in_tiles = framebuffer->draw_tiles_y;
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 = framebuffer->supertile_width;
config.supertile_height_in_tiles = framebuffer->supertile_height;
config.supertile_width_in_tiles = tiling->supertile_width;
config.supertile_height_in_tiles = tiling->supertile_height;
config.total_frame_width_in_supertiles =
framebuffer->frame_width_in_supertiles;
tiling->frame_width_in_supertiles;
config.total_frame_height_in_supertiles =
framebuffer->frame_height_in_supertiles;
tiling->frame_height_in_supertiles;
}
/* Emit the clear and also the workaround for GFXH-1742 */
@ -209,9 +211,9 @@ emit_tlb_clear_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
emit_tlb_clear_per_tile_rcl(cmd_buffer, attachment_count, attachments, layer);
uint32_t supertile_w_in_pixels =
framebuffer->tile_width * framebuffer->supertile_width;
tiling->tile_width * tiling->supertile_width;
uint32_t supertile_h_in_pixels =
framebuffer->tile_height * framebuffer->supertile_height;
tiling->tile_height * tiling->supertile_height;
const uint32_t max_render_x = framebuffer->width - 1;
const uint32_t max_render_y = framebuffer->height - 1;
@ -229,7 +231,7 @@ emit_tlb_clear_layer_rcl(struct v3dv_cmd_buffer *cmd_buffer,
}
static void
emit_tlb_clear_rcl(struct v3dv_cmd_buffer *cmd_buffer,
emit_tlb_clear_job(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t attachment_count,
const VkClearAttachment *attachments,
uint32_t base_layer,
@ -242,11 +244,6 @@ emit_tlb_clear_rcl(struct v3dv_cmd_buffer *cmd_buffer,
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
struct v3dv_cl *rcl = &job->rcl;
v3dv_cl_ensure_space_with_branch(rcl, 200 +
layer_count * 256 *
cl_packet_length(SUPERTILE_COORDINATES));
/* Check how many color attachments we have and also if we have a
* depth/stencil attachment.
*/
@ -262,13 +259,29 @@ emit_tlb_clear_rcl(struct v3dv_cmd_buffer *cmd_buffer,
}
}
const uint8_t internal_bpp =
v3dv_framebuffer_compute_internal_bpp(framebuffer, subpass);
struct v3dv_frame_tiling frame_tiling;
v3dv_framebuffer_compute_tiling_params(framebuffer, subpass, internal_bpp,
&frame_tiling);
v3dv_cmd_buffer_start_frame(cmd_buffer, framebuffer, &frame_tiling,
color_attachment_count);
struct v3dv_cl *rcl = &job->rcl;
v3dv_cl_ensure_space_with_branch(rcl, 200 +
layer_count * 256 *
cl_packet_length(SUPERTILE_COORDINATES));
const struct v3dv_frame_tiling *tiling = &job->frame_tiling;
cl_emit(rcl, TILE_RENDERING_MODE_CFG_COMMON, config) {
config.early_z_disable = true;
config.image_width_pixels = framebuffer->width;
config.image_height_pixels = framebuffer->height;
config.number_of_render_targets = MAX2(color_attachment_count, 1);
config.multisample_mode_4x = false; /* FIXME */
config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp;
config.maximum_bpp_of_all_render_targets = tiling->internal_bpp;
}
for (uint32_t i = 0; i < color_attachment_count; i++) {
@ -386,16 +399,22 @@ emit_tlb_clear(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t base_layer,
uint32_t layer_count)
{
const struct v3dv_framebuffer *framebuffer = cmd_buffer->state.framebuffer;
const struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, false);
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
/* Save a copy of the current subpass tiling spec */
struct v3dv_frame_tiling subpass_tiling;
memcpy(&subpass_tiling, &job->frame_tiling, sizeof(subpass_tiling));
job = v3dv_cmd_buffer_start_job(cmd_buffer, false);
/* vkCmdClearAttachments runs inside a render pass */
job->is_subpass_continue = true;
v3dv_cmd_buffer_start_frame(cmd_buffer, framebuffer);
emit_tlb_clear_rcl(cmd_buffer,
emit_tlb_clear_job(cmd_buffer,
attachment_count,
attachments,
base_layer, layer_count);
@ -409,7 +428,10 @@ emit_tlb_clear(struct v3dv_cmd_buffer *cmd_buffer,
* after the clear.
*/
job = v3dv_cmd_buffer_start_job(cmd_buffer, false);
v3dv_cmd_buffer_start_frame(cmd_buffer, framebuffer);
uint32_t subpass_color_count =
state->pass->subpasses[state->subpass_idx].color_count;
v3dv_cmd_buffer_start_frame(cmd_buffer, framebuffer, &subpass_tiling,
subpass_color_count);
job->is_subpass_continue = true;
}

View File

@ -43,6 +43,7 @@
*/
struct fake_framebuffer {
struct v3dv_framebuffer fb;
struct v3dv_frame_tiling tiling;
uint32_t internal_type;
uint32_t min_x_supertile;
uint32_t min_y_supertile;
@ -64,14 +65,13 @@ setup_framebuffer_params(struct fake_framebuffer *fb,
fb->fb.width = width;
fb->fb.height = height;
fb->fb.layers = layer_count;
fb->fb.internal_bpp = MAX2(RENDER_TARGET_MAXIMUM_32BPP, internal_bpp);
/* We are only interested in the framebufer description required to compute
* the tiling setup parameters below, so we don't need real attachments,
* only the framebuffer size and the internal bpp.
* only the framebuffer size, the internal bpp and the number of attachments.
*/
fb->fb.attachment_count = 0;
fb->fb.color_attachment_count = 0;
fb->fb.attachment_count = 1;
fb->fb.color_attachment_count = 1;
/* For simplicity, we store the internal type of the single render target
* that functions in this file need in the fake framebuffer objects so
@ -79,10 +79,14 @@ setup_framebuffer_params(struct fake_framebuffer *fb,
*/
fb->internal_type = internal_type;
v3dv_framebuffer_compute_tiling_params(&fb->fb);
fb->tiling.internal_bpp = MAX2(RENDER_TARGET_MAXIMUM_32BPP, internal_bpp);
v3dv_framebuffer_compute_tiling_params(&fb->fb, NULL,
fb->tiling.internal_bpp, &fb->tiling);
uint32_t supertile_w_in_pixels = fb->fb.tile_width * fb->fb.supertile_width;
uint32_t supertile_h_in_pixels = fb->fb.tile_height * fb->fb.supertile_height;
uint32_t supertile_w_in_pixels =
fb->tiling.tile_width * fb->tiling.supertile_width;
uint32_t supertile_h_in_pixels =
fb->tiling.tile_height * fb->tiling.supertile_height;
fb->min_x_supertile = 0;
fb->min_y_supertile = 0;
fb->max_x_supertile = (fb->fb.width - 1) / supertile_w_in_pixels;
@ -216,13 +220,14 @@ emit_rcl_prologue(struct v3dv_job *job,
framebuffer->fb.layers * 256 *
cl_packet_length(SUPERTILE_COORDINATES));
const struct v3dv_frame_tiling *tiling = &framebuffer->tiling;
cl_emit(rcl, TILE_RENDERING_MODE_CFG_COMMON, config) {
config.early_z_disable = true;
config.image_width_pixels = framebuffer->fb.width;
config.image_height_pixels = framebuffer->fb.height;
config.number_of_render_targets = 1;
config.multisample_mode_4x = false;
config.maximum_bpp_of_all_render_targets = framebuffer->fb.internal_bpp;
config.maximum_bpp_of_all_render_targets = tiling->internal_bpp;
}
if (clear_value && (aspects & VK_IMAGE_ASPECT_COLOR_BIT)) {
@ -251,7 +256,7 @@ emit_rcl_prologue(struct v3dv_job *job,
clear.render_target_number = 0;
};
if (framebuffer->fb.internal_bpp >= V3D_INTERNAL_BPP_64) {
if (tiling->internal_bpp >= V3D_INTERNAL_BPP_64) {
cl_emit(rcl, TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART2, clear) {
clear.clear_color_mid_low_32_bits =
((color[1] >> 24) | (color[2] << 8));
@ -261,7 +266,7 @@ emit_rcl_prologue(struct v3dv_job *job,
};
}
if (framebuffer->fb.internal_bpp >= V3D_INTERNAL_BPP_128 || clear_pad) {
if (tiling->internal_bpp >= V3D_INTERNAL_BPP_128 || clear_pad) {
cl_emit(rcl, TILE_RENDERING_MODE_CFG_CLEAR_COLORS_PART3, clear) {
clear.uif_padded_height_in_uif_blocks = clear_pad;
clear.clear_color_high_16_bits = color[3] >> 16;
@ -271,7 +276,7 @@ emit_rcl_prologue(struct v3dv_job *job,
}
cl_emit(rcl, TILE_RENDERING_MODE_CFG_COLOR, rt) {
rt.render_target_0_internal_bpp = framebuffer->fb.internal_bpp;
rt.render_target_0_internal_bpp = tiling->internal_bpp;
rt.render_target_0_internal_type = framebuffer->internal_type;
rt.render_target_0_clamp = V3D_RENDER_TARGET_CLAMP_NONE;
}
@ -299,23 +304,24 @@ emit_frame_setup(struct v3dv_job *job,
struct v3dv_cl *rcl = &job->rcl;
const uint32_t tile_alloc_offset =
64 * layer * framebuffer->fb.draw_tiles_x * framebuffer->fb.draw_tiles_y;
64 * layer * framebuffer->tiling.draw_tiles_x *
framebuffer->tiling.draw_tiles_y;
cl_emit(rcl, MULTICORE_RENDERING_TILE_LIST_SET_BASE, list) {
list.address = v3dv_cl_address(job->tile_alloc, tile_alloc_offset);
}
cl_emit(rcl, MULTICORE_RENDERING_SUPERTILE_CFG, config) {
config.number_of_bin_tile_lists = 1;
config.total_frame_width_in_tiles = framebuffer->fb.draw_tiles_x;
config.total_frame_height_in_tiles = framebuffer->fb.draw_tiles_y;
config.total_frame_width_in_tiles = framebuffer->tiling.draw_tiles_x;
config.total_frame_height_in_tiles = framebuffer->tiling.draw_tiles_y;
config.supertile_width_in_tiles = framebuffer->fb.supertile_width;
config.supertile_height_in_tiles = framebuffer->fb.supertile_height;
config.supertile_width_in_tiles = framebuffer->tiling.supertile_width;
config.supertile_height_in_tiles = framebuffer->tiling.supertile_height;
config.total_frame_width_in_supertiles =
framebuffer->fb.frame_width_in_supertiles;
framebuffer->tiling.frame_width_in_supertiles;
config.total_frame_height_in_supertiles =
framebuffer->fb.frame_height_in_supertiles;
framebuffer->tiling.frame_height_in_supertiles;
}
/* Implement GFXH-1742 workaround. Also, if we are clearing we have to do
@ -666,9 +672,9 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer,
/* Limit supertile coverage to the requested region */
uint32_t supertile_w_in_pixels =
framebuffer.fb.tile_width * framebuffer.fb.supertile_width;
framebuffer.tiling.tile_width * framebuffer.tiling.supertile_width;
uint32_t supertile_h_in_pixels =
framebuffer.fb.tile_height * framebuffer.fb.supertile_height;
framebuffer.tiling.tile_height * framebuffer.tiling.supertile_height;
const uint32_t max_render_x =
region->imageOffset.x + region->imageExtent.width - 1;
const uint32_t max_render_y =
@ -681,7 +687,8 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer,
framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels;
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
emit_copy_image_to_buffer_rcl(job, buffer, image, &framebuffer, region);
@ -822,9 +829,9 @@ copy_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
/* Limit supertile coverage to the requested region */
uint32_t supertile_w_in_pixels =
framebuffer.fb.tile_width * framebuffer.fb.supertile_width;
framebuffer.tiling.tile_width * framebuffer.tiling.supertile_width;
uint32_t supertile_h_in_pixels =
framebuffer.fb.tile_height * framebuffer.fb.supertile_height;
framebuffer.tiling.tile_height * framebuffer.tiling.supertile_height;
const uint32_t max_render_x = region->extent.width - 1;
const uint32_t max_render_y = region->extent.height - 1;
@ -835,7 +842,8 @@ copy_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels;
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
emit_copy_image_rcl(job, dst, src, &framebuffer, region);
@ -967,7 +975,8 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
internal_bpp, internal_type);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
/* If this triggers it is an application bug: the spec requires
@ -1122,7 +1131,7 @@ setup_framebuffer_for_pixel_count(struct fake_framebuffer *framebuffer,
/* Skip tiling calculations if the framebuffer setup has not changed */
if (w != framebuffer->fb.width ||
h != framebuffer->fb.height ||
internal_bpp != framebuffer->fb.internal_bpp ||
internal_bpp != framebuffer->tiling.internal_bpp ||
internal_type != framebuffer->internal_type) {
setup_framebuffer_params(framebuffer, w, h, 1,
internal_bpp, internal_type);
@ -1172,7 +1181,8 @@ copy_buffer(struct v3dv_cmd_buffer *cmd_buffer,
internal_bpp, internal_type);
job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
@ -1328,7 +1338,8 @@ fill_buffer(struct v3dv_cmd_buffer *cmd_buffer,
internal_bpp, internal_type);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
@ -1517,9 +1528,9 @@ copy_buffer_to_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
/* Limit supertile coverage to the requested region */
uint32_t supertile_w_in_pixels =
framebuffer.fb.tile_width * framebuffer.fb.supertile_width;
framebuffer.tiling.tile_width * framebuffer.tiling.supertile_width;
uint32_t supertile_h_in_pixels =
framebuffer.fb.tile_height * framebuffer.fb.supertile_height;
framebuffer.tiling.tile_height * framebuffer.tiling.supertile_height;
const uint32_t max_render_x =
region->imageOffset.x + region->imageExtent.width - 1;
const uint32_t max_render_y =
@ -1532,7 +1543,8 @@ copy_buffer_to_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
framebuffer.max_y_supertile = max_render_y / supertile_h_in_pixels;
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
v3dv_cmd_buffer_start_frame(cmd_buffer, &framebuffer.fb);
v3dv_cmd_buffer_start_frame(cmd_buffer,
&framebuffer.fb, &framebuffer.tiling, 1);
v3dv_job_emit_binning_flush(job);
emit_copy_buffer_to_image_rcl(job, image, buffer, &framebuffer, region);

View File

@ -403,6 +403,12 @@ struct v3dv_framebuffer {
uint32_t height;
uint32_t layers;
uint32_t attachment_count;
uint32_t color_attachment_count;
struct v3dv_image_view *attachments[0];
};
struct v3dv_frame_tiling {
uint32_t internal_bpp;
uint32_t tile_width;
uint32_t tile_height;
@ -412,13 +418,15 @@ struct v3dv_framebuffer {
uint32_t supertile_height;
uint32_t frame_width_in_supertiles;
uint32_t frame_height_in_supertiles;
uint32_t attachment_count;
uint32_t color_attachment_count;
struct v3dv_image_view *attachments[0];
};
void v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer);
uint8_t v3dv_framebuffer_compute_internal_bpp(const struct v3dv_framebuffer *framebuffer,
const struct v3dv_subpass *subpass);
void v3dv_framebuffer_compute_tiling_params(const struct v3dv_framebuffer *framebuffer,
const struct v3dv_subpass *subpass,
uint8_t internal_bpp,
struct v3dv_frame_tiling *tiling);
struct v3dv_cmd_pool {
VkAllocationCallbacks alloc;
@ -562,6 +570,8 @@ struct v3dv_job {
/* If this job is the last job emitted for a subpass. */
bool is_subpass_finish;
struct v3dv_frame_tiling frame_tiling;
enum v3dv_ez_state ez_state;
enum v3dv_ez_state first_ez_state;
};
@ -636,7 +646,9 @@ struct v3dv_job *v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer,
int32_t subpass_idx);
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);
const struct v3dv_framebuffer *framebuffer,
const struct v3dv_frame_tiling *tiling,
int32_t num_render_targets);
void v3dv_render_pass_setup_render_target(struct v3dv_cmd_buffer *cmd_buffer,
int rt,