Bläddra i källkod

Vulkan: Depth-stencil image bound in the shader now properly uses the depth aspect only

BearishSun 9 år sedan
förälder
incheckning
fa27cbfa05

+ 34 - 11
Source/BansheeVulkanRenderAPI/Include/BsVulkanTexture.h

@@ -62,11 +62,22 @@ namespace bs
 		/** Notifies the resource that the current image layout has changed. */
 		/** Notifies the resource that the current image layout has changed. */
 		void setLayout(VkImageLayout layout) { mLayout = layout; }
 		void setLayout(VkImageLayout layout) { mLayout = layout; }
 
 
-		/** Returns an image view that covers all faces and mip maps of the texture. */
-		VkImageView getView() const { return mMainView; };
+		/** 
+		 * Returns an image view that covers all faces and mip maps of the texture. 
+		 * 
+		 * @param[in]	framebuffer	Set to true if the view will be used as a framebuffer attachment. Ensures proper
+		 *							attachment flags are set on the view.
+		 */
+		VkImageView getView(bool framebuffer) const;
 
 
-		/** Returns an image view that covers the specified faces and mip maps of the texture. */
-		VkImageView getView(const TextureSurface& surface) const;
+		/** 
+		 * Returns an image view that covers the specified faces and mip maps of the texture. 
+		 *
+		 * @param[in]	surface		Surface that describes which faces and mip levels to retrieve the view for.
+		 * @param[in]	framebuffer	Set to true if the view will be used as a framebuffer attachment. Ensures proper
+		 *							attachment flags are set on the view.
+		 */
+		VkImageView getView(const TextureSurface& surface, bool framebuffer) const;
 		
 		
 		/** Retrieves a subresource range covering all the sub-resources of the image. */
 		/** Retrieves a subresource range covering all the sub-resources of the image. */
 		VkImageSubresourceRange getRange() const;
 		VkImageSubresourceRange getRange() const;
@@ -113,12 +124,13 @@ namespace bs
 
 
 	private:
 	private:
 		/** Creates a new view of the provided part (or entirety) of surface. */
 		/** Creates a new view of the provided part (or entirety) of surface. */
-		VkImageView createView(const TextureSurface& surface) const;
+		VkImageView createView(const TextureSurface& surface, VkImageAspectFlags aspectMask) const;
 
 
 		/** Contains information about view for a specific surface(s) of this image. */
 		/** Contains information about view for a specific surface(s) of this image. */
 		struct ImageViewInfo
 		struct ImageViewInfo
 		{
 		{
 			TextureSurface surface;
 			TextureSurface surface;
+			bool framebuffer;
 			VkImageView view;
 			VkImageView view;
 		};
 		};
 
 
@@ -126,8 +138,10 @@ namespace bs
 		VkDeviceMemory mMemory;
 		VkDeviceMemory mMemory;
 		VkImageLayout mLayout;
 		VkImageLayout mLayout;
 		VkImageView mMainView;
 		VkImageView mMainView;
+		VkImageView mFramebufferMainView;
 		bool mOwnsImage;
 		bool mOwnsImage;
 		bool mIsStorage;
 		bool mIsStorage;
+		bool mIsDepthStencil;
 
 
 		UINT32 mNumFaces;
 		UINT32 mNumFaces;
 		UINT32 mNumMipLevels;
 		UINT32 mNumMipLevels;
@@ -157,16 +171,25 @@ namespace bs
 		VulkanImage* getResource(UINT32 deviceIdx) const { return mImages[deviceIdx]; }
 		VulkanImage* getResource(UINT32 deviceIdx) const { return mImages[deviceIdx]; }
 
 
 		/** 
 		/** 
-		 * Returns an image view that covers all faces and mip maps of the texture. Usable only on the specified device. 
-		 * If texture device mask doesn't include the provided device, null is returned. 
+		 * Returns an image view that covers all faces and mip maps of the texture. 
+		 * 
+		 * @param[in]	deviceIdx	Index of the device to retrieve the view for. If texture device mask doesn't include the
+		 *							provided device, null is returned. 
+		 * @param[in]	framebuffer	Set to true if the view will be used as a framebuffer attachment. Ensures proper
+		 *							attachment flags are set on the view.
 		 */
 		 */
