Bläddra i källkod

Vulkan resource descriptors WIP

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

+ 30 - 30
Source/BansheeCore/Include/BsGpuParams.h

@@ -134,30 +134,6 @@ namespace BansheeEngine
 
 		virtual ~TGpuParams();
 
-		/**
-		 * Binds a new parameter buffer to the specified slot. Any following parameter reads or writes that are referencing
-		 * that buffer slot will use the new buffer.
-		 *
-		 * @note	
-		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
-		 * values once and then share the buffer among all other GpuParams.
-		 * @note
-		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
-		 */
-		void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
-
-		/**
-		 * Replaces the parameter buffer with the specified name. Any following parameter reads or writes that are 
-		 * referencing that buffer will use the new buffer.
-		 *
-		 * @note	
-		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
-		 * values once and then share the buffer among all other GpuParams.
-		 * @note
-		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
-		 */
-		void setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer);
-
 		/**
 		 * Returns a handle for the parameter with the specified name. Handle may then be stored and used for quickly 
 		 * setting or retrieving values to/from that parameter.
@@ -201,20 +177,44 @@ namespace BansheeEngine
 		/** Gets information that determines which texture surfaces to bind as load/store parameters. */
 		const TextureSurface& getLoadStoreSurface(UINT32 set, UINT32 slot) const;
 
+		/**
+		 * Sets the parameter buffer with the specified name. Any following parameter reads or writes that are 
+		 * referencing that buffer will use the new buffer.
+		 *
+		 * @note	
+		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
+		 * values once and then share the buffer among all other GpuParams.
+		 * @note
+		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
+		 */
+		void setParamBlockBuffer(GpuProgramType type, const String& name, const ParamsBufferType& paramBlockBuffer);
+
+		/**
+		 * Binds a new parameter buffer to the specified slot. Any following parameter reads or writes that are referencing
+		 * that buffer slot will use the new buffer.
+		 *
+		 * @note	
+		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
+		 * values once and then share the buffer among all other GpuParams.
+		 * @note
+		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
+		 */
+		virtual void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer);
+
 		/**	Sets a texture at the specified set/slot combination. */
-		void setTexture(UINT32 set, UINT32 slot, const TextureType& texture);
+		virtual void setTexture(UINT32 set, UINT32 slot, const TextureType& texture);
 
 		/**	Sets a load/store texture at the specified set/slot combination. */
-		void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
+		virtual void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface);
 
 		/**	Sets a buffer at the specified set/slot combination. */
-		void setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer);
+		virtual void setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer);
 
 		/**	Sets a sampler state at the specified set/slot combination. */
-		void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
+		virtual void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler);
 
 		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
-		void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface);
+		virtual void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface);
 
 	protected:
 		/** Type of elements stored in this object. */
@@ -260,7 +260,7 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuParamsCore : public CoreObjectCore, public TGpuParams<true>
 	{
 	public:
-		~GpuParamsCore() { }
+		virtual ~GpuParamsCore() { }
 
 		/** 
 		 * @copydoc GpuParams::create 

+ 2 - 0
Source/BansheeVulkanRenderAPI/CMakeSources.cmake

@@ -21,6 +21,7 @@ set(BS_BANSHEEVULKANRENDERAPI_INC_NOFILTER
 	"Include/BsVulkanSwapChain.h"
 	"Include/BsVulkanFramebuffer.h"
 	"Include/BsVulkanUtility.h"
+	"Include/BsVulkanGpuParams.h"
 )
 
 set(BS_BANSHEEVULKANRENDERAPI_INC_MANAGERS
@@ -58,6 +59,7 @@ set(BS_BANSHEEVULKANRENDERAPI_SRC_NOFILTER
 	"Source/BsVulkanSwapChain.cpp"
 	"Source/BsVulkanFramebuffer.cpp"
 	"Source/BsVulkanUtility.cpp"
+	"Source/BsVulkanGpuParams.cpp"
 )
 
 set(BS_BANSHEEVULKANRENDERAPI_SRC_MANAGERS

+ 56 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanGpuParams.h

@@ -0,0 +1,56 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsVulkanPrerequisites.h"
+#include "BsGpuParams.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Vulkan
+	 *  @{
+	 */
+
+	/** Vulkan implementation of GpuParams, containing resource descriptors for all shader stages. */
+	class VulkanGpuParams : public GpuParamsCore
+	{
+	public:
+		~VulkanGpuParams();
+
+		/** @copydoc GpuParamsCore::setParamBlockBuffer(UINT32, UINT32, const ParamsBufferType&) */
+		void setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer) override;
+
+		/** @copydoc GpuParamsCore::setTexture */
+		void setTexture(UINT32 set, UINT32 slot, const TextureType& texture) override;
+
+		/** @copydoc GpuParamsCore::setLoadStoreTexture */
+		void setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, 
+			const TextureSurface& surface) override;
+
+		/** @copydoc GpuParamsCore::setBuffer */
+		void setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer) override;
+
+		/** @copydoc GpuParamsCore::setSamplerState */
+		void setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler) override;
+
+		/** @copydoc GpuParamsCore::setLoadStoreSurface */
+		void setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface) override;
+
+	protected:
+		friend class VulkanHardwareBufferCoreManager;
+
+		/** Information about a single descriptor set. */
+		struct SetInfo
+		{
+			VkDescriptorSetLayout layout;
+			VkDescriptorSet set;
+		};
+
+		VulkanGpuParams(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask);
+
+		SetInfo* mSets;
+		UINT32 mNumSets;
+	};
+
+	/** @} */
+}

