Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate required dedicated allocations #9087

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions layers/core_checks/cc_device_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,34 @@ bool CoreChecks::ValidateBindBufferMemory(VkBuffer buffer, VkDeviceMemory memory
"to use protected memory.",
FormatHandle(memory).c_str(), FormatHandle(buffer).c_str());
}

if (IsExtEnabled(device_extensions.vk_khr_dedicated_allocation)) {
VkBufferMemoryRequirementsInfo2 buffer_memory_requirements_info_2 = vku::InitStructHelper();
buffer_memory_requirements_info_2.buffer = buffer;
VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();
VkMemoryRequirements2 memory_requirements = vku::InitStructHelper(&memory_dedicated_requirements);
DispatchGetBufferMemoryRequirements2Helper(device, &buffer_memory_requirements_info_2, &memory_requirements);

if (memory_dedicated_requirements.requiresDedicatedAllocation) {
const auto *memory_dedicated_allocate_info =
vku::FindStructInPNextChain<VkMemoryDedicatedAllocateInfo>(mem_info->allocate_info.pNext);
const char *vuid =
bind_buffer_mem_2 ? "VUID-VkBindBufferMemoryInfo-buffer-01444" : "VUID-vkBindBufferMemory-buffer-01444";
if (!memory_dedicated_allocate_info) {
const LogObjectList objlist(buffer, memory);
skip |= LogError(vuid, objlist, loc.dot(Field::memory),
"was created without a VkMemoryDedicatedAllocateInfo in the pNext chain, but "
"vkGetBufferMemoryRequirements2() reports "
"VkBufferMemoryRequirementsInfo2::requiresDedicatedAllocation = VK_TRUE.");
} else if (memory_dedicated_allocate_info->buffer != buffer) {
const LogObjectList objlist(buffer, memory);
skip |=
LogError(vuid, objlist, loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::pNext).dot(Field::buffer),
"is %s, but VkBindBufferMemoryInfo::buffer is %s.",
FormatHandle(memory_dedicated_allocate_info->buffer).c_str(), FormatHandle(buffer).c_str());
}
}
}
}
return skip;
}
Expand Down Expand Up @@ -2011,6 +2039,34 @@ bool CoreChecks::ValidateBindImageMemory(uint32_t bindInfoCount, const VkBindIma
}
}
}

if (mem_info && IsExtEnabled(device_extensions.vk_khr_dedicated_allocation)) {
VkImageMemoryRequirementsInfo2 image_memory_requirements_info_2 = vku::InitStructHelper();
image_memory_requirements_info_2.image = bind_info.image;
VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();
VkMemoryRequirements2 memory_requirements = vku::InitStructHelper(&memory_dedicated_requirements);
DispatchGetImageMemoryRequirements2Helper(device, &image_memory_requirements_info_2, &memory_requirements);

if (memory_dedicated_requirements.requiresDedicatedAllocation) {
const auto *memory_dedicated_allocate_info =
vku::FindStructInPNextChain<VkMemoryDedicatedAllocateInfo>(mem_info->allocate_info.pNext);
const char *vuid =
bind_image_mem_2 ? "VUID-VkBindImageMemoryInfo-image-01445" : "VUID-vkBindImageMemory-image-01445";
if (!memory_dedicated_allocate_info) {
const LogObjectList objlist(bind_info.image, bind_info.memory);
skip |= LogError(vuid, objlist, loc.dot(Field::memory),
"was created without a VkMemoryDedicatedAllocateInfo in the pNext chain, but "
"vkGetImageMemoryRequirements2() reports "
"VkImageMemoryRequirementsInfo2::requiresDedicatedAllocation = VK_TRUE.");
} else if (memory_dedicated_allocate_info->image != bind_info.image) {
const LogObjectList objlist(bind_info.image, bind_info.memory);
skip |= LogError(
vuid, objlist, loc.pNext(Struct::VkMemoryDedicatedAllocateInfo, Field::pNext).dot(Field::image),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the VkMemoryDedicatedAllocateInfo is not part of the location of the caller, so just flip this, so something like

LogError(vuid, objlist, loc.dot(Feild::buffer), "is %s, but the memory was created with a VkMemoryDedicatedAllocateInfo::buffer of %s.",
                    FormatHandle(buffer).c_str(),
                    FormatHandle(memory_dedicated_allocate_info->buffer).c_str());

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, mixed this up with the buffer one above, but comment applies to both

"is %s, but VkBindImageMemoryInfo::image is %s.",
FormatHandle(memory_dedicated_allocate_info->image).c_str(), FormatHandle(bind_info.image).c_str());
}
}
}
}

