1616
1717VESPERENGINE_NAMESPACE_BEGIN
1818
19+ PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT = nullptr ;
20+ PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT = nullptr ;
21+
1922// local callback functions
2023static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback (
2124 VkDebugUtilsMessageSeverityFlagBitsEXT _messageSeverity,
@@ -198,7 +201,12 @@ void Device::CreateLogicalDevice()
198201 VkPhysicalDeviceFeatures deviceFeatures = {};
199202 deviceFeatures.samplerAnisotropy = VK_TRUE ;
200203
201- // EXT features
204+ // EXT features -> Dynamic state
205+ VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamicStateFeatures = {};
206+ dynamicStateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT ;
207+ dynamicStateFeatures.extendedDynamicState = VK_TRUE ;
208+
209+ // EXT features -> Indexing
202210 VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures = {};
203211 indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT ;
204212 indexingFeatures.runtimeDescriptorArray = VK_TRUE ;
@@ -212,13 +220,19 @@ void Device::CreateLogicalDevice()
212220// indexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE;
213221// indexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE;
214222
223+
215224 VkPhysicalDeviceFeatures2 deviceFeatures2 = {};
216225 deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 ;
217226 deviceFeatures2.features = deviceFeatures; // Include base features like samplerAnisotropy
218227
219228 if (m_bIsBindlessResourcesSupported)
220229 {
221- deviceFeatures2.pNext = &indexingFeatures;
230+ dynamicStateFeatures.pNext = &indexingFeatures;
231+ deviceFeatures2.pNext = &dynamicStateFeatures;
232+ }
233+ else
234+ {
235+ dynamicStateFeatures.pNext = &indexingFeatures;
222236 }
223237
224238 VkDeviceCreateInfo createInfo = {};
@@ -243,7 +257,16 @@ void Device::CreateLogicalDevice()
243257
244258 // Use features2 instead of pEnabledFeatures
245259 createInfo.pEnabledFeatures = nullptr ;
246- createInfo.pNext = &deviceFeatures2;
260+
261+ if (m_bIsBindlessResourcesSupported)
262+ {
263+ createInfo.pNext = &deviceFeatures2;
264+ }
265+ else
266+ {
267+ createInfo.pNext = &dynamicStateFeatures;;
268+ }
269+ //
247270
248271 if (vkCreateDevice (m_physicalDevice, &createInfo, nullptr , &m_device) != VK_SUCCESS )
249272 {
@@ -252,6 +275,22 @@ void Device::CreateLogicalDevice()
252275
253276 vkGetDeviceQueue (m_device, indices.GraphicsFamily , 0 , &m_graphicsQueue);
254277 vkGetDeviceQueue (m_device, indices.PresentFamily , 0 , &m_presentQueue);
278+
279+ if (VK_EXT_extended_dynamic_state2_enabled)
280+ {
281+ // the function name vkCmdSetCullMode does not have EXT vkCmdSetCullModeEXT, because in Vulkan 1.3 they were promoted to Core
282+ vkCmdSetCullModeEXT = reinterpret_cast <PFN_vkCmdSetCullModeEXT>(vkGetDeviceProcAddr (m_device, " vkCmdSetCullMode" ));
283+ vkCmdSetFrontFaceEXT = reinterpret_cast <PFN_vkCmdSetFrontFaceEXT>(vkGetDeviceProcAddr (m_device, " vkCmdSetFrontFace" ));
284+
285+ if (!vkCmdSetCullModeEXT || !vkCmdSetFrontFaceEXT)
286+ {
287+ throw std::runtime_error (" failed to create logical device! Device does not support VK_EXT_extended_dynamic_state2, which is required!" );
288+ }
289+ }
290+ else
291+ {
292+ throw std::runtime_error (" failed to create logical device! Device does not support VK_EXT_extended_dynamic_state2, which is required!" );
293+ }
255294}
256295
257296void Device::CreateCommandPool ()
@@ -536,6 +575,10 @@ bool Device::CheckDeviceExtensionSupport(VkPhysicalDevice _device)
536575 {
537576 VK_EXT_descriptor_indexing_extension_enabled = true ;
538577 }
578+ else if (strcmp (extension.extensionName , VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME ) == 0 )
579+ {
580+ VK_EXT_extended_dynamic_state2_enabled = true ;
581+ }
539582
540583 requiredExtensions.erase (extension.extensionName );
541584 }
0 commit comments