+ 4 - 0
Source/BansheeVulkanRenderAPI/Include/BsVulkanHardwareBufferManager.h

@@ -33,6 +33,10 @@ namespace BansheeEngine
 		/** @copydoc HardwareBufferCoreManager::createGpuBufferInternal */
 		SPtr<GpuBufferCore> createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
 			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
+
+		/** @copydoc HardwareBufferCoreManager::createGpuParamsInternal */
+		SPtr<GpuParamsCore> createGpuParamsInternal(const GPU_PARAMS_DESC& desc, 
+			GpuDeviceFlags deviceMask = GDF_DEFAULT) override;
 	};
 
 	/** @} */

+ 157 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuParams.cpp

@@ -0,0 +1,157 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsVulkanGpuParams.h"
+#include "BsGpuParamDesc.h"
+
+namespace BansheeEngine
+{
+	VulkanGpuParams::VulkanGpuParams(const GPU_PARAMS_DESC& desc, GpuDeviceFlags deviceMask)
+		:GpuParamsCore(desc, deviceMask)
+	{
+		UINT32 numBindings = 0;
+		UINT32 numSets = 0;
+		
+		UINT32 numElementTypes = (UINT32)ElementType::Count;
+		for (UINT32 i = 0; i < numElementTypes; i++)
+		{
+			numBindings += mNumElements[i];
+			numSets = std::max(numSets, mNumSets[i]);
+		}
+
+		UINT32 bindingsPerSetBytes = sizeof(UINT32) * numSets;
+		UINT32* bindingsPerSet = (UINT32*)bs_stack_alloc(bindingsPerSetBytes);
+
+		UINT32 bindingsSize = sizeof(VkDescriptorSetLayoutBinding) * numBindings;
+		VkDescriptorSetLayoutBinding* bindings = (VkDescriptorSetLayoutBinding*)bs_stack_alloc(bindingsSize);
+		memset(bindings, 0, bindingsSize);
+
+		UINT32 globalBindingIdx = 0;
+		for(UINT32 i = 0; i < numSets; i++)
+		{
+			bindingsPerSet[i] = 0;
+			for(UINT32 j = 0; j < numElementTypes; j++)
+			{
+				if (i >= mNumSets[j])
+					continue;
+
+				UINT32 start = mOffsets[j][i];
+
+				UINT32 end;
+				if (i < (mNumSets[j] - 1))
+					end = mOffsets[j][i + 1];
+				else
+					end = mNumElements[j];
+
+				UINT32 elementsInSet = end - start;
+				for(UINT32 k = 0; k < elementsInSet; k++)
+				{
+					VkDescriptorSetLayoutBinding& binding = bindings[globalBindingIdx + k];
+					binding.binding = bindingsPerSet[i] + k;
+				};
+
+				globalBindingIdx += elementsInSet;
+				bindingsPerSet[i] += elementsInSet;
+			}
+		}
+
+		UINT32* bindingOffsets = (UINT32*)bs_stack_alloc(sizeof(UINT32) * numSets);
+		if (numSets > 0)
+		{
+			bindingOffsets[0] = 0;
+
+			for (UINT32 i = 1; i < numSets; i++)
+				bindingOffsets[i] = bindingsPerSet[i - 1];
+		}
+
+		VkShaderStageFlags stageFlagsLookup[6];
+		stageFlagsLookup[GPT_VERTEX_PROGRAM] = VK_SHADER_STAGE_VERTEX_BIT;
+		stageFlagsLookup[GPT_HULL_PROGRAM] = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+		stageFlagsLookup[GPT_DOMAIN_PROGRAM] = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+		stageFlagsLookup[GPT_GEOMETRY_PROGRAM] = VK_SHADER_STAGE_GEOMETRY_BIT;
+		stageFlagsLookup[GPT_FRAGMENT_PROGRAM] = VK_SHADER_STAGE_FRAGMENT_BIT;
+		stageFlagsLookup[GPT_COMPUTE_PROGRAM] = VK_SHADER_STAGE_COMPUTE_BIT;
+
+		UINT32 numParamDescs = sizeof(mParamDescs) / sizeof(mParamDescs[0]);
+		for (UINT32 i = 0; i < numParamDescs; i++)
+		{
+			const SPtr<GpuParamDesc>& paramDesc = mParamDescs[i];
+			if (paramDesc == nullptr)
+				continue;
+
+			auto setUpBindings = [&](auto& params, VkDescriptorType descType)
+			{
+				for (auto& entry : params)
+				{
+					UINT32 bindingIdx = bindingOffsets[entry.second.set] + entry.second.slot;
+
+					VkDescriptorSetLayoutBinding& binding = bindings[bindingIdx];
+					binding.descriptorCount = 1;
+					binding.stageFlags |= stageFlagsLookup[i];
+					binding.descriptorType = descType;
+				}
+			};
+
+			// Note: Assuming all textures and samplers use the same set/slot combination, and that they're combined
+			setUpBindings(paramDesc->paramBlocks, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
+			setUpBindings(paramDesc->textures, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
+			setUpBindings(paramDesc->loadStoreTextures, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
+			setUpBindings(paramDesc->buffers, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
+			setUpBindings(paramDesc->samplers, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
+		}
+
+
+		for (UINT32 i = 0; i < numSets; i++)
+		{
+		}
+
+		// TODO - Actually allocate and create layouts and sets
+		// TODO - Create sets per-device
+		// TODO - Prepare write descs and see what's the best way to update them
+
+		bs_stack_free(bindingOffsets);
+		bs_stack_free(bindings);
+		bs_stack_free(bindingsPerSet);
+
+		
+
+
+		// Note: Set layout creation should be moved up to Shader, since one layout can be shared between multiple
+		// GPU params. Right now we take the easy route and just create a new layout every time (meaning there's a lot of
+		// duplicates).
+	}
+
+	VulkanGpuParams::~VulkanGpuParams()
+	{
+		// TODO - CLean up mSets
+	}
+
+	void VulkanGpuParams::setParamBlockBuffer(UINT32 set, UINT32 slot, const ParamsBufferType& paramBlockBuffer)
+	{
+		GpuParamsCore::setParamBlockBuffer(set, slot, paramBlockBuffer);
+	}
+
+	void VulkanGpuParams::setTexture(UINT32 set, UINT32 slot, const TextureType& texture)
+	{
+		GpuParamsCore::setTexture(set, slot, texture);
+	}
+
+	void VulkanGpuParams::setLoadStoreTexture(UINT32 set, UINT32 slot, const TextureType& texture, const TextureSurface& surface)
+	{
+		GpuParamsCore::setLoadStoreTexture(set, slot, texture, surface);
+	}
+
+	void VulkanGpuParams::setBuffer(UINT32 set, UINT32 slot, const BufferType& buffer)
+	{
+		GpuParamsCore::setBuffer(set, slot, buffer);
+	}
+
+	void VulkanGpuParams::setSamplerState(UINT32 set, UINT32 slot, const SamplerType& sampler)
+	{
+		GpuParamsCore::setSamplerState(set, slot, sampler);
+	}
+
+	void VulkanGpuParams::setLoadStoreSurface(UINT32 set, UINT32 slot, const TextureSurface& surface)
+	{
+		GpuParamsCore::setLoadStoreSurface(set, slot, surface);
+	}
+}

+ 1 - 1
Source/BansheeVulkanRenderAPI/Source/BsVulkanHardwareBuffer.cpp

@@ -30,7 +30,7 @@ namespace BansheeEngine
 		}
 
 		VkMemoryPropertyFlags flags = useSystemMem ?
-			(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) : // Note: Use cached uncoherent memory
+			(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) : // Note: Try using cached uncoherent memory
 			VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
 
 		for (UINT32 i = 0; i < BS_MAX_VULKAN_DEVICES; i++)

+ 11 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanHardwareBufferManager.cpp

@@ -5,6 +5,7 @@
 #include "BsVulkanIndexBuffer.h"
 #include "BsVulkanGpuBuffer.h"
 #include "BsVulkanGpuParamBlockBuffer.h"
+#include "BsVulkanGpuParams.h"
 #include "BsGpuParamDesc.h"
 
 namespace BansheeEngine
@@ -52,4 +53,14 @@ namespace BansheeEngine
 
 		return bufferPtr;
 	}
+
+	SPtr<GpuParamsCore> VulkanHardwareBufferCoreManager::createGpuParamsInternal(const GPU_PARAMS_DESC& desc,
+		GpuDeviceFlags deviceMask)
+	{
+		VulkanGpuParams* params = new (bs_alloc<VulkanGpuParams>()) VulkanGpuParams(desc, deviceMask);
+		SPtr<GpuParamsCore> paramsPtr = bs_shared_ptr<GpuParamsCore>(params);
+		paramsPtr->_setThisPtr(paramsPtr);
+
+		return paramsPtr;
+	}
 }