2222 * IN THE SOFTWARE.
2323 * ----------------------------------------------------------------------------
2424 */
25+ #include < vulkan/utility/vk_safe_struct.hpp>
26+ #include < vulkan/utility/vk_struct_helper.hpp>
2527
2628#include " device.hpp"
2729#include " framework/device_dispatch_table.hpp"
@@ -119,16 +121,17 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateImage<user_tag>(VkDevice device,
119121 }
120122 }
121123
122- VkImageCreateInfo newCreateInfo = *pCreateInfo;
123-
124- VkImageCompressionControlEXT newCompressionControl;
125- // TODO: This currently relies on const_cast to make user struct writable
126- // We should replace this with a generic clone (issue #56)
127- auto * userCompressionControl =
128- searchNextList<VkImageCompressionControlEXT>(VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT,
129- pCreateInfo->pNext );
124+ // Create modifiable structures we can patch
125+ vku::safe_VkImageCreateInfo newCreateInfoSafe (pCreateInfo);
126+ auto * newCreateInfo = reinterpret_cast <VkImageCreateInfo*>(&newCreateInfoSafe);
127+ // We know we can const-cast here because this is a safe-struct clone
128+ void * pNextBase = const_cast <void *>(newCreateInfoSafe.pNext );
130129
130+ // Create extra structures we can patch in
131+ VkImageCompressionControlEXT newCompressionControl = vku::InitStructHelper ();
131132 VkImageCompressionControlEXT* compressionControl = &newCompressionControl;
133+
134+ auto * userCompressionControl = vku::FindStructInPNextChain<VkImageCompressionControlEXT>(pNextBase);
132135 if (userCompressionControl)
133136 {
134137 compressionControl = userCompressionControl;
@@ -138,21 +141,18 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateImage<user_tag>(VkDevice device,
138141
139142 if (forceDisable)
140143 {
141- compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT;
142144 compressionControl->flags = VK_IMAGE_COMPRESSION_DISABLED_EXT;
143145 compressionControl->compressionControlPlaneCount = 0 ;
144146 compressionControl->pFixedRateFlags = nullptr ;
145147 }
146148 else if (forceDefault)
147149 {
148- compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT;
149150 compressionControl->flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT;
150151 compressionControl->compressionControlPlaneCount = 0 ;
151152 compressionControl->pFixedRateFlags = nullptr ;
152153 }
153154 else if (selectedLevel)
154155 {
155- compressionControl->sType = VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT;
156156 compressionControl->flags = VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
157157 compressionControl->compressionControlPlaneCount = 1 ;
158158 compressionControl->pFixedRateFlags = reinterpret_cast <VkImageCompressionFixedRateFlagsEXT*>(&selectedLevel);
@@ -162,12 +162,11 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateImage<user_tag>(VkDevice device,
162162 patchNeeded = false ;
163163 }
164164
165- // If this is new, patch it in to the pNext chain
165+ // Add a config if not already configured by the application
166166 if (patchNeeded)
167167 {
168- compressionControl->pNext = newCreateInfo.pNext ;
169- newCreateInfo.pNext = reinterpret_cast <const void *>(compressionControl);
168+ vku::AddToPnext (newCreateInfoSafe, *compressionControl);
170169 }
171170
172- return layer->driver .vkCreateImage (device, & newCreateInfo, pAllocator, pImage);
171+ return layer->driver .vkCreateImage (device, newCreateInfo, pAllocator, pImage);
173172}
0 commit comments