From 4d0e497a3e69c9665b12bed87b964f35d3142f7d Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Tue, 28 Jan 2020 13:03:41 +0100 Subject: [PATCH] v3dv: implement support for depth testing This ignores stencil for now and focuses on depth testing without support for early depth testing. To implement this we need to start considering how many of our framebuffer attachments are color attachments, since some of the computations we use to determine tile sizes and binning configuration depend on this. Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 118 +++++++++++++++++++++++--- src/broadcom/vulkan/v3dv_device.c | 11 ++- src/broadcom/vulkan/v3dv_formats.c | 31 +++++-- src/broadcom/vulkan/v3dv_image.c | 4 - src/broadcom/vulkan/v3dv_meta_copy.c | 1 + src/broadcom/vulkan/v3dv_pipeline.c | 6 +- src/broadcom/vulkan/v3dv_private.h | 1 + 7 files changed, 142 insertions(+), 30 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 615a7aefab1..ca745200fd5 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -24,6 +24,7 @@ #include "v3dv_private.h" #include "broadcom/cle/v3dx_pack.h" #include "util/u_pack_color.h" +#include "vk_format_info.h" const struct v3dv_dynamic_state default_dynamic_state = { .viewport = { @@ -238,7 +239,9 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer) /* FIXME: resolve attachments */ - /* FIXME: also check depth/stencil attachment */ + if (subpass->ds_attachment.attachment != + prev_subpass->ds_attachment.attachment) + return false; return true; } @@ -295,7 +298,8 @@ v3dv_cmd_buffer_start_frame(struct v3dv_cmd_buffer *cmd_buffer, 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.number_of_render_targets = + MAX2(framebuffer->color_attachment_count, 1); config.multisample_mode_4x = false; /* FIXME */ config.maximum_bpp_of_all_render_targets = framebuffer->internal_bpp; } @@ -562,6 +566,23 @@ cmd_buffer_state_set_attachment_clear_color(struct v3dv_cmd_buffer *cmd_buffer, } } +static void +cmd_buffer_state_set_attachment_clear_depth_stencil( + struct v3dv_cmd_buffer *cmd_buffer, + uint32_t attachment_idx, + bool clear_depth, bool clear_stencil, + const VkClearDepthStencilValue *ds) +{ + struct v3dv_cmd_buffer_attachment_state *attachment_state = + &cmd_buffer->state.attachments[attachment_idx]; + + if (clear_depth) + attachment_state->clear_value.z = ds->depth; + + if (clear_stencil) + attachment_state->clear_value.s = ds->stencil; +} + static void cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer, uint32_t count, const VkClearValue *values) @@ -577,9 +598,18 @@ cmd_buffer_state_set_clear_values(struct v3dv_cmd_buffer *cmd_buffer, if (attachment->desc.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR) continue; - /* FIXME: support depth/stencil */ - cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i, - &values[i].color); + VkImageAspectFlags aspects = vk_format_aspects(attachment->desc.format); + if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) { + cmd_buffer_state_set_attachment_clear_color(cmd_buffer, i, + &values[i].color); + } else if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT)) { + cmd_buffer_state_set_attachment_clear_depth_stencil( + cmd_buffer, i, + aspects & VK_IMAGE_ASPECT_DEPTH_BIT, + aspects & VK_IMAGE_ASPECT_STENCIL_BIT, + &values[i].depthStencil); + } } } @@ -701,6 +731,7 @@ setup_render_target(struct v3dv_cmd_buffer *cmd_buffer, int rt, const struct v3dv_framebuffer *framebuffer = state->framebuffer; assert(attachment_idx < framebuffer->attachment_count); struct v3dv_image_view *iview = framebuffer->attachments[attachment_idx]; + assert(iview->aspects & VK_IMAGE_ASPECT_COLOR_BIT); *rt_bpp = iview->internal_bpp; *rt_type = iview->internal_type; @@ -788,6 +819,25 @@ cmd_buffer_render_pass_emit_loads(struct v3dv_cmd_buffer *cmd_buffer, } } + uint32_t ds_attachment_idx = subpass->ds_attachment.attachment; + if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { + const struct v3dv_render_pass_attachment *ds_attachment = + &state->pass->attachments[ds_attachment_idx]; + const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state = + &state->attachments[ds_attachment_idx]; + + assert(state->job->first_subpass >= ds_attachment_state->first_subpass); + bool needs_load = + state->job->first_subpass > ds_attachment_state->first_subpass || + ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD; + + if (needs_load) { + struct v3dv_image_view *iview = + framebuffer->attachments[ds_attachment_idx]; + cmd_buffer_render_pass_emit_load(cmd_buffer, cl, iview, layer, Z); + } + } + cl_emit(cl, END_OF_LOADS, end); } @@ -869,7 +919,7 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer, has_stores = true; } - /* FIXME: depth/stencil store + /* FIXME: separate stencil * * GFXH-1461/GFXH-1689: The per-buffer store command's clear * buffer bit is broken for depth/stencil. In addition, the @@ -882,6 +932,25 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer, * not want to do that. We might want to consider emitting clears for * all RTs needing clearing just once ahead of the first subpass. */ + bool needs_ds_clear = false; + uint32_t ds_attachment_idx = subpass->ds_attachment.attachment; + if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { + const struct v3dv_render_pass_attachment *ds_attachment = + &state->pass->attachments[ds_attachment_idx]; + const struct v3dv_cmd_buffer_attachment_state *ds_attachment_state = + &state->attachments[ds_attachment_idx]; + + /* Only clear once on the first subpass that uses the attachment */ + assert(state->job->first_subpass >= ds_attachment_state->first_subpass); + needs_ds_clear = + state->job->first_subpass == ds_attachment_state->first_subpass && + ds_attachment->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR; + + cmd_buffer_render_pass_emit_store(cmd_buffer, cl, + ds_attachment_idx, layer, + Z, needs_ds_clear); + has_stores = true; + } /* We always need to emit at least one dummy store */ if (!has_stores) { @@ -889,6 +958,14 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer, store.buffer_to_store = NONE; } } + + /* FIXME: see fixme remark for depth/stencil above */ + if (needs_ds_clear) { + cl_emit(cl, CLEAR_TILE_BUFFERS, clear) { + clear.clear_z_stencil_buffer = true; + clear.clear_all_render_targets = true; + } + } } static void @@ -1054,13 +1131,23 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer) * Z_STENCIL_CLEAR_VALUES must be last. The ones in between are optional * updates to the previous HW state. */ + const uint32_t ds_attachment_idx = subpass->ds_attachment.attachment; + cl_emit(rcl, TILE_RENDERING_MODE_CFG_COMMON, config) { - config.early_z_disable = true; /* FIXME */ config.image_width_pixels = framebuffer->width; 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; + + if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { + const struct v3dv_image_view *iview = + framebuffer->attachments[ds_attachment_idx]; + config.internal_depth_type = iview->internal_type; + config.early_z_disable = true; /* FIXME */ + } else { + config.early_z_disable = true; + } } for (uint32_t i = 0; i < subpass->color_count; i++) { @@ -1143,10 +1230,19 @@ cmd_buffer_emit_render_pass_rcl(struct v3dv_cmd_buffer *cmd_buffer) } /* Ends rendering mode config. */ - cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) { - clear.z_clear_value = 0; /* FIXME */ - clear.stencil_clear_value = 0; /* FIXME */ - }; + if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) { + cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) { + clear.z_clear_value = + state->attachments[ds_attachment_idx].clear_value.z; + clear.stencil_clear_value = + state->attachments[ds_attachment_idx].clear_value.s; + }; + } else { + cl_emit(rcl, TILE_RENDERING_MODE_CFG_ZS_CLEAR_VALUES, clear) { + clear.z_clear_value = 1.0f; + clear.stencil_clear_value = 0; + }; + } /* Always set initial block size before the first branch, which needs * to match the value from binning mode config. diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 34e504bef50..417f1211428 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -1659,7 +1659,9 @@ compute_internal_bpp_from_attachments(struct v3dv_framebuffer *framebuffer) uint8_t max_bpp = RENDER_TARGET_MAXIMUM_32BPP; for (uint32_t i = 0; i < framebuffer->attachment_count; i++) { const struct v3dv_image_view *att = framebuffer->attachments[i]; - if (att) + assert(att); + + if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT) max_bpp = MAX2(max_bpp, att->internal_bpp); } framebuffer->internal_bpp = max_bpp; @@ -1680,9 +1682,9 @@ v3dv_framebuffer_compute_tiling_params(struct v3dv_framebuffer *framebuffer) /* FIXME: MSAA */ - if (framebuffer->attachment_count > 2) + if (framebuffer->color_attachment_count > 2) tile_size_index += 2; - else if (framebuffer->attachment_count > 1) + else if (framebuffer->color_attachment_count > 1) tile_size_index += 1; tile_size_index += framebuffer->internal_bpp; @@ -1739,9 +1741,12 @@ v3dv_CreateFramebuffer(VkDevice _device, framebuffer->height = pCreateInfo->height; framebuffer->layers = pCreateInfo->layers; framebuffer->attachment_count = pCreateInfo->attachmentCount; + framebuffer->color_attachment_count = 0; for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { framebuffer->attachments[i] = v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]); + if (framebuffer->attachments[i]->aspects & VK_IMAGE_ASPECT_COLOR_BIT) + framebuffer->color_attachment_count++; } compute_internal_bpp_from_attachments(framebuffer); diff --git a/src/broadcom/vulkan/v3dv_formats.c b/src/broadcom/vulkan/v3dv_formats.c index 803544e0aa0..ad1da916c70 100644 --- a/src/broadcom/vulkan/v3dv_formats.c +++ b/src/broadcom/vulkan/v3dv_formats.c @@ -60,11 +60,18 @@ #define SWIZ_000X SWIZ(0, 0, 0, X) static const struct v3dv_format format_table[] = { - FORMAT(R8G8B8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_XYZW, 16), - FORMAT(B8G8R8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_ZYXW, 16), - FORMAT(R8G8B8A8_UNORM, RGBA8, RGBA8, SWIZ_XYZW, 16), - FORMAT(B8G8R8A8_UNORM, RGBA8, RGBA8, SWIZ_ZYXW, 16), - FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32), + /* Color */ + FORMAT(R8G8B8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_XYZW, 16), + FORMAT(B8G8R8A8_SRGB, SRGB8_ALPHA8, RGBA8, SWIZ_ZYXW, 16), + FORMAT(R8G8B8A8_UNORM, RGBA8, RGBA8, SWIZ_XYZW, 16), + FORMAT(B8G8R8A8_UNORM, RGBA8, RGBA8, SWIZ_ZYXW, 16), + FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32), + FORMAT(R32G32B32A32_SFLOAT, RGBA32F, RGBA32F, SWIZ_XYZW, 32), + + /* Depth */ + FORMAT(D16_UNORM, D16, DEPTH_COMP16, SWIZ_XXXX, 32), + FORMAT(D32_SFLOAT, D32F, DEPTH_COMP32F, SWIZ_XXXX, 32), + FORMAT(X8_D24_UNORM_PACK32, D24S8, DEPTH24_X8, SWIZ_XXXX, 32), }; const struct v3dv_format * @@ -228,7 +235,9 @@ image_format_features(VkFormat vk_format, const VkImageAspectFlags aspects = vk_format_aspects(vk_format); - if (aspects != VK_IMAGE_ASPECT_COLOR_BIT) + const uint32_t supported_aspects = + VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; + if ((aspects & supported_aspects) != aspects) return 0; VkFormatFeatureFlags flags = @@ -239,9 +248,13 @@ image_format_features(VkFormat vk_format, VK_FORMAT_FEATURE_TRANSFER_DST_BIT; if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) { - flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | - VK_FORMAT_FEATURE_BLIT_DST_BIT; + flags |= VK_FORMAT_FEATURE_BLIT_DST_BIT; + if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) { + flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; + } else if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { + flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + } } return flags; diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index 80516c62a59..1ac33d12865 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -411,10 +411,6 @@ v3dv_CreateImageView(VkDevice _device, assert(range->layerCount > 0); assert(range->baseMipLevel < image->levels); - /* FIXME: we don't handle depth/stencil yet */ - assert((range->aspectMask & - (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0); - #ifdef DEBUG switch (image->type) { case VK_IMAGE_TYPE_1D: diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index a7bb1159757..9a58b7babde 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -285,6 +285,7 @@ setup_framebuffer_params(struct v3dv_framebuffer *fb, * only the framebuffer size and the internal bpp. */ fb->attachment_count = 0; + fb->color_attachment_count = 0; v3dv_framebuffer_compute_tiling_params(fb); } diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index fd13a942e6d..b3bb7ef5931 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -963,10 +963,10 @@ pack_cfg_bits(struct v3dv_pipeline *pipeline, /* Note: ez state may update based on the compiled FS, along with zsa * (FIXME: not done) */ - config.early_z_updates_enable = true; + config.early_z_updates_enable = false; if (ds_info && ds_info->depthTestEnable) { - config.z_updates_enable = false; - config.early_z_enable = config.early_z_enable; + config.z_updates_enable = true; + config.early_z_enable = false; config.depth_test_function = ds_info->depthCompareOp; } else { config.depth_test_function = VK_COMPARE_OP_ALWAYS; diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index f3fb8f887c6..7ab3ca07805 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -386,6 +386,7 @@ struct v3dv_framebuffer { uint32_t frame_height_in_supertiles; uint32_t attachment_count; + uint32_t color_attachment_count; struct v3dv_image_view *attachments[0]; };