Browse Source

vulkan: remove dynamic rendering (part 2)

niki 3 years ago
parent
commit
3e762c9772
2 changed files with 70 additions and 55 deletions
  1. 50 51
      src/modules/graphics/vulkan/Graphics.cpp
  2. 20 4
      src/modules/graphics/vulkan/Graphics.h

+ 50 - 51
src/modules/graphics/vulkan/Graphics.cpp

@@ -46,7 +46,7 @@ constexpr bool enableValidationLayers = true;
 
 
 constexpr int MAX_FRAMES_IN_FLIGHT = 2;
 constexpr int MAX_FRAMES_IN_FLIGHT = 2;
 
 
-constexpr uint32_t vulkanApiVersion = VK_API_VERSION_1_3;
+constexpr uint32_t vulkanApiVersion = VK_API_VERSION_1_0;
 
 
 const char* Graphics::getName() const {
 const char* Graphics::getName() const {
 	return "love.graphics.vulkan";
 	return "love.graphics.vulkan";
@@ -821,10 +821,6 @@ void Graphics::createLogicalDevice() {
 		queueCreateInfos.push_back(queueCreateInfo);
 		queueCreateInfos.push_back(queueCreateInfo);
 	}
 	}
 
 
-	VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeature{};
-	dynamicRenderingFeature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
-	dynamicRenderingFeature.dynamicRendering = VK_FALSE;
-
 	VkPhysicalDeviceFeatures deviceFeatures{};
 	VkPhysicalDeviceFeatures deviceFeatures{};
 	deviceFeatures.samplerAnisotropy = VK_TRUE;
 	deviceFeatures.samplerAnisotropy = VK_TRUE;
 	deviceFeatures.fillModeNonSolid = VK_TRUE;
 	deviceFeatures.fillModeNonSolid = VK_TRUE;
@@ -834,7 +830,6 @@ void Graphics::createLogicalDevice() {
 	createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
 	createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
 	createInfo.pQueueCreateInfos = queueCreateInfos.data();
 	createInfo.pQueueCreateInfos = queueCreateInfos.data();
 	createInfo.pEnabledFeatures = &deviceFeatures;
 	createInfo.pEnabledFeatures = &deviceFeatures;
-	createInfo.pNext = &dynamicRenderingFeature;
 
 
 	createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
 	createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
 	createInfo.ppEnabledExtensionNames = deviceExtensions.data();
 	createInfo.ppEnabledExtensionNames = deviceExtensions.data();
@@ -1047,41 +1042,37 @@ void Graphics::createImageViews() {
 	}
 	}
 }
 }
 
 
-std::vector<VkFramebuffer> Graphics::createSwapChainFramebuffers(VkRenderPass renderPass) {
-    std::vector<VkFramebuffer> swapChainFramebuffers;
-    swapChainFramebuffers.resize(swapChainImageViews.size());
-
-    for (size_t i = 0; i < swapChainImageViews.size(); i++) {
-        VkImageView attachments[] = {
-            swapChainImageViews[i]
-        };
+VkFramebuffer Graphics::createFramebuffer(FramebufferConfiguration configuration) {
+	VkImageView attachments[] = {
+		configuration.imageView
+	};
 
 
-        VkFramebufferCreateInfo createInfo{};
-        createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
-        createInfo.renderPass = renderPass;
-        createInfo.attachmentCount = 1;
-        createInfo.pAttachments = attachments;
-        createInfo.width = swapChainExtent.width;
-        createInfo.height = swapChainExtent.height;
-        createInfo.layers = 1;
-
-        if (vkCreateFramebuffer(device, &createInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
-            throw love::Exception("failed to create framebuffer");
-        }
-    }
+	VkFramebufferCreateInfo createInfo{};
+	createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+	createInfo.renderPass = configuration.renderPass;
+	createInfo.attachmentCount = 1;
+	createInfo.pAttachments = attachments;
+	createInfo.width = configuration.width;
+	createInfo.height = configuration.height;
+	createInfo.layers = 1;	// is this correct?
 
 
-    return swapChainFramebuffers;
+	VkFramebuffer frameBuffer;
+	if (vkCreateFramebuffer(device, &createInfo, nullptr, &frameBuffer) != VK_SUCCESS) {
+		throw love::Exception("failed to create framebuffer");
+	}
+	return frameBuffer;
 }
 }
 
 
-VkFramebuffer Graphics::getSwapChainFramebuffer(VkRenderPass renderPass) {
-    auto it = swapChainFramebufferVector.find(renderPass);
-    if (it != swapChainFramebufferVector.end()) {
-        return it->second.at(imageIndex);
-    } else {
-        auto frameBuffers = createSwapChainFramebuffers(renderPass);
-        swapChainFramebufferVector[renderPass] = frameBuffers;
-        return frameBuffers.at(imageIndex);
-    }
+VkFramebuffer Graphics::getFramebuffer(FramebufferConfiguration configuration) {
+	auto it = framebuffers.find(configuration);
+	if (it != framebuffers.end()) {
+		return it->second;
+	}
+	else {
+		VkFramebuffer framebuffer = createFramebuffer(configuration);
+		framebuffers[configuration] = framebuffer;
+		return framebuffer;
+	} 
 }
 }
 
 
 void Graphics::createDefaultShaders() {
 void Graphics::createDefaultShaders() {
@@ -1258,21 +1249,13 @@ void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
     RenderPassConfiguration renderPassConfiguration{};
     RenderPassConfiguration renderPassConfiguration{};
 
 
 	if (texture) {
 	if (texture) {
-		auto vulkanFormat = Vulkan::getTextureFormat(texture->getPixelFormat());
-		currentFramebufferOutputFormat = vulkanFormat.internalFormat;
-        renderPassConfiguration.frameBufferFormat = vulkanFormat.internalFormat;
-
+        renderPassConfiguration.frameBufferFormat = Vulkan::getTextureFormat(texture->getPixelFormat()).internalFormat;
 		renderTargetTexture = texture;
 		renderTargetTexture = texture;
 	} else {
 	} else {
-		currentFramebufferOutputFormat = swapChainImageFormat;
         renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
         renderPassConfiguration.frameBufferFormat = swapChainImageFormat;
-
 		renderTargetTexture = nullptr;
 		renderTargetTexture = nullptr;
 	}
 	}
 
 
-	currentViewportWidth = (float)w;
-	currentViewportHeight = (float)h;
-
     VkRenderPass renderPass;
     VkRenderPass renderPass;
 
 
     auto it = renderPasses.find(renderPassConfiguration);
     auto it = renderPasses.find(renderPassConfiguration);
@@ -1283,14 +1266,21 @@ void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
         renderPasses[renderPassConfiguration] = renderPass;
         renderPasses[renderPassConfiguration] = renderPass;
     }
     }
 
 
+	FramebufferConfiguration configuration{};
+	configuration.renderPass = renderPass;
+	if (renderTargetTexture == nullptr) {
+		configuration.imageView = swapChainImageViews.at(imageIndex);
+	}
+	else {
+		configuration.imageView = (VkImageView)texture->getRenderTargetHandle();
+	}
+	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;
-    if (renderTargetTexture == nullptr)  {
-        renderPassInfo.framebuffer = getSwapChainFramebuffer(renderPass);
-    } else {
-        renderPassInfo.framebuffer = (VkFramebuffer) texture->getRenderTargetHandle();
-    }
+	renderPassInfo.framebuffer = getFramebuffer(configuration);
     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);
