From 57d172df4db1451ba3caeeb0ca485d0845a61912 Mon Sep 17 00:00:00 2001 From: aura Date: Mon, 13 Jul 2026 10:15:03 +0200 Subject: push source --- vktest/vktest.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 vktest/vktest.c (limited to 'vktest') diff --git a/vktest/vktest.c b/vktest/vktest.c new file mode 100644 index 0000000..31bc828 --- /dev/null +++ b/vktest/vktest.c @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include +#include + +#define W 1260 +#define H 720 + +#define CK(x) do { VkResult _r = (x); if (_r != VK_SUCCESS) { \ + fprintf(stderr, "FAIL %s -> %d\n", #x, _r); exit(1); } } while (0) + +int main() +{ + Display *dpy = XOpenDisplay( NULL ); + if (!dpy) { fprintf( stderr, "no display\n" ); return 1; } + Window win = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 10, 10, W, H, 0, 0, 0 ); + XStoreName( dpy, win, "vktest" ); + XMapWindow( dpy, win ); + XFlush( dpy ); + + const char *iexts[] = { "VK_KHR_surface", "VK_KHR_xlib_surface" }; + VkApplicationInfo ai = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; + ai.apiVersion = VK_API_VERSION_1_1; + VkInstanceCreateInfo ici = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; + ici.pApplicationInfo = &ai; + ici.enabledExtensionCount = 2; + ici.ppEnabledExtensionNames = iexts; + VkInstance inst; + CK( vkCreateInstance(&ici, NULL, &inst )); + + uint32_t n = 1; + VkPhysicalDevice phys; + vkEnumeratePhysicalDevices( inst, &n, &phys ); + + VkSurfaceKHR surf; + VkXlibSurfaceCreateInfoKHR sci = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR }; + sci.dpy = dpy; + sci.window = win; + CK( vkCreateXlibSurfaceKHR( inst, &sci, NULL, &surf ) ); + + uint32_t nfam = 0; + vkGetPhysicalDeviceQueueFamilyProperties( phys, &nfam, NULL ); + VkQueueFamilyProperties fam[8]; + if( nfam > 8 ) nfam = 8; + vkGetPhysicalDeviceQueueFamilyProperties( phys, &nfam, fam ); + uint32_t qf = UINT32_MAX; + for( uint32_t i = 0; i < nfam; i++ ) { + VkBool32 pres = VK_FALSE; + vkGetPhysicalDeviceSurfaceSupportKHR( phys, i, surf, &pres ); + if( (fam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && pres ) { qf = i; break; } + } + if( qf == UINT32_MAX ) { fprintf( stderr, "no queue\n" ); return 1; } + + float prio = 1.0f; + VkDeviceQueueCreateInfo qci = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; + qci.queueFamilyIndex = qf; + qci.queueCount = 1; + qci.pQueuePriorities = &prio; + const char *dexts[] = { "VK_KHR_swapchain" }; + VkDeviceCreateInfo dci = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; + dci.queueCreateInfoCount = 1; + dci.pQueueCreateInfos = &qci; + dci.enabledExtensionCount = 1; + dci.ppEnabledExtensionNames = dexts; + VkDevice dev; + CK( vkCreateDevice( phys, &dci, NULL, &dev ) ); + VkQueue q; + vkGetDeviceQueue( dev, qf, 0, &q ); + + VkSurfaceFormatKHR fmts[16]; + uint32_t nfmt = 16; + vkGetPhysicalDeviceSurfaceFormatsKHR( phys, surf, &nfmt, fmts ); + VkSurfaceCapabilitiesKHR caps; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR( phys, surf, &caps ); + + VkSwapchainCreateInfoKHR scci = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; + scci.surface = surf; + scci.minImageCount = caps.minImageCount; + scci.imageFormat = fmts[0].format; + scci.imageColorSpace = fmts[0].colorSpace; + scci.imageExtent.width = W; + scci.imageExtent.height = H; + scci.imageArrayLayers = 1; + scci.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + scci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + scci.preTransform = caps.currentTransform; + scci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + scci.presentMode = VK_PRESENT_MODE_FIFO_KHR; + scci.clipped = VK_TRUE; + VkSwapchainKHR sc; + CK( vkCreateSwapchainKHR( dev, &scci, NULL, &sc ) ); + printf( "swapchain format: %d\n", fmts[0].format ); + + uint32_t nimg = 8; + VkImage imgs[8]; + vkGetSwapchainImagesKHR( dev, sc, &nimg, imgs ); + + VkCommandPoolCreateInfo cpci = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + cpci.queueFamilyIndex = qf; + VkCommandPool pool; + CK( vkCreateCommandPool( dev, &cpci, NULL, &pool )); + VkCommandBufferAllocateInfo cbai = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + cbai.commandPool = pool; + cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cbai.commandBufferCount = 1; + VkCommandBuffer cb; + CK( vkAllocateCommandBuffers( dev, &cbai, &cb ) ); + + VkSemaphoreCreateInfo semci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + VkSemaphore acq, ren; + CK( vkCreateSemaphore( dev, &semci, NULL, &acq ) ); + CK( vkCreateSemaphore( dev, &semci, NULL, &ren ) ); + VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + VkFence fence; + CK( vkCreateFence(dev, &fci, NULL, &fence )); + + VkBufferCreateInfo bci = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bci.size = (VkDeviceSize)W * H * 4; + bci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; + VkBuffer rb; + CK( vkCreateBuffer( dev, &bci, NULL, &rb ) ); + VkMemoryRequirements mr; + vkGetBufferMemoryRequirements( dev, rb, &mr ); + VkPhysicalDeviceMemoryProperties mp; + vkGetPhysicalDeviceMemoryProperties( phys, &mp ); + uint32_t type = 0; + for( uint32_t i = 0; i < mp.memoryTypeCount; i++ ) { + if( (mr.memoryTypeBits & (1u << i)) && (mp.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ) { + type = i; break; + } + } + VkMemoryAllocateInfo mai = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + mai.allocationSize = mr.size; + mai.memoryTypeIndex = type; + VkDeviceMemory rmem; + CK( vkAllocateMemory(dev, &mai, NULL, &rmem ) ); + CK( vkBindBufferMemory(dev, rb, rmem, 0 ) ); + + VkImageSubresourceRange range; + memset( &range, 0, sizeof( range )); + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.levelCount = 1; + range.layerCount = 1; + + for( ;; ) { + uint32_t idx; + CK( vkAcquireNextImageKHR(dev, sc, UINT64_MAX, acq, VK_NULL_HANDLE, &idx ) ); + + VkCommandBufferBeginInfo bi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + CK( vkBeginCommandBuffer( cb, &bi ) ); + + VkImageMemoryBarrier b = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + b.srcAccessMask = 0; + b.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + b.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + b.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + b.srcQueueFamilyIndex = b.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + b.image = imgs[idx]; + b.subresourceRange = range; + vkCmdPipelineBarrier( + cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, + 0, NULL, 1, &b + ); + + VkClearColorValue col = { { 0.05f, 0.10f, 0.20f, 1.0f } }; + vkCmdClearColorImage( cb, imgs[idx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &col, 1, &range ); + + b.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + b.dstAccessMask = 0; + b.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + b.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + vkCmdPipelineBarrier( + cb, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, + 0, NULL, 1, &b + ); + CK( vkEndCommandBuffer( cb ) ); + + VkPipelineStageFlags wait = VK_PIPELINE_STAGE_TRANSFER_BIT; + VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; + si.waitSemaphoreCount = 1; + si.pWaitSemaphores = &acq; + si.pWaitDstStageMask = &wait; + si.commandBufferCount = 1; + si.pCommandBuffers = &cb; + si.signalSemaphoreCount = 1; + si.pSignalSemaphores = &ren; + CK( vkQueueSubmit(q, 1, &si, VK_NULL_HANDLE ) ); + + VkPresentInfoKHR pi = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; + pi.waitSemaphoreCount = 1; + pi.pWaitSemaphores = &ren; + pi.swapchainCount = 1; + pi.pSwapchains = ≻ + pi.pImageIndices = &idx; + CK( vkQueuePresentKHR( q, &pi ) ); + vkQueueWaitIdle( q ); + usleep( 1 ); + } + + return 0; +} -- cgit v1.2.3