Skip to content

Instantly share code, notes, and snippets.

@AlpyneDreams
Last active December 4, 2024 07:44
Show Gist options
  • Save AlpyneDreams/210dc9156f1a63c278c1fc6a92bebe10 to your computer and use it in GitHub Desktop.
Save AlpyneDreams/210dc9156f1a63c278c1fc6a92bebe10 to your computer and use it in GitHub Desktop.
DXVK Interop - ImportDevice Example
// Get physical device
VkPhysicalDevice physDev = VK_NULL_HANDLE;
dxvk->GetPhysicalDeviceHandle( nAdapter, &physDev );
if ( physDev == VK_NULL_HANDLE )
{
return nullptr;
}
// Get VkDeviceCreateInfo
D3D9VkDeviceCreateInfo* createInfo = nullptr;
HRESULT hr = dxvk->GetDeviceCreateInfo( nAdapter, &createInfo );
if ( FAILED( hr ) || !createInfo )
{
if ( createInfo )
dxvk->FreeDeviceCreateInfo( createInfo );
return nullptr;
}
// Setup queues
float queuePriority = 1.f;
std::unordered_set<uint32> queueFamilies;
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
for ( uint32 i = 0; i < createInfo->info.queueCreateInfoCount; i++ )
{
queueFamilies.insert( createInfo->info.pQueueCreateInfos[i].queueFamilyIndex );
queueCreateInfos.push_back( createInfo->info.pQueueCreateInfos[i] );
queueCreateInfos[i].pQueuePriorities = &queuePriority;
}
auto queues = vk::PhysicalDevice( physDev ).getQueueFamilyProperties();
auto FindQueue = [&]( vk::QueueFlags mask, vk::QueueFlags flags )
{
uint32 i = 0;
for ( auto& queue : queues )
{
if ( (queue.queueFlags & mask) == flags )
return i;
i++;
}
return vk::QueueFamilyIgnored;
};
// Find async compute queue
using enum vk::QueueFlagBits;
uint32 compute = FindQueue( eGraphics | eCompute, eCompute );
if ( compute == vk::QueueFamilyIgnored )
compute = createInfo->graphicsQueueFamily;
if ( !queueFamilies.contains( compute ) )
{
queueFamilies.insert( compute );
VkDeviceQueueCreateInfo queue = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
queue.queueFamilyIndex = compute;
queue.queueCount = 1;
queue.pQueuePriorities = &queuePriority;
queueCreateInfos.push_back( queue );
}
createInfo->info.queueCreateInfoCount = queueCreateInfos.size();
createInfo->info.pQueueCreateInfos = queueCreateInfos.data();
createInfo->info.enabledLayerCount = 0;
createInfo->info.ppEnabledLayerNames = nullptr;
//
// Create Vulkan device!!!!!!
//
VkDevice device = VK_NULL_HANDLE;
VkResult result = VULKAN_HPP_DEFAULT_DISPATCHER.vkCreateDevice( physDev, &createInfo->info, nullptr, &device );
if ( result != VK_SUCCESS || device == VK_NULL_HANDLE )
{
dxvk->FreeDeviceCreateInfo( createInfo );
return nullptr;
}
//
// Create D3D9 device!!!!!!
//
D3D9VkDeviceImportInfo info;
info.device = device;
info.deviceType = devType;
info.extensionCount = createInfo->info.enabledExtensionCount;
info.extensionNames = const_cast<const char**>( createInfo->info.ppEnabledExtensionNames );
info.features = &createInfo->features.core;
info.queueLockCallback = nullptr;
// Queues
std::unordered_map<uint32, VkQueue> queueSet;
auto FindOrCreateQueue = [&]( uint32 family ) -> VkQueue
{
if ( auto it = queueSet.find( family ); it != queueSet.end() )
return it->second;
return queueSet[family] = vk::Device(device).getQueue( family, 0 );
};
info.graphicsQueue = FindOrCreateQueue( createInfo->graphicsQueueFamily );
info.graphicsQueueFamily = createInfo->graphicsQueueFamily;
info.transferQueue = FindOrCreateQueue( createInfo->transferQueueFamily );
info.transferQueueFamily = createInfo->transferQueueFamily;
info.sparseQueue = FindOrCreateQueue( createInfo->sparseQueueFamily );
info.sparseQueueFamily = createInfo->sparseQueueFamily;
hr = dxvk->ImportDevice( nAdapter, devType,
(VD3DHWND)hWnd, deviceCreationFlags, &m_PresentParameters, nullptr, &info, &pD3DDeviceEx );
if ( FAILED( hr ) || !pD3DDeviceEx )
{
return nullptr;
}
dxvk->FreeDeviceCreateInfo( createInfo );
createInfo = nullptr;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment