From 6ec177b116a43f1bf8d3e00c1cfcbdd021e38ab7 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Tue, 9 Jan 2024 22:07:14 -0600 Subject: [PATCH] vulkan: Rework vk_render_pass_state::attachments The new bitfield has a separat flag for each of the color attachments. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/freedreno/vulkan/tu_pipeline.cc | 40 ++++++++++++++------------ src/imagination/vulkan/pvr_pipeline.c | 14 +++++---- src/vulkan/runtime/vk_graphics_state.c | 19 ++++++------ src/vulkan/runtime/vk_graphics_state.h | 34 +++++++++++++++++++--- 4 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src/freedreno/vulkan/tu_pipeline.cc b/src/freedreno/vulkan/tu_pipeline.cc index 45489055ec4..e1c0616d698 100644 --- a/src/freedreno/vulkan/tu_pipeline.cc +++ b/src/freedreno/vulkan/tu_pipeline.cc @@ -2783,13 +2783,13 @@ tu_calc_bandwidth(struct tu_bandwidth *bandwidth, bandwidth->color_bandwidth_per_sample = total_bpp / 8; - if (rp->attachment_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { + if (rp->attachments & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) { bandwidth->depth_cpp_per_sample = util_format_get_component_bits( vk_format_to_pipe_format(rp->depth_attachment_format), UTIL_FORMAT_COLORSPACE_ZS, 0) / 8; } - if (rp->attachment_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { + if (rp->attachments & MESA_VK_RP_ATTACHMENT_STENCIL_BIT) { bandwidth->stencil_cpp_per_sample = util_format_get_component_bits( vk_format_to_pipe_format(rp->stencil_attachment_format), UTIL_FORMAT_COLORSPACE_ZS, 1) / 8; @@ -3149,7 +3149,7 @@ tu6_emit_rb_depth_cntl(struct tu_cs *cs, const struct vk_render_pass_state *rp, const struct vk_rasterization_state *rs) { - if (rp->attachment_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { + if (rp->attachments & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) { bool depth_test = ds->depth.test_enable; enum adreno_compare_func zfunc = tu6_compare_func(ds->depth.compare_op); @@ -3276,8 +3276,8 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder, struct vk_color_blend_state dummy_cb = {}; const struct vk_color_blend_state *cb = builder->graphics_state.cb; if (attachments_valid && - !(builder->graphics_state.rp->attachment_aspects & - VK_IMAGE_ASPECT_COLOR_BIT)) { + !(builder->graphics_state.rp->attachments & + MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) { /* If there are no color attachments, then the original blend state may * be NULL and the common code sanitizes it to always be NULL. In this * case we want to emit an empty blend/bandwidth/etc. rather than @@ -3305,8 +3305,8 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder, builder->graphics_state.rp); DRAW_STATE(blend_constants, TU_DYNAMIC_STATE_BLEND_CONSTANTS, cb); if (attachments_valid && - !(builder->graphics_state.rp->attachment_aspects & - VK_IMAGE_ASPECT_COLOR_BIT)) { + !(builder->graphics_state.rp->attachments & + MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) { /* Don't actually make anything dynamic as that may mean a partially-set * state group where the group is NULL which angers common code. */ @@ -3538,10 +3538,10 @@ tu_pipeline_builder_parse_depth_stencil( const VkPipelineDepthStencilStateCreateInfo *ds_info = builder->create_info->pDepthStencilState; - if ((builder->graphics_state.rp->attachment_aspects & - VK_IMAGE_ASPECT_METADATA_BIT) || - (builder->graphics_state.rp->attachment_aspects & - VK_IMAGE_ASPECT_DEPTH_BIT)) { + if ((builder->graphics_state.rp->attachments == + MESA_VK_RP_ATTACHMENT_INFO_INVALID) || + (builder->graphics_state.rp->attachments & + MESA_VK_RP_ATTACHMENT_DEPTH_BIT)) { pipeline->ds.raster_order_attachment_access = ds_info && (ds_info->flags & (VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT | @@ -3576,11 +3576,13 @@ tu_pipeline_builder_parse_multisample_and_color_blend( static const VkPipelineColorBlendStateCreateInfo dummy_blend_info = {}; const VkPipelineColorBlendStateCreateInfo *blend_info = - (builder->graphics_state.rp->attachment_aspects & - VK_IMAGE_ASPECT_COLOR_BIT) ? builder->create_info->pColorBlendState : - &dummy_blend_info; + (builder->graphics_state.rp->attachments & + MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS) + ? builder->create_info->pColorBlendState + : &dummy_blend_info; - if (builder->graphics_state.rp->attachment_aspects & VK_IMAGE_ASPECT_COLOR_BIT) { + if (builder->graphics_state.rp->attachments & + MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS) { pipeline->output.raster_order_attachment_access = blend_info && (blend_info->flags & VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT); @@ -3847,16 +3849,16 @@ tu_fill_render_pass_state(struct vk_render_pass_state *rp, const uint32_t a = subpass->depth_stencil_attachment.attachment; rp->depth_attachment_format = VK_FORMAT_UNDEFINED; rp->stencil_attachment_format = VK_FORMAT_UNDEFINED; - rp->attachment_aspects = 0; + rp->attachments = MESA_VK_RP_ATTACHMENT_NONE; if (a != VK_ATTACHMENT_UNUSED) { VkFormat ds_format = pass->attachments[a].format; if (vk_format_has_depth(ds_format)) { rp->depth_attachment_format = ds_format; - rp->attachment_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; } if (vk_format_has_stencil(ds_format)) { rp->stencil_attachment_format = ds_format; - rp->attachment_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; } } @@ -3868,7 +3870,7 @@ tu_fill_render_pass_state(struct vk_render_pass_state *rp, } rp->color_attachment_formats[i] = pass->attachments[a].format; - rp->attachment_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i); } } diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index 482a56ebc6b..46fcd6d489d 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -2250,22 +2250,26 @@ pvr_create_renderpass_state(const VkGraphicsPipelineCreateInfo *const info) const struct pvr_render_subpass *const subpass = &pass->subpasses[info->subpass]; - VkImageAspectFlags attachment_aspects = VK_IMAGE_ASPECT_NONE; + enum vk_rp_attachment_flags attachments = 0; assert(info->subpass < pass->subpass_count); for (uint32_t i = 0; i < subpass->color_count; i++) { - attachment_aspects |= - pass->attachments[subpass->color_attachments[i]].aspects; + if (pass->attachments[subpass->color_attachments[i]].aspects) + attachments |= MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << i; } if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) { - attachment_aspects |= + VkImageAspectFlags ds_aspects = pass->attachments[subpass->depth_stencil_attachment].aspects; + if (ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) + attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; + if (ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) + attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; } return (struct vk_render_pass_state){ - .attachment_aspects = attachment_aspects, + .attachments = attachments, /* TODO: This is only needed for VK_KHR_create_renderpass2 (or core 1.2), * which is not currently supported. diff --git a/src/vulkan/runtime/vk_graphics_state.c b/src/vulkan/runtime/vk_graphics_state.c index 0b5ec547448..620cff8389b 100644 --- a/src/vulkan/runtime/vk_graphics_state.c +++ b/src/vulkan/runtime/vk_graphics_state.c @@ -1211,7 +1211,7 @@ vk_render_pass_state_init(struct vk_render_pass_state *rp, */ if (info->renderPass == VK_NULL_HANDLE && !(lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) { - rp->attachment_aspects = VK_IMAGE_ASPECT_METADATA_BIT; + rp->attachments = MESA_VK_RP_ATTACHMENT_INFO_INVALID; return; } @@ -1220,16 +1220,16 @@ vk_render_pass_state_init(struct vk_render_pass_state *rp, for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) { rp->color_attachment_formats[i] = r_info->pColorAttachmentFormats[i]; if (r_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED) - rp->attachment_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i); } rp->depth_attachment_format = r_info->depthAttachmentFormat; if (r_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) - rp->attachment_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT; rp->stencil_attachment_format = r_info->stencilAttachmentFormat; if (r_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) - rp->attachment_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; + rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT; const VkAttachmentSampleCountInfoAMD *asc_info = vk_get_pipeline_sample_count_info_amd(info); @@ -1561,18 +1561,17 @@ vk_graphics_pipeline_state_fill(const struct vk_device *device, * where we only have fragment shader state and no render pass, the * vk_render_pass_state will be incomplete. */ - if ((rp.attachment_aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | - VK_IMAGE_ASPECT_STENCIL_BIT)) || - !vk_render_pass_state_has_attachment_info(&rp)) + if (!vk_render_pass_state_has_attachment_info(&rp) || + (rp.attachments & (MESA_VK_RP_ATTACHMENT_DEPTH_BIT | + MESA_VK_RP_ATTACHMENT_STENCIL_BIT))) needs |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT; needs |= MESA_VK_GRAPHICS_STATE_INPUT_ATTACHMENT_MAP_BIT; } if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) { - if (rp.attachment_aspects & (VK_IMAGE_ASPECT_COLOR_BIT)) { + if (rp.attachments & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS) needs |= MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT; - } needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT; @@ -1978,7 +1977,7 @@ vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn, * the other blend states will be initialized. Normally this would be * initialized with the other blend states. */ - if (!p->rp || !(p->rp->attachment_aspects & VK_IMAGE_ASPECT_COLOR_BIT)) { + if (!p->rp || !(p->rp->attachments & MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) { dyn->cb.attachment_count = 0; BITSET_SET(dyn->set, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT); } diff --git a/src/vulkan/runtime/vk_graphics_state.h b/src/vulkan/runtime/vk_graphics_state.h index 7d9339f119e..8741902c559 100644 --- a/src/vulkan/runtime/vk_graphics_state.h +++ b/src/vulkan/runtime/vk_graphics_state.h @@ -29,6 +29,7 @@ #include "vk_limits.h" #include "util/bitset.h" +#include "util/enum_operators.h" #ifdef __cplusplus extern "C" { @@ -667,6 +668,31 @@ struct vk_color_blend_state { float blend_constants[4]; }; +enum vk_rp_attachment_flags { + MESA_VK_RP_ATTACHMENT_NONE = 0, + + MESA_VK_RP_ATTACHMENT_COLOR_0_BIT = (1 << 0), + MESA_VK_RP_ATTACHMENT_COLOR_1_BIT = (1 << 1), + MESA_VK_RP_ATTACHMENT_COLOR_2_BIT = (1 << 2), + MESA_VK_RP_ATTACHMENT_COLOR_3_BIT = (1 << 3), + MESA_VK_RP_ATTACHMENT_COLOR_4_BIT = (1 << 4), + MESA_VK_RP_ATTACHMENT_COLOR_5_BIT = (1 << 5), + MESA_VK_RP_ATTACHMENT_COLOR_6_BIT = (1 << 6), + MESA_VK_RP_ATTACHMENT_COLOR_7_BIT = (1 << 7), + MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS = 0xff, + + MESA_VK_RP_ATTACHMENT_DEPTH_BIT = (1 << 8), + MESA_VK_RP_ATTACHMENT_STENCIL_BIT = (1 << 9), + + MESA_VK_RP_ATTACHMENT_INFO_INVALID = 0xffff, +}; +MESA_DEFINE_CPP_ENUM_BITFIELD_OPERATORS(vk_rp_attachment_flags) +static_assert(MESA_VK_MAX_COLOR_ATTACHMENTS == 8, + "This enum must match the global runtime limit"); + +#define MESA_VK_RP_ATTACHMENT_COLOR_BIT(n) \ + ((enum vk_rp_attachment_flags)(MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << (n))) + /***/ struct vk_input_attachment_location_state { /** VkRenderingInputAttachmentIndexInfoKHR::pColorAttachmentLocations @@ -701,10 +727,10 @@ struct vk_color_attachment_location_state { struct vk_render_pass_state { /** Set of image aspects bound as color/depth/stencil attachments * - * Set to VK_IMAGE_ASPECT_METADATA_BIT to indicate that attachment info - * is invalid. + * Set to MESA_VK_RP_ATTACHMENT_INFO_INVALID to indicate that attachment + * info is invalid. */ - VkImageAspectFlags attachment_aspects; + enum vk_rp_attachment_flags attachments; /** VkPipelineRenderingCreateInfo::viewMask */ uint32_t view_mask; @@ -731,7 +757,7 @@ struct vk_render_pass_state { static inline bool vk_render_pass_state_has_attachment_info(const struct vk_render_pass_state *rp) { - return rp->attachment_aspects != VK_IMAGE_ASPECT_METADATA_BIT; + return rp->attachments != MESA_VK_RP_ATTACHMENT_INFO_INVALID; } static inline VkImageAspectFlags