const auto bind_image_memory_device_group = vku::FindStructInPNextChain<VkBindImageMemoryDeviceGroupInfo>(bind_info.pNext);
Expand Down
26 changes: 13 additions & 13 deletions layers/vulkan/generated/feature_requirements_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4357,21 +4357,21 @@ FeatureAndName AddFeature(APIVersion api_version, vkt::Feature feature, void **i
}
#ifdef VK_ENABLE_BETA_EXTENSIONS

case Feature::constantAlphaColorBlendFactors : {
auto vk_struct = const_cast<VkPhysicalDevicePortabilitySubsetFeaturesKHR *>(
vku::FindStructInPNextChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(*inout_pnext_chain));
if (!vk_struct) {
vk_struct = new VkPhysicalDevicePortabilitySubsetFeaturesKHR;
*vk_struct = vku::InitStructHelper();
if (*inout_pnext_chain) {
vvl::PnextChainAdd(*inout_pnext_chain, vk_struct);
} else {
*inout_pnext_chain = vk_struct;
}
case Feature::constantAlphaColorBlendFactors : {
auto vk_struct = const_cast<VkPhysicalDevicePortabilitySubsetFeaturesKHR *>(
vku::FindStructInPNextChain<VkPhysicalDevicePortabilitySubsetFeaturesKHR>(*inout_pnext_chain));
if (!vk_struct) {
vk_struct = new VkPhysicalDevicePortabilitySubsetFeaturesKHR;
*vk_struct = vku::InitStructHelper();
if (*inout_pnext_chain) {
vvl::PnextChainAdd(*inout_pnext_chain, vk_struct);
} else {
*inout_pnext_chain = vk_struct;
}
return {&vk_struct->constantAlphaColorBlendFactors,
"VkPhysicalDevicePortabilitySubsetFeaturesKHR::constantAlphaColorBlendFactors"};
}
return {&vk_struct->constantAlphaColorBlendFactors,
"VkPhysicalDevicePortabilitySubsetFeaturesKHR::constantAlphaColorBlendFactors"};
}
#endif // VK_ENABLE_BETA_EXTENSIONS
#ifdef VK_ENABLE_BETA_EXTENSIONS

Expand Down
30 changes: 30 additions & 0 deletions layers/vulkan/generated/validation_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,34 @@ void ValidationObject::DispatchGetPhysicalDeviceExternalBufferPropertiesHelper(
}
}

void ValidationObject::DispatchGetImageMemoryRequirements2Helper(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements) const {
if (api_version >= VK_API_VERSION_1_1) {
return dispatch_->GetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
} else {
return dispatch_->GetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
}
}

void ValidationObject::DispatchGetBufferMemoryRequirements2Helper(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements) const {
if (api_version >= VK_API_VERSION_1_1) {
return dispatch_->GetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
} else {
return dispatch_->GetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
}
}

void ValidationObject::DispatchGetImageSparseMemoryRequirements2Helper(
VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) const {
if (api_version >= VK_API_VERSION_1_1) {
return dispatch_->GetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
pSparseMemoryRequirements);
} else {
return dispatch_->GetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
pSparseMemoryRequirements);
}
}

// NOLINTEND
7 changes: 7 additions & 0 deletions layers/vulkan/generated/validation_object_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ void DispatchGetPhysicalDeviceExternalFencePropertiesHelper(VkPhysicalDevice phy
void DispatchGetPhysicalDeviceExternalBufferPropertiesHelper(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
VkExternalBufferProperties* pExternalBufferProperties) const;
void DispatchGetImageMemoryRequirements2Helper(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements) const;
void DispatchGetBufferMemoryRequirements2Helper(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements) const;
void DispatchGetImageSparseMemoryRequirements2Helper(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
uint32_t* pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) const;
// Pre/post hook point declarations
virtual bool PreCallValidateCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance, const ErrorObject& error_obj) const {
Expand Down
1 change: 1 addition & 0 deletions scripts/generators/layer_chassis_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class LayerChassisOutputGenerator(BaseGenerator):
'VK_KHR_external_semaphore_capabilities',
'VK_KHR_external_fence_capabilities',
'VK_KHR_external_memory_capabilities',
'VK_KHR_get_memory_requirements2',
)

