Jump to content
  • Advertisement
Sign in to follow this  
Aks9

OpenGL Vulkan Win32 WMI

This topic is 928 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Has anyone encountered a problem with deallocating Win32 surface using NVIDIA drivers?

 

Unfortunately, there is no appropriate tutorial how to deal with the window system integration (WMI). I followed the samples from the LunarG SDK and modified a bit in order to incorporate into my code (framework). All functions return VK_SUCCESS, however, with 356.39-vkonly_geforce_win8 drivers, the application crashes at Vulkan instance destroy. With 356.45-vkonly_geforce_win8 drivers, the application doesn't crash, but there is a memory leak (pretty the same as if I prevent the instance destroying with 356.39).

 

 

Detected memory leaks!

Dumping objects ->
{355} normal block at 0x06B223F0, 16 bytes long.
 Data: <` k     P       > 60 B1 6B 04 00 00 00 00 50 18 B2 06 00 00 00 00 
{349} normal block at 0x046BD9C8, 12 bytes long.
 Data: <            > 02 00 00 00 03 00 00 00 01 00 00 00 
{348} normal block at 0x046BD978, 16 bytes long.
 Data: <,       2       > 2C 00 00 00 00 00 00 00 32 00 00 00 00 00 00 00 

 

 

Also, is there any requirements for the window pixel format (like in OpenGL) in order to draw correctly on the surface?

 

So far it seems WMI is the most complicated part of the Vulkan. wacko.png

I hope after finishing correctly some interface functions for presentation on the windows I wouldn't have to change that code ever since.

 

Thanks in advance for any assistance or useful hints!

Aleksandar

Share this post


Link to post
Share on other sites
Advertisement

Huh! sad.png

It is not easy to post a reasonable amount of code when you code using Vulkan... I didn't expected that it needs about a thousand lines of code just to initialize...

Well, here is a code "fragment" that initializes swap chain:

char* APP_SHORT_NAME = "VkRenderer";
instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
 
VkApplicationInfo app_info = {};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pNext = NULL;
app_info.pApplicationName = APP_SHORT_NAME;
app_info.applicationVersion = 1;
app_info.pEngineName = APP_SHORT_NAME;
app_info.engineVersion = 1;
app_info.apiVersion = VK_API_VERSION;
 
VkInstanceCreateInfo inst_info = {};
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
inst_info.pNext = NULL;
inst_info.flags = 0;
inst_info.pApplicationInfo = &app_info;
inst_info.enabledExtensionCount = instance_extension_names.size();
inst_info.ppEnabledExtensionNames = inst_info.enabledExtensionCount ? instance_extension_names.data() : NULL;
inst_info.enabledLayerCount = 0;
inst_info.ppEnabledLayerNames = NULL;
 
VkResult res;
 
res = vkCreateInstance(&inst_info, NULL, &m_vkInst);
 
//...
 

VkWin32SurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.hinstance = GetModuleHandle(NULL); //info.connection;
createInfo.hwnd = wnd;
VkResult res = vkCreateWin32SurfaceKHR(m_vkInst, &createInfo, NULL, &m_surface);
 

VkBool32 *supportsPresent = (VkBool32 *)malloc(queue_count * sizeof(VkBool32));
for (uint32_t i = 0; i < queue_count; i++) {
vkGetPhysicalDeviceSurfaceSupportKHR(m_vGPU[0], i, m_surface, &supportsPresent[i]);
}
 

uint32_t graphicsQueueNodeIndex = UINT32_MAX;
for (uint32_t i = 0; i < queue_count; i++) {
if ((m_queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
if (supportsPresent[i] == VK_TRUE) {
graphicsQueueNodeIndex = i;
break;
}
}
}
//...

float queue_priorities[1] = { 0.0 };
device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
 
VkDeviceQueueCreateInfo queue_info = {};
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info.pNext = NULL;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = queue_priorities;
 
VkDeviceCreateInfo device_info = {};
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_info.pNext = NULL;
device_info.queueCreateInfoCount = 1;
device_info.pQueueCreateInfos = &queue_info;
device_info.enabledExtensionCount = device_extension_names.size();
device_info.ppEnabledExtensionNames = device_info.enabledExtensionCount ? device_extension_names.data() : NULL;
device_info.enabledLayerCount = 0;
device_info.ppEnabledLayerNames = NULL;
device_info.pEnabledFeatures = NULL;
 
res = vkCreateDevice(m_vGPU[0], &device_info, NULL, &m_vkDevice);
 
//...
 

uint32_t formatCount;
VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(m_vGPU[0], m_surface, &formatCount, NULL);
assert(res == VK_SUCCESS);
VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
res = vkGetPhysicalDeviceSurfaceFormatsKHR(m_vGPU[0], m_surface, &formatCount, surfFormats);
assert(res == VK_SUCCESS);
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format.  Otherwise, at least one
// supported format will be returned.
VkFormat format;
if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
format = VK_FORMAT_B8G8R8A8_UNORM;
}
else {
assert(formatCount >= 1);
format = surfFormats[0].format;
}
 
VkSurfaceCapabilitiesKHR surfCapabilities;
 
res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_vGPU[0], m_surface, &surfCapabilities);
 
uint32_t presentModeCount;
res = vkGetPhysicalDeviceSurfacePresentModesKHR(m_vGPU[0], m_surface, &presentModeCount, NULL);
 
VkPresentModeKHR *presentModes = (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
 
res = vkGetPhysicalDeviceSurfacePresentModesKHR(m_vGPU[0], m_surface, &presentModeCount, presentModes);
 

VkExtent2D swapChainExtent;
 
if (surfCapabilities.currentExtent.width == (uint32_t)-1) {
swapChainExtent.width = width;
swapChainExtent.height = height;
}
else {
swapChainExtent = surfCapabilities.currentExtent;
}
 

VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
for (size_t i = 0; i < presentModeCount; i++) {
if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
(presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
}
}
 

uint32_t desiredNumberOfSwapChainImages =
surfCapabilities.minImageCount + 1;
if ((surfCapabilities.maxImageCount > 0) &&
(desiredNumberOfSwapChainImages > surfCapabilities.maxImageCount)) {
desiredNumberOfSwapChainImages = surfCapabilities.maxImageCount;
}
 
VkSurfaceTransformFlagBitsKHR preTransform;
if (surfCapabilities.supportedTransforms &
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
}
else {
preTransform = surfCapabilities.currentTransform;
}
 
VkSwapchainCreateInfoKHR swap_chain = {};
swap_chain.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swap_chain.pNext = NULL;
swap_chain.surface = m_surface;
swap_chain.minImageCount = desiredNumberOfSwapChainImages;
swap_chain.imageFormat = format;
swap_chain.imageExtent.width = swapChainExtent.width;
swap_chain.imageExtent.height = swapChainExtent.height;
swap_chain.preTransform = preTransform;
swap_chain.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swap_chain.imageArrayLayers = 1;
swap_chain.presentMode = swapchainPresentMode;
swap_chain.oldSwapchain = NULL;
swap_chain.clipped = true;
swap_chain.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
swap_chain.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swap_chain.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swap_chain.queueFamilyIndexCount = 0;
swap_chain.pQueueFamilyIndices = NULL;
 
res = vkCreateSwapchainKHR(m_vkDevice, &swap_chain, NULL, &m_swap_chain);
 
res = vkGetSwapchainImagesKHR(m_vkDevice, m_swap_chain, &m_swapchainImageCount, NULL);
 
VkImage *swapchainImages = (VkImage *)malloc(m_swapchainImageCount * sizeof(VkImage));
 
res = vkGetSwapchainImagesKHR(m_vkDevice, m_swap_chain, &m_swapchainImageCount, swapchainImages);
 
m_buffers.resize(m_swapchainImageCount);
 
CreateCommandBuffer();
ExecuteBeginCommandBuffer();
 

vkGetDeviceQueue(m_vkDevice, m_graphicsQueueFamilyIndex, 0, &m_queue);
 
for (uint32_t i = 0; i < m_swapchainImageCount; i++) {
VkImageViewCreateInfo color_image_view = {};
color_image_view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
color_image_view.pNext = NULL;
color_image_view.format = format;
color_image_view.components.r = VK_COMPONENT_SWIZZLE_R;
color_image_view.components.g = VK_COMPONENT_SWIZZLE_G;
color_image_view.components.b = VK_COMPONENT_SWIZZLE_B;
color_image_view.components.a = VK_COMPONENT_SWIZZLE_A;
color_image_view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
color_image_view.subresourceRange.baseMipLevel = 0;
color_image_view.subresourceRange.levelCount = 1;
color_image_view.subresourceRange.baseArrayLayer = 0;
color_image_view.subresourceRange.layerCount = 1;
color_image_view.viewType = VK_IMAGE_VIEW_TYPE_2D;
color_image_view.flags = 0;
 
m_buffers[i].image = swapchainImages[i];
 
SetImageLayout(m_buffers[i].image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
 
color_image_view.image = m_buffers[i].image;
 
res = vkCreateImageView(m_vkDevice, &color_image_view, NULL, &m_buffers[i].view);
 
}
 
ExecuteEndCommandBuffer();
ExecuteQueueCommandBuffer();









 

This is not the whole code. All handles are valid and functions always return VK_SUCCESS. The dealocation code is like following:

for (uint32_t i = 0; i < m_swapchainImageCount; i++) {
vkDestroyImageView(m_vkDevice, m_buffers[i].view, NULL);
}
vkDestroySwapchainKHR(m_vkDevice, m_swap_chain, NULL);

 

I'm sorry for so much code, but that is Vulkan! unsure.png

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!