Browse Source

vulkan: remove dep on VK_KHR_push_descriptor
It's not sure if this extension is supported everywhere
This commit uses normal descriptor pools, sets and writes,
which are all availabel in base vulkan.

niki 3 years ago
parent
commit
be8778b4eb

+ 0 - 13
src/modules/graphics/vulkan/Graphics.cpp

@@ -36,9 +36,6 @@ const std::vector<const char*> validationLayers = {
 
 
 const std::vector<const char*> deviceExtensions = {
 const std::vector<const char*> deviceExtensions = {
 	VK_KHR_SWAPCHAIN_EXTENSION_NAME,
 	VK_KHR_SWAPCHAIN_EXTENSION_NAME,
-
-	// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_push_descriptor.html
-	VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME
 };
 };
 
 
 #ifdef NDEBUG
 #ifdef NDEBUG
@@ -551,10 +548,6 @@ graphics::Texture* Graphics::getDefaultTexture() const {
 	return dynamic_cast<graphics::Texture*>(standardTexture.get());
 	return dynamic_cast<graphics::Texture*>(standardTexture.get());
 }
 }
 
 
-const PFN_vkCmdPushDescriptorSetKHR Graphics::getVkCmdPushDescriptorSetKHRFunctionPointer() const {
-	return vkCmdPushDescriptorSet;
-}
-
 VkCommandBuffer Graphics::getDataTransferCommandBuffer() {
 VkCommandBuffer Graphics::getDataTransferCommandBuffer() {
 	return dataTransferCommandBuffers.at(currentFrame);
 	return dataTransferCommandBuffers.at(currentFrame);
 }
 }
@@ -861,12 +854,6 @@ void Graphics::createLogicalDevice() {
 
 
 	vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
 	vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
 	vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
 	vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
-
-	vkCmdPushDescriptorSet = (PFN_vkCmdPushDescriptorSetKHR) vkGetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR");
-	if (!vkCmdPushDescriptorSet) {
-		// fixme: how widely adopted is this extension?
-		throw love::Exception("could not get a valid function pointer for vkCmdPushDescriptorSetKHR");
-	}
 }
 }
 
 
 void Graphics::initVMA() {
 void Graphics::initVMA() {

+ 0 - 2
src/modules/graphics/vulkan/Graphics.h

@@ -139,7 +139,6 @@ public:
 	void queueCleanUp(std::function<void()> cleanUp);
 	void queueCleanUp(std::function<void()> cleanUp);
 
 
 	uint32_t getNumImagesInFlight() const;
 	uint32_t getNumImagesInFlight() const;
-	const PFN_vkCmdPushDescriptorSetKHR getVkCmdPushDescriptorSetKHRFunctionPointer() const;
 	const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
 	const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
 	graphics::Texture* getDefaultTexture() const;
 	graphics::Texture* getDefaultTexture() const;
 	VkSampler getCachedSampler(const SamplerState&);
 	VkSampler getCachedSampler(const SamplerState&);
@@ -220,7 +219,6 @@ private:
 	std::vector<VkFence> inFlightFences;
 	std::vector<VkFence> inFlightFences;
 	std::vector<VkFence> imagesInFlight;
 	std::vector<VkFence> imagesInFlight;
 	VkDeviceSize minUniformBufferOffsetAlignment = 0;
 	VkDeviceSize minUniformBufferOffsetAlignment = 0;
-	PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSet = nullptr;
 	size_t currentFrame = 0;
 	size_t currentFrame = 0;
 	uint32_t imageIndex = 0;
 	uint32_t imageIndex = 0;
 	bool framebufferResized = false;
 	bool framebufferResized = false;

+ 74 - 21
src/modules/graphics/vulkan/Shader.cpp

@@ -118,6 +118,7 @@ static const TBuiltInResource defaultTBuiltInResource = {
 };
 };
 
 
 static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
 static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
+static const uint32_t DESCRIPTOR_POOL_SIZE = 32;
 
 
 static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
 static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
 	switch (type) {
 	switch (type) {
@@ -159,8 +160,11 @@ bool Shader::loadVolatile() {
 	createDescriptorSetLayout();
 	createDescriptorSetLayout();
 	createPipelineLayout();
 	createPipelineLayout();
 	createStreamBuffers();
 	createStreamBuffers();
+	descriptorSetsVector.resize(((Graphics*)gfx)->getNumImagesInFlight());
 	currentFrame = 0;
 	currentFrame = 0;
-	count = 0;
+	currentUsedUniformStreamBuffersCount = 0;
+	currentUsedDescriptorSetsCount = 0;
+	currentAllocatedDescriptorSets = DESCRIPTOR_POOL_SIZE;
 
 
 	return true;
 	return true;
 }
 }
@@ -171,7 +175,10 @@ void Shader::unloadVolatile() {
 	}
 	}
 
 
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
-	gfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout](){
+	gfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout, descriptorPools = descriptorPools](){
+		for (const auto pool : descriptorPools) {
+			vkDestroyDescriptorPool(device, pool, nullptr);
+		}
 		for (const auto shaderModule : shaderModules) {
 		for (const auto shaderModule : shaderModules) {
 			vkDestroyShaderModule(device, shaderModule, nullptr);
 			vkDestroyShaderModule(device, shaderModule, nullptr);
 		}
 		}
@@ -186,6 +193,8 @@ void Shader::unloadVolatile() {
 	shaderModules.clear();
 	shaderModules.clear();
 	shaderStages.clear();
 	shaderStages.clear();
 	streamBuffers.clear();
 	streamBuffers.clear();
+	descriptorPools.clear();
+	descriptorSetsVector.clear();
 }
 }
 
 
 const std::vector<VkPipelineShaderStageCreateInfo>& Shader::getShaderStages() const {
 const std::vector<VkPipelineShaderStageCreateInfo>& Shader::getShaderStages() const {
@@ -212,7 +221,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 	// detect wether a new frame has begun
 	// detect wether a new frame has begun
 	if (currentFrame != frameIndex) {
 	if (currentFrame != frameIndex) {
 		currentFrame = frameIndex;
 		currentFrame = frameIndex;
-		count = 0;
+
+		currentUsedUniformStreamBuffersCount = 0;
+		currentUsedDescriptorSetsCount = 0;
 
 
 		// we needed more memory last frame, let's collapse all buffers into a single one.
 		// we needed more memory last frame, let's collapse all buffers into a single one.
 		if (streamBuffers.at(currentFrame).size() > 1) {
 		if (streamBuffers.at(currentFrame).size() > 1) {
@@ -223,7 +234,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 			}
 			}
 			streamBuffers.at(currentFrame).clear();
 			streamBuffers.at(currentFrame).clear();
 			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, newSize));
 			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, newSize));
