Browse Source

vulkan: render targets with mip and slice

niki 2 years ago
parent
commit
726cd147c8

+ 2 - 12
src/modules/graphics/vulkan/Graphics.cpp

@@ -2097,20 +2097,10 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
 	// fixme: msaaSamples
 	RenderPassConfiguration renderPassConfiguration{};
 	for (const auto &color : rts.colors)
-	{
-		// fixme: use mipmap and slice.
-		color.mipmap;
-		color.slice;
 		renderPassConfiguration.colorAttachments.push_back({ Vulkan::getTextureFormat(color.texture->getPixelFormat()).internalFormat, false });
-	}
 	if (rts.depthStencil.texture != nullptr)
-	{
-		// fixme: use mipmap and slice:
-		rts.depthStencil.mipmap;
-		rts.depthStencil.slice;
 		if (rts.depthStencil.texture != nullptr)
 			renderPassConfiguration.staticData.depthAttachment = { Vulkan::getTextureFormat(rts.depthStencil.texture->getPixelFormat()).internalFormat, false };
-	}
 
 	FramebufferConfiguration configuration{};
 
@@ -2118,11 +2108,11 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
 
 	for (const auto &color : rts.colors)
 	{
-		configuration.colorViews.push_back((VkImageView)color.texture->getRenderTargetHandle());
+		configuration.colorViews.push_back(dynamic_cast<Texture*>(color.texture)->getRenderTargetView(color.mipmap, color.slice));
 		transitionImages.push_back((VkImage) color.texture->getHandle());
 	}
 	if (rts.depthStencil.texture != nullptr)
-		configuration.staticData.depthView = (VkImageView)rts.depthStencil.texture->getRenderTargetHandle();
+		configuration.staticData.depthView = dynamic_cast<Texture*>(rts.depthStencil.texture)->getRenderTargetView(rts.depthStencil.mipmap, rts.depthStencil.slice);
 
 	configuration.staticData.width = static_cast<uint32_t>(pixelw);
 	configuration.staticData.height = static_cast<uint32_t>(pixelh);

+ 41 - 2
src/modules/graphics/vulkan/Texture.cpp

@@ -96,7 +96,7 @@ bool Texture::loadVolatile()
 	bool hasdata = slices.get(0, 0) != nullptr;
 
 	if (hasdata)
-		for (int mip = 0; mip < layerCount; mip++)
+		for (int mip = 0; mip < getMipmapCount(); mip++)
 		{
 			// fixme: deal with compressed images.
 
@@ -120,6 +120,36 @@ bool Texture::loadVolatile()
 	if (slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE)
 		generateMipmaps();
 
+	if (renderTarget)
+	{
+		renderTargetImageViews.resize(getMipmapCount());
+		for (int mip = 0; mip < getMipmapCount(); mip++)
+		{
+			renderTargetImageViews.at(mip).resize(layerCount);
+
+			for (int slice = 0; slice < layerCount; slice++)
+			{
+				VkImageViewCreateInfo viewInfo{};
+				viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+				viewInfo.image = textureImage;
+				viewInfo.viewType = Vulkan::getImageViewType(getTextureType());
+				viewInfo.format = vulkanFormat.internalFormat;
+				viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+				viewInfo.subresourceRange.baseMipLevel = mip;
+				viewInfo.subresourceRange.levelCount = 1;
+				viewInfo.subresourceRange.baseArrayLayer = slice;
+				viewInfo.subresourceRange.layerCount = 1;
+				viewInfo.components.r = vulkanFormat.swizzleR;
+				viewInfo.components.g = vulkanFormat.swizzleG;
+				viewInfo.components.b = vulkanFormat.swizzleB;
+				viewInfo.components.a = vulkanFormat.swizzleA;
+
+				if (vkCreateImageView(device, &viewInfo, nullptr, &renderTargetImageViews.at(mip).at(slice)) != VK_SUCCESS)
+					throw love::Exception("could not create render target image view");
+			}
+		}
+	}
+
 	return true;
 }
 
@@ -133,9 +163,13 @@ void Texture::unloadVolatile()
 		textureImageView = textureImageView, 
 		allocator = allocator, 
 		textureImage = textureImage, 
-		textureImageAllocation = textureImageAllocation] () {
+		textureImageAllocation = textureImageAllocation,
+		textureImageViews = std::move(renderTargetImageViews)] () {
 		vkDestroyImageView(device, textureImageView, nullptr);
 		vmaDestroyImage(allocator, textureImage, textureImageAllocation);
+		for (const auto &views : textureImageViews)
+			for (const auto &view : views)
+				vkDestroyImageView(device, view, nullptr);
 	});
 
 	textureImage = VK_NULL_HANDLE;
@@ -156,6 +190,11 @@ ptrdiff_t Texture::getSamplerHandle() const
 	return (ptrdiff_t)textureSampler;
 }
 
+VkImageView Texture::getRenderTargetView(int mip, int layer)
+{
+	return renderTargetImageViews.at(mip).at(layer);
+}
+
 int Texture::getMSAA() const
 {
 	return 0;

+ 3 - 0
src/modules/graphics/vulkan/Texture.h

@@ -36,6 +36,8 @@ public:
 	ptrdiff_t getRenderTargetHandle() const override;
 	ptrdiff_t getSamplerHandle() const override;
 
+	VkImageView getRenderTargetView(int mip, int layer);
+
 	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) override;
 
 	void generateMipmapsInternal()  override;
@@ -56,6 +58,7 @@ private:
 	VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 	VmaAllocation textureImageAllocation = VK_NULL_HANDLE;
 	VkImageView textureImageView = VK_NULL_HANDLE;
+	std::vector<std::vector<VkImageView>> renderTargetImageViews;
 	VkSampler textureSampler = VK_NULL_HANDLE;
 	Slices slices;
 	int layerCount = 0;