Quellcode durchsuchen

More Various Vulkan fixes

BearishSun vor 9 Jahren
Ursprung
Commit
5dc78284b8

+ 0 - 2
Source/BansheeVulkanRenderAPI/Include/BsVulkanPrerequisites.h

@@ -13,8 +13,6 @@
 	#define VK_USE_PLATFORM_WIN32_KHR
 #endif
 
-#define BS_NUM_BACK_BUFFERS 1
-
 /** Maximum number of GPU queues that may exist at once. */
 #define BS_MAX_UNIQUE_QUEUES BS_MAX_QUEUES_PER_TYPE * bs::GQT_COUNT // Must fit within 4 bytes
 

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

@@ -61,6 +61,9 @@ namespace bs
 		/** Gets Vulkan flags representing the number of samples in an image. Sample count must be a power of 2. */
 		static VkSampleCountFlagBits getSampleFlags(UINT32 numSamples);
 
+		/** Gets Vulkan flags representing a certain shader stage. */
+		static VkShaderStageFlagBits getShaderStage(GpuProgramType type);
+
 		/** 
 		 * Populates the provided array with Vulkan devices that correspond to provided flags. Sets null in unused slots. 
 		 * Each device is placed at its own index in the output array.

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

@@ -161,7 +161,7 @@ namespace bs
 
 		VkPipelineLayout pipelineLayout;
 		VkResult result = vkCreatePipelineLayout(mDevice.getLogical(), &layoutCI, gVulkanAllocator, &pipelineLayout);
-		assert(result != VK_SUCCESS);
+		assert(result == VK_SUCCESS);
 
 		bs_stack_free(setLayouts);
 

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

@@ -185,7 +185,7 @@ namespace bs
 			VkAttachmentDescription& attachmentDesc = mAttachments[i];
 			VkAttachmentReference& attachmentRef = mColorReferences[i];
 
-			if (loadMask.isSet((RenderSurfaceMaskBits)attachment.index))
+			if (loadMask.isSet((RenderSurfaceMaskBits)(1 << attachment.index)))
 			{
 				attachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
 				attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@@ -196,7 +196,7 @@ namespace bs
 				attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 			}
 
-			if(readMask.isSet((RenderSurfaceMaskBits)attachment.index))
+			if(readMask.isSet((RenderSurfaceMaskBits)(1 << attachment.index)))
 				attachmentRef.layout = VK_IMAGE_LAYOUT_GENERAL;
 			else
 				attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

+ 15 - 3
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuPipelineState.cpp

@@ -151,9 +151,21 @@ namespace bs
 		mViewportInfo.pViewports = nullptr; // Dynamic
 		mViewportInfo.pScissors = nullptr; // Dynamic
 
-		const RasterizerProperties& rstProps = getRasterizerState()->getProperties();
-		const BlendProperties& blendProps = getBlendState()->getProperties();
-		const DepthStencilProperties dsProps = getDepthStencilState()->getProperties();
+		RasterizerStateCore* rasterizerState = getRasterizerState().get();
+		if (rasterizerState == nullptr)
+			rasterizerState = RasterizerStateCore::getDefault().get();
+
+		BlendStateCore* blendState = getBlendState().get();
+		if (blendState == nullptr)
+			blendState = BlendStateCore::getDefault().get();
+
+		DepthStencilStateCore* depthStencilState = getDepthStencilState().get();
+		if (depthStencilState == nullptr)
+			depthStencilState = DepthStencilStateCore::getDefault().get();
+
+		const RasterizerProperties& rstProps = rasterizerState->getProperties();
+		const BlendProperties& blendProps = blendState->getProperties();
+		const DepthStencilProperties dsProps = depthStencilState->getProperties();
 
 		mRasterizationInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
 		mRasterizationInfo.pNext = nullptr;

+ 25 - 11
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuProgram.cpp

@@ -355,17 +355,28 @@ namespace bs
 		{
 			const glslang::TType* ttype = program->getUniformBlockTType(i);
 
+			if (!ttype->getQualifier().hasBinding())
+			{
+				log = "Uniform parsing error: Found a uniform block without a binding qualifier. Each uniform block must "
+					" have an explicitly defined binding number.";
+
+				return false;
+			}
+
 			const char* name = program->getUniformBlockName(i);
 			int size = program->getUniformBlockSize(i); 
 			int index = program->getUniformBlockIndex(i);
 
 			GpuParamBlockDesc param;
 			param.name = name;
-			param.blockSize = size;
+			param.blockSize = size / 4;
 			param.isShareable = true;
 			param.slot = ttype->getQualifier().layoutBinding;
 			param.set = ttype->getQualifier().layoutSet;
 
+			if (param.set == glslang::TQualifier::layoutSetEnd)
+				param.set = 0;
+
 			desc.paramBlocks[name] = param;
 			uniformBlockMap[index] = name;
 		}
@@ -377,19 +388,19 @@ namespace bs
 			const glslang::TType* ttype = program->getUniformTType(i);
 			const char* name = program->getUniformName(i);
 
-			if(!ttype->getQualifier().hasBinding())
-			{
-				log = "Uniform parsing error: Found an uniform without a binding qualifier. Each uniform must have an "
-					  "explicitly defined binding number.";
-
-				return false;
-			}
-
 			if (ttype->getBasicType() == glslang::EbtSampler) // Object type
 			{
 				// Note: Even though the type is named EbtSampler, all object types are categorized under it (including non
 				// sampled images and buffers)
 
+				if (!ttype->getQualifier().hasBinding())
+				{
+					log = "Uniform parsing error: Found an uniform without a binding qualifier. Each uniform must have an "
+						"explicitly defined binding number.";
+
+					return false;
+				}
+
 				const glslang::TSampler& sampler = ttype->getSampler();
 
 				GpuParamObjectDesc param;
@@ -397,6 +408,9 @@ namespace bs
 				param.slot = ttype->getQualifier().layoutBinding;
 				param.set = ttype->getQualifier().layoutSet;
 
+				if (param.set == glslang::TQualifier::layoutSetEnd)
+					param.set = 0;
+
 				if (sampler.isImage())
 				{
 					switch (sampler.dim)
@@ -611,8 +625,8 @@ namespace bs
 		// Add special header so code is recognized as GLSL
 		UINT32* header = (UINT32*)codeBytes;
 		header[0] = ICD_SPV_MAGIC;
-		header[1] = ICD_SPV_VERSION;
-		header[2] = 0;
+		header[1] = 0;
+		header[2] = VulkanUtility::getShaderStage(mProperties.getType());
 
 		UINT32* glslBytes = codeBytes + 3;
 		memcpy(glslBytes, sourceBytes, source.size());

+ 4 - 2
Source/BansheeVulkanRenderAPI/Source/BsVulkanHardwareBuffer.cpp

@@ -13,9 +13,11 @@ namespace bs
 	VulkanBuffer::VulkanBuffer(VulkanResourceManager* owner, VkBuffer buffer, VkBufferView view, VkDeviceMemory memory,
 							   UINT32 rowPitch, UINT32 slicePitch)
 		: VulkanResource(owner, false), mBuffer(buffer), mView(view), mMemory(memory), mRowPitch(rowPitch)
-		, mSliceHeight(slicePitch / rowPitch)
 	{
-
+		if (rowPitch != 0)
+			mSliceHeight = slicePitch / rowPitch;
+		else
+			mSliceHeight = 0;
 	}
 
 	VulkanBuffer::~VulkanBuffer()

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

@@ -59,25 +59,30 @@ namespace bs
 					break;
 				}
 
-				if (presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
+				if (presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
 					presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
 			}
 		}
 		else
 		{
+			// Mailbox comes with lower input latency than FIFO, but can waste GPU power by rendering frames that are never
+			// displayed, especially if the app runs much faster than the refresh rate. This is a concern for mobiles.
+#if BS_PLATFORM != BS_PLATFORM_ANDROID && BS_PLATFORM != BS_PLATFORM_IOS
 			for (UINT32 i = 0; i < numPresentModes; i++)
 			{
+
 				if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
 				{
 					presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
 					break;
 				}
 			}
+#endif
 		}
 
 		bs_stack_free(presentModes);
 
-		uint32_t numImages = std::min(surfaceCaps.minImageCount + BS_NUM_BACK_BUFFERS, surfaceCaps.maxImageCount);
+		uint32_t numImages = surfaceCaps.minImageCount;
 
 		VkSurfaceTransformFlagsKHR transform;
 		if (surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)

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

@@ -220,6 +220,25 @@ namespace bs
 		return VK_SAMPLE_COUNT_1_BIT;
 	}
 
+	VkShaderStageFlagBits VulkanUtility::getShaderStage(GpuProgramType type)
+	{
+		switch(type)
+		{
+		case GPT_FRAGMENT_PROGRAM:
+			return VK_SHADER_STAGE_FRAGMENT_BIT;
+		case GPT_HULL_PROGRAM:
+			return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+		case GPT_DOMAIN_PROGRAM:
+			return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+		case GPT_GEOMETRY_PROGRAM:
+			return VK_SHADER_STAGE_GEOMETRY_BIT;
+		case GPT_VERTEX_PROGRAM:
+			return VK_SHADER_STAGE_VERTEX_BIT;
+		case GPT_COMPUTE_PROGRAM:
+			return VK_SHADER_STAGE_COMPUTE_BIT;
+		}
+	}
+
 	VkSamplerAddressMode VulkanUtility::getAddressingMode(TextureAddressingMode mode)
 	{
 		switch (mode)

+ 32 - 7
Source/BansheeVulkanRenderAPI/Source/Win32/BsWin32RenderWindow.cpp

@@ -145,10 +145,8 @@ namespace bs
 		assert(result == VK_SUCCESS);
 		assert(numFormats > 0);
 
-		VkSurfaceFormatKHR* formats = bs_stack_alloc<VkSurfaceFormatKHR>(numFormats);
-
-		Vector<VkSurfaceFormatKHR> surfaceFormats(numFormats);
-		result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &numFormats, surfaceFormats.data());
+		VkSurfaceFormatKHR* surfaceFormats = bs_stack_alloc<VkSurfaceFormatKHR>(numFormats);
+		result = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &numFormats, surfaceFormats);
 		assert(result == VK_SUCCESS);
 
 		// If there is no preferred format, use standard RGBA
@@ -165,14 +163,38 @@ namespace bs
 		{
 			bool foundFormat = false;
 
-			VkFormat wantedFormats[] = 
+			VkFormat wantedFormatsUNORM[] =
+			{
+				VK_FORMAT_R8G8B8A8_UNORM,
+				VK_FORMAT_B8G8R8A8_UNORM,
+				VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+				VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+				VK_FORMAT_R8G8B8_UNORM,
+				VK_FORMAT_B8G8R8_UNORM
+			};
+
+			VkFormat wantedFormatsSRGB[] = 
 			{
 				VK_FORMAT_R8G8B8A8_SRGB,
+				VK_FORMAT_B8G8R8A8_SRGB,
+				VK_FORMAT_A8B8G8R8_SRGB_PACK32,
 				VK_FORMAT_A8B8G8R8_SRGB_PACK32,
 				VK_FORMAT_R8G8B8_SRGB,
+				VK_FORMAT_B8G8R8_SRGB
 			};
 
-			UINT32 numWantedFormats = sizeof(wantedFormats) / sizeof(wantedFormats[0]);
+			UINT32 numWantedFormats;
+			VkFormat* wantedFormats;
+			if (mDesc.gamma)
+			{
+				numWantedFormats = sizeof(wantedFormatsSRGB) / sizeof(wantedFormatsSRGB[0]);
+				wantedFormats = wantedFormatsSRGB;
+			}
+			else
+			{
+				numWantedFormats = sizeof(wantedFormatsUNORM) / sizeof(wantedFormatsUNORM[0]);
+				wantedFormats = wantedFormatsUNORM;
+			}
 
 			for(UINT32 i = 0; i < numWantedFormats; i++)
 			{
@@ -187,6 +209,9 @@ namespace bs
 						break;
 					}
 				}
+
+				if (foundFormat)
+					break;
 			}
 
 			// If we haven't found anything, fall back to first available
@@ -202,7 +227,7 @@ namespace bs
 
 		mDepthFormat = VK_FORMAT_D24_UNORM_S8_UINT;
 		
-		bs_stack_free(formats);
+		bs_stack_free(surfaceFormats);
 
 		// Create swap chain
 		mSwapChain = bs_shared_ptr_new<VulkanSwapChain>();