-		} 
+		}
 		// no collapse necessary, can just call nextFrame to reset the current (only) streambuffer
 		// no collapse necessary, can just call nextFrame to reset the current (only) streambuffer
 		else {
 		else {
 			streamBuffers.at(currentFrame).at(0)->nextFrame();
 			streamBuffers.at(currentFrame).at(0)->nextFrame();
@@ -231,14 +242,18 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 	}
 	}
 	// still the same frame
 	// still the same frame
 	else {
 	else {
-		auto usedStreamBufferMemory = count * uniformBufferSizeAligned;
+		auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
 		if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize()) {
 		if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize()) {
 			// we ran out of memory in the current frame, need to allocate more.
 			// we ran out of memory in the current frame, need to allocate more.
 			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
 			streamBuffers.at(currentFrame).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
-			count = 0;
+			currentUsedUniformStreamBuffersCount = 0;
 		}
 		}
 	}
 	}
 
 
+	if (currentUsedDescriptorSetsCount >= descriptorSetsVector.at(currentFrame).size()) {
+		descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
+	}
+
 	// additional data is always added onto the last stream buffer in the current frame
 	// additional data is always added onto the last stream buffer in the current frame
 	auto currentStreamBuffer = streamBuffers.at(currentFrame).back();
 	auto currentStreamBuffer = streamBuffers.at(currentFrame).back();
 
 
@@ -249,16 +264,18 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 
 
 	VkDescriptorBufferInfo bufferInfo{};
 	VkDescriptorBufferInfo bufferInfo{};
 	bufferInfo.buffer = (VkBuffer)currentStreamBuffer->getHandle();
 	bufferInfo.buffer = (VkBuffer)currentStreamBuffer->getHandle();
-	bufferInfo.offset = count * uniformBufferSizeAligned;
+	bufferInfo.offset = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
 	bufferInfo.range = sizeof(BuiltinUniformData);
 	bufferInfo.range = sizeof(BuiltinUniformData);
 	
 	
+	VkDescriptorSet currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
+
 	std::vector<VkWriteDescriptorSet> descriptorWrite{};
 	std::vector<VkWriteDescriptorSet> descriptorWrite{};
 
 
 	// uniform buffer update always happens
 	// uniform buffer update always happens
 	// (are there cases without ubos at all?)
 	// (are there cases without ubos at all?)
 	VkWriteDescriptorSet uniformWrite{};
 	VkWriteDescriptorSet uniformWrite{};
 	uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
 	uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-	uniformWrite.dstSet = 0;
