2929 * implemented as library code which can be swapped for alternative
3030 * implementations on a per-layer basis if needed.
3131 */
32-
32+ # include < cstring >
3333#include < vulkan/utility/vk_struct_helper.hpp>
3434
3535#include " framework/manual_functions.hpp"
@@ -621,15 +621,44 @@ VkResult layer_vkEnumerateInstanceExtensionProperties<default_tag>(const char* p
621621{
622622 LAYER_TRACE (__func__);
623623
624- UNUSED (pProperties);
625-
626- if (!pLayerName || strcmp (pLayerName, layerProps[0 ].layerName ))
624+ // Query for a layer
625+ if (pLayerName)
627626 {
628- return VK_ERROR_LAYER_NOT_PRESENT;
627+ // ... but not this layer
628+ if (strcmp (pLayerName, layerProps[0 ].layerName ))
629+ {
630+ return VK_ERROR_LAYER_NOT_PRESENT;
631+ }
632+
633+ size_t count = Instance::injectedInstanceExtensions.size ();
634+
635+ // Size query
636+ if (!pProperties)
637+ {
638+ *pPropertyCount = static_cast <uint32_t >(count);
639+ return VK_SUCCESS;
640+ }
641+
642+ // Property query, clamped to size of user array if smaller
643+ size_t emitCount = std::min (count, static_cast <size_t >(*pPropertyCount));
644+ for (size_t i = 0 ; i < emitCount; i++)
645+ {
646+ const auto & ref = Instance::injectedInstanceExtensions[i];
647+ std::strcpy (pProperties[i].extensionName , ref.first .c_str ());
648+ pProperties[i].specVersion = ref.second ;
649+ }
650+
651+ *pPropertyCount = static_cast <uint32_t >(emitCount);
652+
653+ if (count > emitCount)
654+ {
655+ return VK_INCOMPLETE;
656+ }
657+
658+ return VK_SUCCESS;
629659 }
630660
631- *pPropertyCount = 0 ;
632- return VK_SUCCESS;
661+ return VK_ERROR_LAYER_NOT_PRESENT;
633662}
634663
635664/* * See Vulkan API for documentation. */
@@ -641,23 +670,50 @@ VkResult layer_vkEnumerateDeviceExtensionProperties<default_tag>(VkPhysicalDevic
641670{
642671 LAYER_TRACE (__func__);
643672
644- UNUSED (pProperties);
645-
646- // Android layer enumeration will always pass a nullptr for the device
647- if (!gpu)
673+ // Query for a layer
674+ if (pLayerName)
648675 {
649- if (!pLayerName || strcmp (pLayerName, layerProps[0 ].layerName ))
676+ // ... but not this layer
677+ if (strcmp (pLayerName, layerProps[0 ].layerName ))
650678 {
651679 return VK_ERROR_LAYER_NOT_PRESENT;
652680 }
653681
654- *pPropertyCount = 0 ;
682+ size_t count = Instance::injectedDeviceExtensions.size ();
683+
684+ // Size query
685+ if (!pProperties)
686+ {
687+ *pPropertyCount = static_cast <uint32_t >(count);
688+ return VK_SUCCESS;
689+ }
690+
691+ // Property query, clamped to size of user array if smaller
692+ size_t emitCount = std::min (count, static_cast <size_t >(*pPropertyCount));
693+ for (size_t i = 0 ; i < emitCount; i++)
694+ {
695+ const auto & ref = Instance::injectedDeviceExtensions[i];
696+ std::strcpy (pProperties[i].extensionName , ref.first .c_str ());
697+ pProperties[i].specVersion = ref.second ;
698+ }
699+
700+ *pPropertyCount = static_cast <uint32_t >(emitCount);
701+
702+ if (count > emitCount)
703+ {
704+ return VK_INCOMPLETE;
705+ }
706+
655707 return VK_SUCCESS;
656708 }
657709
710+ // Query for a device, but on Android discovery may pass a null device
711+ if (!gpu)
712+ {
713+ return VK_ERROR_LAYER_NOT_PRESENT;
714+ }
715+
658716 // For other cases forward to the driver to handle it
659- assert (!pLayerName);
660- assert (gpu);
661717
662718 // Hold the lock to access layer-wide global store
663719 std::unique_lock<std::mutex> lock {g_vulkanLock};
@@ -674,20 +730,26 @@ VkResult layer_vkEnumerateInstanceLayerProperties<default_tag>(uint32_t* pProper
674730{
675731 LAYER_TRACE (__func__);
676732
677- if (pProperties)
678- {
679- size_t count = std::min (layerProps.size (), static_cast <size_t >(*pPropertyCount));
680- if (count < layerProps.size ())
681- {
682- return VK_INCOMPLETE;
683- }
733+ size_t count = layerProps.size ();
684734
685- memcpy (pProperties, layerProps.data (), count * sizeof (VkLayerProperties));
686- *pPropertyCount = count;
735+ // Size query
736+ if (!pProperties)
737+ {
738+ *pPropertyCount = static_cast <uint32_t >(count);
687739 return VK_SUCCESS;
688740 }
689741
690- *pPropertyCount = layerProps.size ();
742+ // Property query, clamped to size of user array if smaller
743+ size_t emitCount = std::min (count, static_cast <size_t >(*pPropertyCount));
744+
745+ std::memcpy (pProperties, layerProps.data (), emitCount * sizeof (VkLayerProperties));
746+ *pPropertyCount = static_cast <uint32_t >(emitCount);
747+
748+ if (count > emitCount)
749+ {
750+ return VK_INCOMPLETE;
751+ }
752+
691753 return VK_SUCCESS;
692754}
693755
@@ -701,20 +763,26 @@ VkResult layer_vkEnumerateDeviceLayerProperties<default_tag>(VkPhysicalDevice gp
701763
702764 UNUSED (gpu);
703765
704- if (pProperties)
705- {
706- size_t count = std::min (layerProps.size (), static_cast <size_t >(*pPropertyCount));
707- if (count < layerProps.size ())
708- {
709- return VK_INCOMPLETE;
710- }
766+ size_t count = layerProps.size ();
711767
712- memcpy (pProperties, layerProps.data (), count * sizeof (VkLayerProperties));
713- *pPropertyCount = count;
768+ // Size query
769+ if (!pProperties)
770+ {
771+ *pPropertyCount = static_cast <uint32_t >(count);
714772 return VK_SUCCESS;
715773 }
716774
717- *pPropertyCount = layerProps.size ();
775+ // Property query, clamped to size of user array if smaller
776+ size_t emitCount = std::min (count, static_cast <size_t >(*pPropertyCount));
777+
778+ std::memcpy (pProperties, layerProps.data (), emitCount * sizeof (VkLayerProperties));
779+ *pPropertyCount = static_cast <uint32_t >(emitCount);
780+
781+ if (count > emitCount)
782+ {
783+ return VK_INCOMPLETE;
784+ }
785+
718786 return VK_SUCCESS;
719787}
720788
0 commit comments