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]; };