コード例 #1
0
ファイル: Example.cpp プロジェクト: YoutaVen/Vulkan
//
// Vulkan update.
//
VkBool32 Example::update(const vkts::IUpdateThreadContext& updateContext)
{
	for (size_t i = 0; i < allUpdateables.size(); i++)
	{
		allUpdateables[i]->update(updateContext.getDeltaTime(), updateContext.getDeltaTicks());
	}

	//

	VkResult result = VK_SUCCESS;

	//

	if (windowDimension != updateContext.getWindowDimension(windowIndex))
	{
		windowDimension = updateContext.getWindowDimension(windowIndex);

		result = VK_ERROR_OUT_OF_DATE_KHR;
	}

	//

	uint32_t currentBuffer;

	if (result == VK_SUCCESS)
	{
		result = swapchain->acquireNextImage(UINT64_MAX, imageAcquiredSemaphore->getSemaphore(), VK_NULL_HANDLE, currentBuffer);
	}

	if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
	{
		glm::mat4 projectionMatrix(1.0f);
		glm::mat4 viewMatrix(1.0f);

		const auto& dimension = updateContext.getWindowDimension(windowIndex);

		projectionMatrix = vkts::perspectiveMat4(45.0f, (float) dimension.x / (float) dimension.y, 1.0f, 100.0f);

		viewMatrix = camera->getViewMatrix();

		glm::vec3 lightDirection = glm::mat3(viewMatrix) * glm::vec3(0.0f, 1.0f, 2.0f);

		lightDirection = glm::normalize(lightDirection);

		if (!fragmentUniformBuffer->upload(0, 0, lightDirection))
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not upload light direction.");

			return VK_FALSE;
		}
		if (!vertexViewProjectionUniformBuffer->upload(0 * sizeof(float) * 16, 0, projectionMatrix))
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not upload matrices.");

			return VK_FALSE;
		}
		if (!vertexViewProjectionUniformBuffer->upload(1 * sizeof(float) * 16, 0, viewMatrix))
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not upload matrices.");

			return VK_FALSE;
		}

		if (scene.get())
		{
			scene->updateRecursive(updateContext);
		}

		//

        VkSemaphore waitSemaphores = imageAcquiredSemaphore->getSemaphore();
        VkSemaphore signalSemaphores = renderingCompleteSemaphore->getSemaphore();


        VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;

        VkSubmitInfo submitInfo;

        memset(&submitInfo, 0, sizeof(VkSubmitInfo));

        submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

        submitInfo.waitSemaphoreCount = 1;
        submitInfo.pWaitSemaphores = &waitSemaphores;
        submitInfo.pWaitDstStageMask = &waitDstStageMask;
        submitInfo.commandBufferCount = 1;
        submitInfo.pCommandBuffers = cmdBuffer[currentBuffer]->getCommandBuffers();
        submitInfo.signalSemaphoreCount = 1;
        submitInfo.pSignalSemaphores = &signalSemaphores;

		result = initialResources->getQueue()->submit(1, &submitInfo, VK_NULL_HANDLE);

		if (result != VK_SUCCESS)
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not submit queue.");

			return VK_FALSE;
		}

        waitSemaphores = renderingCompleteSemaphore->getSemaphore();

        VkSwapchainKHR swapchains = swapchain->getSwapchain();

        result = swapchain->queuePresent(initialResources->getQueue()->getQueue(), 1, &waitSemaphores, 1, &swapchains, &currentBuffer, nullptr);

		if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
		{
			result = initialResources->getQueue()->waitIdle();

			if (result != VK_SUCCESS)
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not wait for idle queue.");

				return VK_FALSE;
			}
		}
		else
		{
			if (result == VK_ERROR_OUT_OF_DATE_KHR)
			{
				terminateResources(updateContext);

				if (!buildResources(updateContext))
				{
					vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

					return VK_FALSE;
				}
			}
			else
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not present queue.");

				return VK_FALSE;
			}
		}
	}
	else
	{
		if (result == VK_ERROR_OUT_OF_DATE_KHR)
		{
			terminateResources(updateContext);

			if (!buildResources(updateContext))
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

				return VK_FALSE;
			}
		}
		else
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not acquire next image.");

			return VK_FALSE;
		}
	}

	//

    result = imageAcquiredSemaphore->reset();

    if (result != VK_SUCCESS)
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not reset semaphore.");

        return VK_FALSE;
    }

    result = renderingCompleteSemaphore->reset();

    if (result != VK_SUCCESS)
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not reset semaphore.");

        return VK_FALSE;
    }

	return VK_TRUE;
}
コード例 #2
0
ファイル: Example.cpp プロジェクト: YoutaVen/Vulkan
//
// Vulkan initialization.
//
VkBool32 Example::init(const vkts::IUpdateThreadContext& updateContext)
{
	if (!updateContext.isWindowAttached(windowIndex))
	{
		return VK_FALSE;
	}

	windowDimension = updateContext.getWindowDimension(windowIndex);

	//


	camera = vkts::cameraCreate(glm::vec4(0.0f, 4.0f, 10.0f, 1.0f), glm::vec4(0.0f, 2.0f, 0.0f, 1.0f));

	if (!camera.get())
	{
		return VK_FALSE;
	}

	allUpdateables.append(camera);

	inputController = vkts::inputControllerCreate(updateContext, windowIndex, 0, camera);

	if (!inputController.get())
	{
		return VK_FALSE;
	}

	allUpdateables.insert(0, inputController);

	//

	commandPool = vkts::commandPoolCreate(initialResources->getDevice()->getDevice(), 0, initialResources->getQueue()->getQueueFamilyIndex());

	if (!commandPool.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get command pool.");

		return VK_FALSE;
	}

	//

    imageAcquiredSemaphore = vkts::semaphoreCreate(initialResources->getDevice()->getDevice(), 0);

    if (!imageAcquiredSemaphore.get())
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create semaphore.");

        return VK_FALSE;
    }

    renderingCompleteSemaphore = vkts::semaphoreCreate(initialResources->getDevice()->getDevice(), 0);

    if (!renderingCompleteSemaphore.get())
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create semaphore.");

        return VK_FALSE;
    }

	//

	if (!buildUniformBuffers())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build uniform buffers.");

		return VK_FALSE;
	}

	if (!buildShader())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build shader.");

		return VK_FALSE;
	}

	if (!buildDescriptorSetLayout())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build descriptor set layout.");

		return VK_FALSE;
	}

	if (!buildPipelineLayout())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build pipeline cache.");

		return VK_FALSE;
	}

	//

	if (!buildResources(updateContext))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

		return VK_FALSE;
	}

	//

	glm::vec3 lightDirection = glm::vec3(0.0f, 1.0f, 2.0f);

	lightDirection = glm::normalize(lightDirection);

	if (!fragmentUniformBuffer->upload(0, 0, lightDirection))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not upload light direction.");

		return VK_FALSE;
	}

	return VK_TRUE;
}
コード例 #3
0
ファイル: Example.cpp プロジェクト: EddyGun/Vulkan
//
// Vulkan update.
//
VkBool32 Example::update(const vkts::IUpdateThreadContext& updateContext)
{

	VkResult result = VK_SUCCESS;

	//

	if (windowDimension != updateContext.getWindowDimension(windowIndex))
	{
		windowDimension = updateContext.getWindowDimension(windowIndex);

		result = VK_ERROR_OUT_OF_DATE_KHR;
	}

	//

	uint32_t currentBuffer;

	if (result == VK_SUCCESS)
	{
		result = swapchain->acquireNextImage(UINT64_MAX, imageAcquiredSemaphore->getSemaphore(), VK_NULL_HANDLE, currentBuffer);
	}

	if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
	{
		VkSemaphore waitSemaphores = imageAcquiredSemaphore->getSemaphore();
		VkSemaphore signalSemaphores = renderingCompleteSemaphore->getSemaphore();


		VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;

		VkSubmitInfo submitInfo;

		memset(&submitInfo, 0, sizeof(VkSubmitInfo));

		submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

		submitInfo.waitSemaphoreCount = 1;
		submitInfo.pWaitSemaphores = &waitSemaphores;
		submitInfo.pWaitDstStageMask = &waitDstStageMask;
		submitInfo.commandBufferCount = 1;
		submitInfo.pCommandBuffers = cmdBuffer[currentBuffer]->getCommandBuffers();
		submitInfo.signalSemaphoreCount = 1;
		submitInfo.pSignalSemaphores = &signalSemaphores;

		result = queue->submit(1, &submitInfo, VK_NULL_HANDLE);

		if (result != VK_SUCCESS)
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not submit queue.");

			return VK_FALSE;
		}

		waitSemaphores = renderingCompleteSemaphore->getSemaphore();

		VkSwapchainKHR swapchains = swapchain->getSwapchain();

		result = swapchain->queuePresent(queue->getQueue(), 1, &waitSemaphores, 1, &swapchains, &currentBuffer, nullptr);

		if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
		{
			result = queue->waitIdle();

			if (result != VK_SUCCESS)
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not wait for idle queue.");

				return VK_FALSE;
			}
		}
		else
		{
			if (result == VK_ERROR_OUT_OF_DATE_KHR)
			{
				terminateResources(updateContext);

				if (!buildResources(updateContext))
				{
					vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

					return VK_FALSE;
				}
			}
			else
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not present queue.");

				return VK_FALSE;
			}
		}
	}
	else
	{
		if (result == VK_ERROR_OUT_OF_DATE_KHR)
		{
			terminateResources(updateContext);

			if (!buildResources(updateContext))
			{
				vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

				return VK_FALSE;
			}
		}
		else
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not acquire next image.");

			return VK_FALSE;
		}
	}

	//

	result = imageAcquiredSemaphore->reset();

	if (result != VK_SUCCESS)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not reset semaphore.");

		return VK_FALSE;
	}

    result = renderingCompleteSemaphore->reset();

    if (result != VK_SUCCESS)
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not reset semaphore.");

        return VK_FALSE;
    }

	return VK_TRUE;
}
コード例 #4
0
ファイル: Example.cpp プロジェクト: EddyGun/Vulkan
//
// Vulkan initialization.
//
VkBool32 Example::init(const vkts::IUpdateThreadContext& updateContext)
{
	if (!updateContext.isDisplayAttached(displayIndex))
	{
		return VK_FALSE;
	}

	if (!updateContext.isWindowAttached(windowIndex))
	{
		return VK_FALSE;
	}

	windowDimension = updateContext.getWindowDimension(windowIndex);

	//

	VkResult result;

	//

	if (!vkts::wsiGatherNeededInstanceExtensions())
	{
		vkts::logPrint(VKTS_LOG_WARNING, "Example: Could not gather instance extensions.");

		return VK_TRUE;
	}

	instance = vkts::instanceCreate(VKTS_EXAMPLE_NAME, VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 0, 0), 0, 0, nullptr, vkts::extensionGetNeededInstanceExtensionCount(), vkts::extensionGetNeededInstanceExtensionNames());

	if (!instance.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create instance.");

		return VK_FALSE;
	}

	if (!vkts::wsiInitInstanceExtensions(instance->getInstance()))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not initialize instance extension.");

		return VK_FALSE;
	}

	physicalDevice = vkts::physicalDeviceCreate(instance->getInstance(), 0);

	if (!physicalDevice.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get physical device.");

		return VK_FALSE;
	}


	if (!vkts::wsiGatherNeededDeviceExtensions(physicalDevice->getPhysicalDevice()))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not gather device extension.");

		return VK_FALSE;
	}

	//

	surface = vkts::wsiSurfaceCreate(instance->getInstance(), updateContext.getNativeDisplay(displayIndex), updateContext.getNativeWindow(windowIndex));

	if (!surface.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create surface.");

		return VK_FALSE;
	}

	//

	std::vector<VkBool32> supportFilter;

	result = vkts::wsiGetPhysicalDeviceSurfaceSupport(physicalDevice->getPhysicalDevice(), surface->getSurface(), (uint32_t) physicalDevice->getAllQueueFamilyProperties().size(), supportFilter);

	if (result != VK_SUCCESS || supportFilter.size() == 0)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get physical device surface support.");

		return VK_FALSE;
	}

	//

	uint32_t queueFamilyIndex;

	if (!vkts::queueGetFamilyIndex(physicalDevice->getAllQueueFamilyProperties(), VK_QUEUE_GRAPHICS_BIT, 0, &supportFilter, queueFamilyIndex))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not find queue family index.");

		return VK_FALSE;
	}

	//

	float queuePriorities[1] = {0.0f};

	VkDeviceQueueCreateInfo deviceQueueCreateInfo;

	memset(&deviceQueueCreateInfo, 0, sizeof(VkDeviceQueueCreateInfo));

	deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;

	deviceQueueCreateInfo.flags = 0;
	deviceQueueCreateInfo.queueFamilyIndex = 0;
	deviceQueueCreateInfo.queueCount = 1;
	deviceQueueCreateInfo.pQueuePriorities = queuePriorities;

	device = vkts::deviceCreate(physicalDevice->getPhysicalDevice(), 0, 1, &deviceQueueCreateInfo, 0, nullptr, vkts::extensionGetNeededDeviceExtensionCount(), vkts::extensionGetNeededDeviceExtensionNames(), nullptr);

	if (!device.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Test: Could not create device.");

		return VK_FALSE;
	}

	if (!vkts::wsiInitDeviceExtensions(device->getDevice()))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not initialize device extension.");

		return VK_FALSE;
	}

	//

	queue = vkts::queueGet(device->getDevice(), queueFamilyIndex, 0);

	if (!queue.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get device queue.");

		return VK_FALSE;
	}

	//

	commandPool = vkts::commandPoolCreate(device->getDevice(), 0, queue->getQueueFamilyIndex());

	if (!commandPool.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get command pool.");

		return VK_FALSE;
	}

	//

	imageAcquiredSemaphore = vkts::semaphoreCreate(device->getDevice(), 0);

	if (!imageAcquiredSemaphore.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create semaphore.");

		return VK_FALSE;
	}

    renderingCompleteSemaphore = vkts::semaphoreCreate(device->getDevice(), 0);

    if (!renderingCompleteSemaphore.get())
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create semaphore.");

        return VK_FALSE;
    }

	//

	if (!buildVertexBuffer())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build vertex buffer.");

		return VK_FALSE;
	}

	if (!buildShader())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build shader.");

		return VK_FALSE;
	}

	if (!buildPipelineCache())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build pipeline cache.");

		return VK_FALSE;
	}

	if (!buildPipelineLayout())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build pipeline layout.");

		return VK_FALSE;
	}

	//

	if (!buildResources(updateContext))
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build resources.");

		return VK_FALSE;
	}

	return VK_TRUE;
}
コード例 #5
0
VkBool32 Example::buildResources( const vkts::IUpdateThreadContext& updateContext)
{
	VkResult result;

	//

	glm::uvec2 dimension = updateContext.getWindowDimension(windowIndex);
	VkExtent2D extent2D = { dimension.x, dimension.y };

	//

	auto lastSwapchain = swapchain;

	VkSwapchainKHR oldSwapchain = lastSwapchain.get() ? lastSwapchain->getSwapchain() : VK_NULL_HANDLE;

	swapchain = vkts::wsiSwapchainCreate(physicalDevice->getPhysicalDevice(), device->getDevice(), 0, surface->getSurface(), VKTS_NUMBER_BUFFERS, extent2D, 1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SHARING_MODE_EXCLUSIVE, 0, nullptr, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_TRUE, oldSwapchain);

	if (!swapchain.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create swap chain.");

		return VK_FALSE;
	}

	//

    swapchainImagesCount = (uint32_t)swapchain->getAllSwapchainImages().size();

    if (swapchainImagesCount == 0)
    {
        vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not get swap chain images count.");

        return VK_FALSE;
    }

    swapchainImageView = vkts::SmartPointerVector<vkts::IImageViewSP>(swapchainImagesCount);
    framebuffer = vkts::SmartPointerVector<vkts::IFramebufferSP>(swapchainImagesCount);
    cmdBuffer = vkts::SmartPointerVector<vkts::ICommandBuffersSP>(swapchainImagesCount);

    //

	if (lastSwapchain.get())
	{
		lastSwapchain->destroy();
	}

	//

	if (!buildRenderPass())
	{
		return VK_FALSE;
	}

	if (!buildPipeline())
	{
		return VK_FALSE;
	}

	//

	vkts::IImageSP stageImage;
	vkts::IDeviceMemorySP stageDeviceMemoryImage;

	vkts::ICommandBuffersSP updateCmdBuffer = vkts::commandBuffersCreate(device->getDevice(), commandPool->getCmdPool(), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1);

	if (!updateCmdBuffer.get())
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not create command buffer.");

		return VK_FALSE;
	}

	result = updateCmdBuffer->beginCommandBuffer(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, VK_NULL_HANDLE, 0, VK_NULL_HANDLE, VK_FALSE, 0, 0);

	if (result != VK_SUCCESS)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not begin command buffer.");

		return VK_FALSE;
	}

    for (uint32_t index = 0; index < swapchain->getMinImageCount(); index++)
    {
        swapchain->cmdPipelineBarrier(updateCmdBuffer->getCommandBuffer(), 0, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, index);
    }

	VkBool32 doUpdateDescriptorSets = VK_FALSE;

	if (!image.get())
	{
		if (!buildTexture(updateCmdBuffer, stageImage, stageDeviceMemoryImage))
		{
			vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not build texture.");

			return VK_FALSE;
		}

		doUpdateDescriptorSets = VK_TRUE;
	}

	result = updateCmdBuffer->endCommandBuffer();

	if (result != VK_SUCCESS)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not end command buffer.");

		return VK_FALSE;
	}

	VkSubmitInfo submitInfo;

	memset(&submitInfo, 0, sizeof(VkSubmitInfo));

	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

	submitInfo.waitSemaphoreCount = 0;
	submitInfo.pWaitSemaphores = nullptr;
	submitInfo.commandBufferCount = updateCmdBuffer->getCommandBufferCount();
	submitInfo.pCommandBuffers = updateCmdBuffer->getCommandBuffers();
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = nullptr;

	result = queue->submit(1, &submitInfo, VK_NULL_HANDLE);

	if (result != VK_SUCCESS)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not submit queue.");

		return VK_FALSE;
	}

	result = queue->waitIdle();

	if (result != VK_SUCCESS)
	{
		vkts::logPrint(VKTS_LOG_ERROR, "Example: Could not wait for idle queue.");

		return VK_FALSE;
	}

	updateCmdBuffer->destroy();

	if (stageImage.get() || stageDeviceMemoryImage.get())
	{
		destroyTexture(stageImage, stageDeviceMemoryImage);
	}

	//

	if (doUpdateDescriptorSets)
	{
		if (!updateDescriptorSets())
		{
			return VK_FALSE;
		}
	}

	for (int32_t i = 0; i < (int32_t)swapchainImagesCount; i++)
	{
		if (!buildSwapchainImageView(i))
		{
			return VK_FALSE;
		}

		if (!buildFramebuffer(i))
		{
			return VK_FALSE;
		}

		if (!buildCmdBuffer(i))
		{
			return VK_FALSE;
		}
	}

	return VK_TRUE;
}