-		VkImageView getView(UINT32 deviceIdx) const;
+		VkImageView getView(UINT32 deviceIdx, bool framebuffer = false) const;
 
 
 		/** 
 		/** 
-		 * Returns an image view that covers the specified faces and mip maps of the texture. Usable only on the specified 
-		 * device. If texture device mask doesn't include the provided device, null is returned. 
+		 * Returns an image view that covers the specified faces and mip maps of the texture. 
+		 * 
+		 * @param[in]	deviceIdx	Index of the device to retrieve the view for. If texture device mask doesn't include the
+		 *							provided device, null is returned. 
+		 * @param[in]	surface		Surface that describes which faces and mip levels to retrieve the view for.							
+		 * @param[in]	framebuffer	Set to true if the view will be used as a framebuffer attachment. Ensures proper
+		 *							attachment flags are set on the view.
 		 */
 		 */
-		VkImageView getView(UINT32 deviceIdx, const TextureSurface& surface) const;
+		VkImageView getView(UINT32 deviceIdx, const TextureSurface& surface, bool framebuffer = false) const;
 
 
 	protected:
 	protected:
 		friend class VulkanTextureCoreManager;
 		friend class VulkanTextureCoreManager;

+ 2 - 2
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderTexture.cpp

@@ -71,7 +71,7 @@ namespace bs
 			}
 			}
 
 
 			fbDesc.color[i].image = image;
 			fbDesc.color[i].image = image;
-			fbDesc.color[i].view = image->getView(surface);
+			fbDesc.color[i].view = image->getView(surface, true);
 			fbDesc.color[i].format = VulkanUtility::getPixelFormat(texture->getProperties().getFormat());
 			fbDesc.color[i].format = VulkanUtility::getPixelFormat(texture->getProperties().getFormat());
 		}
 		}
 
 
@@ -111,7 +111,7 @@ namespace bs
 				}
 				}
 
 
 				fbDesc.depth.image = image;
 				fbDesc.depth.image = image;
-				fbDesc.depth.view = image->getView(surface);
+				fbDesc.depth.view = image->getView(surface, true);
 				fbDesc.depth.format = VulkanUtility::getPixelFormat(texture->getProperties().getFormat());
 				fbDesc.depth.format = VulkanUtility::getPixelFormat(texture->getProperties().getFormat());
 				fbDesc.depth.baseLayer = view->getFirstArraySlice();
 				fbDesc.depth.baseLayer = view->getFirstArraySlice();
 			}
 			}

+ 2 - 2
Source/BansheeVulkanRenderAPI/Source/BsVulkanSwapChain.cpp

@@ -145,7 +145,7 @@ namespace bs
 
 
 			mSurfaces[i].acquired = false;
 			mSurfaces[i].acquired = false;
 			mSurfaces[i].image = resManager.create<VulkanImage>(imageDesc, false);
 			mSurfaces[i].image = resManager.create<VulkanImage>(imageDesc, false);
-			mSurfaces[i].view = mSurfaces[i].image->getView();
+			mSurfaces[i].view = mSurfaces[i].image->getView(true);
 			mSurfaces[i].sync = resManager.create<VulkanSemaphore>();
 			mSurfaces[i].sync = resManager.create<VulkanSemaphore>();
 		}
 		}
 
 
