Merge pull request 'fix(device): preferred mask + required-only fallback for GetMemoryType (#59)' (#87) from claude/issue-59 into master

This commit is contained in:
catbot 2026-06-16 18:04:20 +02:00
commit c58b68ec40
6 changed files with 218 additions and 13 deletions

View file

@ -811,17 +811,32 @@ void Device::Initialize() {
}
}
std::uint32_t Device::GetMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties) {
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++)
std::uint32_t Device::GetMemoryType(uint32_t typeBits, VkMemoryPropertyFlags required, VkMemoryPropertyFlags preferred) {
// First pass: honour the preferred bits on top of the required ones.
// Second pass (when nothing matched, or no preferences were given): drop
// the preferences and match the required bits alone. Vulkan orders the
// memory types so first-superset-match is generally optimal, so a plain
// linear scan suffices for each pass. We only throw when even `required`
// cannot be satisfied — i.e. no valid memory exists for the allocation.
for (VkMemoryPropertyFlags wanted : {required | preferred, required})
{
if ((typeBits & 1) == 1)
uint32_t bits = typeBits;
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++)
{
if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
if ((bits & 1) == 1)
{
return i;
if ((memoryProperties.memoryTypes[i].propertyFlags & wanted) == wanted)
{
return i;
}
}
bits >>= 1;
}
// No preferences to fall back from — the second pass would be identical.
if (preferred == 0) {
break;
}
typeBits >>= 1;
}
throw std::runtime_error("Could not find a matching memory type");