VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool( VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) { DeviceMapStruct *devMap = get_dev_info(device); assert(devMap); VkLayerDispatchTable *pDisp = devMap->device_dispatch_table; VkResult result = pDisp->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); // Save the command pool on a map if we are taking screenshots. loader_platform_thread_lock_mutex(&globalLock); if (screenshotEnvQueried && screenshotFrames.empty()) { // No screenshots in the list to take loader_platform_thread_unlock_mutex(&globalLock); return result; } // Create a mapping from a device to a commandPool devMap->commandPool = *pCommandPool; loader_platform_thread_unlock_mutex(&globalLock); return result; }
static void after_device_create(VkPhysicalDevice gpu, VkDevice device, layer_data *data) { VkResult U_ASSERT_ONLY err; data->gpu = gpu; data->dev = device; data->frame = 0; data->cmdBuffersThisFrame = 0; VkLayerDispatchTable *pTable = data->device_dispatch_table; /* Get our WSI hooks in. */ data->pfnCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)pTable->GetDeviceProcAddr(device, "vkCreateSwapchainKHR"); data->pfnGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)pTable->GetDeviceProcAddr(device, "vkGetSwapchainImagesKHR"); data->pfnQueuePresentKHR = (PFN_vkQueuePresentKHR)pTable->GetDeviceProcAddr(device, "vkQueuePresentKHR"); data->pfnDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)pTable->GetDeviceProcAddr(device, "vkDestroySwapchainKHR"); data->swapChains = new std::unordered_map<VkSwapchainKHR, SwapChainData *>; /* Command pool */ VkCommandPoolCreateInfo cpci; cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cpci.pNext = nullptr; cpci.queueFamilyIndex = data->graphicsQueueFamilyIndex; cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; err = pTable->CreateCommandPool(device, &cpci, nullptr, &data->pool); assert(!err); /* Create the objects we need */ /* Compile the shaders */ compile_shader(device, VULKAN_SAMPLES_BASE_DIR "/Layer-Samples/data/overlay-vert.spv", &data->vsShaderModule); compile_shader(device, VULKAN_SAMPLES_BASE_DIR "/Layer-Samples/data/overlay-frag.spv", &data->fsShaderModule); /* Upload the font bitmap */ VkImageCreateInfo ici; memset(&ici, 0, sizeof(ici)); ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; ici.imageType = VK_IMAGE_TYPE_2D; ici.format = VK_FORMAT_R8_UNORM; ici.extent.width = FONT_ATLAS_SIZE; ici.extent.height = FONT_ATLAS_SIZE; ici.extent.depth = 1; ici.mipLevels = 1; ici.arrayLayers = 1; ici.samples = VK_SAMPLE_COUNT_1_BIT; ici.tiling = VK_IMAGE_TILING_LINEAR; ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT; ici.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; err = pTable->CreateImage(device, &ici, nullptr, &data->fontGlyphsImage); assert(!err); VkMemoryRequirements mem_reqs; pTable->GetImageMemoryRequirements(device, data->fontGlyphsImage, &mem_reqs); VkMemoryAllocateInfo mem_alloc; memset(&mem_alloc, 0, sizeof(mem_alloc)); mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; mem_alloc.allocationSize = mem_reqs.size; mem_alloc.memoryTypeIndex = choose_memory_type(gpu, mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); err = pTable->AllocateMemory(device, &mem_alloc, nullptr, &data->fontGlyphsMemory); assert(!err); err = pTable->BindImageMemory(device, data->fontGlyphsImage, data->fontGlyphsMemory, 0); assert(!err); VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subres.mipLevel = 0; subres.arrayLayer = 0; VkSubresourceLayout layout; void *bits; pTable->GetImageSubresourceLayout(device, data->fontGlyphsImage, &subres, &layout); /* ensure we can directly upload into this layout */ assert(!layout.offset); assert(layout.size >= FONT_ATLAS_SIZE * FONT_ATLAS_SIZE); assert(layout.rowPitch == FONT_ATLAS_SIZE); err = pTable->MapMemory(device, data->fontGlyphsMemory, 0, VK_WHOLE_SIZE, 0, &bits); assert(!err); /* Load the font glyphs directly into the mapped buffer */ std::vector<unsigned char> fontData; get_file_contents(VULKAN_SAMPLES_BASE_DIR "/Layer-Samples/data/FreeSans.ttf", fontData); stbtt_BakeFontBitmap(&fontData[0], 0, FONT_SIZE_PIXELS, (unsigned char *)bits, FONT_ATLAS_SIZE, FONT_ATLAS_SIZE, 32, 96, data->glyphs); pTable->UnmapMemory(device, data->fontGlyphsMemory); VkImageViewCreateInfo ivci; ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; ivci.pNext = nullptr; ivci.format = ici.format; ivci.components.r = VK_COMPONENT_SWIZZLE_R; ivci.components.g = VK_COMPONENT_SWIZZLE_G; ivci.components.b = VK_COMPONENT_SWIZZLE_B; ivci.components.a = VK_COMPONENT_SWIZZLE_A; ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; ivci.subresourceRange.baseMipLevel = 0; ivci.subresourceRange.levelCount = 1; ivci.subresourceRange.baseArrayLayer = 0; ivci.subresourceRange.layerCount = 1; ivci.image = data->fontGlyphsImage; ivci.flags = 0; err = pTable->CreateImageView(device, &ivci, nullptr, &data->fontGlyphsImageView); assert(!err); /* transition from undefined layout to shader readonly so we can use it. * requires a command buffer. */ VkCommandBufferAllocateInfo cbai; cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; cbai.pNext = nullptr; cbai.commandPool = data->pool; cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cbai.commandBufferCount = 1; VkCommandBuffer cmd; err = pTable->AllocateCommandBuffers(device, &cbai, &cmd); assert(!err); /* We have just created a dispatchable object, but the dispatch table has * not been placed in the object yet. * When a "normal" application creates a command buffer, * the dispatch table is installed by the top-level binding (trampoline.c). * But here, we have to do it ourselves. */ if (!data->pfn_dev_init) { *((const void **)cmd) = *(void **)device; } else { err = data->pfn_dev_init(device, (void *)cmd); assert(!err); } VkCommandBufferBeginInfo cbbi; cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cbbi.pNext = nullptr; cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; cbbi.pInheritanceInfo = nullptr; err = pTable->BeginCommandBuffer(cmd, &cbbi); assert(!err); VkImageMemoryBarrier imb; imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imb.pNext = nullptr; imb.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; imb.srcAccessMask = 0; imb.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imb.image = data->fontGlyphsImage; imb.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imb.subresourceRange.baseMipLevel = 0; imb.subresourceRange.levelCount = 1; imb.subresourceRange.baseArrayLayer = 0; imb.subresourceRange.layerCount = 1; imb.srcQueueFamilyIndex = data->graphicsQueueFamilyIndex; imb.dstQueueFamilyIndex = data->graphicsQueueFamilyIndex; pTable->CmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0 /* dependency flags */, 0, nullptr, /* memory barriers */ 0, nullptr, /* buffer memory barriers */ 1, &imb); /* image memory barriers */ pTable->EndCommandBuffer(cmd); data->fontUploadCmdBuffer = cmd; data->fontUploadComplete = false; /* we will schedule this at first present on this device */ #ifdef OVERLAY_DEBUG printf("Font upload done.\n"); #endif /* create a sampler to use with the texture */ VkSamplerCreateInfo sci; sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sci.pNext = nullptr; sci.flags = 0; sci.magFilter = VK_FILTER_NEAREST; sci.minFilter = VK_FILTER_NEAREST; sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; sci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sci.mipLodBias = 0.0f; sci.anisotropyEnable = false; sci.maxAnisotropy = 1; sci.compareEnable = false; sci.compareOp = VK_COMPARE_OP_NEVER; sci.minLod = 0.0f; sci.maxLod = 0.0f; sci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; sci.unnormalizedCoordinates = VK_FALSE; err = pTable->CreateSampler(device, &sci, nullptr, &data->sampler); assert(!err); /* descriptor set stuff so we can use the texture from a shader. */ VkDescriptorSetLayoutBinding dslb[1]; dslb[0].binding = 0; dslb[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; dslb[0].descriptorCount = 1; dslb[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; dslb[0].pImmutableSamplers = nullptr; VkDescriptorSetLayoutCreateInfo dslci; memset(&dslci, 0, sizeof(dslci)); dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dslci.pNext = nullptr; dslci.bindingCount = 1; dslci.pBindings = dslb; err = pTable->CreateDescriptorSetLayout(device, &dslci, nullptr, &data->dsl); assert(!err); VkPipelineLayoutCreateInfo plci; memset(&plci, 0, sizeof(plci)); plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; plci.setLayoutCount = 1; plci.pSetLayouts = &data->dsl; err = pTable->CreatePipelineLayout(device, &plci, nullptr, &data->pl); assert(!err); VkDescriptorPoolSize dtc[1]; dtc[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; dtc[0].descriptorCount = 1; VkDescriptorPoolCreateInfo dpci; dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; dpci.pNext = nullptr; dpci.flags = 0; dpci.maxSets = 1; dpci.poolSizeCount = 1; dpci.pPoolSizes = dtc; err = pTable->CreateDescriptorPool(device, &dpci, nullptr, &data->desc_pool); assert(!err); VkDescriptorSetAllocateInfo dsai; dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; dsai.pNext = nullptr; dsai.descriptorPool = data->desc_pool; dsai.descriptorSetCount = 1; dsai.pSetLayouts = &data->dsl; err = pTable->AllocateDescriptorSets(device, &dsai, &data->desc_set); assert(!err); VkDescriptorImageInfo descs[1]; descs[0].sampler = data->sampler; descs[0].imageView = data->fontGlyphsImageView; descs[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; // TODO: cube does this, is it correct? VkWriteDescriptorSet writes[1]; memset(&writes, 0, sizeof(writes)); writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[0].dstSet = data->desc_set; writes[0].dstBinding = 0; writes[0].descriptorCount = 1; writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; writes[0].pImageInfo = descs; pTable->UpdateDescriptorSets(device, 1, writes, 0, nullptr); VkFenceCreateInfo fci; fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fci.pNext = NULL; fci.flags = VK_FENCE_CREATE_SIGNALED_BIT; pTable->CreateFence(device, &fci, NULL, &data->fence); }