瀏覽代碼

Cleaned up render API capabilities class
Added API capabilities for Vulkan

BearishSun 9 年之前
父節點
當前提交
142c7970fc

+ 8 - 7
Source/BansheeCore/Include/BsRenderAPI.h

@@ -450,15 +450,17 @@ namespace BansheeEngine
 		 */
 		virtual void executeCommands(const SPtr<CommandBuffer>& commandBuffer) = 0;
 
-		/** Returns information about the driver version. */
-		virtual const DriverVersion& getDriverVersion() const;
-
 		/**
-		 * Gets the capabilities of the render system.
+		 * Gets the capabilities of a specific GPU.
+		 * 
+		 * @param[in]	deviceIdx	Index of the device to get the capabilities for.
 		 *
 		 * @note	Thread safe.
 		 */
-		const RenderAPICapabilities& getCapabilities() const { return *mCurrentCapabilities; }
+		const RenderAPICapabilities& getCapabilities(UINT32 deviceIdx) const;
+
+		/** Returns the number of devices supported by this render API. */
+		UINT32 getNumDevices() const { return mNumDevices; }
 
 		/**
 		 * Returns information about available output devices and their video modes.
@@ -539,9 +541,8 @@ namespace BansheeEngine
 
 		SPtr<RenderTargetCore> mActiveRenderTarget;
 
-		DriverVersion mDriverVersion;
-
 		RenderAPICapabilities* mCurrentCapabilities;
+		UINT32 mNumDevices;
 		SPtr<VideoModeInfo> mVideoModeInfo;
 	};
 

+ 15 - 205
Source/BansheeCore/Include/BsRenderAPICapabilities.h

@@ -23,68 +23,27 @@ namespace BansheeEngine
 	enum CapabilitiesCategory : UINT64
 	{
 		CAPS_CATEGORY_COMMON = 0,
-		CAPS_CATEGORY_D3D9 = 1,
-		CAPS_CATEGORY_GL = 2,
-		CAPS_CATEGORY_D3D11 = 3,
+		CAPS_CATEGORY_GL = 1,
+		CAPS_CATEGORY_D3D11 = 2,
+		CAPS_CATEGORY_VULKAN = 3,
 		CAPS_CATEGORY_COUNT = 32 /**< Maximum number of categories. */
 	};
 
 	/** Enum describing the different hardware capabilities we can check for. */
 	enum Capabilities : UINT64
 	{
-		RSC_AUTOMIPMAP				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0), /**< Supports generating mipmaps in hardware. */
-		RSC_ANISOTROPY				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1), /**< Supports anisotropic texture filtering. */
-		RSC_CUBEMAPPING				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2), /**< Supports cube mapping. */
-		RSC_TWO_SIDED_STENCIL		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3), /**< Supports separate stencil updates for both front and back faces. */
-		RSC_STENCIL_WRAP			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4), /**< Supports wrapping the stencil value at the range extremes. */
-		RSC_HWOCCLUSION				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5), /**< Supports hardware occlusion queries. */
-		RSC_USER_CLIP_PLANES		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 6), /**< Supports user clipping planes. */
-		RSC_VERTEX_FORMAT_UBYTE4	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7), /**< Supports the VET_UBYTE4 vertex element type. */
-		RSC_INFINITE_FAR_PLANE		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 8), /**< Supports infinite far plane projection. */
-		RSC_HWRENDER_TO_TEXTURE		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9), /**< Supports hardware render-to-texture. */
-		RSC_TEXTURE_FLOAT			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10), /**< Supports float textures and render targets. */
-		RSC_NON_POWER_OF_2_TEXTURES = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11), /**< Supports non-power of two textures. */
-		RSC_TEXTURE_3D				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12), /**< Supports 3d (volume) textures. */
-		RSC_POINT_SPRITES			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13), /**< Supports basic point sprite rendering. */
-
-		RSC_POINT_EXTENDED_PARAMETERS	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14), /**< Supports extra point parameters (minsize, maxsize, attenuation). */
-		RSC_VERTEX_TEXTURE_FETCH		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15), /**< Supports vertex texture fetch. */
-		RSC_MIPMAP_LOD_BIAS				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16), /**< Supports mipmap LOD biasing. */
-		RSC_GEOMETRY_PROGRAM			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17), /**< Supports hardware geometry programs. */
-
-		RSC_TEXTURE_COMPRESSION			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18), /**< Supports compressed textures. */
-		RSC_TEXTURE_COMPRESSION_DXT		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19), /**< Supports compressed textures in the DXT/ST3C formats. */
-		RSC_TEXTURE_COMPRESSION_VTC		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20), /**< Supports compressed textures in the VTC format. */
-		RSC_TEXTURE_COMPRESSION_PVRTC	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21), /**< Supports compressed textures in the PVRTC format. */
-		RSC_MRT_DIFFERENT_BIT_DEPTHS	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22), /**< Supports multiple render targets with different bit depths. */
-		RSC_ALPHA_TO_COVERAGE			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23), /**< Supports Alpha to Coverage. */
-		RSC_ADVANCED_BLEND_OPERATIONS	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24), /**< Supports blend operations like subtract, min, max. */
-		RSC_SHADER_SUBROUTINE			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25), /**< Supports dynamic shader linking. */
-		RSC_HWOCCLUSION_ASYNCHRONOUS	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26), /**< Support for async occlusion queries. */
-		RSC_HWRENDER_TO_VERTEX_BUFFER	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27), /**< Supports rendering to vertex buffers. */
-		RSC_TESSELLATION_PROGRAM		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 28), /**< Supports hardware tessellation programs. */
-		RSC_COMPUTE_PROGRAM				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 29), /**< Supports hardware compute programs. */
-
-		// ***** DirectX 9 specific caps *****
-		RSC_PERSTAGECONSTANT = BS_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0), /**< Are per stage constants supported. */
-
-		// ***** GL Specific caps *****
-		RSC_FBO              = BS_CAPS_VALUE(CAPS_CATEGORY_GL, 0), /**< Support for Frame Buffer Objects. */
-		RSC_PBUFFER			 = BS_CAPS_VALUE(CAPS_CATEGORY_GL, 1), /**< Support for PBuffers. */
+		RSC_TEXTURE_COMPRESSION_BC		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0), /**< Supports compressed textures in the BC formats. */
+		RSC_TEXTURE_COMPRESSION_ETC2	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1), /**< Supports compressed textures in the ETC2 and EAC format. */
+		RSC_TEXTURE_COMPRESSION_ASTC	= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2), /**< Supports compressed textures in the ASTC format. */
+		RSC_GEOMETRY_PROGRAM			= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3), /**< Supports hardware geometry programs. */
+		RSC_TESSELLATION_PROGRAM		= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4), /**< Supports hardware tessellation programs. */
+		RSC_COMPUTE_PROGRAM				= BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5), /**< Supports hardware compute programs. */
 	};
 
 	/** Holds data about render system driver version. */
 	struct BS_CORE_EXPORT DriverVersion 
 	{
-		int major;
-		int minor;
-		int release;
-		int build;
-
-		DriverVersion() 
-		{
-			major = minor = release = build = 0;
-		}
+		DriverVersion() { }
 
 		/**	Returns the driver version as a single string. */
 		String toString() const 
@@ -110,6 +69,11 @@ namespace BansheeEngine
 			}
 
 		}