@@ -181,7 +181,7 @@ namespace bs
 			imageDesc.memory = mDevice->allocateMemory(depthStencilImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
 			imageDesc.memory = mDevice->allocateMemory(depthStencilImage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
 
 
 			mDepthStencilImage = resManager.create<VulkanImage>(imageDesc, true);
 			mDepthStencilImage = resManager.create<VulkanImage>(imageDesc, true);
-			mDepthStencilView = mDepthStencilImage->getView();
+			mDepthStencilView = mDepthStencilImage->getView(true);
 		}
 		}
 		else
 		else
 		{
 		{

+ 46 - 14
Source/BansheeVulkanRenderAPI/Source/BsVulkanTexture.cpp

@@ -35,7 +35,8 @@ namespace bs
 
 
 	VulkanImage::VulkanImage(VulkanResourceManager* owner, const VULKAN_IMAGE_DESC& desc, bool ownsImage)
 	VulkanImage::VulkanImage(VulkanResourceManager* owner, const VULKAN_IMAGE_DESC& desc, bool ownsImage)
 		: VulkanResource(owner, false), mImage(desc.image), mMemory(desc.memory), mLayout(desc.layout)
 		: VulkanResource(owner, false), mImage(desc.image), mMemory(desc.memory), mLayout(desc.layout)
-		, mOwnsImage(ownsImage), mNumFaces(desc.numFaces), mNumMipLevels(desc.numMipLevels), mIsStorage(desc.isStorage)
+		, mFramebufferMainView(VK_NULL_HANDLE), mOwnsImage(ownsImage), mNumFaces(desc.numFaces)
+		, mNumMipLevels(desc.numMipLevels), mIsStorage(desc.isStorage)
 	{
 	{
 		mImageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
 		mImageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
 		mImageViewCI.pNext = nullptr;
 		mImageViewCI.pNext = nullptr;
@@ -66,13 +67,16 @@ namespace bs
 			break;
 			break;
 		}
 		}
 
 
-		if (desc.isDepthStencil)
-			mImageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-		else
-			mImageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+		mIsDepthStencil = desc.isDepthStencil;
 
 
 		TextureSurface completeSurface(0, desc.numMipLevels, 0, desc.numFaces);
 		TextureSurface completeSurface(0, desc.numMipLevels, 0, desc.numFaces);
-		mMainView = createView(completeSurface);
+		if (mIsDepthStencil)
+		{
+			mFramebufferMainView = createView(completeSurface, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
+			mMainView = createView(completeSurface, VK_IMAGE_ASPECT_DEPTH_BIT);
+		}
+		else
+			mMainView = createView(completeSurface, VK_IMAGE_ASPECT_COLOR_BIT);
 
 
 		UINT32 numSubresources = mNumFaces * mNumMipLevels;
 		UINT32 numSubresources = mNumFaces * mNumMipLevels;
 		mSubresources = (VulkanImageSubresource**)bs_alloc(sizeof(VulkanImageSubresource*) * numSubresources);
 		mSubresources = (VulkanImageSubresource**)bs_alloc(sizeof(VulkanImageSubresource*) * numSubresources);
@@ -95,6 +99,9 @@ namespace bs
 
 
 		vkDestroyImageView(vkDevice, mMainView, gVulkanAllocator);
 		vkDestroyImageView(vkDevice, mMainView, gVulkanAllocator);
 
 
+		if(mFramebufferMainView != VK_NULL_HANDLE)
+			vkDestroyImageView(vkDevice, mFramebufferMainView, gVulkanAllocator);
+
 		for(auto& entry : mImageInfos)
 		for(auto& entry : mImageInfos)
 			vkDestroyImageView(vkDevice, entry.view, gVulkanAllocator);
 			vkDestroyImageView(vkDevice, entry.view, gVulkanAllocator);
 
 
@@ -105,7 +112,15 @@ namespace bs
 		}
 		}
 	}
 	}
 
 
-	VkImageView VulkanImage::getView(const TextureSurface& surface) const
+	VkImageView VulkanImage::getView(bool framebuffer) const
+	{
+		if (!mIsDepthStencil || !framebuffer)
+			return mMainView;
+
+		return mFramebufferMainView;
+	}
+
+	VkImageView VulkanImage::getView(const TextureSurface& surface, bool framebuffer) const
 	{
 	{
 		for(auto& entry : mImageInfos)
 		for(auto& entry : mImageInfos)
 		{
 		{
@@ -114,20 +129,36 @@ namespace bs
 				surface.arraySlice == entry.surface.arraySlice &&
 				surface.arraySlice == entry.surface.arraySlice &&
 				surface.numArraySlices == entry.surface.numArraySlices)
 				surface.numArraySlices == entry.surface.numArraySlices)
 			{
 			{
-				return entry.view;
+				if(!mIsDepthStencil)
+					return entry.view;
+				else
+				{
+					if (framebuffer == entry.framebuffer)
+						return entry.view;
+				}
 			}
 			}
 		}
 		}
 
 
 		ImageViewInfo info;
 		ImageViewInfo info;
 		info.surface = surface;
 		info.surface = surface;
-		info.view = createView(surface);
+		info.framebuffer = framebuffer;
+
+		if (mIsDepthStencil)
+		{
+			if(framebuffer)
+				info.view = createView(surface, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
+			else
+				info.view = createView(surface, VK_IMAGE_ASPECT_DEPTH_BIT);
+		}
+		else
+			info.view = createView(surface, VK_IMAGE_ASPECT_COLOR_BIT);
 
 
 		mImageInfos.push_back(info);
 		mImageInfos.push_back(info);
 
 
 		return info.view;
 		return info.view;
 	}
 	}
 
 