+	uniformWrite.dstSet = currentDescriptorSet;
 	uniformWrite.dstBinding = builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->location;
 	uniformWrite.dstBinding = builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->location;
 	uniformWrite.dstArrayElement = 0;
 	uniformWrite.dstArrayElement = 0;
 	uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
 	uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -267,9 +284,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 
 
 	descriptorWrite.push_back(uniformWrite);
 	descriptorWrite.push_back(uniformWrite);
 
 
-	// Vulkan needs the image infos as a pointer.
-	// we collect them all here to properly free them up
-	// after the vulkan call.
 	std::vector<VkDescriptorImageInfo*> imageInfos;
 	std::vector<VkDescriptorImageInfo*> imageInfos;
 	
 	
 	// update everything other than uniform buffers (since that's already taken care of.
 	// update everything other than uniform buffers (since that's already taken care of.
@@ -278,7 +292,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 		if (val.baseType == UNIFORM_SAMPLER) {
 		if (val.baseType == UNIFORM_SAMPLER) {
 			VkWriteDescriptorSet write{};
 			VkWriteDescriptorSet write{};
 			write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
 			write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-			write.dstSet = 0;
+			write.dstSet = currentDescriptorSet;
 			write.dstBinding = val.location;
 			write.dstBinding = val.location;
 			write.dstArrayElement = 0;
 			write.dstArrayElement = 0;
 			write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
 			write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
@@ -295,16 +309,16 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
 		}
 		}
 	}
 	}
 
 
-	vkCmdPushDescriptorSet(
-		commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, 
-		pipelineLayout, 0, 
-		static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data());
+	vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
 
 
 	for (const auto imageInfo : imageInfos) {
 	for (const auto imageInfo : imageInfos) {
 		delete imageInfo;
 		delete imageInfo;
 	}
 	}
 
 
-	count++;
+	vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
+
+	currentUsedUniformStreamBuffersCount++;
+	currentUsedDescriptorSetsCount++;
 }
 }
 
 
 Shader::~Shader() {
 Shader::~Shader() {
@@ -614,9 +628,6 @@ void Shader::compileShaders() {
 }
 }
 
 
 void Shader::createDescriptorSetLayout() {
 void Shader::createDescriptorSetLayout() {
-	auto vgfx = (Graphics*)gfx;
-	vkCmdPushDescriptorSet = vgfx->getVkCmdPushDescriptorSetKHRFunctionPointer();
-
 	std::vector<VkDescriptorSetLayoutBinding> bindings;
 	std::vector<VkDescriptorSetLayoutBinding> bindings;
 
 
 	for (auto const& [key, val] : uniformInfos) {
 	for (auto const& [key, val] : uniformInfos) {
@@ -631,7 +642,6 @@ void Shader::createDescriptorSetLayout() {
 
 
 	VkDescriptorSetLayoutCreateInfo layoutInfo{};
 	VkDescriptorSetLayoutCreateInfo layoutInfo{};
 	layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
 	layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
-	layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
 	layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
 	layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
 	layoutInfo.pBindings = bindings.data();
 	layoutInfo.pBindings = bindings.data();
 
 
@@ -691,6 +701,49 @@ void Shader::setMainTex(graphics::Texture* texture) {
 		builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0] = texture;
 		builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0] = texture;
 	}
 	}
 }
 }
+
+VkDescriptorSet Shader::allocateDescriptorSet() {
+	if (currentAllocatedDescriptorSets >= DESCRIPTOR_POOL_SIZE) {
+		// fixme: we can optimize this, since sizes should never change for a given shader.
+		std::vector<VkDescriptorPoolSize> sizes;
+
+		for (const auto& [key, val] : uniformInfos) {
+			VkDescriptorPoolSize size{};
+			size.type = Vulkan::getDescriptorType(val.baseType);
+			size.descriptorCount = 1;
+			sizes.push_back(size);
+		}
+
+		VkDescriptorPoolCreateInfo createInfo{};
+		createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+		createInfo.maxSets = DESCRIPTOR_POOL_SIZE;
+		createInfo.poolSizeCount = static_cast<uint32_t>(sizes.size());
+		createInfo.pPoolSizes = sizes.data();
+
+		VkDescriptorPool pool;
+		if (vkCreateDescriptorPool(device, &createInfo, nullptr, &pool) != VK_SUCCESS) {
+			throw love::Exception("failed to create descriptor pool");
+		}
+		descriptorPools.push_back(pool);
+
+		currentAllocatedDescriptorSets = 0;
+	}
+
+	VkDescriptorSetAllocateInfo allocInfo{};
+	allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+	allocInfo.descriptorPool = descriptorPools.back();
+	allocInfo.descriptorSetCount = 1;
+	allocInfo.pSetLayouts = &descriptorSetLayout;
+
+	VkDescriptorSet descriptorSet;
+	if (vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet) != VK_SUCCESS) {
+		throw love::Exception("failed to allocate descriptor set");
+	}
+
+	currentAllocatedDescriptorSets++;
+
+	return descriptorSet;
+}
 } // vulkan
 } // vulkan
 } // graphics
 } // graphics
 } // love
 } // love

