Update VK_Image_Layouts test to check preinitialised data also

This commit is contained in:
baldurk
2026-07-24 17:52:48 +01:00
parent 57702b7896
commit c6c8f807c9
2 changed files with 128 additions and 60 deletions
+88 -60
View File
@@ -65,8 +65,9 @@ RD_TEST(VK_Image_Layouts, VulkanGraphicsTest)
vb.upload(DefaultTri);
vkh::ImageCreateInfo preinitInfo(4, 4, 0, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
vkh::ImageCreateInfo preinitInfo(
4, 4, 0, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
preinitInfo.tiling = VK_IMAGE_TILING_LINEAR;
preinitInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
@@ -77,15 +78,11 @@ RD_TEST(VK_Image_Layouts, VulkanGraphicsTest)
vkCreateImage(device, preinitInfo, NULL, &unboundImg);
setName(unboundImg, "Unbound image");
VkImage preinitImg = VK_NULL_HANDLE;
VkDeviceMemory preinitMem = VK_NULL_HANDLE;
while(Running())
{
VkImage preinitImg = VK_NULL_HANDLE;
VkDeviceMemory preinitMem = VK_NULL_HANDLE;
vkCreateImage(device, preinitInfo, NULL, &preinitImg);
setName(preinitImg, "Image:Preinitialised");
AllocatedImage undefImg(
this,
vkh::ImageCreateInfo(4, 4, 0, VK_FORMAT_R8G8B8A8_UNORM,
@@ -94,36 +91,6 @@ RD_TEST(VK_Image_Layouts, VulkanGraphicsTest)
setName(undefImg.image, "Image:Undefined");
{
VkMemoryRequirements mrq;
vkGetImageMemoryRequirements(device, preinitImg, &mrq);
VkMemoryAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
info.allocationSize = mrq.size;
info.memoryTypeIndex = 100;
for(uint32_t i = 0; i < props->memoryTypeCount; i++)
{
if(mrq.memoryTypeBits & (1 << i) &&
(props->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
{
info.memoryTypeIndex = i;
break;
}
}
TEST_ASSERT(info.memoryTypeIndex != 100, "Couldn't find compatible memory type");
vkAllocateMemory(device, &info, NULL, &preinitMem);
vkBindImageMemory(device, preinitImg, preinitMem, 0);
void *data = NULL;
vkMapMemory(device, preinitMem, 0, mrq.size, 0, &data);
memset(data, 0x40, (size_t)mrq.size);
vkUnmapMemory(device, preinitMem);
}
VkCommandBuffer cmd = GetCommandBuffer();
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
@@ -148,27 +115,31 @@ RD_TEST(VK_Image_Layouts, VulkanGraphicsTest)
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
vkh::ImageSubresourceRange());
// the manual images are transitioned into general for copying, from pre-initialised and
// undefined
vkh::cmdPipelineBarrier(
cmd, {
vkh::ImageMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, preinitImg),
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, undefImg.image),
});
if(preinitImg != VK_NULL_HANDLE)
{
// the manual images are transitioned into general for copying, from pre-initialised and
// undefined
vkh::cmdPipelineBarrier(
cmd,
{
vkh::ImageMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, preinitImg),
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, undefImg.image),
});
VkImageCopy region = {
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0},
{4, 4, 1},
};
VkImageCopy region = {
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0},
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0},
{4, 4, 1},
};
vkCmdCopyImage(cmd, preinitImg, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, undefImg.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
vkCmdCopyImage(cmd, preinitImg, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, undefImg.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(mainWindow->rp, mainWindow->GetFB(), mainWindow->scissor),
@@ -182,22 +153,79 @@ RD_TEST(VK_Image_Layouts, VulkanGraphicsTest)
vkCmdEndRenderPass(cmd);
if(preinitImg != VK_NULL_HANDLE)
{
vkh::cmdPipelineBarrier(
cmd, {
vkh::ImageMemoryBarrier(
VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, preinitImg),
});
setMarker(cmd, "Preinit clear");
vkCmdClearColorImage(cmd, preinitImg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.8f, 0.8f, 0.8f, 1.0f), 1,
vkh::ImageSubresourceRange());
}
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
vkEndCommandBuffer(cmd);
Submit(0, 1, {cmd});
Present();
vkDeviceWaitIdle(device);
vkDestroyImage(device, preinitImg, NULL);
vkFreeMemory(device, preinitMem, NULL);
undefImg.free();
{
VkMemoryRequirements mrq;
vkCreateImage(device, preinitInfo, NULL, &preinitImg);
vkGetImageMemoryRequirements(device, preinitImg, &mrq);
vkDestroyImage(device, preinitImg, NULL);
VkMemoryAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
info.allocationSize = mrq.size;
info.memoryTypeIndex = 100;
for(uint32_t i = 0; i < props->memoryTypeCount; i++)
{
if(mrq.memoryTypeBits & (1 << i) &&
(props->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
{
info.memoryTypeIndex = i;
break;
}
}
TEST_ASSERT(info.memoryTypeIndex != 100, "Couldn't find compatible memory type");
vkAllocateMemory(device, &info, NULL, &preinitMem);
void *data = NULL;
vkMapMemory(device, preinitMem, 0, mrq.size, 0, &data);
memset(data, 0x40, (size_t)mrq.size);
vkUnmapMemory(device, preinitMem);
}
Present();
// make preinit image for next frame so the write must be preserved
vkCreateImage(device, preinitInfo, NULL, &preinitImg);
vkBindImageMemory(device, preinitImg, preinitMem, 0);
setName(preinitImg, "Image:Preinitialised");
}
vkDestroyImage(device, unboundImg, NULL);
vkDestroyImage(device, preinitImg, NULL);
vkFreeMemory(device, preinitMem, NULL);
return 0;
}
};
@@ -47,9 +47,12 @@ class VK_Image_Layouts(rdtest.TestCase):
if res.name == "Image:Preinitialised":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_PREINITIALIZED":
raise rdtest.TestFailureException("Pre-initialised image is in {} layout".format(img.layouts[0].name))
# check the preinitialised image has the right data
self.check_pixel_value(img.resourceId, 0, 0, [0.25, 0.25, 0.25, 0.25], eps=0.01)
elif res.name == "Image:Undefined":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_UNDEFINED":
raise rdtest.TestFailureException("Undefined image is in {} layout".format(img.layouts[0].name))
# don't check undefined image contents
elif res.name == "Image:Swapchain":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR":
raise rdtest.TestFailureException("Swapchain image is in {} layout".format(img.layouts[0].name))
@@ -69,9 +72,46 @@ class VK_Image_Layouts(rdtest.TestCase):
if res.name == "Image:Preinitialised":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL":
raise rdtest.TestFailureException("Pre-initialised image is in {} layout".format(img.layouts[0].name))
# check the preinitialised image has the right data
self.check_pixel_value(img.resourceId, 0, 0, [0.25, 0.25, 0.25, 0.25], eps=0.01)
elif res.name == "Image:Undefined":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL":
raise rdtest.TestFailureException("Undefined image is in {} layout".format(img.layouts[0].name))
# check the preinitialised image data was copied correctly to the previously undefined image
self.check_pixel_value(img.resourceId, 0, 0, [0.25, 0.25, 0.25, 0.25], eps=0.01)
elif img.resourceId == pipe.currentPass.framebuffer.attachments[0].resource:
if img.layouts[0].name != "VK_IMAGE_LAYOUT_GENERAL":
raise rdtest.TestFailureException("Rendered swapchain image is in {} layout".format(img.layouts[0].name))
action = self.find_action("Preinit clear")
self.check(action is not None)
self.controller.SetFrameEvent(action.eventId+1, False)
pipe: rd.VKState = self.controller.GetVulkanPipelineState()
# check that the pre-initialised image has transitioned + been cleared
for img in pipe.images:
img: rd.VKImageData
res = self.get_resource(img.resourceId)
if res.name == "Image:Preinitialised":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_GENERAL":
raise rdtest.TestFailureException("Pre-initialised image is in {} layout".format(img.layouts[0].name))
# check the preinitialised image has the right data
self.check_pixel_value(img.resourceId, 0, 0, [0.8, 0.8, 0.8, 1.0], eps=0.01)
# finally check that it has reset to the correct value back at the start of the frame
self.controller.SetFrameEvent(1, False)
pipe: rd.VKState = self.controller.GetVulkanPipelineState()
for img in pipe.images:
img: rd.VKImageData
res = self.get_resource(img.resourceId)
if res.name == "Image:Preinitialised":
if img.layouts[0].name != "VK_IMAGE_LAYOUT_PREINITIALIZED":
raise rdtest.TestFailureException("Pre-initialised image is in {} layout".format(img.layouts[0].name))
# check the preinitialised image has the right data
self.check_pixel_value(img.resourceId, 0, 0, [0.25, 0.25, 0.25, 0.25], eps=0.01)