Browse Source

vulkan: correctly order gpu commands

niki 2 years ago
parent
commit
816e3f01a2

+ 1 - 1
src/modules/graphics/vulkan/Buffer.cpp

@@ -114,7 +114,7 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
 
 
 void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
 void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
 {
 {
-	auto commandBuffer = vgfx->getReadbackCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	VkBufferCopy bufferCopy{};
 	VkBufferCopy bufferCopy{};
 	bufferCopy.srcOffset = sourceoffset;
 	bufferCopy.srcOffset = sourceoffset;

+ 106 - 181
src/modules/graphics/vulkan/Graphics.cpp

@@ -89,6 +89,9 @@ love::graphics::Buffer *Graphics::newBuffer(const love::graphics::Buffer::Settin
 
 
 void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth)
 void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth)
 {
 {
+	if (!renderPassState.active)
+		startRenderPass();
+
 	VkClearAttachment attachment{};
 	VkClearAttachment attachment{};
 
 
 	if (color.hasValue)
 	if (color.hasValue)
@@ -120,8 +123,8 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d
 
 
 	VkClearRect rect{};
 	VkClearRect rect{};
 	rect.layerCount = 1;
 	rect.layerCount = 1;
-	rect.rect.extent.width = static_cast<uint32_t>(currentViewportWidth);
-	rect.rect.extent.height = static_cast<uint32_t>(currentViewportHeight);
+	rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
+	rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
 
 
 	vkCmdClearAttachments(
 	vkCmdClearAttachments(
 		commandBuffers[currentFrame], 
 		commandBuffers[currentFrame], 
@@ -131,6 +134,9 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d
 
 
 void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
 void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
 {
 {
+	if (!renderPassState.active)
+		startRenderPass();
+
 	std::vector<VkClearAttachment> attachments;
 	std::vector<VkClearAttachment> attachments;
 	for (const auto &color : colors)
 	for (const auto &color : colors)
 	{
 	{
@@ -163,8 +169,8 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
 
 
 	VkClearRect rect{};
 	VkClearRect rect{};
 	rect.layerCount = 1;
 	rect.layerCount = 1;
-	rect.rect.extent.width = static_cast<uint32_t>(currentViewportWidth);
-	rect.rect.extent.height = static_cast<uint32_t>(currentViewportHeight);
+	rect.rect.extent.width = static_cast<uint32_t>(renderPassState.width);
+	rect.rect.extent.height = static_cast<uint32_t>(renderPassState.height);
 
 
 	vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect);
 	vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect);
 }
 }
@@ -179,11 +185,7 @@ void Graphics::submitGpuCommands(bool present)
 		vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
 		vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
 	imagesInFlight[imageIndex] = inFlightFences[currentFrame];
 	imagesInFlight[imageIndex] = inFlightFences[currentFrame];
 
 
-	std::vector<VkCommandBuffer> submitCommandbuffers = { 
-		dataTransferCommandBuffers.at(currentFrame),
-		computeCommandBuffers.at(currentFrame),
-		commandBuffers.at(currentFrame), 
-		readbackCommandBuffers.at(currentFrame)};
+	std::array<VkCommandBuffer, 1> submitCommandbuffers = { commandBuffers.at(currentFrame) };
 
 
 	VkSubmitInfo submitInfo{};
 	VkSubmitInfo submitInfo{};
 	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
 	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -339,8 +341,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
 	restoreState(states.back());
 	restoreState(states.back());
 
 
 	setViewportSize(width, height, pixelwidth, pixelheight);
 	setViewportSize(width, height, pixelwidth, pixelheight);
-	currentViewportWidth = 1.0f;
-	currentViewportHeight = 1.0f;
 
 
 	Vulkan::resetShaderSwitches();
 	Vulkan::resetShaderSwitches();
 
 
@@ -715,11 +715,14 @@ graphics::StreamBuffer *Graphics::newStreamBuffer(BufferUsage type, size_t size)
 
 
 bool Graphics::dispatch(int x, int y, int z)
 bool Graphics::dispatch(int x, int y, int z)
 {
 {
-	vkCmdBindPipeline(computeCommandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
+	if (renderPassState.active)
+		endRenderPass();
+
+	vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
 
 
-	computeShader->cmdPushDescriptorSets(computeCommandBuffers.at(currentFrame), currentFrame, VK_PIPELINE_BIND_POINT_COMPUTE);
+	computeShader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), currentFrame, VK_PIPELINE_BIND_POINT_COMPUTE);
 
 
-	vkCmdDispatch(computeCommandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
+	vkCmdDispatch(commandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
 
 
 	return true;
 	return true;
 }
 }
@@ -732,13 +735,14 @@ Matrix4 Graphics::computeDeviceProjection(const Matrix4 &projection, bool render
 
 
 void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
 void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
 {
 {
-	endRenderPass();
+	if (renderPassState.active)
+		endRenderPass();
 
 
 	bool isWindow = rts.getFirstTarget().texture == nullptr;
 	bool isWindow = rts.getFirstTarget().texture == nullptr;
 	if (isWindow)
 	if (isWindow)
-		startDefaultRenderPass();
+		setDefaultRenderPass();
 	else
 	else
-		startRenderPass(rts, pixelw, pixelh, hasSRGBtexture);
+		setRenderPass(rts, pixelw, pixelh, hasSRGBtexture);
 }
 }
 
 
 // END IMPLEMENTATION OVERRIDDEN FUNCTIONS
 // END IMPLEMENTATION OVERRIDDEN FUNCTIONS
@@ -753,8 +757,8 @@ void Graphics::initDynamicState()
 	VkViewport viewport{};
 	VkViewport viewport{};
 	viewport.x = 0.0f;
 	viewport.x = 0.0f;
 	viewport.y = 0.0f;
 	viewport.y = 0.0f;
-	viewport.width = swapChainExtent.width;
-	viewport.height = swapChainExtent.height;
+	viewport.width = static_cast<float>(swapChainExtent.width);
+	viewport.height = static_cast<float>(swapChainExtent.height);
 	viewport.minDepth = 0.0f;
 	viewport.minDepth = 0.0f;
 	viewport.maxDepth = 1.0f;
 	viewport.maxDepth = 1.0f;
 
 
@@ -790,7 +794,8 @@ void Graphics::beginFrame()
 	while (true)
 	while (true)
 	{
 	{
 		VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
 		VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
-		if (result == VK_ERROR_OUT_OF_DATE_KHR) {
+		if (result == VK_ERROR_OUT_OF_DATE_KHR)
+		{
 			recreateSwapChain();
 			recreateSwapChain();
 			continue;
 			continue;
 		}
 		}
@@ -802,16 +807,22 @@ void Graphics::beginFrame()
 
 
 	imageRequested = true;
 	imageRequested = true;
 
 
-	for (auto& readbackCallback : readbackCallbacks.at(currentFrame))
+	for (auto &readbackCallback : readbackCallbacks.at(currentFrame))
 		readbackCallback();
 		readbackCallback();
 	readbackCallbacks.at(currentFrame).clear();
 	readbackCallbacks.at(currentFrame).clear();
 
 
-	for (auto& cleanUpFn : cleanUpFunctions.at(currentFrame))
+	for (auto &cleanUpFn : cleanUpFunctions.at(currentFrame))
 		cleanUpFn();
 		cleanUpFn();
 	cleanUpFunctions.at(currentFrame).clear();
 	cleanUpFunctions.at(currentFrame).clear();
 
 
 	startRecordingGraphicsCommands(true);
 	startRecordingGraphicsCommands(true);
 
 
+	Vulkan::cmdTransitionImageLayout(
+		commandBuffers.at(currentFrame),
+		swapChainImages[imageIndex],
+		VK_IMAGE_LAYOUT_UNDEFINED,
+		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
 	Vulkan::resetShaderSwitches();
 	Vulkan::resetShaderSwitches();
 }
 }
 
 
@@ -824,35 +835,25 @@ void Graphics::startRecordingGraphicsCommands(bool newFrame)
 
 
 	if (vkBeginCommandBuffer(commandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
 	if (vkBeginCommandBuffer(commandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
 		throw love::Exception("failed to begin recording command buffer");
 		throw love::Exception("failed to begin recording command buffer");
-	if (vkBeginCommandBuffer(dataTransferCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
-		throw love::Exception("failed to begin recording data transfer command buffer");
-	if (vkBeginCommandBuffer(readbackCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
-		throw love::Exception("failed to begin recording readback command buffer");
-	if (vkBeginCommandBuffer(computeCommandBuffers.at(currentFrame), &beginInfo) != VK_SUCCESS)
-		throw love::Exception("failed to begin recording compute command buffer");
 
 
 	initDynamicState();
 	initDynamicState();
 
 
-	if (newFrame)
-		Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-	startDefaultRenderPass();
+	setDefaultRenderPass();
 }
 }
 
 
 void Graphics::endRecordingGraphicsCommands(bool present) {
 void Graphics::endRecordingGraphicsCommands(bool present) {
-	endRenderPass();
+	if (renderPassState.active)
+		endRenderPass();
 
 
 	if (present)
 	if (present)
-		Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), swapChainImages[imageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
+		Vulkan::cmdTransitionImageLayout(
+			commandBuffers.at(currentFrame), 
+			swapChainImages[imageIndex], 
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+			VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
 
 
 	if (vkEndCommandBuffer(commandBuffers.at(currentFrame)) != VK_SUCCESS)
 	if (vkEndCommandBuffer(commandBuffers.at(currentFrame)) != VK_SUCCESS)
 		throw love::Exception("failed to record command buffer");
 		throw love::Exception("failed to record command buffer");
-	if (vkEndCommandBuffer(dataTransferCommandBuffers.at(currentFrame)) != VK_SUCCESS)
-		throw love::Exception("failed to record data transfer command buffer");
-	if (vkEndCommandBuffer(readbackCommandBuffers.at(currentFrame)) != VK_SUCCESS)
-		throw love::Exception("failed to record read back command buffer");
-	if (vkEndCommandBuffer(computeCommandBuffers.at(currentFrame)) != VK_SUCCESS)
-		throw love::Exception("failed to record compute command buffer");
 }
 }
 
 
 void Graphics::updatedBatchedDrawBuffers()
 void Graphics::updatedBatchedDrawBuffers()
@@ -880,52 +881,12 @@ graphics::Texture *Graphics::getDefaultTexture() const
 	return dynamic_cast<graphics::Texture*>(standardTexture.get());
 	return dynamic_cast<graphics::Texture*>(standardTexture.get());
 }
 }
 
 
-VkCommandBuffer Graphics::getDataTransferCommandBuffer()
-{
-	return dataTransferCommandBuffers.at(currentFrame);
-}
-
-VkCommandBuffer Graphics::getReadbackCommandBuffer()
-{
-	return readbackCommandBuffers.at(currentFrame);
-}
-
-void Graphics::oneTimeCommand(std::function<void(VkCommandBuffer)> cmd)
+VkCommandBuffer Graphics::getCommandBufferForDataTransfer()
 {
 {
-	VkCommandBufferAllocateInfo allocInfo{};
-	allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-	allocInfo.commandPool = commandPool;
-	allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-	allocInfo.commandBufferCount = 1;
-
-	VkCommandBuffer commandBuffer;
-	if (vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS)
-		throw love::Exception("failed to allocate one time command buffer");
-
-	VkCommandBufferBeginInfo beginInfo{};
-	beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-	beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-
-	if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS)
-		throw love::Exception("failed to start recording one time command buffer");
-
-	cmd(commandBuffer);
-
-	if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
-		throw love::Exception("failed to end recording one time command buffer");
+	if (renderPassState.active)
+		endRenderPass();
 
 
-	VkSubmitInfo submitInfo{};
-	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-	submitInfo.commandBufferCount = 1;
-	submitInfo.pCommandBuffers = &commandBuffer;
-
-	if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
-		throw love::Exception("failed to submit to queue");
-	
-	if (vkQueueWaitIdle(graphicsQueue) != VK_SUCCESS)
-		throw love::Exception("failed to wait for queue idle");
-
-	vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
+	return commandBuffers.at(currentFrame);
 }
 }
 
 
 void Graphics::queueCleanUp(std::function<void()> cleanUp)
 void Graphics::queueCleanUp(std::function<void()> cleanUp)
@@ -1381,7 +1342,7 @@ void Graphics::initVMA()
 void Graphics::createSurface()
 void Graphics::createSurface()
 {
 {
 	auto window = Module::getInstance<love::window::Window>(M_WINDOW);
 	auto window = Module::getInstance<love::window::Window>(M_WINDOW);
-	const void* handle = window->getHandle();
+	const void *handle = window->getHandle();
 	if (SDL_Vulkan_CreateSurface((SDL_Window*)handle, instance, &surface) != SDL_TRUE)
 	if (SDL_Vulkan_CreateSurface((SDL_Window*)handle, instance, &surface) != SDL_TRUE)
 		throw love::Exception("failed to create window surface");
 		throw love::Exception("failed to create window surface");
 }
 }
@@ -1606,7 +1567,6 @@ void Graphics::createDefaultRenderPass()
 {
 {
 	RenderPassConfiguration renderPassConfiguration{};
 	RenderPassConfiguration renderPassConfiguration{};
 	renderPassConfiguration.colorFormats.push_back(swapChainImageFormat);
 	renderPassConfiguration.colorFormats.push_back(swapChainImageFormat);
-	renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 	renderPassConfiguration.staticData.msaaSamples = msaaSamples;
 	renderPassConfiguration.staticData.msaaSamples = msaaSamples;
 	renderPassConfiguration.staticData.depthFormat = findDepthFormat();
 	renderPassConfiguration.staticData.depthFormat = findDepthFormat();
 	if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
 	if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
@@ -1704,7 +1664,7 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
 	std::vector<VkAttachmentReference> colorAttachmentRefs;
 	std::vector<VkAttachmentReference> colorAttachmentRefs;
 
 
 	uint32_t attachment = 0;
 	uint32_t attachment = 0;
-	for (const auto& colorFormat : configuration.colorFormats)
+	for (const auto &colorFormat : configuration.colorFormats)
 	{
 	{
 		VkAttachmentReference reference{};
 		VkAttachmentReference reference{};
 		reference.attachment = attachment++;
 		reference.attachment = attachment++;
@@ -1714,14 +1674,11 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
 		VkAttachmentDescription colorDescription{};
 		VkAttachmentDescription colorDescription{};
 		colorDescription.format = colorFormat;
 		colorDescription.format = colorFormat;
 		colorDescription.samples = configuration.staticData.msaaSamples;
 		colorDescription.samples = configuration.staticData.msaaSamples;
-        if (configuration.staticData.initialColorImageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
-		    colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
-        else
-            colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+		colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
 		colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
 		colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
 		colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 		colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 		colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
 		colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-		colorDescription.initialLayout = configuration.staticData.initialColorImageLayout;
+		colorDescription.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 		colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 		colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 		attachments.push_back(colorDescription);
 		attachments.push_back(colorDescription);
 	}
 	}
@@ -1880,16 +1837,19 @@ void Graphics::createVulkanVertexFormat(
 
 
 void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType primitiveType, CullMode cullmode)
 void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType primitiveType, CullMode cullmode)
 {
 {
+	if (!renderPassState.active)
+		startRenderPass();
+
 	GraphicsPipelineConfiguration configuration{};
 	GraphicsPipelineConfiguration configuration{};
 
 
-    configuration.renderPass = currentRenderPass;
+    configuration.renderPass = renderPassState.renderPass;
 	configuration.vertexAttributes = attributes;
 	configuration.vertexAttributes = attributes;
 	configuration.shader = (Shader*)Shader::current;
 	configuration.shader = (Shader*)Shader::current;
 	configuration.wireFrame = states.back().wireframe;
 	configuration.wireFrame = states.back().wireframe;
 	configuration.blendState = states.back().blend;
 	configuration.blendState = states.back().blend;
 	configuration.colorChannelMask = states.back().colorMask;
 	configuration.colorChannelMask = states.back().colorMask;
-	configuration.msaaSamples = currentMsaaSamples;
-	configuration.numColorAttachments = currentNumColorAttachments;
+	configuration.msaaSamples = renderPassState.msaa;
+	configuration.numColorAttachments = renderPassState.numColorAttachments;
 	configuration.primitiveType = primitiveType;
 	configuration.primitiveType = primitiveType;
 
 
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
@@ -1933,37 +1893,35 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
 	vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
 	vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
 }
 }
 
 
-void Graphics::startDefaultRenderPass()
+void Graphics::setDefaultRenderPass()
 {
 {
-	VkRenderPassBeginInfo renderPassInfo{};
-	renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-	renderPassInfo.renderPass = defaultRenderPass;
-	renderPassInfo.framebuffer = defaultFramebuffers[imageIndex];
-	renderPassInfo.renderArea.offset = { 0, 0 };
-	renderPassInfo.renderArea.extent = swapChainExtent;
-
-	vkCmdBeginRenderPass(commandBuffers.at(currentFrame), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
+	renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+	renderPassState.beginInfo.renderPass = defaultRenderPass;
+	renderPassState.beginInfo.framebuffer = defaultFramebuffers[imageIndex];
+	renderPassState.beginInfo.renderArea.offset = { 0, 0 };
+	renderPassState.beginInfo.renderArea.extent = swapChainExtent;
+	renderPassState.beginInfo.clearValueCount = 0;
 
 
-	currentRenderPass = defaultRenderPass;
-	currentGraphicsPipeline = VK_NULL_HANDLE;
-	postRenderPass = std::nullopt;
-	currentViewportWidth = (float)swapChainExtent.width;
-	currentViewportHeight = (float)swapChainExtent.height;
-	currentMsaaSamples = msaaSamples;
-	currentNumColorAttachments = 1;
+	renderPassState.renderPass = defaultRenderPass;
+	renderPassState.pipeline = VK_NULL_HANDLE;
+	renderPassState.width = static_cast<float>(swapChainExtent.width);
+	renderPassState.height = static_cast<float>(swapChainExtent.height);
+	renderPassState.msaa = msaaSamples;
+	renderPassState.numColorAttachments = 1;
+	renderPassState.transitionImages.clear();
 
 
 	VkViewport viewport{};
 	VkViewport viewport{};
 	viewport.x = 0.0f;
 	viewport.x = 0.0f;
 	viewport.y = 0.0f;
 	viewport.y = 0.0f;
-	viewport.width = currentViewportWidth;
-	viewport.height = currentViewportHeight;
+	viewport.width = renderPassState.width;
+	viewport.height = renderPassState.height;
 	viewport.minDepth = 0.0f;
 	viewport.minDepth = 0.0f;
 	viewport.maxDepth = 1.0f;
 	viewport.maxDepth = 1.0f;
 
 
 	vkCmdSetViewport(commandBuffers.at(currentFrame), 0, 1, &viewport);
 	vkCmdSetViewport(commandBuffers.at(currentFrame), 0, 1, &viewport);
 }
 }
 
 
-void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
+void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
 {
 {
 	VkViewport viewport{};
 	VkViewport viewport{};
 	viewport.x = 0.0f;
 	viewport.x = 0.0f;
@@ -1980,7 +1938,6 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
 	// fixme: hasSRGBtexture
 	// fixme: hasSRGBtexture
 	// fixme: msaaSamples
 	// fixme: msaaSamples
 	RenderPassConfiguration renderPassConfiguration{};
 	RenderPassConfiguration renderPassConfiguration{};
-	renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 	for (const auto &color : rts.colors)
 	for (const auto &color : rts.colors)
 	{
 	{
 		// fixme: use mipmap and slice.
 		// fixme: use mipmap and slice.
@@ -2009,13 +1966,12 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
 
 
 	FramebufferConfiguration configuration{};
 	FramebufferConfiguration configuration{};
 
 
-	std::vector<VkImage> transitionBackImages;
+	std::vector<VkImage> transitionImages;
 
 
 	for (const auto& color : rts.colors)
 	for (const auto& color : rts.colors)
 	{
 	{
 		configuration.colorViews.push_back((VkImageView)color.texture->getRenderTargetHandle());
 		configuration.colorViews.push_back((VkImageView)color.texture->getRenderTargetHandle());
-		Vulkan::cmdTransitionImageLayout(currentCommandBuffer, (VkImage)color.texture->getHandle(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-		transitionBackImages.push_back((VkImage) color.texture->getHandle());
+		transitionImages.push_back((VkImage) color.texture->getHandle());
 	}
 	}
 	if (rts.depthStencil.texture != nullptr)
 	if (rts.depthStencil.texture != nullptr)
 		// fixme: layout transition of depth stencil image?
 		// fixme: layout transition of depth stencil image?
@@ -2026,39 +1982,41 @@ void Graphics::startRenderPass(const RenderTargets &rts, int pixelw, int pixelh,
 	configuration.staticData.height = static_cast<uint32_t>(pixelh);
 	configuration.staticData.height = static_cast<uint32_t>(pixelh);
 	VkFramebuffer framebuffer = getFramebuffer(configuration);
 	VkFramebuffer framebuffer = getFramebuffer(configuration);
 
 
-    VkRenderPassBeginInfo renderPassInfo{};
-    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-    renderPassInfo.renderPass = renderPass;
-	renderPassInfo.framebuffer = framebuffer;
-    renderPassInfo.renderArea.offset = {0, 0};
-    renderPassInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
-    renderPassInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
-
-    vkCmdBeginRenderPass(currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
-
-    currentRenderPass = renderPass;
-	currentGraphicsPipeline = VK_NULL_HANDLE;
-	currentViewportWidth = (float)pixelw;
-	currentViewportHeight = (float)pixelh;
-	currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT;
-	currentNumColorAttachments = static_cast<uint32_t>(rts.colors.size());
-
-	postRenderPass = [=]() {
-		for (const auto& image : transitionBackImages)
-			Vulkan::cmdTransitionImageLayout(currentCommandBuffer, image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-	};
+	renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+	renderPassState.beginInfo.renderPass = renderPass;
+	renderPassState.beginInfo.framebuffer = framebuffer;
+	renderPassState.beginInfo.renderArea.offset = {0, 0};
+	renderPassState.beginInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
+	renderPassState.beginInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
+	renderPassState.beginInfo.clearValueCount = 0;
+
+	renderPassState.renderPass = renderPass;
+	renderPassState.pipeline = VK_NULL_HANDLE;
+	renderPassState.width = static_cast<float>(pixelw);
+	renderPassState.height = static_cast<float>(pixelh);
+	renderPassState.msaa = VK_SAMPLE_COUNT_1_BIT;
+	renderPassState.numColorAttachments = static_cast<uint32_t>(rts.colors.size());
+	renderPassState.transitionImages = std::move(transitionImages);
+}
+
+void Graphics::startRenderPass()
+{
+	renderPassState.active = true;
+
+	for (const auto& image : renderPassState.transitionImages)
+		Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+	vkCmdBeginRenderPass(commandBuffers.at(currentFrame), &renderPassState.beginInfo, VK_SUBPASS_CONTENTS_INLINE);
 }
 }
 
 
 void Graphics::endRenderPass()
 void Graphics::endRenderPass()
 {
 {
+	renderPassState.active = false;
+
 	vkCmdEndRenderPass(commandBuffers.at(currentFrame));
 	vkCmdEndRenderPass(commandBuffers.at(currentFrame));
-    currentRenderPass = VK_NULL_HANDLE;
 
 
-	if (postRenderPass)
-	{
-		postRenderPass.value()();
-		postRenderPass = std::nullopt;
-	}
+	for (const auto &image : renderPassState.transitionImages)
+		Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 }
 }
 
 
 VkSampler Graphics::createSampler(const SamplerState &samplerState)
 VkSampler Graphics::createSampler(const SamplerState &samplerState)
@@ -2287,10 +2245,10 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration
 	auto it = graphicsPipelines.find(configuration);
 	auto it = graphicsPipelines.find(configuration);
 	if (it != graphicsPipelines.end())
 	if (it != graphicsPipelines.end())
 	{
 	{
-		if (it->second != currentGraphicsPipeline)
+		if (it->second != renderPassState.pipeline)
 		{
 		{
 			vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second);
 			vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, it->second);
-			currentGraphicsPipeline = it->second;
+			renderPassState.pipeline = it->second;
 		}
 		}
 	}
 	}
 	else
 	else
@@ -2298,7 +2256,7 @@ void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration
 		VkPipeline pipeline = createGraphicsPipeline(configuration);
 		VkPipeline pipeline = createGraphicsPipeline(configuration);
 		graphicsPipelines.insert({configuration, pipeline});
 		graphicsPipelines.insert({configuration, pipeline});
 		vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
 		vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-		currentGraphicsPipeline = pipeline;
+		renderPassState.pipeline = pipeline;
 	}
 	}
 }
 }
 
 
@@ -2459,9 +2417,6 @@ void Graphics::createCommandPool()
 void Graphics::createCommandBuffers()
 void Graphics::createCommandBuffers()
 {
 {
 	commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
 	commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
-	dataTransferCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
-	readbackCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
-	computeCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
 
 
 	VkCommandBufferAllocateInfo allocInfo{};
 	VkCommandBufferAllocateInfo allocInfo{};
 	allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
 	allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
@@ -2471,33 +2426,6 @@ void Graphics::createCommandBuffers()
 
 
 	if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS)
 	if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS)
 		throw love::Exception("failed to allocate command buffers");
 		throw love::Exception("failed to allocate command buffers");
-
-	VkCommandBufferAllocateInfo dataTransferAllocInfo{};
-	dataTransferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-	dataTransferAllocInfo.commandPool = commandPool;
-	dataTransferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-	dataTransferAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
-
-	if (vkAllocateCommandBuffers(device, &dataTransferAllocInfo, dataTransferCommandBuffers.data()) != VK_SUCCESS)
-		throw love::Exception("failed to allocate data transfer command buffers");
-
-	VkCommandBufferAllocateInfo readbackAllocInfo{};
-	readbackAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-	readbackAllocInfo.commandPool = commandPool;
-	readbackAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-	readbackAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
-
-	if (vkAllocateCommandBuffers(device, &readbackAllocInfo, readbackCommandBuffers.data()) != VK_SUCCESS)
-		throw love::Exception("failed to allocate readback command buffers");
-
-	VkCommandBufferAllocateInfo commandAllocInfo{};
-	commandAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-	commandAllocInfo.commandPool = commandPool;
-	commandAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-	commandAllocInfo.commandBufferCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
-
-	if (vkAllocateCommandBuffers(device, &commandAllocInfo, computeCommandBuffers.data()) != VK_SUCCESS)
-		throw love::Exception("failed to allocate compute command buffers");
 }
 }
 
 
 void Graphics::createSyncObjects()
 void Graphics::createSyncObjects()
@@ -2548,9 +2476,6 @@ void Graphics::cleanup()
 	}
 	}
 
 
 	vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, commandBuffers.data());
 	vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, commandBuffers.data());
-	vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, dataTransferCommandBuffers.data());
-	vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, readbackCommandBuffers.data());
-	vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, computeCommandBuffers.data());
 
 
 	for (auto const &p : samplers)
 	for (auto const &p : samplers)
 		vkDestroySampler(device, p.second, nullptr);
 		vkDestroySampler(device, p.second, nullptr);

+ 18 - 19
src/modules/graphics/vulkan/Graphics.h

@@ -32,7 +32,6 @@ struct RenderPassConfiguration
 
 
 	struct StaticRenderPassConfiguration
 	struct StaticRenderPassConfiguration
 	{
 	{
-		VkImageLayout initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 		VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
 		VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
 		VkFormat depthFormat = VK_FORMAT_UNDEFINED;
 		VkFormat depthFormat = VK_FORMAT_UNDEFINED;
 		bool resolve = false;
 		bool resolve = false;
@@ -204,6 +203,19 @@ struct SwapChainSupportDetails
 	std::vector<VkPresentModeKHR> presentModes;
 	std::vector<VkPresentModeKHR> presentModes;
 };
 };
 
 
+struct RenderpassState
+{
+	bool active = false;
+	VkRenderPassBeginInfo beginInfo{};
+	VkRenderPass renderPass = VK_NULL_HANDLE;
+	VkPipeline pipeline = VK_NULL_HANDLE;
+	std::vector<VkImage> transitionImages;
+	uint32_t numColorAttachments = 0;
+	float width = 0.0f;
+	float height = 0.0f;
+	VkSampleCountFlagBits msaa = VK_SAMPLE_COUNT_1_BIT;
+};
+
 class Graphics final : public love::graphics::Graphics
 class Graphics final : public love::graphics::Graphics
 {
 {
 public:
 public:
@@ -261,10 +273,7 @@ public:
 	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
 	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
 	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
 	graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
 
 
-	VkCommandBuffer getDataTransferCommandBuffer();
-	VkCommandBuffer getReadbackCommandBuffer();
-
-	void oneTimeCommand(std::function<void(VkCommandBuffer)> cmd);
+	VkCommandBuffer getCommandBufferForDataTransfer();
 
 
 	void queueCleanUp(std::function<void()> cleanUp);
 	void queueCleanUp(std::function<void()> cleanUp);
 	void addReadbackCallback(std::function<void()> callback);
 	void addReadbackCallback(std::function<void()> callback);
@@ -339,8 +348,9 @@ private:
 		std::vector<VkVertexInputBindingDescription> &bindingDescriptions, 
 		std::vector<VkVertexInputBindingDescription> &bindingDescriptions, 
 		std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
 		std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
 	void prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType, CullMode);
 	void prepareDraw(const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture, PrimitiveType, CullMode);
-	void startRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
-	void startDefaultRenderPass();
+	void setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
+	void setDefaultRenderPass();
+	void startRenderPass();
 	void endRenderPass();
 	void endRenderPass();
 	VkSampler createSampler(const SamplerState&);
 	VkSampler createSampler(const SamplerState&);
 
 
@@ -361,8 +371,6 @@ private:
 	VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
 	VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
 	VkExtent2D swapChainExtent = VkExtent2D();
 	VkExtent2D swapChainExtent = VkExtent2D();
 	std::vector<VkImageView> swapChainImageViews;
 	std::vector<VkImageView> swapChainImageViews;
-	VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
-    VkRenderPass currentRenderPass = VK_NULL_HANDLE;
 	VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
 	VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
 	VkImage colorImage = VK_NULL_HANDLE;
 	VkImage colorImage = VK_NULL_HANDLE;
 	VkImageView colorImageView = VK_NULL_HANDLE;
 	VkImageView colorImageView = VK_NULL_HANDLE;
@@ -377,10 +385,7 @@ private:
 	std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
 	std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
 	std::unordered_map<SamplerState, VkSampler, SamplerStateHasher> samplers;
 	std::unordered_map<SamplerState, VkSampler, SamplerStateHasher> samplers;
 	VkCommandPool commandPool = VK_NULL_HANDLE;
 	VkCommandPool commandPool = VK_NULL_HANDLE;
-	std::vector<VkCommandBuffer> dataTransferCommandBuffers;
-	std::vector<VkCommandBuffer> computeCommandBuffers;
 	std::vector<VkCommandBuffer> commandBuffers;
 	std::vector<VkCommandBuffer> commandBuffers;
-	std::vector<VkCommandBuffer> readbackCommandBuffers;
 	Shader* computeShader = nullptr;
 	Shader* computeShader = nullptr;
 	std::vector<VkSemaphore> imageAvailableSemaphores;
 	std::vector<VkSemaphore> imageAvailableSemaphores;
 	std::vector<VkSemaphore> renderFinishedSemaphores;
 	std::vector<VkSemaphore> renderFinishedSemaphores;
@@ -400,13 +405,7 @@ private:
 	// just like batchedDrawBuffers we need a vector for each frame in flight.
 	// just like batchedDrawBuffers we need a vector for each frame in flight.
 	std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
 	std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
 	std::vector<std::vector<std::function<void()>>> readbackCallbacks;
 	std::vector<std::vector<std::function<void()>>> readbackCallbacks;
-
-	// render pass variables.
-	std::optional<std::function<void()>> postRenderPass;
-	uint32_t currentNumColorAttachments = 0;
-	float currentViewportWidth = 0;
-	float currentViewportHeight = 0;
-	VkSampleCountFlagBits currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT;
+	RenderpassState renderPassState;
 };
 };
 
 
 } // vulkan
 } // vulkan

+ 10 - 12
src/modules/graphics/vulkan/Texture.cpp

@@ -77,19 +77,17 @@ bool Texture::loadVolatile()
 	if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
 	if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
 		throw love::Exception("failed to create image");
 		throw love::Exception("failed to create image");
 
 
-	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	if (computeWrite)
 	if (computeWrite)
 		imageLayout = VK_IMAGE_LAYOUT_GENERAL;
 		imageLayout = VK_IMAGE_LAYOUT_GENERAL;
 	else
 	else
 		imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
 		imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
 
 
-	vgfx->oneTimeCommand([=](VkCommandBuffer commandBuffer) {
-		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
-			VK_IMAGE_LAYOUT_UNDEFINED, imageLayout,
-			0, VK_REMAINING_MIP_LEVELS,
-			0, VK_REMAINING_ARRAY_LAYERS);
-	});
+	Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage,
+		VK_IMAGE_LAYOUT_UNDEFINED, imageLayout,
+		0, VK_REMAINING_MIP_LEVELS,
+		0, VK_REMAINING_ARRAY_LAYERS);
 
 
 	bool hasdata = slices.get(0, 0) != nullptr;
 	bool hasdata = slices.get(0, 0) != nullptr;
 
 
@@ -200,7 +198,7 @@ void Texture::createTextureImageView()
 
 
 void Texture::clear()
 void Texture::clear()
 {
 {
-	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	auto clearColor = getClearValue();
 	auto clearColor = getClearValue();
 
 
@@ -258,7 +256,7 @@ VkClearColorValue Texture::getClearValue()
 
 
 void Texture::generateMipmapsInternal()
 void Texture::generateMipmapsInternal()
 {
 {
-	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
 	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, 
 		Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, 
@@ -374,7 +372,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
 		static_cast<uint32_t>(r.h), 1
 		static_cast<uint32_t>(r.h), 1
 	};
 	};
 
 
-	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 
 
 	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
 	if (imageLayout != VK_IMAGE_LAYOUT_GENERAL)
@@ -414,7 +412,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
 
 
 void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
 void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
 {
 {
-	auto commandBuffer = vgfx->getDataTransferCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	VkImageSubresourceLayers layers{};
 	VkImageSubresourceLayers layers{};
 	layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
 	layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@@ -444,7 +442,7 @@ void Texture::copyFromBuffer(graphics::Buffer *source, size_t sourceoffset, int
 
 
 void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size)
 void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size)
 {
 {
-	auto commandBuffer = vgfx->getReadbackCommandBuffer();
+	auto commandBuffer = vgfx->getCommandBufferForDataTransfer();
 
 
 	VkImageSubresourceLayers layers{};
 	VkImageSubresourceLayers layers{};
 	layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
 	layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;