Procházet zdrojové kódy

Vulkan: Fixing a few issues related to binding sampled buffers and non-sampled buffers in the same shader

BearishSun před 9 roky
rodič
revize
c41585f7af

+ 1 - 0
Source/BansheeCore/Include/BsGpuPipelineParamInfo.h

@@ -67,6 +67,7 @@ namespace bs
 		{
 		{
 			UINT32* slotIndices;
 			UINT32* slotIndices;
 			ParamType* slotTypes;
 			ParamType* slotTypes;
+			UINT32* slotSamplers;
 			UINT32 numSlots;
 			UINT32 numSlots;
 		};
 		};
 
 

+ 39 - 11
Source/BansheeCore/Source/BsGpuPipelineParamInfo.cpp

@@ -88,7 +88,8 @@ namespace bs
 
 
 		mAlloc.reserve<SetInfo>(mNumSets)
 		mAlloc.reserve<SetInfo>(mNumSets)
 			.reserve<UINT32>(totalNumSlots)
 			.reserve<UINT32>(totalNumSlots)
-			.reserve<ParamType>(totalNumSlots);
+			.reserve<ParamType>(totalNumSlots)
+			.reserve<UINT32>(totalNumSlots);
 
 
 		for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
 		for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
 			mAlloc.reserve<ResourceInfo>(mNumElementsPerType[i]);
 			mAlloc.reserve<ResourceInfo>(mNumElementsPerType[i]);
@@ -111,6 +112,9 @@ namespace bs
 			memset(mSetInfos[i].slotIndices, -1, sizeof(UINT32) * mSetInfos[i].numSlots);
 			memset(mSetInfos[i].slotIndices, -1, sizeof(UINT32) * mSetInfos[i].numSlots);
 
 
 			mSetInfos[i].slotTypes = mAlloc.alloc<ParamType>(mSetInfos[i].numSlots);
 			mSetInfos[i].slotTypes = mAlloc.alloc<ParamType>(mSetInfos[i].numSlots);
+
+			mSetInfos[i].slotSamplers = mAlloc.alloc<UINT32>(mSetInfos[i].numSlots);
+			memset(mSetInfos[i].slotSamplers, -1, sizeof(UINT32) * mSetInfos[i].numSlots);
 		}
 		}
 
 
 		for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
 		for (UINT32 i = 0; i < (UINT32)ParamType::Count; i++)
@@ -153,8 +157,32 @@ namespace bs
 			for (auto& buffer : paramDesc->buffers)
 			for (auto& buffer : paramDesc->buffers)
 				populateSetInfo(buffer.second, ParamType::Buffer);
 				populateSetInfo(buffer.second, ParamType::Buffer);
 
 
-			for (auto& sampler : paramDesc->samplers)
-				populateSetInfo(sampler.second, ParamType::SamplerState);
+			// Samplers need to be handled specially because certain slots could be texture/buffer + sampler combinations
+			{
+				int typeIdx = (int)ParamType::SamplerState;
+				UINT32 sequentialIdx = mNumElementsPerType[typeIdx];
+
+				for (auto& entry : paramDesc->samplers)
+				{
+					const GpuParamObjectDesc& samplerDesc = entry.second;
+
+					SetInfo& setInfo = mSetInfos[samplerDesc.set];
+					if (setInfo.slotIndices[samplerDesc.slot] == -1) // Slot is sampler only
+					{
+						setInfo.slotIndices[samplerDesc.slot] = sequentialIdx;
+						setInfo.slotTypes[samplerDesc.slot] = ParamType::SamplerState;
+					}
+					else // Slot is a combination
+					{
+						setInfo.slotSamplers[samplerDesc.slot] = sequentialIdx;
+					}
+
+					mResourceInfos[typeIdx][sequentialIdx].set = samplerDesc.set;
+					mResourceInfos[typeIdx][sequentialIdx].slot = samplerDesc.slot;
+
+					mNumElementsPerType[typeIdx]++;
+				}
+			}
 		}
 		}
 	}
 	}
 
 
@@ -181,16 +209,16 @@ namespace bs
 		ParamType slotType = mSetInfos[set].slotTypes[slot];
 		ParamType slotType = mSetInfos[set].slotTypes[slot];
 		if(slotType != type)
 		if(slotType != type)
 		{
 		{
-			// Allow sampler states & textures to share the same slot, as some APIs combine them
-			bool potentialCombinedSampler = (slotType == ParamType::SamplerState && type == ParamType::Texture) ||
-				(slotType == ParamType::Texture && type == ParamType::SamplerState);
-
-			if (!potentialCombinedSampler)
+			// Allow sampler states & textures/buffers to share the same slot, as some APIs combine them
+			if(type == ParamType::SamplerState)
 			{
 			{
-				LOGERR("Requested parameter is not of the valid type. Requested: " + toString((UINT32)type) + ". Actual: " +
-					   toString((UINT32)mSetInfos[set].slotTypes[slot]) + ".");
-				return -1;
+				if (mSetInfos[set].slotSamplers[slot] != -1)
+					return mSetInfos[set].slotSamplers[slot];
 			}
 			}
+
+			LOGERR("Requested parameter is not of the valid type. Requested: " + toString((UINT32)type) + ". Actual: " +
+					toString((UINT32)mSetInfos[set].slotTypes[slot]) + ".");
+			return -1;
 		}
 		}
 
 
 #endif
 #endif

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

