blob: 5744384247646f57947d125227150d044d1ffdec [file] [log] [blame]
/* Copyright (c) 2015-2025 The Khronos Group Inc.
* Copyright (c) 2015-2025 Valve Corporation
* Copyright (c) 2015-2025 LunarG, Inc.
* Copyright (C) 2015-2024 Google Inc.
*
* 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 "stateless/stateless_validation.h"
namespace stateless {
bool Device::manual_PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
const Context &context) const {
// Validation for pAttachments which is excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
bool skip = false;
const auto &error_obj = context.error_obj;
const Location create_info_loc = error_obj.location.dot(Field::pCreateInfo);
if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT) == 0) {
skip |= context.ValidateArray(create_info_loc.dot(Field::attachmentCount), create_info_loc.dot(Field::pAttachments),
pCreateInfo->attachmentCount, &pCreateInfo->pAttachments, false, true, kVUIDUndefined,
"VUID-VkFramebufferCreateInfo-flags-02778");
// VUID-VkFramebufferCreateInfo-flags-02778 above is already checking if pAttachments is NULL
if (pCreateInfo->pAttachments) {
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
if (pCreateInfo->pAttachments[i] == VK_NULL_HANDLE) {
skip |=
LogError("VUID-VkFramebufferCreateInfo-flags-02778", device, create_info_loc.dot(Field::pAttachments, i),
"is VK_NULL_HANDLE, but must be a valid VkImageView handle");
}
}
}
} else {
if (!enabled_features.imagelessFramebuffer) {
skip |= LogError("VUID-VkFramebufferCreateInfo-flags-03189", device, create_info_loc.dot(Field::flags),
"includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, but the imagelessFramebuffer feature is not enabled.");
}
const auto *framebuffer_attachments_create_info =
vku::FindStructInPNextChain<VkFramebufferAttachmentsCreateInfo>(pCreateInfo->pNext);
if (framebuffer_attachments_create_info == nullptr) {
skip |= LogError("VUID-VkFramebufferCreateInfo-flags-03190", device, create_info_loc.dot(Field::flags),
"includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, but no instance of VkFramebufferAttachmentsCreateInfo "
"is present in the pNext chain.");
} else {
if (framebuffer_attachments_create_info->attachmentImageInfoCount != 0 &&
framebuffer_attachments_create_info->attachmentImageInfoCount != pCreateInfo->attachmentCount) {
skip |= LogError("VUID-VkFramebufferCreateInfo-flags-03191", device,
create_info_loc.pNext(Struct::VkFramebufferAttachmentsCreateInfo, Field::attachmentImageInfoCount),
"is %" PRIu32 " which is not equal to pCreateInfo->attachmentCount (%" PRIu32 ").",
framebuffer_attachments_create_info->attachmentImageInfoCount, pCreateInfo->attachmentCount);
}
}
}
// Verify FB dimensions are greater than zero
if (pCreateInfo->width == 0) {
skip |= LogError("VUID-VkFramebufferCreateInfo-width-00885", device, create_info_loc.dot(Field::width), "is zero.");
}
if (pCreateInfo->height == 0) {
skip |= LogError("VUID-VkFramebufferCreateInfo-height-00887", device, create_info_loc.dot(Field::height), "is zero.");
}
if (pCreateInfo->layers == 0) {
skip |= LogError("VUID-VkFramebufferCreateInfo-layers-00889", device, create_info_loc.dot(Field::layers), "is zero.");
}
if (pCreateInfo->width > phys_dev_props.limits.maxFramebufferWidth) {
skip |= LogError("VUID-VkFramebufferCreateInfo-width-00886", device, create_info_loc.dot(Field::width),
"(%" PRIu32 ") is greater than maxFramebufferWidth (%" PRIu32 ").", pCreateInfo->width,
phys_dev_props.limits.maxFramebufferWidth);
}
if (pCreateInfo->height > phys_dev_props.limits.maxFramebufferHeight) {
skip |= LogError("VUID-VkFramebufferCreateInfo-height-00888", device, create_info_loc.dot(Field::height),
"(%" PRIu32 ") is greater than maxFramebufferHeight (%" PRIu32 ").", pCreateInfo->height,
phys_dev_props.limits.maxFramebufferHeight);
}
if (pCreateInfo->layers > phys_dev_props.limits.maxFramebufferLayers) {
skip |= LogError("VUID-VkFramebufferCreateInfo-layers-00890", device, create_info_loc.dot(Field::layers),
"(%" PRIu32 ") is greater than maxFramebufferLayers (%" PRIu32 ").", pCreateInfo->layers,
phys_dev_props.limits.maxFramebufferLayers);
}
return skip;
}
} // namespace stateless