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; } shaderData;
struct { struct {
VkDeviceMemory memory; VkDeviceMemory memory;
VkDeviceSize memorySize;
void * mappedData; void * mappedData;
struct { // must match perFrameDescriptorCount struct { // must match perFrameDescriptorCount
VkBuffer sceneBuffer; VkBuffer sceneBuffer;

View File

@ -2,6 +2,13 @@
#include <assert.h> #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) inline static constexpr VkDeviceSize roundAlignment(VkDeviceSize offset, VkDeviceSize alignment)
{ {
// must be a power of two // must be a power of two
@ -9,6 +16,22 @@ inline static constexpr VkDeviceSize roundAlignment(VkDeviceSize offset, VkDevic
return (offset + (alignment - 1)) & (-alignment); 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, VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties, VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
VkMemoryRequirements const & memoryRequirements, VkMemoryRequirements const & memoryRequirements,
@ -18,6 +41,7 @@ VkDeviceSize allocateFromMemoryRequirements(VkDevice device,
VkDeviceMemory * memory); VkDeviceMemory * memory);
VkDeviceSize allocateFromMemoryRequirements2(VkDevice device, VkDeviceSize allocateFromMemoryRequirements2(VkDevice device,
VkPhysicalDeviceProperties const & physicalDeviceProperties,
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties, VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryAllocateFlags memoryAllocateFlags, VkMemoryAllocateFlags memoryAllocateFlags,

View File

@ -236,14 +236,15 @@ namespace collada::scene {
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT }; VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
VkMemoryAllocateFlags memoryAllocateFlags{ }; VkMemoryAllocateFlags memoryAllocateFlags{ };
allocateFromMemoryRequirements2(device, shaderDataDevice.memorySize = allocateFromMemoryRequirements2(device,
physicalDeviceMemoryProperties, physicalDeviceProperties,
memoryPropertyFlags, physicalDeviceMemoryProperties,
memoryAllocateFlags, memoryPropertyFlags,
uniformBufferDescriptorCount, memoryAllocateFlags,
memoryRequirements, uniformBufferDescriptorCount,
&shaderDataDevice.memory, memoryRequirements,
offsets); &shaderDataDevice.memory,
offsets);
VkDeviceSize offset{ 0 }; VkDeviceSize offset{ 0 };
VkDeviceSize size{ VK_WHOLE_SIZE }; VkDeviceSize size{ VK_WHOLE_SIZE };
@ -301,7 +302,7 @@ namespace collada::scene {
}; };
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{ VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.maxSets = 2, .maxSets = maxFrames + 1, // +1 for descriptorSet1
.poolSizeCount = descriptorPoolSizesCount, .poolSizeCount = descriptorPoolSizesCount,
.pPoolSizes = descriptorPoolSizes .pPoolSizes = descriptorPoolSizes
}; };
@ -519,16 +520,20 @@ namespace collada::scene {
// flush // flush
VkDeviceSize materialColorsFlushSize{ shaderDataDevice.constant.materialColorsSize }; VkMappedMemoryRange mappedMemoryRanges[1]{
VkMappedMemoryRange shaderDataMemoryRanges[1]{
{ {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory, .memory = shaderDataDevice.memory,
.offset = shaderDataDevice.constant.materialColorsOffset, .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 // flush
VkDeviceSize sceneFlushSize{ shaderDataDevice.frame[frameIndex].sceneSize }; VkMappedMemoryRange mappedMemoryRanges[2]{
VkDeviceSize nodesFlushSize{ shaderDataDevice.frame[frameIndex].nodesSize };
//fprintf(stderr, "sceneFlushSize %ld\n", sceneFlushSize);
//fprintf(stderr, "nodesFlushSize %ld\n", nodesFlushSize);
VkMappedMemoryRange shaderDataMemoryRanges[2]{
{ {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory, .memory = shaderDataDevice.memory,
.offset = shaderDataDevice.frame[frameIndex].sceneOffset, .offset = shaderDataDevice.frame[frameIndex].sceneOffset,
.size = roundAlignment(sceneFlushSize, physicalDeviceProperties.limits.nonCoherentAtomSize), .size = shaderDataDevice.frame[frameIndex].sceneSize,
}, },
{ {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = shaderDataDevice.memory, .memory = shaderDataDevice.memory,
.offset = shaderDataDevice.frame[frameIndex].nodesOffset, .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, 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, .width = surfaceCapabilities.currentExtent.width,
.height = surfaceCapabilities.currentExtent.height, .height = surfaceCapabilities.currentExtent.height,
}; };
if ((imageExtent.width == ~0u) && (imageExtent.width == ~0u)) {
imageExtent.width = windowSize.x;
imageExtent.height = windowSize.y;
}
VkFormat imageFormat{ surfaceFormat.format }; VkFormat imageFormat{ surfaceFormat.format };
VkColorSpaceKHR imageColorSpace{ surfaceFormat.colorSpace }; VkColorSpaceKHR imageColorSpace{ surfaceFormat.colorSpace };
@ -463,6 +459,10 @@ int main()
SDL_CHECK(SDL_GetWindowSize(window, &windowSize.x, &windowSize.y)); SDL_CHECK(SDL_GetWindowSize(window, &windowSize.x, &windowSize.y));
VkSurfaceCapabilitiesKHR surfaceCapabilities{}; VkSurfaceCapabilitiesKHR surfaceCapabilities{};
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &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); printf("surfaceCapabilities currentExtent %d %d\n", surfaceCapabilities.currentExtent.width, surfaceCapabilities.currentExtent.height);
// surface format // surface format
@ -1623,6 +1623,10 @@ int main()
updateSwapchain = false; updateSwapchain = false;
VK_CHECK(vkDeviceWaitIdle(device)); VK_CHECK(vkDeviceWaitIdle(device));
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &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;
}
recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceMemoryProperties, surfaceCapabilities); recreateSwapchain(surfaceFormat, depthFormat, physicalDeviceMemoryProperties, surfaceCapabilities);
} }
} }

View File

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