fix vkFlushMappedMemoryRanges and vkCmdBeginRendering validation errors

This commit is contained in:
Zack Buhman 2026-04-15 16:57:11 -05:00
parent cdce2d64f3
commit 3e78886a95
5 changed files with 62 additions and 27 deletions

View File

@ -73,6 +73,7 @@ namespace collada::scene {
} shaderData;
struct {
VkDeviceMemory memory;
VkDeviceSize memorySize;
void * mappedData;
struct { // must match perFrameDescriptorCount
VkBuffer sceneBuffer;

View File

@ -2,6 +2,13 @@
#include <assert.h>
inline static constexpr VkDeviceSize roundDownAlignment(VkDeviceSize offset, VkDeviceSize alignment)
{
// must be a power of two
assert(alignment && ((alignment & (alignment - 1)) == 0));
return offset & ~(alignment - 1);
}
inline static constexpr VkDeviceSize roundAlignment(VkDeviceSize offset, VkDeviceSize alignment)
{
// must be a power of two
@ -9,6 +16,22 @@ inline static constexpr VkDeviceSize roundAlignment(VkDeviceSize offset, VkDevic
return (offset + (alignment - 1)) & (-alignment);
}
inline static constexpr void alignMappedMemoryRanges(uint32_t nonCoherentAtomSize,
VkDeviceSize memorySize,
uint32_t count,
VkMappedMemoryRange * ranges)
{
for (uint32_t i = 0; i < count; i++) {
VkDeviceSize alignedOffset{ roundDownAlignment(ranges[i].offset, nonCoherentAtomSize) };
VkDeviceSize alignedSize{ roundAlignment(ranges[i].size + (ranges[i].offset - alignedOffset), nonCoherentAtomSize) };
if (alignedOffset + alignedSize > memorySize) {
alignedSize = VK_WHOLE_SIZE;
}
ranges[i].offset = alignedOffset;
ranges[i].size = alignedSize;
}
}
VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
VkMemoryRequirements const & memoryRequirements,
@ -18,6 +41,7 @@ VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
VkDeviceMemory * memory);
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
VkPhysicalDeviceProperties const & physicalDeviceProperties,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryAllocateFlags memoryAllocateFlags,

View File

@ -236,7 +236,8 @@ namespace collada::scene {
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
VkMemoryAllocateFlags memoryAllocateFlags{ };
allocateFromMemoryRequirements2(device,
shaderDataDevice.memorySize = allocateFromMemoryRequirements2(device,
physicalDeviceProperties,
physicalDeviceMemoryProperties,
memoryPropertyFlags,
memoryAllocateFlags,
@ -301,7 +302,7 @@ namespace collada::scene {
};
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.maxSets = 2,
.maxSets = maxFrames + 1, // +1 for descriptorSet1
.poolSizeCount = descriptorPoolSizesCount,
.pPoolSizes = descriptorPoolSizes
};
@ -519,16 +520,20 @@ namespace collada::scene {
// flush
VkDeviceSize materialColorsFlushSize{ shaderDataDevice.constant.materialColorsSize };
VkMappedMemoryRange shaderDataMemoryRanges[1]{
VkMappedMemoryRange mappedMemoryRanges[1]{
{
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory,
.offset = shaderDataDevice.constant.materialColorsOffset,
.size = roundAlignment(materialColorsFlushSize, physicalDeviceProperties.limits.nonCoherentAtomSize),
.size = shaderDataDevice.constant.materialColorsSize,
},
};
vkFlushMappedMemoryRanges(device, 1, shaderDataMemoryRanges);
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
shaderDataDevice.memorySize,
1, mappedMemoryRanges);
//fprintf(stderr, "flush materials start %ld %ld %ld %ld : %ld\n", offset, size, alignedOffset, alignedSize, shaderDataDevice.memorySize);
vkFlushMappedMemoryRanges(device, 1, mappedMemoryRanges);
//fprintf(stderr, "flush materials end\n");
}
//////////////////////////////////////////////////////////////////////
@ -811,25 +816,25 @@ namespace collada::scene {
// flush
VkDeviceSize sceneFlushSize{ shaderDataDevice.frame[frameIndex].sceneSize };
VkDeviceSize nodesFlushSize{ shaderDataDevice.frame[frameIndex].nodesSize };
//fprintf(stderr, "sceneFlushSize %ld\n", sceneFlushSize);
//fprintf(stderr, "nodesFlushSize %ld\n", nodesFlushSize);
VkMappedMemoryRange shaderDataMemoryRanges[2]{
VkMappedMemoryRange mappedMemoryRanges[2]{
{
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory,
.offset = shaderDataDevice.frame[frameIndex].sceneOffset,
.size = roundAlignment(sceneFlushSize, physicalDeviceProperties.limits.nonCoherentAtomSize),
.size = shaderDataDevice.frame[frameIndex].sceneSize,
},
{
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory,
.offset = shaderDataDevice.frame[frameIndex].nodesOffset,
.size = roundAlignment(nodesFlushSize, physicalDeviceProperties.limits.nonCoherentAtomSize),
.size = shaderDataDevice.frame[frameIndex].nodesSize,
}
};
vkFlushMappedMemoryRanges(device, 2, shaderDataMemoryRanges);
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
shaderDataDevice.memorySize,
2,
mappedMemoryRanges);
vkFlushMappedMemoryRanges(device, 2, mappedMemoryRanges);
}
void vulkan::draw_node(int32_t node_index,

View File

@ -200,10 +200,6 @@ void recreateSwapchain(VkSurfaceFormatKHR surfaceFormat, VkFormat depthFormat, V
.width = surfaceCapabilities.currentExtent.width,
.height = surfaceCapabilities.currentExtent.height,
};
if ((imageExtent.width == ~0u) && (imageExtent.width == ~0u)) {
imageExtent.width = windowSize.x;
imageExtent.height = windowSize.y;
}
VkFormat imageFormat{ surfaceFormat.format };
VkColorSpaceKHR imageColorSpace{ surfaceFormat.colorSpace };
@ -463,6 +459,10 @@ int main()
SDL_CHECK(SDL_GetWindowSize(window, &windowSize.x, &windowSize.y));
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfaceCapabilities));
if ((surfaceCapabilities.currentExtent.width == ~0u) && (surfaceCapabilities.currentExtent.width == ~0u)) {
surfaceCapabilities.currentExtent.width = windowSize.x;
surfaceCapabilities.currentExtent.height = windowSize.y;
}
printf("surfaceCapabilities currentExtent %d %d\n", surfaceCapabilities.currentExtent.width, surfaceCapabilities.currentExtent.height);
// surface format
@ -1623,6 +1623,10 @@ int main()
updateSwapchain = false;
VK_CHECK(vkDeviceWaitIdle(device));
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfaceCapabilities));
if ((surfaceCapabilities.currentExtent.width == ~0u) && (surfaceCapabilities.currentExtent.width == ~0u)) {
surfaceCapabilities.currentExtent.width = windowSize.x;
surfaceCapabilities.currentExtent.height = windowSize.y;
}
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceMemoryProperties, surfaceCapabilities);
}
}

View File

@ -65,6 +65,7 @@ VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
}
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
VkPhysicalDeviceProperties const & physicalDeviceProperties,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryAllocateFlags memoryAllocateFlags,
@ -95,10 +96,10 @@ VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
VkMemoryAllocateInfo memoryAllocateInfo{
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &memoryAllocateFlagsInfo,
.allocationSize = offset,
.allocationSize = roundAlignment(offset, physicalDeviceProperties.limits.nonCoherentAtomSize),
.memoryTypeIndex = memoryTypeIndex,
};
VK_CHECK(vkAllocateMemory(device, &memoryAllocateInfo, nullptr, memory));
return offset;
return memoryAllocateInfo.allocationSize;
}