+
+		INT32 major = 0;
+		INT32 minor = 0;
+		INT32 release = 0;
+		INT32 build = 0;
 	};
 
 	/** Types of GPU vendors. */
@@ -198,12 +162,6 @@ namespace BansheeEngine
 			mNumCombinedUniformBlocks = num;
 		}
 
-		/**	Sets maximum stencil buffer depth in bits. */
-		void setStencilBufferBitDepth(UINT16 num)
-		{
-			mStencilBufferBitDepth = num;
-		}
-
 		/**	Sets maximum number of bound vertex buffers. */
 		void setMaxBoundVertexBuffers(UINT32 num)
 		{
@@ -264,12 +222,6 @@ namespace BansheeEngine
 			return mNumCombinedUniformBlocks;
 		}
 
-		/** Returns the maximum number of bits available for the stencil buffer. */
-		UINT16 getStencilBufferBitDepth() const
-		{
-			return mStencilBufferBitDepth;
-		}
-
 		/** Returns the maximum number of vertex buffers that can be bound at once. */
 		UINT32 getMaxBoundVertexBuffers() const
 		{
@@ -343,60 +295,6 @@ namespace BansheeEngine
 			return "";
 		}
 
-		/** Gets the number of floating-point constants vertex programs support. */
-		UINT16 getVertexProgramConstantFloatCount() const
-		{
-			return mVertexProgramConstantFloatCount;           
-		}
-
-		/**	Gets the number of integer constants vertex programs support. */
-		UINT16 getVertexProgramConstantIntCount() const
-		{
-			return mVertexProgramConstantIntCount;           
-		}
-
-		/**	Gets the number of boolean constants vertex programs support. */
-		UINT16 getVertexProgramConstantBoolCount() const
-		{
-			return mVertexProgramConstantBoolCount;           
-		}
-
-		/**	Gets the number of floating-point constants geometry programs support. */
-		UINT16 getGeometryProgramConstantFloatCount() const
-		{
-			return mGeometryProgramConstantFloatCount;           
-		}
-
-		/**	 Gets the number of integer constants geometry programs support. */
-		UINT16 getGeometryProgramConstantIntCount() const
-		{
-			return mGeometryProgramConstantIntCount;           
-		}
-
-		/**	 Gets the number of boolean constants geometry programs support. */
-		UINT16 getGeometryProgramConstantBoolCount() const
-		{
-			return mGeometryProgramConstantBoolCount;           
-		}
-
-		/**	Gets the number of floating-point constants fragment programs support. */
-		UINT16 getFragmentProgramConstantFloatCount() const
-		{
-			return mFragmentProgramConstantFloatCount;           
-		}
-
-		/**	Gets the number of integer constants fragment programs support. */
-		UINT16 getFragmentProgramConstantIntCount() const
-		{
-			return mFragmentProgramConstantIntCount;           
-		}
-		
-		/** Gets the number of boolean constants fragment programs support. */
-		UINT16 getFragmentProgramConstantBoolCount() const
-		{
-			return mFragmentProgramConstantBoolCount;           
-		}
-
 		/**	Sets the current GPU device name. */
 		void setDeviceName(const String& name)
 		{
@@ -409,72 +307,6 @@ namespace BansheeEngine
 			return mDeviceName;
 		}
 
-		/**	Sets the number of floating-point constants vertex programs support. */
-		void setVertexProgramConstantFloatCount(UINT16 c)
-		{
-			mVertexProgramConstantFloatCount = c;           
-		}
-
-		/**	Sets the number of integer constants vertex programs support. */
-		void setVertexProgramConstantIntCount(UINT16 c)
-		{
-			mVertexProgramConstantIntCount = c;           
-		}
-
-		/**	Sets the number of boolean constants vertex programs support. */
-		void setVertexProgramConstantBoolCount(UINT16 c)
-		{
-			mVertexProgramConstantBoolCount = c;           
-		}
-
-		/**	Sets the number of floating-point constants geometry programs support. */
-		void setGeometryProgramConstantFloatCount(UINT16 c)
-		{
-			mGeometryProgramConstantFloatCount = c;           
-		}
-
-		/**	Sets the number of integer constants geometry programs support. */
-		void setGeometryProgramConstantIntCount(UINT16 c)
-		{
-			mGeometryProgramConstantIntCount = c;           
-		}
-
-		/**	Sets the number of boolean constants geometry programs support. */
-		void setGeometryProgramConstantBoolCount(UINT16 c)
-		{
-			mGeometryProgramConstantBoolCount = c;           
-		}
-
-		/**	Sets the number of floating-point constants fragment programs support. */
-		void setFragmentProgramConstantFloatCount(UINT16 c)
-		{
-			mFragmentProgramConstantFloatCount = c;           
-		}
-
-		/**	Sets the number of integer constants fragment programs support. */
-		void setFragmentProgramConstantIntCount(UINT16 c)
-		{
-			mFragmentProgramConstantIntCount = c;           
-		}
-
-		/**	Sets the number of boolean constants fragment programs support. */
-		void setFragmentProgramConstantBoolCount(UINT16 c)
-		{
-			mFragmentProgramConstantBoolCount = c;           
-		}
-
-		/**	Sets the maximum point screen size in pixels. */
-		void setMaxPointSize(float s)
-		{
-			mMaxPointSize = s;
-		}
-
-		/**	Gets the maximum point screen size in pixels. */
-		float getMaxPointSize(void) const
-		{
-			return mMaxPointSize;
-		}
-
 		/**	Sets the number of vertices a single geometry program run can emit. */
 		void setGeometryProgramNumOutputVertices(int numOutputVertices)
 		{
@@ -521,8 +353,6 @@ namespace BansheeEngine
 		Map<GpuProgramType, UINT16> mNumLoadStoreTextureUnitsPerStage;
 		// Total number of load-store texture units available
 		UINT16 mNumCombinedLoadStoreTextureUnits = 0;
-		// The stencil buffer bit depth
-		UINT16 mStencilBufferBitDepth = 0;
 		// Maximum number of vertex buffers we can bind at once
 		UINT32 mMaxBoundVertexBuffers = 0;
 		// Stores the capabilities flags.
@@ -532,28 +362,8 @@ namespace BansheeEngine
 		// The identifier associated with the render API for which these capabilities are valid
 		StringID mRenderAPIName;
 
-		// The number of floating-point constants vertex programs support
-		UINT16 mVertexProgramConstantFloatCount = 0;
-		// The number of integer constants vertex programs support
-		UINT16 mVertexProgramConstantIntCount = 0;
-		// The number of boolean constants vertex programs support
-		UINT16 mVertexProgramConstantBoolCount = 0;
-		// The number of floating-point constants geometry programs support
-		UINT16 mGeometryProgramConstantFloatCount = 0;
-		// The number of integer constants vertex geometry support
-		UINT16 mGeometryProgramConstantIntCount = 0;
-		// The number of boolean constants vertex geometry support
-		UINT16 mGeometryProgramConstantBoolCount = 0;
-		// The number of floating-point constants fragment programs support
-		UINT16 mFragmentProgramConstantFloatCount = 0;
-		// The number of integer constants fragment programs support
-		UINT16 mFragmentProgramConstantIntCount = 0;
-		// The number of boolean constants fragment programs support
-		UINT16 mFragmentProgramConstantBoolCount = 0;
 		// The number of simultaneous render targets supported
 		UINT16 mNumMultiRenderTargets = 0;
-		// The maximum point size in pixels
-		float mMaxPointSize = 0.0f;
 		// The number of vertices a geometry program can emit in a single run
 		UINT32 mGeometryProgramNumOutputVertices = 0;
 

+ 2 - 2
Source/BansheeCore/Source/BsGpuProgram.cpp

@@ -28,9 +28,9 @@ namespace BansheeEngine
 			return false;
 
 		RenderAPICore* rapi = RenderAPICore::instancePtr();
-		String profile = rapi->getCapabilities().gpuProgProfileToRSSpecificProfile(getProperties().getProfile());
+		String profile = rapi->getCapabilities(0).gpuProgProfileToRSSpecificProfile(getProperties().getProfile());
 
-		return rapi->getCapabilities().isShaderProfileSupported(profile);
+		return rapi->getCapabilities(0).isShaderProfileSupported(profile);
     }
 
 	bool GpuProgramCore::isRequiredCapabilitiesSupported() const