-	VkImageView VulkanImage::createView(const TextureSurface& surface) const
+	VkImageView VulkanImage::createView(const TextureSurface& surface, VkImageAspectFlags aspectMask) const
 	{
 	{
 		VkImageViewType oldViewType = mImageViewCI.viewType;
 		VkImageViewType oldViewType = mImageViewCI.viewType;
 
 
@@ -149,6 +180,7 @@ namespace bs
 			}
 			}
 		}
 		}
 
 
+		mImageViewCI.subresourceRange.aspectMask = aspectMask;
 		mImageViewCI.subresourceRange.baseMipLevel = surface.mipLevel;
 		mImageViewCI.subresourceRange.baseMipLevel = surface.mipLevel;
 		mImageViewCI.subresourceRange.levelCount = surface.numMipLevels;
 		mImageViewCI.subresourceRange.levelCount = surface.numMipLevels;
 		mImageViewCI.subresourceRange.baseArrayLayer = surface.arraySlice;
 		mImageViewCI.subresourceRange.baseArrayLayer = surface.arraySlice;
@@ -556,20 +588,20 @@ namespace bs
 			return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
 			return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
 	}
 	}
 
 
-	VkImageView VulkanTextureCore::getView(UINT32 deviceIdx) const
+	VkImageView VulkanTextureCore::getView(UINT32 deviceIdx, bool framebuffer) const
 	{
 	{
 		if (mImages[deviceIdx] == nullptr)
 		if (mImages[deviceIdx] == nullptr)
 			return VK_NULL_HANDLE;
 			return VK_NULL_HANDLE;
 
 
-		return mImages[deviceIdx]->getView();
+		return mImages[deviceIdx]->getView(framebuffer);
 	}
 	}
 
 
-	VkImageView VulkanTextureCore::getView(UINT32 deviceIdx, const TextureSurface& surface) const
+	VkImageView VulkanTextureCore::getView(UINT32 deviceIdx, const TextureSurface& surface, bool framebuffer) const
 	{
 	{
 		if (mImages[deviceIdx] == nullptr)
 		if (mImages[deviceIdx] == nullptr)
 			return VK_NULL_HANDLE;
 			return VK_NULL_HANDLE;
 
 
-		return mImages[deviceIdx]->getView(surface);
+		return mImages[deviceIdx]->getView(surface, framebuffer);
 	}
 	}
 
 
 	void VulkanTextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel,
 	void VulkanTextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel,

+ 2 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanTextureManager.cpp

@@ -43,17 +43,16 @@ namespace bs
 		desc.usage = TU_LOADSTORE;
 		desc.usage = TU_LOADSTORE;
 
 
 		mDummyStorageTexture = std::static_pointer_cast<VulkanTextureCore>(createTexture(desc));
 		mDummyStorageTexture = std::static_pointer_cast<VulkanTextureCore>(createTexture(desc));
-		mDummyStorageTexture->writeData(*whitePixelData);
 	}
 	}
 
 
 	VkImageView VulkanTextureCoreManager::getDummyReadImageView(UINT32 deviceIdx) const
 	VkImageView VulkanTextureCoreManager::getDummyReadImageView(UINT32 deviceIdx) const
 	{
 	{
-		return mDummyReadTexture->getResource(deviceIdx)->getView();
+		return mDummyReadTexture->getResource(deviceIdx)->getView(false);
 	}
 	}
 
 
 	VkImageView VulkanTextureCoreManager::getDummyStorageImageView(UINT32 deviceIdx) const
 	VkImageView VulkanTextureCoreManager::getDummyStorageImageView(UINT32 deviceIdx) const
 	{
 	{
-		return mDummyStorageTexture->getResource(deviceIdx)->getView();
+		return mDummyStorageTexture->getResource(deviceIdx)->getView(false);
 	}
 	}
 
 
 	SPtr<TextureCore> VulkanTextureCoreManager::createTextureInternal(const TEXTURE_DESC& desc,
 	SPtr<TextureCore> VulkanTextureCoreManager::createTextureInternal(const TEXTURE_DESC& desc,