@@ -1303,6 +1293,8 @@ void Graphics::startRenderPass(Texture* texture, uint32_t w, uint32_t h) {
 
 
     currentRenderPass = renderPass;
     currentRenderPass = renderPass;
 	currentGraphicsPipeline = VK_NULL_HANDLE;
 	currentGraphicsPipeline = VK_NULL_HANDLE;
+	currentViewportWidth = (float)w;
+	currentViewportHeight = (float)h;
 }
 }
 
 
 void Graphics::endRenderPass() {
 void Graphics::endRenderPass() {
@@ -1587,6 +1579,10 @@ void Graphics::cleanup() {
 	}
 	}
 	samplers.clear();
 	samplers.clear();
 
 
+	for (const auto& [key, val] : renderPasses) {
+		vkDestroyRenderPass(device, val, nullptr);
+	}
+
 	// fixme: maybe we should clean up some pipelines if they haven't been used in a while.
 	// fixme: maybe we should clean up some pipelines if they haven't been used in a while.
 	for (auto const& p : graphicsPipelines) {
 	for (auto const& p : graphicsPipelines) {
 		vkDestroyPipeline(device, p.second, nullptr);
 		vkDestroyPipeline(device, p.second, nullptr);
@@ -1600,6 +1596,9 @@ void Graphics::cleanup() {
 }
 }
 
 
 void Graphics::cleanupSwapChain() {
 void Graphics::cleanupSwapChain() {
+	for (const auto& [key, val] : framebuffers) {
+		vkDestroyFramebuffer(device, val, nullptr);
+	}
     for (auto & swapChainImageView : swapChainImageViews) {
     for (auto & swapChainImageView : swapChainImageViews) {
         vkDestroyImageView(device, swapChainImageView, nullptr);
         vkDestroyImageView(device, swapChainImageView, nullptr);
     }
     }

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

@@ -38,6 +38,23 @@ struct RenderPassConfigurationHasher {
     }
     }
 };
 };
 
 
+struct FramebufferConfiguration {
+	VkRenderPass renderPass = VK_NULL_HANDLE;
+	VkImageView imageView = VK_NULL_HANDLE;
+	uint32_t width = 0;
+	uint32_t height = 0;
+
+	bool operator==(const FramebufferConfiguration& conf) const {
+		return memcmp(this, &conf, sizeof(FramebufferConfiguration)) == 0;
+	}
+};
+
+struct FramebufferConfigurationHasher {
+	size_t operator()(const FramebufferConfiguration& configuration) const {
+		return XXH32(&configuration, sizeof(FramebufferConfiguration), 0);
+	}
+};
+
 struct GraphicsPipelineConfiguration {
 struct GraphicsPipelineConfiguration {
     VkRenderPass renderPass;
     VkRenderPass renderPass;
 	VertexAttributes vertexAttributes;
 	VertexAttributes vertexAttributes;
@@ -186,8 +203,8 @@ private:
 	VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
 	VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
 	void createSwapChain();
 	void createSwapChain();
 	void createImageViews();
 	void createImageViews();
-    std::vector<VkFramebuffer> createSwapChainFramebuffers(VkRenderPass);
-    VkFramebuffer getSwapChainFramebuffer(VkRenderPass);
+    VkFramebuffer createFramebuffer(FramebufferConfiguration);
+    VkFramebuffer getFramebuffer(FramebufferConfiguration);
 	void createDefaultShaders();
 	void createDefaultShaders();
     VkRenderPass createRenderPass(RenderPassConfiguration);
     VkRenderPass createRenderPass(RenderPassConfiguration);
 	VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
 	VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
@@ -224,10 +241,10 @@ 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;
-    std::unordered_map<VkRenderPass, std::vector<VkFramebuffer>> swapChainFramebufferVector;
 	VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
 	VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
     VkRenderPass currentRenderPass = VK_NULL_HANDLE;
     VkRenderPass currentRenderPass = VK_NULL_HANDLE;
     std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
     std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
+	std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
 	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;
@@ -252,7 +269,6 @@ private:
 	graphics::Texture* currentTexture = nullptr;
 	graphics::Texture* currentTexture = nullptr;
 
 
 	// render pass variables.
 	// render pass variables.
-	VkFormat currentFramebufferOutputFormat = VK_FORMAT_UNDEFINED;
 	Texture* renderTargetTexture = nullptr;
 	Texture* renderTargetTexture = nullptr;
 	float currentViewportWidth = 0;
 	float currentViewportWidth = 0;
 	float currentViewportHeight = 0;
 	float currentViewportHeight = 0;