Browse Source

Vulkan sampler state WIP

BearishSun 9 years ago
parent
commit
a20ec1ffd5

+ 1 - 3
Source/BansheeCore/Include/BsSamplerState.h

@@ -7,8 +7,6 @@
 #include "BsIReflectable.h"
 #include "BsCoreObject.h"
 
-#include <cfloat>
-
 namespace BansheeEngine 
 {
 	/** @addtogroup RenderAPI
@@ -146,7 +144,7 @@ namespace BansheeEngine
 	public:
 		friend class SamplerStateRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
     };
 
 	/** @} */

+ 2 - 0
Source/BansheeVulkanRenderAPI/CMakeSources.cmake

@@ -27,6 +27,7 @@ set(BS_BANSHEEVULKANRENDERAPI_INC_NOFILTER
 	"Include/BsVulkanResource.h"
 	"Include/BsVulkanQueue.h"
 	"Include/BsVulkanDescriptorSet.h"
+	"Include/BsVulkanSamplerState.h"
 )
 
 set(BS_BANSHEEVULKANRENDERAPI_INC_MANAGERS
@@ -71,6 +72,7 @@ set(BS_BANSHEEVULKANRENDERAPI_SRC_NOFILTER
 	"Source/BsVulkanResource.cpp"
 	"Source/BsVulkanQueue.cpp"
 	"Source/BsVulkanDescriptorSet.cpp"
+	"Source/BsVulkanSamplerState.cpp"
 )
 
 set(BS_BANSHEEVULKANRENDERAPI_SRC_MANAGERS

+ 50 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanSamplerState.h

@@ -0,0 +1,50 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsVulkanPrerequisites.h"
+#include "BsVulkanResource.h"
+#include "BsSamplerState.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Vulkan
+	 *  @{
+	 */
+
+	/** Wrapper around a Vulkan sampler object that manages its usage and lifetime. */
+	class VulkanSampler : public VulkanResource
+	{
+	public:
+		VulkanSampler(VulkanResourceManager* owner, VkSampler sampler);
+		~VulkanSampler();
+
+		/** Returns the internal handle to the Vulkan object. */
+		VkSampler getHandle() const { return mSampler; }
+
+	private:
+		VkSampler mSampler;
+	};
+
+	/**	Vulkan implementation of a sampler state. Wraps a Vulkan sampler object. */
+	class VulkanSamplerStateCore : public SamplerStateCore
+	{
+	public:
+		~VulkanSamplerStateCore();
+
+		/** Gets the resource wrapping the sampler object. */
+		VulkanSampler* getResource() const { return mSampler; }
+
+	protected:
+		friend class D3D11RenderStateCoreManager;
+
+		VulkanSamplerStateCore(const SAMPLER_STATE_DESC& desc);
+
+		/** @copydoc SamplerStateCore::createInternal */
+		void createInternal() override;
+
+		VulkanSampler* mSampler;
+	};
+
+	/** @} */
+}

+ 6 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanUtility.h

@@ -52,6 +52,12 @@ namespace BansheeEngine
 		/**	Converts between Banshee and Vulkan draw operation (i.e. primitive topology). */
 		static VkPrimitiveTopology getDrawOp(DrawOperationType op);
 
+		/**	Converts between Banshee and Vulkan texture filtering modes. */
+		static VkFilter getFilter(FilterOptions filter);
+
+		/**	Converts between Banshee and Vulkan texture filtering modes. */
+		static VkSamplerMipmapMode getMipFilter(FilterOptions filter);
+
 		/** Gets Vulkan flags representing the number of samples in an image. Sample count must be a power of 2. */
 		static VkSampleCountFlagBits getSampleFlags(UINT32 numSamples);
 

+ 65 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanSamplerState.cpp

@@ -0,0 +1,65 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsVulkanSamplerState.h"
+#include "BsVulkanDevice.h"
+#include "BsVulkanUtility.h"
+
+namespace BansheeEngine
+{
+	VulkanSampler::VulkanSampler(VulkanResourceManager* owner, VkSampler sampler)
+		:VulkanResource(owner, true), mSampler(sampler)
+	{ }
+
+	VulkanSampler::~VulkanSampler()
+	{
+		vkDestroySampler(mOwner->getDevice().getLogical(), mSampler, gVulkanAllocator);
+	}
+
+	VulkanSamplerStateCore::VulkanSamplerStateCore(const SAMPLER_STATE_DESC& desc)
+		:SamplerStateCore(desc), mSampler(nullptr)
+	{ }
+
+	VulkanSamplerStateCore::~VulkanSamplerStateCore()
+	{
+		if(mSampler != nullptr)
+			mSampler->destroy();
+	}
+
+	void VulkanSamplerStateCore::createInternal()
+	{
+		FilterOptions minFilter = getProperties().getTextureFiltering(FT_MIN);
+		FilterOptions magFilter = getProperties().getTextureFiltering(FT_MAG);
+		FilterOptions mipFilter = getProperties().getTextureFiltering(FT_MIP);
+
+		bool anisotropy = minFilter == FO_ANISOTROPIC || magFilter == FO_ANISOTROPIC || mipFilter == FO_ANISOTROPIC;
+		const UVWAddressingMode& addressMode = getProperties().getTextureAddressingMode();
+
+		CompareFunction compareFunc = getProperties().getComparisonFunction();
+
+		VkSamplerCreateInfo samplerInfo;
+		samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+		samplerInfo.flags = 0;
+		samplerInfo.pNext = nullptr;
+		samplerInfo.magFilter = VulkanUtility::getFilter(magFilter);
+		samplerInfo.minFilter = VulkanUtility::getFilter(minFilter);
+		samplerInfo.mipmapMode = VulkanUtility::getMipFilter(mipFilter);
+		samplerInfo.addressModeU = VulkanUtility::getAddressingMode(addressMode.u);
+		samplerInfo.addressModeV = VulkanUtility::getAddressingMode(addressMode.v);
+		samplerInfo.addressModeW = VulkanUtility::getAddressingMode(addressMode.w);
+		samplerInfo.mipLodBias = getProperties().getTextureMipmapBias();
+		samplerInfo.anisotropyEnable = anisotropy;
+		samplerInfo.maxAnisotropy = (float)getProperties().getTextureAnisotropy();
+		samplerInfo.compareEnable = compareFunc != CMPF_ALWAYS_PASS;
+		samplerInfo.compareOp = VulkanUtility::getCompareOp(compareFunc);
+		samplerInfo.minLod = mProperties.getMinimumMip();
+		samplerInfo.maxLod = mProperties.getMaximumMip();
+		samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+		samplerInfo.unnormalizedCoordinates = false;
+
+		// TODO - Create state per device
+
+		VkSampler sampler;
+		VkResult result = vkCreateSampler(mOwner->getDevice().getLogical(), &samplerInfo, gVulkanAllocator, &sampler);
+		assert(result == VK_SUCCESS);
+	}
+}

+ 32 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanUtility.cpp

@@ -403,6 +403,38 @@ namespace BansheeEngine
 		return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
 	}
 
+	VkFilter VulkanUtility::getFilter(FilterOptions filter)
+	{
+		switch(filter)
+		{
+		case FO_LINEAR:
+		case FO_ANISOTROPIC:
+			return VK_FILTER_LINEAR;
+		case FO_POINT:
+		case FO_NONE:
+			return VK_FILTER_NEAREST;
+		}
+
+		// Unsupported type
+		return VK_FILTER_LINEAR;
+	}
+
+	VkSamplerMipmapMode VulkanUtility::getMipFilter(FilterOptions filter)
+	{
+		switch (filter)
+		{
+		case FO_LINEAR:
+		case FO_ANISOTROPIC:
+			return VK_SAMPLER_MIPMAP_MODE_LINEAR;
+		case FO_POINT:
+		case FO_NONE:
+			return VK_SAMPLER_MIPMAP_MODE_NEAREST;
+		}
+
+		// Unsupported type
+		return VK_SAMPLER_MIPMAP_MODE_LINEAR;
+	}
+
 	void VulkanUtility::getDevices(const VulkanRenderAPI& rapi, GpuDeviceFlags flags, VulkanDevice*(&devices)[BS_MAX_LINKED_DEVICES])
 	{
 		if(flags == GDF_DEFAULT)