+ 10 - 6
Source/BansheeCore/Source/BsRenderAPI.cpp

@@ -155,7 +155,7 @@ namespace BansheeEngine
 	}
 
     RenderAPICore::RenderAPICore()
-        : mCurrentCapabilities(nullptr)
+        : mCurrentCapabilities(nullptr), mNumDevices(0)
     {
     }
 
@@ -163,7 +163,7 @@ namespace BansheeEngine
     {
 		// Base classes need to call virtual destroy_internal method instead of a destructor
 
-		bs_delete(mCurrentCapabilities);
+		bs_deleteN(mCurrentCapabilities, mNumDevices);
 		mCurrentCapabilities = nullptr;
     }
 
@@ -200,11 +200,15 @@ namespace BansheeEngine
 		mActiveRenderTarget = nullptr;
 	}
 
-	const DriverVersion& RenderAPICore::getDriverVersion() const 
-	{ 
-		THROW_IF_NOT_CORE_THREAD;
+	const RenderAPICapabilities& RenderAPICore::getCapabilities(UINT32 deviceIdx) const
+	{
+		if(deviceIdx >= mNumDevices)
+		{
+			LOGWRN("Invalid device index provided: " + toString(deviceIdx) + ". Valid range is: [0, " + toString(mNumDevices) + ").");
+			return mCurrentCapabilities[0];
+		}
 
-		return mDriverVersion; 
+		return mCurrentCapabilities[deviceIdx];
 	}
 
 	UINT32 RenderAPICore::vertexCountToPrimCount(DrawOperationType type, UINT32 elementCount)

+ 1 - 1
Source/BansheeD3D11RenderAPI/Include/BsD3D11RenderAPI.h

@@ -203,7 +203,7 @@ namespace BansheeEngine
 		void applyViewport();
 
 		/** Creates and populates a set of render system capabilities describing which functionality is available. */
-		RenderAPICapabilities* createRenderSystemCapabilities() const;
+		void initCapabilites(IDXGIAdapter* adapter, RenderAPICapabilities& caps) const;
 
 	private:
 		IDXGIFactory* mDXGIFactory;

+ 1 - 1
Source/BansheeD3D11RenderAPI/Source/BsD3D11GpuProgram.cpp

@@ -43,7 +43,7 @@ namespace BansheeEngine
 		}
 
 		D3D11RenderAPI* rapi = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr());
-		String hlslProfile = rapi->getCapabilities().gpuProgProfileToRSSpecificProfile(mProperties.getProfile());
+		String hlslProfile = rapi->getCapabilities(0).gpuProgProfileToRSSpecificProfile(mProperties.getProfile());
 
 		ID3DBlob* microcode = compileMicrocode(hlslProfile);
 

+ 94 - 127
Source/BansheeD3D11RenderAPI/Source/BsD3D11RenderAPI.cpp

@@ -97,16 +97,6 @@ namespace BansheeEngine
 
 		mDevice = bs_new<D3D11Device>(device);
 		
-		// This must query for DirectX 10 interface as this is unsupported for DX11
-		LARGE_INTEGER driverVersion; 
-		if(SUCCEEDED(selectedAdapter->CheckInterfaceSupport(IID_ID3D10Device, &driverVersion)))
-		{
-			mDriverVersion.major =  HIWORD(driverVersion.HighPart);
-			mDriverVersion.minor = LOWORD(driverVersion.HighPart);
-			mDriverVersion.release = HIWORD(driverVersion.LowPart);
-			mDriverVersion.build = LOWORD(driverVersion.LowPart);
-		}
-
 		// Create the texture manager for use by others		
 		TextureManager::startUp<D3D11TextureManager>();
 		TextureCoreManager::startUp<D3D11TextureCoreManager>();
@@ -125,9 +115,10 @@ namespace BansheeEngine
 		// Create render state manager
 		RenderStateCoreManager::startUp<D3D11RenderStateCoreManager>();
 
-		mCurrentCapabilities = createRenderSystemCapabilities();
-
-		mCurrentCapabilities->addShaderProfile("hlsl");
+		mNumDevices = 1;
+		mCurrentCapabilities = bs_newN<RenderAPICapabilities>(mNumDevices);
+		initCapabilites(selectedAdapter, mCurrentCapabilities[0]);
+				
 		GpuProgramCoreManager::instance().addFactory(mHLSLFactory);
 
 		mIAManager = bs_new<D3D11InputLayoutManager>();
@@ -640,7 +631,7 @@ namespace BansheeEngine
 		{
 			THROW_IF_NOT_CORE_THREAD;
 
-			UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers();
+			UINT32 maxBoundVertexBuffers = mCurrentCapabilities[0].getMaxBoundVertexBuffers();
 			if (index < 0 || (index + numBuffers) >= maxBoundVertexBuffers)
 			{
 				BS_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) +
@@ -968,7 +959,7 @@ namespace BansheeEngine
 			// Clear render surfaces
 			if (buffers & FBT_COLOR)
 			{
-				UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
+				UINT32 maxRenderTargets = mCurrentCapabilities[0].getNumMultiRenderTargets();
 
 				ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*>(maxRenderTargets);
 				memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
@@ -1037,7 +1028,7 @@ namespace BansheeEngine
 
 			mActiveRenderTarget = target;
 
-			UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets();
+			UINT32 maxRenderTargets = mCurrentCapabilities[0].getNumMultiRenderTargets();
 			ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*>(maxRenderTargets);
 			memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets);
 
@@ -1136,119 +1127,115 @@ namespace BansheeEngine
 		mDevice->getImmediateContext()->RSSetViewports(1, &mViewport);
 	}
 
-	RenderAPICapabilities* D3D11RenderAPI::createRenderSystemCapabilities() const
+	void D3D11RenderAPI::initCapabilites(IDXGIAdapter* adapter, RenderAPICapabilities& caps) const
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		RenderAPICapabilities* rsc = bs_new<RenderAPICapabilities>();
-
-		rsc->setDriverVersion(mDriverVersion);
-		rsc->setDeviceName(mActiveD3DDriver->getDriverDescription());
-		rsc->setRenderAPIName(getName());
-
-		rsc->setStencilBufferBitDepth(8);
-
-		rsc->setCapability(RSC_ANISOTROPY);
-		rsc->setCapability(RSC_AUTOMIPMAP);
+		// This must query for DirectX 10 interface as this is unsupported for DX11
+		LARGE_INTEGER driverVersionNum;
+		DriverVersion driverVersion;
+		if (SUCCEEDED(adapter->CheckInterfaceSupport(IID_ID3D10Device, &driverVersionNum)))
+		{
+			driverVersion.major = HIWORD(driverVersionNum.HighPart);
+			driverVersion.minor = LOWORD(driverVersionNum.HighPart);
+			driverVersion.release = HIWORD(driverVersionNum.LowPart);
+			driverVersion.build = LOWORD(driverVersionNum.LowPart);
+		}
 
-		// Cube map
-		rsc->setCapability(RSC_CUBEMAPPING);
+		caps.setDriverVersion(driverVersion);
+		caps.setDeviceName(mActiveD3DDriver->getDriverDescription());
+		caps.setRenderAPIName(getName());
 
-		// We always support compression, D3DX will decompress if device does not support
-		rsc->setCapability(RSC_TEXTURE_COMPRESSION);
-		rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
-		rsc->setCapability(RSC_TWO_SIDED_STENCIL);
-		rsc->setCapability(RSC_STENCIL_WRAP);
-		rsc->setCapability(RSC_HWOCCLUSION);
-		rsc->setCapability(RSC_HWOCCLUSION_ASYNCHRONOUS);
+		caps.setCapability(RSC_TEXTURE_COMPRESSION_BC);
+		caps.addShaderProfile("hlsl");
 
 		if(mFeatureLevel >= D3D_FEATURE_LEVEL_10_1)
-			rsc->setMaxBoundVertexBuffers(32);
+			caps.setMaxBoundVertexBuffers(32);
 		else
-			rsc->setMaxBoundVertexBuffers(16);
+			caps.setMaxBoundVertexBuffers(16);
 
 		if(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0)
 		{
-			rsc->addShaderProfile("ps_4_0");
-			rsc->addShaderProfile("vs_4_0");
-			rsc->addShaderProfile("gs_4_0");
+			caps.setCapability(RSC_GEOMETRY_PROGRAM);
+
+			caps.addShaderProfile("ps_4_0");
+			caps.addShaderProfile("vs_4_0");
+			caps.addShaderProfile("gs_4_0");
 
-			rsc->addGpuProgramProfile(GPP_FS_4_0, "ps_4_0");
-			rsc->addGpuProgramProfile(GPP_VS_4_0, "vs_4_0");
-			rsc->addGpuProgramProfile(GPP_GS_4_0, "gs_4_0");
+			caps.addGpuProgramProfile(GPP_FS_4_0, "ps_4_0");
+			caps.addGpuProgramProfile(GPP_VS_4_0, "vs_4_0");
+			caps.addGpuProgramProfile(GPP_GS_4_0, "gs_4_0");
 
-			rsc->setNumTextureUnits(GPT_FRAGMENT_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
-			rsc->setNumTextureUnits(GPT_VERTEX_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
-			rsc->setNumTextureUnits(GPT_GEOMETRY_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
+			caps.setNumTextureUnits(GPT_FRAGMENT_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
+			caps.setNumTextureUnits(GPT_VERTEX_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
+			caps.setNumTextureUnits(GPT_GEOMETRY_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
 
-			rsc->setNumCombinedTextureUnits(rsc->getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
-				+ rsc->getNumTextureUnits(GPT_VERTEX_PROGRAM) + rsc->getNumTextureUnits(GPT_VERTEX_PROGRAM));
+			caps.setNumCombinedTextureUnits(caps.getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_VERTEX_PROGRAM) + caps.getNumTextureUnits(GPT_GEOMETRY_PROGRAM));
 
-			rsc->setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-			rsc->setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-			rsc->setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+			caps.setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+			caps.setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+			caps.setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
 
-			rsc->setNumCombinedGpuParamBlockBuffers(rsc->getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
-				+ rsc->getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + rsc->getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM));
+			caps.setNumCombinedGpuParamBlockBuffers(caps.getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM));
 		}
 
 		if(mFeatureLevel >= D3D_FEATURE_LEVEL_10_1)
 		{
-			rsc->addShaderProfile("ps_4_1");
-			rsc->addShaderProfile("vs_4_1");
-			rsc->addShaderProfile("gs_4_1");
+			caps.addShaderProfile("ps_4_1");
+			caps.addShaderProfile("vs_4_1");
+			caps.addShaderProfile("gs_4_1");
 
-			rsc->addGpuProgramProfile(GPP_FS_4_1, "ps_4_1");
-			rsc->addGpuProgramProfile(GPP_VS_4_1, "vs_4_1");
-			rsc->addGpuProgramProfile(GPP_GS_4_1, "gs_4_1");
+			caps.addGpuProgramProfile(GPP_FS_4_1, "ps_4_1");
+			caps.addGpuProgramProfile(GPP_VS_4_1, "vs_4_1");
+			caps.addGpuProgramProfile(GPP_GS_4_1, "gs_4_1");
 		}
 
 		if(mFeatureLevel >= D3D_FEATURE_LEVEL_11_0)
 		{
-			rsc->addShaderProfile("ps_5_0");
-			rsc->addShaderProfile("vs_5_0");
-			rsc->addShaderProfile("gs_5_0");
-			rsc->addShaderProfile("cs_5_0");
-			rsc->addShaderProfile("hs_5_0");
-			rsc->addShaderProfile("ds_5_0");
-
-			rsc->addGpuProgramProfile(GPP_FS_5_0, "ps_5_0");
-			rsc->addGpuProgramProfile(GPP_VS_5_0, "vs_5_0");
-			rsc->addGpuProgramProfile(GPP_GS_5_0, "gs_5_0");
-			rsc->addGpuProgramProfile(GPP_CS_5_0, "cs_5_0");
-			rsc->addGpuProgramProfile(GPP_HS_5_0, "hs_5_0");
-			rsc->addGpuProgramProfile(GPP_DS_5_0, "ds_5_0");
-
-			rsc->setNumTextureUnits(GPT_HULL_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
-			rsc->setNumTextureUnits(GPT_DOMAIN_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
-			rsc->setNumTextureUnits(GPT_COMPUTE_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
-
-			rsc->setNumCombinedTextureUnits(rsc->getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
-				+ rsc->getNumTextureUnits(GPT_VERTEX_PROGRAM) + rsc->getNumTextureUnits(GPT_VERTEX_PROGRAM)
-				+ rsc->getNumTextureUnits(GPT_HULL_PROGRAM) + rsc->getNumTextureUnits(GPT_DOMAIN_PROGRAM)
-				+ rsc->getNumTextureUnits(GPT_COMPUTE_PROGRAM));
-
-			rsc->setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-			rsc->setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-			rsc->setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
-
-			rsc->setNumCombinedGpuParamBlockBuffers(rsc->getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
-				+ rsc->getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + rsc->getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM)
-				+ rsc->getNumGpuParamBlockBuffers(GPT_HULL_PROGRAM) + rsc->getNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM)
-				+ rsc->getNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM));
-
-			rsc->setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, D3D11_PS_CS_UAV_REGISTER_COUNT);
-			rsc->setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, D3D11_PS_CS_UAV_REGISTER_COUNT);
-
-			rsc->setNumCombinedLoadStoreTextureUnits(rsc->getNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM)
-				+ rsc->getNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM));
-
-			rsc->setCapability(RSC_SHADER_SUBROUTINE);
+			caps.setCapability(RSC_TESSELLATION_PROGRAM);
+			caps.setCapability(RSC_COMPUTE_PROGRAM);
+
+			caps.addShaderProfile("ps_5_0");
+			caps.addShaderProfile("vs_5_0");
+			caps.addShaderProfile("gs_5_0");
+			caps.addShaderProfile("cs_5_0");
+			caps.addShaderProfile("hs_5_0");
+			caps.addShaderProfile("ds_5_0");
+
+			caps.addGpuProgramProfile(GPP_FS_5_0, "ps_5_0");
+			caps.addGpuProgramProfile(GPP_VS_5_0, "vs_5_0");
+			caps.addGpuProgramProfile(GPP_GS_5_0, "gs_5_0");
+			caps.addGpuProgramProfile(GPP_CS_5_0, "cs_5_0");
+			caps.addGpuProgramProfile(GPP_HS_5_0, "hs_5_0");
+			caps.addGpuProgramProfile(GPP_DS_5_0, "ds_5_0");
+
+			caps.setNumTextureUnits(GPT_HULL_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
+			caps.setNumTextureUnits(GPT_DOMAIN_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
+			caps.setNumTextureUnits(GPT_COMPUTE_PROGRAM, D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT);
+
+			caps.setNumCombinedTextureUnits(caps.getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_VERTEX_PROGRAM) + caps.getNumTextureUnits(GPT_GEOMETRY_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_HULL_PROGRAM) + caps.getNumTextureUnits(GPT_DOMAIN_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_COMPUTE_PROGRAM));
+
+			caps.setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+			caps.setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+			caps.setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+
+			caps.setNumCombinedGpuParamBlockBuffers(caps.getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_HULL_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM));
+
+			caps.setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, D3D11_PS_CS_UAV_REGISTER_COUNT);
+			caps.setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, D3D11_PS_CS_UAV_REGISTER_COUNT);
+
+			caps.setNumCombinedLoadStoreTextureUnits(caps.getNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM));
 		}
 
-		rsc->setCapability(RSC_USER_CLIP_PLANES);
-		rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
-
 		// Adapter details
 		const DXGI_ADAPTER_DESC& adapterID = mActiveD3DDriver->getAdapterIdentifier();
 
@@ -1256,41 +1243,21 @@ namespace BansheeEngine
 		switch(adapterID.VendorId)
 		{
 		case 0x10DE:
-			rsc->setVendor(GPU_NVIDIA);
+			caps.setVendor(GPU_NVIDIA);
 			break;
 		case 0x1002:
-			rsc->setVendor(GPU_AMD);
+			caps.setVendor(GPU_AMD);
 			break;
 		case 0x163C:
 		case 0x8086:
-			rsc->setVendor(GPU_INTEL);
+			caps.setVendor(GPU_INTEL);
 			break;
 		default:
-			rsc->setVendor(GPU_UNKNOWN);
+			caps.setVendor(GPU_UNKNOWN);
 			break;
 		};
 
-		rsc->setCapability(RSC_INFINITE_FAR_PLANE);
-
-		rsc->setCapability(RSC_TEXTURE_3D);
-		rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
-		rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
-		rsc->setCapability(RSC_TEXTURE_FLOAT);
-
-		rsc->setNumMultiRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);
-		rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS);
-
-		rsc->setCapability(RSC_POINT_SPRITES);
-		rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS);
-		rsc->setMaxPointSize(256);
-
-		rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
-
-		rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
-
-		rsc->setCapability(RSC_PERSTAGECONSTANT);
-
-		return rsc;
+		caps.setNumMultiRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);
 	}
 
 	void D3D11RenderAPI::determineMultisampleSettings(UINT32 multisampleCount, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outputSampleDesc)

+ 1 - 1
Source/BansheeGLRenderAPI/Include/BsGLRenderAPI.h

@@ -167,7 +167,7 @@ namespace BansheeEngine
 		GLint getGLDrawMode() const;
 
 		/**	Creates render system capabilities that specify which features are or aren't supported. */
-		RenderAPICapabilities* createRenderSystemCapabilities() const;
+		void initCapabilities(RenderAPICapabilities& caps) const;
 
 		/**	Finish initialization by setting up any systems dependant on render systemcapabilities. */
 		void initFromCaps(RenderAPICapabilities* caps);

+ 50 - 223
Source/BansheeGLRenderAPI/Source/BsGLRenderAPI.cpp

@@ -128,19 +128,10 @@ namespace BansheeEngine
 		mGLSupport->initializeExtensions();
 		checkForErrors();
 
-		Vector<BansheeEngine::String> tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
+		mNumDevices = 1;
+		mCurrentCapabilities = bs_newN<RenderAPICapabilities>(mNumDevices);
+		initCapabilities(mCurrentCapabilities[0]);		
 
-		if (!tokens.empty())
-		{
-			mDriverVersion.major = parseINT32(tokens[0]);
-			if (tokens.size() > 1)
-				mDriverVersion.minor = parseINT32(tokens[1]);
-			if (tokens.size() > 2)
-				mDriverVersion.release = parseINT32(tokens[2]);
-		}
-		mDriverVersion.build = 0;
-
-		mCurrentCapabilities = createRenderSystemCapabilities();
 		initFromCaps(mCurrentCapabilities);
 		GLVertexArrayObjectManager::startUp();
 		glFrontFace(GL_CW);
@@ -1471,7 +1462,7 @@ namespace BansheeEngine
 	{
 		static bool lasta2c = false;
 
-		if (enable != lasta2c && getCapabilities().hasCapability(RSC_ALPHA_TO_COVERAGE))
+		if (enable != lasta2c)
 		{
 			if (enable)
 				glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
@@ -1751,7 +1742,7 @@ namespace BansheeEngine
 	{
 		if (mActiveTextureUnit != unit)
 		{
-			if (unit < getCapabilities().getNumCombinedTextureUnits())
+			if (unit < getCapabilities(0).getNumCombinedTextureUnits())
 			{
 				glActiveTexture(GL_TEXTURE0 + unit);
 				mActiveTextureUnit = unit;
@@ -1765,7 +1756,7 @@ namespace BansheeEngine
 			else
 			{
 				LOGWRN("Provided texture unit index is higher than OpenGL supports. Provided: " + toString(unit) + 
-					". Supported range: 0 .. " + toString(getCapabilities().getNumCombinedTextureUnits() - 1));
+					". Supported range: 0 .. " + toString(getCapabilities(0).getNumCombinedTextureUnits() - 1));
 				return false;
 			}
 		}
@@ -2051,19 +2042,7 @@ namespace BansheeEngine
 			GpuProgramCoreManager::instance().addFactory(mGLSLProgramFactory);
 		}
 
-		// Check for framebuffer object extension
-		if(caps->hasCapability(RSC_FBO))
-		{
-			if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE))
-			{
-				// Create FBO manager
-				GLRTTManager::startUp<GLRTTManager>();
-			}
-		}
-		else
-		{
-			BS_EXCEPT(RenderingAPIException, "GPU doesn't support frame buffer objects. OpenGL versions lower than 3.0 are not supported.");
-		}
+		GLRTTManager::startUp<GLRTTManager>();
 
 		UINT32 curTexUnitOffset = 0;
 		for (UINT32 i = 0; i < 6; i++)
@@ -2106,277 +2085,125 @@ namespace BansheeEngine
 		glStencilMask(mStencilWriteMask);
 	}
 
-	RenderAPICapabilities* GLRenderAPI::createRenderSystemCapabilities() const
+	void GLRenderAPI::initCapabilities(RenderAPICapabilities& caps) const
 	{
-		RenderAPICapabilities* rsc = bs_new<RenderAPICapabilities>();
+		Vector<String> tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
 
-		rsc->setDriverVersion(mDriverVersion);
+		DriverVersion driverVersion;
+		if (!tokens.empty())
+		{
+			driverVersion.major = parseINT32(tokens[0]);
+			if (tokens.size() > 1)
+				driverVersion.minor = parseINT32(tokens[1]);
+			if (tokens.size() > 2)
+				driverVersion.release = parseINT32(tokens[2]);
+		}
+		driverVersion.build = 0;
+
+		caps.setDriverVersion(driverVersion);
 		const char* deviceName = (const char*)glGetString(GL_RENDERER);
 		const char* vendorName = (const char*)glGetString(GL_VENDOR);
-		rsc->setDeviceName(deviceName);
-		rsc->setRenderAPIName(getName());
+		caps.setDeviceName(deviceName);
+		caps.setRenderAPIName(getName());
 
 		// determine vendor
 		if (strstr(vendorName, "NVIDIA"))
-			rsc->setVendor(GPU_NVIDIA);
+			caps.setVendor(GPU_NVIDIA);
 		else if (strstr(vendorName, "ATI"))
-			rsc->setVendor(GPU_AMD);
+			caps.setVendor(GPU_AMD);
 		else if (strstr(vendorName, "AMD"))
-			rsc->setVendor(GPU_AMD);
+			caps.setVendor(GPU_AMD);
 		else if (strstr(vendorName, "Intel"))
-			rsc->setVendor(GPU_INTEL);
+			caps.setVendor(GPU_INTEL);
 		else
-			rsc->setVendor(GPU_UNKNOWN);
-
-		// Check for hardware mipmapping support.
-		if(GLEW_VERSION_1_4)
-		{
-			rsc->setCapability(RSC_AUTOMIPMAP);
-		}
+			caps.setVendor(GPU_UNKNOWN);
 
-		// Check for Anisotropy support
-		if (getGLSupport()->checkExtension("GL_EXT_texture_filter_anisotropic"))
-		{
-			rsc->setCapability(RSC_ANISOTROPY);
-		}
-
-		// Check for cube mapping
-		if(GLEW_VERSION_1_3 || 
-			getGLSupport()->checkExtension("GL_ARB_texture_cube_map") ||
-			getGLSupport()->checkExtension("GL_EXT_texture_cube_map"))
-		{
-			rsc->setCapability(RSC_CUBEMAPPING);
-		}
-
-		// Point sprites
-		if (GLEW_VERSION_2_0 || getGLSupport()->checkExtension("GL_ARB_point_sprite"))
-		{
-			rsc->setCapability(RSC_POINT_SPRITES);
-		}
-
-		// Check for hardware stencil support and set bit depth
-		GLint stencil;
-		glGetIntegerv(GL_STENCIL_BITS, &stencil);
-
-		if(stencil)
-		{
-			rsc->setStencilBufferBitDepth(stencil);
-		}
-
-		if (GLEW_VERSION_2_0 || 
-			(getGLSupport()->checkExtension("GL_ARB_shading_language_100") &&
-			getGLSupport()->checkExtension("GL_ARB_shader_objects") &&
-			getGLSupport()->checkExtension("GL_ARB_fragment_shader") &&
-			getGLSupport()->checkExtension("GL_ARB_vertex_shader")))
-		{
-			rsc->addShaderProfile("glsl");
-		}
+		caps.addShaderProfile("glsl");
+		caps.setCapability(RSC_TEXTURE_COMPRESSION_BC);
 
 		// Check if geometry shaders are supported
 		if (GLEW_VERSION_2_0 &&
 			getGLSupport()->checkExtension("GL_EXT_geometry_shader4"))
 		{
-			rsc->setCapability(RSC_GEOMETRY_PROGRAM);
-
-			rsc->setGeometryProgramConstantBoolCount(0);
-			rsc->setGeometryProgramConstantIntCount(0);
-
-			GLint floatConstantCount = 0;
-			glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT, &floatConstantCount);
-			rsc->setGeometryProgramConstantFloatCount(floatConstantCount);
+			caps.setCapability(RSC_GEOMETRY_PROGRAM);
 
 			GLint maxOutputVertices;
 			glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&maxOutputVertices);
-			rsc->setGeometryProgramNumOutputVertices(maxOutputVertices);
-		}
-
-		//Check if render to vertex buffer (transform feedback in OpenGL)
-		if (GLEW_VERSION_2_0 && getGLSupport()->checkExtension("GL_EXT_transform_feedback"))
-		{
-			rsc->setCapability(RSC_HWRENDER_TO_VERTEX_BUFFER);
-		}
-
-		// Check for texture compression
-		if (GLEW_VERSION_1_3 || getGLSupport()->checkExtension("GL_ARB_texture_compression"))
-		{   
-			rsc->setCapability(RSC_TEXTURE_COMPRESSION);
-
-			// Check for dxt compression
-			if (getGLSupport()->checkExtension("GL_EXT_texture_compression_s3tc"))
-			{
-				rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
-			}
-
-			// Check for vtc compression
-			if (getGLSupport()->checkExtension("GL_NV_texture_compression_vtc"))
-			{
-				rsc->setCapability(RSC_TEXTURE_COMPRESSION_VTC);
-			}
-		}
-
-		// As are user clipping planes
-		rsc->setCapability(RSC_USER_CLIP_PLANES);
-
-		// 2-sided stencil?
-		if (GLEW_VERSION_2_0 || getGLSupport()->checkExtension("GL_EXT_stencil_two_side"))
-		{
-			rsc->setCapability(RSC_TWO_SIDED_STENCIL);
-		}
-
-		// stencil wrapping?
-		if (GLEW_VERSION_1_4 || getGLSupport()->checkExtension("GL_EXT_stencil_wrap"))
-		{
-			rsc->setCapability(RSC_STENCIL_WRAP);
-		}
-
-		// Check for hardware occlusion support
-		if (GLEW_VERSION_1_5 || getGLSupport()->checkExtension("GL_ARB_occlusion_query"))
-		{
-			rsc->setCapability(RSC_HWOCCLUSION);
-		}
-
-		// UBYTE4 always supported
-		rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
-
-		// Infinite far plane always supported
-		rsc->setCapability(RSC_INFINITE_FAR_PLANE);
-
-		// Check for non-power-of-2 texture support
-		if (getGLSupport()->checkExtension("GL_ARB_texture_non_power_of_two"))
-		{
-			rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
-		}
-
-		// Check for Float textures
-		if (getGLSupport()->checkExtension("GL_ATI_texture_float") || getGLSupport()->checkExtension("GL_ARB_texture_float"))
-		{
-			rsc->setCapability(RSC_TEXTURE_FLOAT);
+			caps.setGeometryProgramNumOutputVertices(maxOutputVertices);
 		}
 
-		// 3D textures should always be supported
-		rsc->setCapability(RSC_TEXTURE_3D);
-
-		// Check for framebuffer object extension
-		if (getGLSupport()->checkExtension("GL_ARB_framebuffer_object"))
-		{
-			// Probe number of draw buffers
-			// Only makes sense with FBO support, so probe here
-			if (GLEW_VERSION_2_0 || getGLSupport()->checkExtension("GL_ARB_draw_buffers") || getGLSupport()->checkExtension("GL_ATI_draw_buffers"))
-			{
-				GLint buffers;
-				glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &buffers);
-				rsc->setNumMultiRenderTargets(std::min<int>(buffers, (GLint)BS_MAX_MULTIPLE_RENDER_TARGETS));
-				rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS);
-
-				rsc->setCapability(RSC_FBO);
-
-			}
-			rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
-		}
-
-		rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
-		rsc->setCapability(RSC_PBUFFER);
-
-		// Point size
-		float ps;
-		glGetFloatv(GL_POINT_SIZE_MAX, &ps);
-		rsc->setMaxPointSize(ps);
-
 		// Max number of fragment shader textures
 		GLint units;
 		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
-		rsc->setNumTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(units));
+		caps.setNumTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(units));
 
 		// Max number of vertex shader textures
 		GLint vUnits;
 		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vUnits);
-		rsc->setNumTextureUnits(GPT_VERTEX_PROGRAM, static_cast<UINT16>(vUnits));
-		if (vUnits > 0)
-		{
-			rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
-		}
+		caps.setNumTextureUnits(GPT_VERTEX_PROGRAM, static_cast<UINT16>(vUnits));
 
 		GLint numUniformBlocks;
 		glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &numUniformBlocks);
-		rsc->setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, numUniformBlocks);
+		caps.setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, numUniformBlocks);
 
 		glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &numUniformBlocks);
-		rsc->setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, numUniformBlocks);
+		caps.setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, numUniformBlocks);
 
 		if (mGLSupport->checkExtension("GL_ARB_geometry_shader4"))
 		{
 			GLint geomUnits;
 			glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &geomUnits);
-			rsc->setNumTextureUnits(GPT_GEOMETRY_PROGRAM, static_cast<UINT16>(geomUnits));
+			caps.setNumTextureUnits(GPT_GEOMETRY_PROGRAM, static_cast<UINT16>(geomUnits));
 
 			glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &numUniformBlocks);
-			rsc->setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, numUniformBlocks);
+			caps.setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, numUniformBlocks);
 		}
 
 		if (mGLSupport->checkExtension("GL_ARB_tessellation_shader"))
 		{
-			rsc->setCapability(RSC_TESSELLATION_PROGRAM);
+			caps.setCapability(RSC_TESSELLATION_PROGRAM);
 
 			glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &numUniformBlocks);
-			rsc->setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, numUniformBlocks);
+			caps.setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, numUniformBlocks);
 
 			glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &numUniformBlocks);
-			rsc->setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, numUniformBlocks);
+			caps.setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, numUniformBlocks);
 		}
 
 		if (mGLSupport->checkExtension("GL_ARB_compute_shader")) 
 		{
-			rsc->setCapability(RSC_COMPUTE_PROGRAM);
+			caps.setCapability(RSC_COMPUTE_PROGRAM);
 
 			GLint computeUnits;
 			glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &computeUnits);
-			rsc->setNumTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(computeUnits));
+			caps.setNumTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(computeUnits));
 
 			glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &numUniformBlocks);
-			rsc->setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, numUniformBlocks);
+			caps.setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, numUniformBlocks);
 
 			// Max number of load-store textures
 			GLint lsfUnits;
 			glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &lsfUnits);
-			rsc->setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(lsfUnits));
+			caps.setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(lsfUnits));
 
 			GLint lscUnits;
 			glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &lscUnits);
-			rsc->setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(lscUnits));
+			caps.setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(lscUnits));
 
 			GLint combinedLoadStoreTextureUnits;
 			glGetIntegerv(GL_MAX_IMAGE_UNITS, &combinedLoadStoreTextureUnits);
-			rsc->setNumCombinedLoadStoreTextureUnits(static_cast<UINT16>(combinedLoadStoreTextureUnits));
+			caps.setNumCombinedLoadStoreTextureUnits(static_cast<UINT16>(combinedLoadStoreTextureUnits));
 		}
 
 		GLint combinedTexUnits;
 		glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &combinedTexUnits);
-		rsc->setNumCombinedTextureUnits(static_cast<UINT16>(combinedTexUnits));
+		caps.setNumCombinedTextureUnits(static_cast<UINT16>(combinedTexUnits));
 
 		GLint combinedUniformBlockUnits;
 		glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &combinedUniformBlockUnits);
-		rsc->setNumCombinedGpuParamBlockBuffers(static_cast<UINT16>(combinedUniformBlockUnits));
-
-		// Mipmap LOD biasing
-
-		if (mGLSupport->checkExtension("GL_EXT_texture_lod_bias"))
-			rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
-
-		// Alpha to coverage?
-		if (mGLSupport->checkExtension("GL_ARB_multisample"))
-		{
-			// Alpha to coverage always 'supported' when MSAA is available
-			// although card may ignore it if it doesn't specifically support A2C
-			rsc->setCapability(RSC_ALPHA_TO_COVERAGE);
-		}
-
-		// Advanced blending operations
-		if(GLEW_VERSION_2_0)
-		{
-			rsc->setCapability(RSC_ADVANCED_BLEND_OPERATIONS);
-		}
+		caps.setNumCombinedGpuParamBlockBuffers(static_cast<UINT16>(combinedUniformBlockUnits));
 
-		return rsc;
+		caps.setNumMultiRenderTargets(8);
 	}
 
 	bool GLRenderAPI::checkForErrors() const

+ 4 - 1
Source/BansheeVulkanRenderAPI/Include/BsVulkanRenderAPI.h

@@ -134,7 +134,7 @@ namespace BansheeEngine
 		 */
 		const Vector<SPtr<VulkanDevice>> _getPrimaryDevices() const { return mPrimaryDevices; }
 
-		/** @}/
+		/** @} */
 	protected:
 		friend class VulkanRenderAPIFactory;
 
@@ -144,6 +144,9 @@ namespace BansheeEngine
 		/** @copydoc RenderAPICore::destroyCore */
 		void destroyCore() override;
 
+		/** Creates and populates a set of render system capabilities describing which functionality is available. */
+		void initCapabilites();
+
 	private:
 		VkInstance mInstance;
 

+ 124 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanRenderAPI.cpp

@@ -241,9 +241,8 @@ namespace BansheeEngine
 		RenderStateCoreManager::startUp<VulkanRenderStateCoreManager>();
 		GpuProgramCoreManager::instance().addFactory(mGLSLFactory);
 
-		// TODO - Create and populate capabilities, per device
-		mCurrentCapabilities->addShaderProfile("glsl");
-
+		initCapabilites();
+		
 		RenderAPICore::initialize();
 	}
 
@@ -423,4 +422,126 @@ namespace BansheeEngine
 		
 		return block;
 	}
+
+	void VulkanRenderAPI::initCapabilites()
+	{
+		mNumDevices = (UINT32)mDevices.size();
+		mCurrentCapabilities = bs_newN<RenderAPICapabilities>(mNumDevices);
+
+		UINT32 deviceIdx = 0;
+		for (auto& device : mDevices)
+		{
+			RenderAPICapabilities& caps = mCurrentCapabilities[deviceIdx];
+
+			const VkPhysicalDeviceProperties& deviceProps = device->getDeviceProperties();
+			const VkPhysicalDeviceFeatures& deviceFeatures = device->getDeviceFeatures();
+			const VkPhysicalDeviceLimits& deviceLimits = deviceProps.limits;
+
+			DriverVersion driverVersion;
+			driverVersion.major = ((uint32_t)(deviceProps.apiVersion) >> 22);
+			driverVersion.minor = ((uint32_t)(deviceProps.apiVersion) >> 12) & 0x3ff;
+			driverVersion.release = (uint32_t)(deviceProps.apiVersion) & 0xfff;
+			driverVersion.build = 0;
+
+			caps.setDriverVersion(driverVersion);
+			caps.setDeviceName(deviceProps.deviceName);
+			
+			// Determine vendor
+			switch (deviceProps.vendorID)
+			{
+			case 0x10DE:
+				caps.setVendor(GPU_NVIDIA);
+				break;
+			case 0x1002:
+				caps.setVendor(GPU_AMD);
+				break;
+			case 0x163C:
+			case 0x8086:
+				caps.setVendor(GPU_INTEL);
+				break;
+			default:
+				caps.setVendor(GPU_UNKNOWN);
+				break;
+			};
+			
+			caps.setRenderAPIName(getName());
+
+			if(deviceFeatures.textureCompressionBC)
+				caps.setCapability(RSC_TEXTURE_COMPRESSION_BC);
+
+			if (deviceFeatures.textureCompressionETC2)
+				caps.setCapability(RSC_TEXTURE_COMPRESSION_ETC2);
+
+			if (deviceFeatures.textureCompressionASTC_LDR)
+				caps.setCapability(RSC_TEXTURE_COMPRESSION_ASTC);
+
+			caps.setMaxBoundVertexBuffers(deviceLimits.maxVertexInputBindings);
+			caps.setNumMultiRenderTargets(deviceLimits.maxColorAttachments);
+
+			caps.setCapability(RSC_COMPUTE_PROGRAM);
+
+			caps.addShaderProfile("ps_5_0");
+			caps.addShaderProfile("vs_5_0");
+			caps.addShaderProfile("cs_5_0");
+
+			caps.addGpuProgramProfile(GPP_FS_5_0, "ps_5_0");
+			caps.addGpuProgramProfile(GPP_VS_5_0, "vs_5_0");
+			caps.addGpuProgramProfile(GPP_CS_5_0, "cs_5_0");
+
+			caps.setNumTextureUnits(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+			caps.setNumTextureUnits(GPT_VERTEX_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+			caps.setNumTextureUnits(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+
+			caps.setNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+			caps.setNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+			caps.setNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+
+			caps.setNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM, deviceLimits.maxPerStageDescriptorStorageImages);
+			caps.setNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM, deviceLimits.maxPerStageDescriptorStorageImages);
+
+			if(deviceFeatures.geometryShader)
+			{
+				caps.setCapability(RSC_GEOMETRY_PROGRAM);
+				caps.addShaderProfile("gs_5_0");
+				caps.addGpuProgramProfile(GPP_GS_5_0, "gs_5_0");
+				caps.setNumTextureUnits(GPT_GEOMETRY_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+				caps.setNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+				caps.setGeometryProgramNumOutputVertices(deviceLimits.maxGeometryOutputVertices);
+			}
+
+			if (deviceFeatures.tessellationShader)
+			{
+				caps.setCapability(RSC_TESSELLATION_PROGRAM);
+
+				caps.addShaderProfile("hs_5_0");
+				caps.addShaderProfile("ds_5_0");
+
+				caps.addGpuProgramProfile(GPP_HS_5_0, "hs_5_0");
+				caps.addGpuProgramProfile(GPP_DS_5_0, "ds_5_0");
+
+				caps.setNumTextureUnits(GPT_HULL_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+				caps.setNumTextureUnits(GPT_DOMAIN_PROGRAM, deviceLimits.maxPerStageDescriptorSampledImages);
+				
+				caps.setNumGpuParamBlockBuffers(GPT_HULL_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+				caps.setNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM, deviceLimits.maxPerStageDescriptorUniformBuffers);
+			}
+
+			caps.setNumCombinedTextureUnits(caps.getNumTextureUnits(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_VERTEX_PROGRAM) + caps.getNumTextureUnits(GPT_GEOMETRY_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_HULL_PROGRAM) + caps.getNumTextureUnits(GPT_DOMAIN_PROGRAM)
+				+ caps.getNumTextureUnits(GPT_COMPUTE_PROGRAM));
+
+			caps.setNumCombinedGpuParamBlockBuffers(caps.getNumGpuParamBlockBuffers(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_VERTEX_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_GEOMETRY_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_HULL_PROGRAM) + caps.getNumGpuParamBlockBuffers(GPT_DOMAIN_PROGRAM)
+				+ caps.getNumGpuParamBlockBuffers(GPT_COMPUTE_PROGRAM));
+
+			caps.setNumCombinedLoadStoreTextureUnits(caps.getNumLoadStoreTextureUnits(GPT_FRAGMENT_PROGRAM)
+				+ caps.getNumLoadStoreTextureUnits(GPT_COMPUTE_PROGRAM));
+
+			caps.addShaderProfile("glsl");
+
+			deviceIdx++;
+		}
+	}
 }