def __init__(self):
Expand Down
11 changes: 9 additions & 2 deletions tests/unit/android_hardware_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,8 +1072,12 @@ TEST_F(NegativeAndroidHardwareBuffer, InvalidBindBufferMemory) {
vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

// Try to get memory requirements prior to binding memory
VkMemoryRequirements mem_reqs;
vk::GetBufferMemoryRequirements(device(), buffer.handle(), &mem_reqs);
VkBufferMemoryRequirementsInfo2 buffer_memory_requirements_info = vku::InitStructHelper();
buffer_memory_requirements_info.buffer = buffer.handle();
VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();
VkMemoryRequirements2 mem_reqs2 = vku::InitStructHelper(&memory_dedicated_requirements);
vk::GetBufferMemoryRequirements2(device(), &buffer_memory_requirements_info, &mem_reqs2);
VkMemoryRequirements mem_reqs = mem_reqs2.memoryRequirements;

VkImportAndroidHardwareBufferInfoANDROID import_ahb_Info = vku::InitStructHelper();
import_ahb_Info.buffer = ahb.handle();
Expand All @@ -1098,6 +1102,9 @@ TEST_F(NegativeAndroidHardwareBuffer, InvalidBindBufferMemory) {
VkDeviceSize buffer_offset = (mem_reqs.size - 1) & ~(mem_reqs.alignment - 1);
if (buffer_offset > 0) {
m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-size-01037");
if (memory_dedicated_requirements.requiresDedicatedAllocation) {
m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-01444");
}
vk::BindBufferMemory(device(), buffer.handle(), memory.handle(), buffer_offset);
m_errorMonitor->VerifyFound();
}
Expand Down
36 changes: 33 additions & 3 deletions tests/unit/external_memory_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,20 @@ TEST_F(NegativeExternalMemorySync, ExportBufferHandleType) {
// Create export memory with a different handle type
auto export_memory_info = vku::InitStruct<VkExportMemoryAllocateInfo>(dedicated_allocation ? &dedicated_info : nullptr);
export_memory_info.handleTypes = handle_type2;
VkMemoryRequirements buffer_mem_reqs;
vk::GetBufferMemoryRequirements(device(), buffer.handle(), &buffer_mem_reqs);
VkBufferMemoryRequirementsInfo2 buffer_memory_requirements_info = vku::InitStructHelper();
buffer_memory_requirements_info.buffer = buffer.handle();
VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();
VkMemoryRequirements2 mem_reqs2 = vku::InitStructHelper(&memory_dedicated_requirements);
vk::GetBufferMemoryRequirements2(device(), &buffer_memory_requirements_info, &mem_reqs2);
VkMemoryRequirements buffer_mem_reqs = mem_reqs2.memoryRequirements;
const auto alloc_info = vkt::DeviceMemory::GetResourceAllocInfo(*m_device, buffer_mem_reqs, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&export_memory_info);
const auto memory = vkt::DeviceMemory(*m_device, alloc_info);

m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-02726");
if (memory_dedicated_requirements.requiresDedicatedAllocation) {
m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-01444");
}
vk::BindBufferMemory(device(), buffer.handle(), memory.handle(), 0);
m_errorMonitor->VerifyFound();

Expand All @@ -444,6 +451,9 @@ TEST_F(NegativeExternalMemorySync, ExportBufferHandleType) {
bind_buffer_info.memory = memory.handle();

m_errorMonitor->SetDesiredError("VUID-VkBindBufferMemoryInfo-memory-02726");
if (memory_dedicated_requirements.requiresDedicatedAllocation) {
m_errorMonitor->SetDesiredError("VUID-VkBindBufferMemoryInfo-buffer-01444");
}
vk::BindBufferMemory2(device(), 1, &bind_buffer_info);
m_errorMonitor->VerifyFound();
}
Expand Down Expand Up @@ -1347,6 +1357,9 @@ TEST_F(NegativeExternalMemorySync, ImportMemoryHandleType) {
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02989");
m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01617");
m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01615");
if (image_dedicated_allocation) {
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-01445");
}
vk::BindImageMemory(device(), image_import.handle(), memory_image_import.handle(), 0);
m_errorMonitor->VerifyFound();

Expand All @@ -1358,6 +1371,9 @@ TEST_F(NegativeExternalMemorySync, ImportMemoryHandleType) {
m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-memory-02989");
m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01617");
m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01615");
if (image_dedicated_allocation) {
m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-image-01445");
}
vk::BindImageMemory2(device(), 1, &bind_image_info);
m_errorMonitor->VerifyFound();
}
Expand Down Expand Up @@ -2049,7 +2065,21 @@ TEST_F(NegativeExternalMemorySync, ImageDedicatedAllocation) {

m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-pNext-00639");
// pNext chain contains VkExportMemoryAllocateInfo but not VkMemoryDedicatedAllocateInfo
vkt::Image image(*m_device, image_info, 0, &export_memory_info);
vkt::Image image;
image.InitNoMemory(*m_device, image_info);
{
VkImageMemoryRequirementsInfo2 image_memory_requirements_info = vku::InitStructHelper();
image_memory_requirements_info.image = image.handle();
VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();

VkMemoryRequirements2 memory_requirements = vku::InitStructHelper(&memory_dedicated_requirements);
vk::GetImageMemoryRequirements2(device(), &image_memory_requirements_info, &memory_requirements);

if (memory_dedicated_requirements.requiresDedicatedAllocation) {
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-01445");
}
}
image.AllocateAndBindMemory(*m_device, 0, &export_memory_info);
m_errorMonitor->VerifyFound();
}

Expand Down
Loading
Loading