@@ -59,6 +59,7 @@ namespace bs { namespace ct
 		{
 		{
 			VkDescriptorImageInfo image;
 			VkDescriptorImageInfo image;
 			VkDescriptorBufferInfo buffer;
 			VkDescriptorBufferInfo buffer;
+			VkBufferView bufferView;
 		};
 		};
 
 
 		/** All GPU param data related to a single descriptor set. */
 		/** All GPU param data related to a single descriptor set. */

+ 21 - 5
Source/BansheeVulkanRenderAPI/Source/BsVulkanGpuParams.cpp

@@ -205,8 +205,9 @@ namespace bs { namespace ct
 							else
 							else
 								bufferView = vkBufManager.getDummyReadBufferView(i);
 								bufferView = vkBufManager.getDummyReadBufferView(i);
 
 
+							perSetData.writeInfos[k].bufferView = bufferView;
 							writeSetInfo.pBufferInfo = nullptr;
 							writeSetInfo.pBufferInfo = nullptr;
-							writeSetInfo.pTexelBufferView = &bufferView;
+							writeSetInfo.pTexelBufferView = &perSetData.writeInfos[k].bufferView;
 						}
 						}
 
 
 						writeSetInfo.pImageInfo = nullptr;
 						writeSetInfo.pImageInfo = nullptr;
@@ -419,10 +420,11 @@ namespace bs { namespace ct
 					else
 					else
 						bufferView = vkBufManager.getDummyReadBufferView(i);
 						bufferView = vkBufManager.getDummyReadBufferView(i);
 
 
-					mPerDeviceData[i].buffers[sequentialIdx] = 0;
+					mPerDeviceData[i].buffers[sequentialIdx] = nullptr;
 				}
 				}
 
 
-				writeSetInfo.pTexelBufferView = &bufferView;
+				perSetData.writeInfos[bindingIdx].bufferView = bufferView;
+				writeSetInfo.pTexelBufferView = &perSetData.writeInfos[bindingIdx].bufferView;
 			}
 			}
 			else // Structured storage buffer
 			else // Structured storage buffer
 			{
 			{
@@ -441,6 +443,8 @@ namespace bs { namespace ct
 					perSetData.writeInfos[bindingIdx].buffer.buffer = vkBufManager.getDummyStructuredBuffer(i);
 					perSetData.writeInfos[bindingIdx].buffer.buffer = vkBufManager.getDummyStructuredBuffer(i);
 					mPerDeviceData[i].buffers[sequentialIdx] = nullptr;
 					mPerDeviceData[i].buffers[sequentialIdx] = nullptr;
 				}
 				}
+
+				writeSetInfo.pTexelBufferView = nullptr;
 			}
 			}
 		}
 		}
 
 
@@ -595,8 +599,20 @@ namespace bs { namespace ct
 
 
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 				UINT32 bindingIdx = vkParamInfo.getBindingIdx(set, slot);
 
 
-				VkBufferView bufferView = resource->getView();
-				perDeviceData.perSetData[set].writeSetInfos[bindingIdx].pTexelBufferView = &bufferView;
+				PerSetData& perSetData = perDeviceData.perSetData[set];
+				VkWriteDescriptorSet& writeSetInfo = perSetData.writeSetInfos[bindingIdx];
+
+				bool useView = writeSetInfo.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+				if (useView)
+				{
+					perSetData.writeInfos[bindingIdx].bufferView = resource->getView();
+					perSetData.writeSetInfos[bindingIdx].pTexelBufferView = &perSetData.writeInfos[bindingIdx].bufferView;
+				}
+				else // Structured storage buffer
+				{
+					perSetData.writeInfos[bindingIdx].buffer.buffer = vkBuffer;
+					perSetData.writeSetInfos[bindingIdx].pTexelBufferView = nullptr;
+				}
 
 
 				mSetsDirty[set] = true;
 				mSetsDirty[set] = true;
 			}
 			}

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

@@ -105,7 +105,8 @@ namespace bs { namespace ct
 			mRequiresView = true;
 			mRequiresView = true;
 			break;
 			break;
 		case BT_STORAGE:
 		case BT_STORAGE:
-			usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+			usageFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | 
+				VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
 			mRequiresView = true;
 			mRequiresView = true;
 			break;
 			break;
 		case BT_STRUCTURED:
 		case BT_STRUCTURED: