Browse Source

vulkan: default renderpass and framebuffers
Since these objects basically get used every frame
we shouldn't store them in a hashmap with potentially
worse performance.
Instead storing them in member variables should be better.

niki 3 years ago
parent
commit
77f75648e8

+ 53 - 35
src/modules/graphics/vulkan/Graphics.cpp

@@ -21,15 +21,6 @@
 namespace love {
 namespace love {
 namespace graphics {
 namespace graphics {
 namespace vulkan {
 namespace vulkan {
-static VkIndexType getVulkanIndexBufferType(IndexDataType type) {
-	switch (type) {
-	case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
-	case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
-	default:
-		throw love::Exception("unknown Index Data type");
-	}
-}
-
 const std::vector<const char*> validationLayers = {
 const std::vector<const char*> validationLayers = {
 	"VK_LAYER_KHRONOS_validation"
 	"VK_LAYER_KHRONOS_validation"
 };
 };
@@ -236,6 +227,8 @@ bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int
 	createSyncObjects();
 	createSyncObjects();
 	createColorResources();
 	createColorResources();
 	createDepthResources();
 	createDepthResources();
+	createDefaultRenderPass();
+	createDefaultFramebuffers();
 	createCommandPool();
 	createCommandPool();
 	createCommandBuffers();
 	createCommandBuffers();
 	startRecordingGraphicsCommands();
 	startRecordingGraphicsCommands();
@@ -408,7 +401,7 @@ void Graphics::draw(const DrawCommand& cmd) {
 void Graphics::draw(const DrawIndexedCommand& cmd) {
 void Graphics::draw(const DrawIndexedCommand& cmd) {
 	prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
 	prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
 
 
-	vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType));
+	vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), Vulkan::getVulkanIndexBufferType(cmd.indexType));
 	vkCmdDrawIndexed(commandBuffers.at(currentFrame), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
 	vkCmdDrawIndexed(commandBuffers.at(currentFrame), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
 }
 }
 
 
@@ -418,7 +411,7 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes& attribute
 
 
 	prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK);
 	prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK);
 
 
-	vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
+	vkCmdBindIndexBuffer(commandBuffers.at(currentFrame), (VkBuffer)quadIndexBuffer->getHandle(), 0, Vulkan::getVulkanIndexBufferType(INDEX_UINT16));
 
 
 	int baseVertex = start * 4;
 	int baseVertex = start * 4;
 
 
@@ -431,6 +424,8 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes& attribute
 }
 }
 
 
 void Graphics::setColor(Colorf c) {
 void Graphics::setColor(Colorf c) {
+	flushBatchedDraws();
+
 	c.r = std::min(std::max(c.r, 0.0f), 1.0f);
 	c.r = std::min(std::max(c.r, 0.0f), 1.0f);
 	c.g = std::min(std::max(c.g, 0.0f), 1.0f);
 	c.g = std::min(std::max(c.g, 0.0f), 1.0f);
 	c.b = std::min(std::max(c.b, 0.0f), 1.0f);
 	c.b = std::min(std::max(c.b, 0.0f), 1.0f);
@@ -1249,6 +1244,25 @@ void Graphics::createImageViews() {
 	}
 	}
 }
 }
 
 
+void Graphics::createDefaultRenderPass() {
+	RenderPassConfiguration renderPassConfiguration{};
+	renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
+	defaultRenderPass = createRenderPass(renderPassConfiguration);
+}
+
+void Graphics::createDefaultFramebuffers() {
+	defaultFramebuffers.clear();
+
+	for (const auto view : swapChainImageViews) {
+		FramebufferConfiguration configuration{};
+		configuration.renderPass = defaultRenderPass;
+		configuration.width = swapChainExtent.width;
+		configuration.height = swapChainExtent.height;
+		configuration.imageView = view;
+		defaultFramebuffers.push_back(createFramebuffer(configuration));
+	}
+}
+
 VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
 VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
 	std::array<VkImageView, 3> attachments = {
 	std::array<VkImageView, 3> attachments = {
 		colorImageView,
 		colorImageView,
@@ -1494,41 +1508,39 @@ void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindi
 }
 }
 
 
 void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
 void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
-    RenderPassConfiguration renderPassConfiguration{};
+    VkRenderPass renderPass;
+	VkFramebuffer framebuffer;
 
 
-	if (texture) {
-        renderPassConfiguration.frameBufferFormat = Vulkan::getTextureFormat(texture->getPixelFormat()).internalFormat;
-		renderTargetTexture = texture;
-	} else {
-        renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
+	if (texture == nullptr) {
 		renderTargetTexture = nullptr;
 		renderTargetTexture = nullptr;
-	}
+		renderPass = defaultRenderPass;
+		framebuffer = defaultFramebuffers[imageIndex];
+	} else {
+		RenderPassConfiguration renderPassConfiguration{};
 
 
-    VkRenderPass renderPass;
+		renderPassConfiguration.frameBufferFormat = Vulkan::getTextureFormat(texture->getPixelFormat()).internalFormat;
+		renderTargetTexture = texture;
 
 
-    auto it = renderPasses.find(renderPassConfiguration);
-    if (it != renderPasses.end()) {
-        renderPass = it->second;
-    } else {
-        renderPass = createRenderPass(renderPassConfiguration);
-        renderPasses[renderPassConfiguration] = renderPass;
-    }
+		auto it = renderPasses.find(renderPassConfiguration);
+		if (it != renderPasses.end()) {
+			renderPass = it->second;
+		} else {
+			renderPass = createRenderPass(renderPassConfiguration);
+			renderPasses[renderPassConfiguration] = renderPass;
+		}
 
 
-	FramebufferConfiguration configuration{};
-	configuration.renderPass = renderPass;
-	if (renderTargetTexture == nullptr) {
-		configuration.imageView = swapChainImageViews.at(imageIndex);
-	}
-	else {
+		FramebufferConfiguration configuration{};
+		configuration.renderPass = renderPass;
 		configuration.imageView = (VkImageView)texture->getRenderTargetHandle();
 		configuration.imageView = (VkImageView)texture->getRenderTargetHandle();
+		configuration.width = w;
+		configuration.height = h;
+		framebuffer = getFramebuffer(configuration);
 	}
 	}
-	configuration.width = w;
-	configuration.height = h;
 
 
     VkRenderPassBeginInfo renderPassInfo{};
     VkRenderPassBeginInfo renderPassInfo{};
     renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
     renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
     renderPassInfo.renderPass = renderPass;
     renderPassInfo.renderPass = renderPass;
-	renderPassInfo.framebuffer = getFramebuffer(configuration);
+	renderPassInfo.framebuffer = framebuffer;
     renderPassInfo.renderArea.offset = {0, 0};
     renderPassInfo.renderArea.offset = {0, 0};
     renderPassInfo.renderArea.extent.width = static_cast<uint32_t>(w);
     renderPassInfo.renderArea.extent.width = static_cast<uint32_t>(w);
     renderPassInfo.renderArea.extent.height = static_cast<uint32_t>(h);
     renderPassInfo.renderArea.extent.height = static_cast<uint32_t>(h);
@@ -2008,6 +2020,10 @@ void Graphics::cleanup() {
 }
 }
 
 
 void Graphics::cleanupSwapChain() {
 void Graphics::cleanupSwapChain() {
+	for (const auto& framebuffer : defaultFramebuffers) {
+		vkDestroyFramebuffer(device, framebuffer, nullptr);
+	}
+	vkDestroyRenderPass(device, defaultRenderPass, nullptr);
 	vkDestroyImageView(device, colorImageView, nullptr);
 	vkDestroyImageView(device, colorImageView, nullptr);
 	vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation);
 	vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation);
 	vkDestroyImageView(device, depthImageView, nullptr);
 	vkDestroyImageView(device, depthImageView, nullptr);
@@ -2032,6 +2048,8 @@ void Graphics::recreateSwapChain() {
 	createImageViews();
 	createImageViews();
 	createColorResources();
 	createColorResources();
 	createDepthResources();
 	createDepthResources();
+	createDefaultRenderPass();
+	createDefaultFramebuffers();
 }
 }
 
 
 love::graphics::Graphics* createInstance() {
 love::graphics::Graphics* createInstance() {

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

@@ -213,6 +213,8 @@ private:
 	VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR& capabilities);
 	VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR& capabilities);
 	void createSwapChain();
 	void createSwapChain();
 	void createImageViews();
 	void createImageViews();
+	void createDefaultRenderPass();
+	void createDefaultFramebuffers();
     VkFramebuffer createFramebuffer(FramebufferConfiguration);
     VkFramebuffer createFramebuffer(FramebufferConfiguration);
     VkFramebuffer getFramebuffer(FramebufferConfiguration);
     VkFramebuffer getFramebuffer(FramebufferConfiguration);
 	void createDefaultShaders();
 	void createDefaultShaders();
@@ -269,6 +271,8 @@ private:
 	VkImage depthImage = VK_NULL_HANDLE;
 	VkImage depthImage = VK_NULL_HANDLE;
 	VkImageView depthImageView = VK_NULL_HANDLE;
 	VkImageView depthImageView = VK_NULL_HANDLE;
 	VmaAllocation depthImageAllocation = VK_NULL_HANDLE;
 	VmaAllocation depthImageAllocation = VK_NULL_HANDLE;
+	VkRenderPass defaultRenderPass;
+	std::vector<VkFramebuffer> defaultFramebuffers;
     std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
     std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
 	std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
 	std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
 	std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;
 	std::unordered_map<GraphicsPipelineConfiguration, VkPipeline, GraphicsPipelineConfigurationHasher> graphicsPipelines;

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

@@ -606,6 +606,15 @@ VkStencilOp Vulkan::getStencilOp(StencilAction action) {
 	}
 	}
 }
 }
 
 
+VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type) {
+	switch (type) {
+	case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
+	case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
+	default:
+		throw love::Exception("unknown Index Data 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

@@ -53,6 +53,7 @@ public:
 	static VkSamplerMipmapMode getMipMapMode(SamplerState::MipmapFilterMode);
 	static VkSamplerMipmapMode getMipMapMode(SamplerState::MipmapFilterMode);
 	static VkDescriptorType getDescriptorType(graphics::Shader::UniformType);
 	static VkDescriptorType getDescriptorType(graphics::Shader::UniformType);
 	static VkStencilOp getStencilOp(StencilAction);
 	static VkStencilOp getStencilOp(StencilAction);
+	static VkIndexType getVulkanIndexBufferType(IndexDataType type);
 
 
 	static void cmdTransitionImageLayout(
 	static void cmdTransitionImageLayout(
 		VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,
 		VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout,