1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* Copyright (c) 2023 The Khronos Group Inc.
* Copyright (c) 2023 Valve Corporation
* Copyright (c) 2023 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "../framework/test_common.h"
#include "generated/pnext_chain_extraction.h"
// Return true iff all sTypes are found in chain, in order
bool FindSTypes(void* chain, const std::vector<VkStructureType>& sTypes_list) {
size_t sTypes_list_i = 0;
while (chain) {
const auto* vk_struct = reinterpret_cast<const VkBaseOutStructure*>(chain);
if (vk_struct->sType != sTypes_list[sTypes_list_i++]) {
return false;
}
chain = vk_struct->pNext;
}
return sTypes_list_i == sTypes_list.size();
}
// Extract all structs from a pNext chain
TEST(PnextChainExtract, Extract1) {
// Those structs extend VkPhysicalDeviceImageFormatInfo2
VkImageCompressionControlEXT s1 = vku::InitStructHelper();
VkImageFormatListCreateInfo s2 = vku::InitStructHelper(&s1);
VkImageStencilUsageCreateInfo s3 = vku::InitStructHelper(&s2);
VkOpticalFlowImageFormatInfoNV s4 = vku::InitStructHelper(&s3);
vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 extracted_chain{};
void* chain_begin = vvl::PnextChainExtract(&s4, extracted_chain);
const std::vector<VkStructureType> expected_sTypes = {s1.sType, s2.sType, s3.sType, s4.sType};
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
}
// Extract all structs mentioned in tuple vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 and found in input pNext chain
TEST(PnextChainExtract, Extract2) {
// Those structs extend VkPhysicalDeviceImageFormatInfo2
VkImageCompressionControlEXT s1 = vku::InitStructHelper();
VkImageFormatListCreateInfo s2 = vku::InitStructHelper(&s1);
VkImageStencilUsageCreateInfo s3 = vku::InitStructHelper(&s2);
VkOpticalFlowImageFormatInfoNV s4 = vku::InitStructHelper(&s3);
// Those do not
VkExternalMemoryImageCreateInfo wrong1 = vku::InitStructHelper(&s4);
VkImageDrmFormatModifierListCreateInfoEXT wrong2 = vku::InitStructHelper(&wrong1);
// And this one does
VkVideoProfileListInfoKHR s5 = vku::InitStructHelper(&wrong2);
vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 extracted_chain{};
void* chain_begin = vvl::PnextChainExtract(&s5, extracted_chain);
const std::vector<VkStructureType> expected_sTypes = {s1.sType, s2.sType, s3.sType, s4.sType, s5.sType};
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
}
// Test that no struct is extracted when no struct from a pNext chain extends the reference struct, here
// VkPhysicalDeviceImageFormatInfo2
TEST(PnextChainExtract, Extract3) {
// Those structs do not extend VkPhysicalDeviceImageFormatInfo2
VkExternalMemoryImageCreateInfo wrong1 = vku::InitStructHelper();
VkImageDrmFormatModifierListCreateInfoEXT wrong2 = vku::InitStructHelper(&wrong1);
vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 extracted_chain{};
void* chain_begin = vvl::PnextChainExtract(&wrong2, extracted_chain);
const std::vector<VkStructureType> expected_sTypes = {};
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
}
// Extract all structs from a pNext chain, add a new element, then remove it
TEST(PnextChainExtract, ExtractAddRemove1) {
// Those structs extend VkPhysicalDeviceImageFormatInfo2
VkImageCompressionControlEXT s1 = vku::InitStructHelper();
VkImageFormatListCreateInfo s2 = vku::InitStructHelper(&s1);
VkImageStencilUsageCreateInfo s3 = vku::InitStructHelper(&s2);
VkOpticalFlowImageFormatInfoNV s4 = vku::InitStructHelper(&s3);
vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 extracted_chain{};
void* chain_begin = vvl::PnextChainExtract(&s4, extracted_chain);
std::vector<VkStructureType> expected_sTypes = {s1.sType, s2.sType, s3.sType, s4.sType};
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
{
VkPhysicalDeviceImageDrmFormatModifierInfoEXT s5 = vku::InitStructHelper();
vvl::PnextChainScopedAdd scoped_add_s5(chain_begin, &s5);
expected_sTypes.emplace_back(s5.sType);
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
expected_sTypes.resize(expected_sTypes.size() - 1);
}
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
}
// Extract all structs from a pNext chain, add two new elements, in a nested fashion, then remove them
TEST(PnextChainExtract, ExtractAddRemove2) {
// Those structs extend VkPhysicalDeviceImageFormatInfo2
VkImageCompressionControlEXT s1 = vku::InitStructHelper();
VkImageFormatListCreateInfo s2 = vku::InitStructHelper(&s1);
VkImageStencilUsageCreateInfo s3 = vku::InitStructHelper(&s2);
VkOpticalFlowImageFormatInfoNV s4 = vku::InitStructHelper(&s3);
vvl::PnextChainVkPhysicalDeviceImageFormatInfo2 extracted_chain{};
void* chain_begin = vvl::PnextChainExtract(&s4, extracted_chain);
std::vector<VkStructureType> expected_sTypes = {s1.sType, s2.sType, s3.sType, s4.sType};
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
{
VkPhysicalDeviceImageDrmFormatModifierInfoEXT s5 = vku::InitStructHelper();
vvl::PnextChainScopedAdd scoped_add_s5(chain_begin, &s5);
expected_sTypes.emplace_back(s5.sType);
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
{
VkPhysicalDeviceImageViewImageFormatInfoEXT s6 = vku::InitStructHelper();
vvl::PnextChainScopedAdd scoped_add_s6(chain_begin, &s6);
expected_sTypes.emplace_back(s6.sType);
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
expected_sTypes.resize(expected_sTypes.size() - 1);
}
expected_sTypes.resize(expected_sTypes.size() - 1);
}
ASSERT_TRUE(FindSTypes(chain_begin, expected_sTypes));
}
|