diff options
author | Jonathan Marek <[email protected]> | 2019-12-05 20:53:34 -0500 |
---|---|---|
committer | Jonathan Marek <[email protected]> | 2019-12-12 20:33:17 -0500 |
commit | aac7d6c1dcab12a820ec8d9c40911dd8212ebce6 (patch) | |
tree | 4103e691c76dd29bfca3e30231995dac6197e654 /src/freedreno/vulkan/tu_cmd_buffer.c | |
parent | 4322cf34c4ce5badb410645b370ab33dbfea1a3c (diff) |
turnip: subpass rework
A renderpass is a tile load/store cycle.
Signed-off-by: Jonathan Marek <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/freedreno/vulkan/tu_cmd_buffer.c')
-rw-r--r-- | src/freedreno/vulkan/tu_cmd_buffer.c | 480 |
1 files changed, 216 insertions, 264 deletions
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 9d466705469..26d460f4143 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -255,37 +255,6 @@ tu_tiling_config_update_pipes(struct tu_tiling_config *tiling, } static void -tu_tiling_config_update(struct tu_tiling_config *tiling, - const struct tu_device *dev, - const uint32_t *buffer_cpp, - uint32_t buffer_count, - const VkRect2D *render_area) -{ - /* see if there is any real change */ - const bool ra_changed = - render_area && - memcmp(&tiling->render_area, render_area, sizeof(*render_area)); - const bool buf_changed = tiling->buffer_count != buffer_count || - memcmp(tiling->buffer_cpp, buffer_cpp, - sizeof(*buffer_cpp) * buffer_count); - if (!ra_changed && !buf_changed) - return; - - if (ra_changed) - tiling->render_area = *render_area; - - if (buf_changed) { - memcpy(tiling->buffer_cpp, buffer_cpp, - sizeof(*buffer_cpp) * buffer_count); - tiling->buffer_count = buffer_count; - } - - tu_tiling_config_update_tile_layout(tiling, dev); - tu_tiling_config_update_pipe_layout(tiling, dev); - tu_tiling_config_update_pipes(tiling, dev); -} - -static void tu_tiling_config_get_tile(const struct tu_tiling_config *tiling, const struct tu_device *dev, uint32_t tx, @@ -416,10 +385,11 @@ tu6_emit_flag_buffer(struct tu_cs *cs, const struct tu_image_view *iview) } static void -tu6_emit_zs(struct tu_cmd_buffer *cmd, struct tu_cs *cs) +tu6_emit_zs(struct tu_cmd_buffer *cmd, + const struct tu_subpass *subpass, + struct tu_cs *cs) { const struct tu_framebuffer *fb = cmd->state.framebuffer; - const struct tu_subpass *subpass = cmd->state.subpass; const struct tu_tiling_config *tiling = &cmd->state.tiling_config; const uint32_t a = subpass->depth_stencil_attachment.attachment; @@ -457,7 +427,7 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_PITCH(tu_image_stride(iview->image, iview->base_mip))); tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(iview->image->layout.layer_size)); tu_cs_emit_qw(cs, tu_image_base(iview->image, iview->base_mip, iview->base_layer)); - tu_cs_emit(cs, tiling->gmem_offsets[subpass->color_count]); + tu_cs_emit(cs, tiling->gmem_offsets[a]); tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_BUFFER_INFO, 1); tu_cs_emit(cs, A6XX_GRAS_SU_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt)); @@ -479,10 +449,11 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd, struct tu_cs *cs) } static void -tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs) +tu6_emit_mrt(struct tu_cmd_buffer *cmd, + const struct tu_subpass *subpass, + struct tu_cs *cs) { const struct tu_framebuffer *fb = cmd->state.framebuffer; - const struct tu_subpass *subpass = cmd->state.subpass; const struct tu_tiling_config *tiling = &cmd->state.tiling_config; unsigned char mrt_comp[MAX_RTS] = { 0 }; unsigned srgb_cntl = 0; @@ -513,7 +484,7 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit(cs, A6XX_RB_MRT_ARRAY_PITCH(iview->image->layout.layer_size)); tu_cs_emit_qw(cs, tu_image_base(iview->image, iview->base_mip, iview->base_layer)); tu_cs_emit( - cs, tiling->gmem_offsets[i]); /* RB_MRT[i].BASE_GMEM */ + cs, tiling->gmem_offsets[a]); /* RB_MRT[i].BASE_GMEM */ tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_MRT_REG(i), 1); tu_cs_emit(cs, A6XX_SP_FS_MRT_REG_COLOR_FORMAT(format->rb) | @@ -552,11 +523,11 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs) } static void -tu6_emit_msaa(struct tu_cmd_buffer *cmd, struct tu_cs *cs) +tu6_emit_msaa(struct tu_cmd_buffer *cmd, + const struct tu_subpass *subpass, + struct tu_cs *cs) { - const struct tu_subpass *subpass = cmd->state.subpass; - const enum a3xx_msaa_samples samples = - tu_msaa_samples(subpass->max_sample_count); + const enum a3xx_msaa_samples samples = tu_msaa_samples(subpass->samples); tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_RAS_MSAA_CNTL, 2); tu_cs_emit(cs, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(samples)); @@ -615,13 +586,21 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd, } static void -tu6_emit_blit_scissor(struct tu_cmd_buffer *cmd, struct tu_cs *cs) +tu6_emit_blit_scissor(struct tu_cmd_buffer *cmd, struct tu_cs *cs, bool align) { const VkRect2D *render_area = &cmd->state.tiling_config.render_area; - const uint32_t x1 = render_area->offset.x; - const uint32_t y1 = render_area->offset.y; - const uint32_t x2 = x1 + render_area->extent.width - 1; - const uint32_t y2 = y1 + render_area->extent.height - 1; + uint32_t x1 = render_area->offset.x; + uint32_t y1 = render_area->offset.y; + uint32_t x2 = x1 + render_area->extent.width - 1; + uint32_t y2 = y1 + render_area->extent.height - 1; + + /* TODO: alignment requirement seems to be less than tile_align_w/h */ + if (align) { + x1 = x1 & ~cmd->device->physical_device->tile_align_w; + y1 = y1 & ~cmd->device->physical_device->tile_align_h; + x2 = ALIGN_POT(x2 + 1, cmd->device->physical_device->tile_align_w) - 1; + y2 = ALIGN_POT(y2 + 1, cmd->device->physical_device->tile_align_h) - 1; + } tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_SCISSOR_TL, 2); tu_cs_emit(cs, @@ -635,10 +614,10 @@ tu6_emit_blit_info(struct tu_cmd_buffer *cmd, struct tu_cs *cs, const struct tu_image_view *iview, uint32_t gmem_offset, - uint32_t blit_info) + bool resolve) { tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1); - tu_cs_emit(cs, blit_info); + tu_cs_emit(cs, resolve ? 0 : (A6XX_RB_BLIT_INFO_UNK0 | A6XX_RB_BLIT_INFO_GMEM)); const struct tu_native_format *format = tu6_get_native_format(iview->vk_format); @@ -667,39 +646,6 @@ tu6_emit_blit_info(struct tu_cmd_buffer *cmd, } static void -tu6_emit_blit_clear(struct tu_cmd_buffer *cmd, - struct tu_cs *cs, - const struct tu_image_view *iview, - uint32_t gmem_offset, - const VkClearValue *clear_value) -{ - const struct tu_native_format *format = - tu6_get_native_format(iview->vk_format); - assert(format && format->rb >= 0); - - tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1); - tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb)); - - tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1); - tu_cs_emit(cs, A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(0xf)); - - tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1); - tu_cs_emit(cs, gmem_offset); - - tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_88D0, 1); - tu_cs_emit(cs, 0); - - uint32_t clear_vals[4] = { 0 }; - tu_pack_clear_value(clear_value, iview->vk_format, clear_vals); - - tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 4); - tu_cs_emit(cs, clear_vals[0]); - tu_cs_emit(cs, clear_vals[1]); - tu_cs_emit(cs, clear_vals[2]); - tu_cs_emit(cs, clear_vals[3]); -} - -static void tu6_emit_blit(struct tu_cmd_buffer *cmd, struct tu_cs *cs) { tu6_emit_marker(cmd, cs); @@ -837,69 +783,120 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd, } static void -tu6_emit_tile_load_attachment(struct tu_cmd_buffer *cmd, - struct tu_cs *cs, - uint32_t a, - uint32_t gmem_index) +tu6_emit_load_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a) { - const struct tu_framebuffer *fb = cmd->state.framebuffer; const struct tu_tiling_config *tiling = &cmd->state.tiling_config; - const struct tu_attachment_state *attachments = cmd->state.attachments; - + const struct tu_framebuffer *fb = cmd->state.framebuffer; const struct tu_image_view *iview = fb->attachments[a].attachment; - const struct tu_attachment_state *att = attachments + a; - if (att->pending_clear_aspects) { - tu6_emit_blit_clear(cmd, cs, iview, - tiling->gmem_offsets[gmem_index], - &att->clear_value); - } else { - tu6_emit_blit_info(cmd, cs, iview, - tiling->gmem_offsets[gmem_index], - A6XX_RB_BLIT_INFO_UNK0 | A6XX_RB_BLIT_INFO_GMEM); - } + const struct tu_render_pass_attachment *attachment = + &cmd->state.pass->attachments[a]; - tu6_emit_blit(cmd, cs); + if (!attachment->needs_gmem) + return; + + const uint32_t x1 = tiling->render_area.offset.x; + const uint32_t y1 = tiling->render_area.offset.y; + const uint32_t x2 = x1 + tiling->render_area.extent.width; + const uint32_t y2 = y1 + tiling->render_area.extent.height; + const uint32_t tile_x2 = + tiling->tile0.offset.x + tiling->tile0.extent.width * tiling->tile_count.width; + const uint32_t tile_y2 = + tiling->tile0.offset.y + tiling->tile0.extent.height * tiling->tile_count.height; + bool need_load = + x1 != tiling->tile0.offset.x || x2 != MIN2(fb->width, tile_x2) || + y1 != tiling->tile0.offset.y || y2 != MIN2(fb->height, tile_y2); + + if (need_load) + tu_finishme("improve handling of unaligned render area"); + + if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_LOAD) + need_load = true; + + if (vk_format_has_stencil(iview->vk_format) && + attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_LOAD) + need_load = true; + + if (need_load) { + tu6_emit_blit_info(cmd, cs, iview, tiling->gmem_offsets[a], false); + tu6_emit_blit(cmd, cs); + } } static void -tu6_emit_tile_load(struct tu_cmd_buffer *cmd, struct tu_cs *cs) +tu6_emit_clear_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, + uint32_t a, + const VkRenderPassBeginInfo *info) { - const struct tu_subpass *subpass = cmd->state.subpass; + const struct tu_tiling_config *tiling = &cmd->state.tiling_config; + const struct tu_framebuffer *fb = cmd->state.framebuffer; + const struct tu_image_view *iview = fb->attachments[a].attachment; + const struct tu_render_pass_attachment *attachment = + &cmd->state.pass->attachments[a]; + unsigned clear_mask = 0; + + /* note: this means it isn't used by any subpass and shouldn't be cleared anyway */ + if (!attachment->needs_gmem) + return; - tu6_emit_blit_scissor(cmd, cs); + if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) + clear_mask = 0xf; - for (uint32_t i = 0; i < subpass->color_count; ++i) { - const uint32_t a = subpass->color_attachments[i].attachment; - if (a != VK_ATTACHMENT_UNUSED) - tu6_emit_tile_load_attachment(cmd, cs, a, i); + if (vk_format_has_stencil(iview->vk_format)) { + clear_mask &= 0x1; + if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) + clear_mask |= 0x2; } + if (!clear_mask) + return; - const uint32_t a = subpass->depth_stencil_attachment.attachment; - if (a != VK_ATTACHMENT_UNUSED) - tu6_emit_tile_load_attachment(cmd, cs, a, subpass->color_count); + const struct tu_native_format *format = + tu6_get_native_format(iview->vk_format); + assert(format && format->rb >= 0); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 1); + tu_cs_emit(cs, A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb)); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1); + tu_cs_emit(cs, A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(clear_mask)); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_BASE_GMEM, 1); + tu_cs_emit(cs, tiling->gmem_offsets[a]); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_88D0, 1); + tu_cs_emit(cs, 0); + + uint32_t clear_vals[4] = { 0 }; + tu_pack_clear_value(&info->pClearValues[a], iview->vk_format, clear_vals); + + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 4); + tu_cs_emit(cs, clear_vals[0]); + tu_cs_emit(cs, clear_vals[1]); + tu_cs_emit(cs, clear_vals[2]); + tu_cs_emit(cs, clear_vals[3]); + + tu6_emit_blit(cmd, cs); } static void tu6_emit_store_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a, - uint32_t gmem_index) + uint32_t gmem_a) { - const struct tu_framebuffer *fb = cmd->state.framebuffer; - const struct tu_tiling_config *tiling = &cmd->state.tiling_config; - - if (a == VK_ATTACHMENT_UNUSED) + if (cmd->state.pass->attachments[a].store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) return; - tu6_emit_blit_info(cmd, cs, fb->attachments[a].attachment, - tiling->gmem_offsets[gmem_index], 0); + tu6_emit_blit_info(cmd, cs, + cmd->state.framebuffer->attachments[a].attachment, + cmd->state.tiling_config.gmem_offsets[gmem_a], true); tu6_emit_blit(cmd, cs); } static void tu6_emit_tile_store(struct tu_cmd_buffer *cmd, struct tu_cs *cs) { - const struct tu_subpass *subpass = cmd->state.subpass; + const struct tu_render_pass *pass = cmd->state.pass; + const struct tu_subpass *subpass = &pass->subpasses[pass->subpass_count-1]; tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3); tu_cs_emit(cs, CP_SET_DRAW_STATE__0_COUNT(0) | @@ -916,22 +913,21 @@ tu6_emit_tile_store(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit(cs, A6XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE) | 0x10); tu6_emit_marker(cmd, cs); - tu6_emit_blit_scissor(cmd, cs); + tu6_emit_blit_scissor(cmd, cs, true); - for (uint32_t i = 0; i < subpass->color_count; ++i) { - tu6_emit_store_attachment(cmd, cs, - subpass->color_attachments[i].attachment, - i); - if (subpass->resolve_attachments) { - tu6_emit_store_attachment(cmd, cs, - subpass->resolve_attachments[i].attachment, - i); - } + for (uint32_t a = 0; a < pass->attachment_count; ++a) { + if (pass->attachments[a].needs_gmem) + tu6_emit_store_attachment(cmd, cs, a, a); } - tu6_emit_store_attachment(cmd, cs, - subpass->depth_stencil_attachment.attachment, - subpass->color_count); + if (subpass->resolve_attachments) { + for (unsigned i = 0; i < subpass->color_count; i++) { + uint32_t a = subpass->resolve_attachments[i].attachment; + if (a != VK_ATTACHMENT_UNUSED) + tu6_emit_store_attachment(cmd, cs, a, + subpass->color_attachments[i].attachment); + } + } } static void @@ -1354,10 +1350,6 @@ tu6_render_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit_pkt4(cs, REG_A6XX_RB_CCU_CNTL, 1); tu_cs_emit(cs, 0x7c400004); /* RB_CCU_CNTL */ - tu6_emit_zs(cmd, cs); - tu6_emit_mrt(cmd, cs); - tu6_emit_msaa(cmd, cs); - if (use_hw_binning(cmd)) { tu6_emit_bin_size(cmd, cs, A6XX_RB_BIN_CONTROL_BINNING_PASS | 0x6000000); @@ -1464,11 +1456,13 @@ tu_cmd_render_tiles(struct tu_cmd_buffer *cmd) } static void -tu_cmd_prepare_tile_load_ib(struct tu_cmd_buffer *cmd) +tu_cmd_prepare_tile_load_ib(struct tu_cmd_buffer *cmd, + const VkRenderPassBeginInfo *info) { - const uint32_t tile_load_space = 16 + 32 * MAX_RTS; - const struct tu_subpass *subpass = cmd->state.subpass; - struct tu_attachment_state *attachments = cmd->state.attachments; + const uint32_t tile_load_space = + 6 + (23+19) * cmd->state.pass->attachment_count + + 21 + (13 * cmd->state.subpass->color_count + 8) + 11; + struct tu_cs sub_cs; VkResult result = tu_cs_begin_sub_stream(cmd->device, &cmd->tile_cs, @@ -1478,22 +1472,27 @@ tu_cmd_prepare_tile_load_ib(struct tu_cmd_buffer *cmd) return; } - /* emit to tile-load sub_cs */ - tu6_emit_tile_load(cmd, &sub_cs); + tu6_emit_blit_scissor(cmd, &sub_cs, true); - cmd->state.tile_load_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs); + for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i) + tu6_emit_load_attachment(cmd, &sub_cs, i); - for (uint32_t i = 0; i < subpass->color_count; ++i) { - const uint32_t a = subpass->color_attachments[i].attachment; - if (a != VK_ATTACHMENT_UNUSED) - attachments[a].pending_clear_aspects = 0; - } + tu6_emit_blit_scissor(cmd, &sub_cs, false); + + for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i) + tu6_emit_clear_attachment(cmd, &sub_cs, i, info); + + tu6_emit_zs(cmd, cmd->state.subpass, &sub_cs); + tu6_emit_mrt(cmd, cmd->state.subpass, &sub_cs); + tu6_emit_msaa(cmd, cmd->state.subpass, &sub_cs); + + cmd->state.tile_load_ib = tu_cs_end_sub_stream(&cmd->tile_cs, &sub_cs); } static void tu_cmd_prepare_tile_store_ib(struct tu_cmd_buffer *cmd) { - const uint32_t tile_store_space = 32 + 32 * MAX_RTS; + const uint32_t tile_store_space = 32 + 23 * cmd->state.pass->attachment_count; struct tu_cs sub_cs; VkResult result = tu_cs_begin_sub_stream(cmd->device, &cmd->tile_cs, @@ -1515,37 +1514,20 @@ tu_cmd_update_tiling_config(struct tu_cmd_buffer *cmd, { const struct tu_device *dev = cmd->device; const struct tu_render_pass *pass = cmd->state.pass; - const struct tu_subpass *subpass = cmd->state.subpass; struct tu_tiling_config *tiling = &cmd->state.tiling_config; - uint32_t buffer_cpp[MAX_RTS + 2]; - uint32_t buffer_count = 0; - - for (uint32_t i = 0; i < subpass->color_count; ++i) { - const uint32_t a = subpass->color_attachments[i].attachment; - if (a == VK_ATTACHMENT_UNUSED) { - buffer_cpp[buffer_count++] = 0; - continue; - } - - const struct tu_render_pass_attachment *att = &pass->attachments[a]; - buffer_cpp[buffer_count++] = - vk_format_get_blocksize(att->format) * att->samples; + tiling->render_area = *render_area; + for (uint32_t a = 0; a < pass->attachment_count; a++) { + if (pass->attachments[a].needs_gmem) + tiling->buffer_cpp[a] = pass->attachments[a].cpp; + else + tiling->buffer_cpp[a] = 0; } + tiling->buffer_count = pass->attachment_count; - if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) { - const uint32_t a = subpass->depth_stencil_attachment.attachment; - const struct tu_render_pass_attachment *att = &pass->attachments[a]; - - /* TODO */ - assert(att->format != VK_FORMAT_D32_SFLOAT_S8_UINT); - - buffer_cpp[buffer_count++] = - vk_format_get_blocksize(att->format) * att->samples; - } - - tu_tiling_config_update(tiling, dev, buffer_cpp, buffer_count, - render_area); + tu_tiling_config_update_tile_layout(tiling, dev); + tu_tiling_config_update_pipe_layout(tiling, dev); + tu_tiling_config_update_pipes(tiling, dev); } const struct tu_dynamic_state default_dynamic_state = { @@ -1804,72 +1786,6 @@ tu_reset_cmd_buffer(struct tu_cmd_buffer *cmd_buffer) return cmd_buffer->record_result; } -static VkResult -tu_cmd_state_setup_attachments(struct tu_cmd_buffer *cmd_buffer, - const VkRenderPassBeginInfo *info) -{ - struct tu_cmd_state *state = &cmd_buffer->state; - const struct tu_framebuffer *fb = state->framebuffer; - const struct tu_render_pass *pass = state->pass; - - for (uint32_t i = 0; i < fb->attachment_count; ++i) { - const struct tu_image_view *iview = fb->attachments[i].attachment; - tu_bo_list_add(&cmd_buffer->bo_list, iview->image->bo, - MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE); - } - - if (pass->attachment_count == 0) { - state->attachments = NULL; - return VK_SUCCESS; - } - - state->attachments = - vk_alloc(&cmd_buffer->pool->alloc, - pass->attachment_count * sizeof(state->attachments[0]), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (state->attachments == NULL) { - cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY; - return cmd_buffer->record_result; - } - - for (uint32_t i = 0; i < pass->attachment_count; ++i) { - const struct tu_render_pass_attachment *att = &pass->attachments[i]; - VkImageAspectFlags att_aspects = vk_format_aspects(att->format); - VkImageAspectFlags clear_aspects = 0; - - if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) { - /* color attachment */ - if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; - } - } else { - /* depthstencil attachment */ - if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && - att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; - if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && - att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) - clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && - att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { - clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; - } - } - - state->attachments[i].pending_clear_aspects = clear_aspects; - state->attachments[i].cleared_views = 0; - if (clear_aspects && info) { - assert(info->clearValueCount > i); - state->attachments[i].clear_value = info->pClearValues[i]; - } - - state->attachments[i].current_layout = att->initial_layout; - } - - return VK_SUCCESS; -} - VkResult tu_AllocateCommandBuffers(VkDevice _device, const VkCommandBufferAllocateInfo *pAllocateInfo, @@ -2130,8 +2046,6 @@ tu_EndCommandBuffer(VkCommandBuffer commandBuffer) tu_cs_end(&cmd_buffer->cs); tu_cs_end(&cmd_buffer->draw_cs); - assert(!cmd_buffer->state.attachments); - cmd_buffer->status = TU_CMD_BUFFER_STATUS_EXECUTABLE; return cmd_buffer->record_result; @@ -2417,26 +2331,28 @@ tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents) { - TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer); + TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); TU_FROM_HANDLE(tu_render_pass, pass, pRenderPassBegin->renderPass); - TU_FROM_HANDLE(tu_framebuffer, framebuffer, pRenderPassBegin->framebuffer); + TU_FROM_HANDLE(tu_framebuffer, fb, pRenderPassBegin->framebuffer); VkResult result; - cmd_buffer->state.pass = pass; - cmd_buffer->state.subpass = pass->subpasses; - cmd_buffer->state.framebuffer = framebuffer; - - result = tu_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin); - if (result != VK_SUCCESS) - return; + cmd->state.pass = pass; + cmd->state.subpass = pass->subpasses; + cmd->state.framebuffer = fb; - tu_cmd_update_tiling_config(cmd_buffer, &pRenderPassBegin->renderArea); - tu_cmd_prepare_tile_load_ib(cmd_buffer); - tu_cmd_prepare_tile_store_ib(cmd_buffer); + tu_cmd_update_tiling_config(cmd, &pRenderPassBegin->renderArea); + tu_cmd_prepare_tile_load_ib(cmd, pRenderPassBegin); + tu_cmd_prepare_tile_store_ib(cmd); /* note: use_hw_binning only checks tiling config */ - if (use_hw_binning(cmd_buffer)) - cmd_buffer->use_vsc_data = true; + if (use_hw_binning(cmd)) + cmd->use_vsc_data = true; + + for (uint32_t i = 0; i < fb->attachment_count; ++i) { + const struct tu_image_view *iview = fb->attachments[i].attachment; + tu_bo_list_add(&cmd->bo_list, iview->image->bo, + MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE); + } } void @@ -2452,14 +2368,53 @@ void tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) { TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + const struct tu_render_pass *pass = cmd->state.pass; + const struct tu_tiling_config *tiling = &cmd->state.tiling_config; + struct tu_cs *cs = &cmd->draw_cs; - tu_cmd_render_tiles(cmd); + VkResult result = tu_cs_reserve_space(cmd->device, cs, 1024); + if (result != VK_SUCCESS) { + cmd->record_result = result; + return; + } - cmd->state.subpass++; + const struct tu_subpass *subpass = cmd->state.subpass++; + /* TODO: + * if msaa samples change between subpasses, + * attachment store is broken for some attachments + */ + if (subpass->resolve_attachments) { + tu6_emit_blit_scissor(cmd, cs, true); + for (unsigned i = 0; i < subpass->color_count; i++) { + uint32_t a = subpass->resolve_attachments[i].attachment; + if (a != VK_ATTACHMENT_UNUSED) { + tu6_emit_store_attachment(cmd, cs, a, + subpass->color_attachments[i].attachment); + } + } + } - tu_cmd_update_tiling_config(cmd, NULL); - tu_cmd_prepare_tile_load_ib(cmd); - tu_cmd_prepare_tile_store_ib(cmd); + /* emit mrt/zs/msaa state for the subpass that is starting */ + tu6_emit_zs(cmd, cmd->state.subpass, cs); + tu6_emit_mrt(cmd, cmd->state.subpass, cs); + tu6_emit_msaa(cmd, cmd->state.subpass, cs); + + /* TODO: + * since we don't know how to do GMEM->GMEM resolve, + * resolve attachments are resolved to memory then loaded to GMEM again if needed + */ + if (subpass->resolve_attachments) { + for (unsigned i = 0; i < subpass->color_count; i++) { + uint32_t a = subpass->resolve_attachments[i].attachment; + const struct tu_image_view *iview = + cmd->state.framebuffer->attachments[a].attachment; + if (a != VK_ATTACHMENT_UNUSED && pass->attachments[a].needs_gmem) { + tu_finishme("missing GMEM->GMEM resolve, performance will suffer\n"); + tu6_emit_blit_info(cmd, cs, iview, tiling->gmem_offsets[a], false); + tu6_emit_blit(cmd, cs); + } + } + } } void @@ -3651,9 +3606,6 @@ tu_CmdEndRenderPass(VkCommandBuffer commandBuffer) tu_cs_discard_entries(&cmd_buffer->draw_cs); tu_cs_begin(&cmd_buffer->draw_cs); - vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments); - cmd_buffer->state.attachments = NULL; - cmd_buffer->state.pass = NULL; cmd_buffer->state.subpass = NULL; cmd_buffer->state.framebuffer = NULL; |