File: bp_framebuffer.cpp

package info (click to toggle)
vulkan-validationlayers 1.4.321.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,412 kB
  • sloc: cpp: 594,175; python: 11,321; sh: 24; makefile: 20; xml: 14
file content (91 lines) | stat: -rw-r--r-- 4,666 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* Copyright (c) 2015-2025 The Khronos Group Inc.
 * Copyright (c) 2015-2025 Valve Corporation
 * Copyright (c) 2015-2025 LunarG, Inc.
 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 * Modifications Copyright (C) 2022 RasterGrid Kft.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "best_practices/best_practices_validation.h"
#include "best_practices/bp_state.h"
#include <vulkan/utility/vk_format_utils.h>
#include "state_tracker/render_pass_state.h"

bool BestPractices::ValidateAttachments(const VkRenderPassCreateInfo2* rpci, uint32_t attachment_count,
                                        const VkImageView* attachments, const Location& loc) const {
    bool skip = false;

    // Check for non-transient attachments that should be transient and vice versa
    for (uint32_t i = 0; i < attachment_count; ++i) {
        const auto& attachment = rpci->pAttachments[i];
        bool attachment_should_be_transient =
            (attachment.loadOp != VK_ATTACHMENT_LOAD_OP_LOAD && attachment.storeOp != VK_ATTACHMENT_STORE_OP_STORE);

        if (vkuFormatHasStencil(attachment.format)) {
            attachment_should_be_transient &= (attachment.stencilLoadOp != VK_ATTACHMENT_LOAD_OP_LOAD &&
                                               attachment.stencilStoreOp != VK_ATTACHMENT_STORE_OP_STORE);
        }

        auto view_state = Get<vvl::ImageView>(attachments[i]);
        ASSERT_AND_CONTINUE(view_state);

        const auto& ici = view_state->image_state->create_info;

        const bool image_is_transient = (ici.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0;

        // The check for an image that should not be transient applies to all GPUs
        if (!attachment_should_be_transient && image_is_transient) {
            skip |=
                LogPerformanceWarning("BestPractices-vkCreateFramebuffer-attachment-should-not-be-transient", device, loc,
                                      "Attachment %u in VkFramebuffer uses loadOp/storeOps which need to access physical memory, "
                                      "but the image backing the image view has VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT set. "
                                      "Physical memory will need to be backed lazily to this image, potentially causing stalls.",
                                      i);
        }

        bool supports_lazy = false;
        for (uint32_t j = 0; j < phys_dev_mem_props.memoryTypeCount; j++) {
            if (phys_dev_mem_props.memoryTypes[j].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
                supports_lazy = true;
            }
        }

        // The check for an image that should be transient only applies to GPUs supporting
        // lazily allocated memory
        if (supports_lazy && attachment_should_be_transient && !image_is_transient) {
            skip |= LogPerformanceWarning(
                "BestPractices-vkCreateFramebuffer-attachment-should-be-transient", device, loc,
                "Attachment %u in VkFramebuffer uses loadOp/storeOps which never have to be backed by physical memory, "
                "but the image backing the image view does not have VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT set. "
                "You can save physical memory by using transient attachment backed by lazily allocated memory here.",
                i);
        }
    }
    return skip;
}

bool BestPractices::PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo,
                                                     const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer,
                                                     const ErrorObject& error_obj) const {
    bool skip = false;

    auto rp_state = Get<vvl::RenderPass>(pCreateInfo->renderPass);
    ASSERT_AND_RETURN_SKIP(rp_state);
    if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)) {
        skip |= ValidateAttachments(rp_state->create_info.ptr(), pCreateInfo->attachmentCount, pCreateInfo->pAttachments,
                                    error_obj.location);
    }

    return skip;
}