+ 7 - 3
src/modules/graphics/vulkan/Shader.h

@@ -70,8 +70,9 @@ private:
 		size_t baseoff, 
 		size_t baseoff, 
 		const std::string& basename);
 		const std::string& basename);
 
 
+	VkDescriptorSet allocateDescriptorSet();
+
 	VkDeviceSize uniformBufferSizeAligned;
 	VkDeviceSize uniformBufferSizeAligned;
-	PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSet;
 
 
 	VkDescriptorSetLayout descriptorSetLayout;
 	VkDescriptorSetLayout descriptorSetLayout;
 	VkPipelineLayout pipelineLayout;
 	VkPipelineLayout pipelineLayout;
@@ -80,6 +81,9 @@ private:
 	// we keep a vector of stream buffers per frame in flight
 	// we keep a vector of stream buffers per frame in flight
 	// that gets dynamically increased if more memory is needed
 	// that gets dynamically increased if more memory is needed
 	std::vector<std::vector<StreamBuffer*>> streamBuffers;
 	std::vector<std::vector<StreamBuffer*>> streamBuffers;
+	std::vector<VkDescriptorPool> descriptorPools;
+	uint32_t currentAllocatedDescriptorSets;
+	std::vector<std::vector<VkDescriptorSet>> descriptorSetsVector;
 
 
 	std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
 	std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
 	std::vector<VkShaderModule> shaderModules;
 	std::vector<VkShaderModule> shaderModules;
@@ -94,8 +98,8 @@ private:
 	size_t builtinUniformDataOffset;
 	size_t builtinUniformDataOffset;
 
 
 	uint32_t currentFrame;
 	uint32_t currentFrame;
-	// todo: give this variable a better name
-	uint32_t count;
+	uint32_t currentUsedUniformStreamBuffersCount;
+	uint32_t currentUsedDescriptorSetsCount;
 };
 };
 }
 }
 }
 }

+ 22 - 0
src/modules/graphics/vulkan/Vulkan.cpp

@@ -552,6 +552,28 @@ VkSamplerMipmapMode Vulkan::getMipMapMode(SamplerState::MipmapFilterMode mode) {
 	}
 	}
 }
 }
 
 
+
+VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type) {
+	switch (type) {
+	case graphics::Shader::UniformType::UNIFORM_FLOAT:
+	case graphics::Shader::UniformType::UNIFORM_MATRIX:
+	case graphics::Shader::UniformType::UNIFORM_INT:
+	case graphics::Shader::UniformType::UNIFORM_UINT:
+	case graphics::Shader::UniformType::UNIFORM_BOOL:
+		return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+	case graphics::Shader::UniformType::UNIFORM_SAMPLER:
+		return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+	case graphics::Shader::UniformType::UNIFORM_STORAGETEXTURE:
+		return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+	case graphics::Shader::UniformType::UNIFORM_TEXELBUFFER:
+		return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+	case graphics::Shader::UniformType::UNIFORM_STORAGEBUFFER:
+		return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+	default:
+		throw love::Exception("unkonwn uniform type");
+	}
+}
+
 void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
 void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
 	uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount) {
 	uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount) {
 	VkImageMemoryBarrier barrier{};
 	VkImageMemoryBarrier barrier{};

+ 1 - 0
src/modules/graphics/vulkan/Vulkan.h

@@ -48,6 +48,7 @@ public:
 	static VkSamplerAddressMode getWrapMode(SamplerState::WrapMode);
 	static VkSamplerAddressMode getWrapMode(SamplerState::WrapMode);
 	static VkCompareOp getCompareOp(CompareMode);
 	static VkCompareOp getCompareOp(CompareMode);
 	static VkSamplerMipmapMode getMipMapMode(SamplerState::MipmapFilterMode);
 	static VkSamplerMipmapMode getMipMapMode(SamplerState::MipmapFilterMode);
+	static VkDescriptorType getDescriptorType(graphics::Shader::UniformType);
 
 
 	static void cmdTransitionImageLayout(
 	static void cmdTransitionImageLayout(
 		VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,
 		VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,