Skip to content
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
3 changes: 3 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,6 @@ streq(const char *a, const char *b)
{
return strcmp(a, b) == 0;
}

int32_t choose_memory_type_index(struct vkcube *vc, uint32_t allowed_memory_types,
VkMemoryPropertyFlags required_props);
17 changes: 4 additions & 13 deletions cube.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ static uint32_t fs_spirv_source[] = {
#include "vkcube.frag.spv.h"
};

static int find_host_coherent_memory(struct vkcube *vc, unsigned allowed)
{
for (unsigned i = 0; (1u << i) <= allowed && i <= vc->memory_properties.memoryTypeCount; ++i) {
if ((allowed & (1u << i)) &&
(vc->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
(vc->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
return i;
}
return -1;
}

static void
init_cube(struct vkcube *vc)
{
Expand Down Expand Up @@ -342,8 +331,10 @@ init_cube(struct vkcube *vc)
VkMemoryRequirements reqs;
vkGetBufferMemoryRequirements(vc->device, vc->buffer, &reqs);

int memory_type = find_host_coherent_memory(vc, reqs.memoryTypeBits);
if (memory_type < 0)
int32_t memory_type = choose_memory_type_index(vc, reqs.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if (memory_type == -1)
fail("find_host_coherent_memory failed");

vkAllocateMemory(vc->device,
Expand Down
37 changes: 26 additions & 11 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,19 @@ xstrdup(const char *s)
return dup;
}

static int find_image_memory(struct vkcube *vc, unsigned allowed)
int32_t
choose_memory_type_index(struct vkcube *vc, uint32_t allowed_memory_types,
VkMemoryPropertyFlags required_props)
{
VkMemoryPropertyFlags flags =
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
(vc->protected ? VK_MEMORY_PROPERTY_PROTECTED_BIT : 0);

for (unsigned i = 0; (1u << i) <= allowed && i <= vc->memory_properties.memoryTypeCount; ++i) {
if ((allowed & (1u << i)) && (vc->memory_properties.memoryTypes[i].propertyFlags & flags))
return i;
}
return -1;
for (uint32_t i = 0; i < vc->memory_properties.memoryTypeCount; ++i) {
VkMemoryPropertyFlags props = vc->memory_properties.memoryTypes[i].propertyFlags;

if (((1u << i) & allowed_memory_types) &&
(required_props & props) == required_props)
return i;
}

return -1;
}

static void
Expand Down Expand Up @@ -433,11 +435,24 @@ init_headless(struct vkcube *vc)
VkMemoryRequirements requirements;
vkGetImageMemoryRequirements(vc->device, b->image, &requirements);

if (vc->protected) {
/* Host-visible protected memory is useless and contradictory.
* And the Vulkan 1.4.304 spec says it does not exist.
*/
fail("headless mode and protected mode are incompatible\n");
}

int32_t mem_type = choose_memory_type_index(vc, requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
if (mem_type == -1) {
fail("failed to choose VkMemoryType\n");
}

vkAllocateMemory(vc->device,
&(VkMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = requirements.size,
.memoryTypeIndex = find_image_memory(vc, requirements.memoryTypeBits),
.memoryTypeIndex = mem_type,
},
NULL,
&b->mem);
Expand Down
Loading