Handle spv::StorageClassPhysicalStorageBuffer

This CL handles the spv::StorageClassPhysicalStorageBuffer enum,
basically the same way spv::StorageClassStorageBuffer is currently
handled. One minor difference found in the tests is that
ApplyDecorationsForAccessChain also can be applied to basic types,
because we can be accessing physical pointers to basic types.

Bug: b/184952772
Change-Id: I599e29f57ae37d3f13543207063ec18bffc08844
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66454
Commit-Queue: Alexis Hétu <sugoi@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 6627b61..c4788bc 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -306,6 +306,7 @@
 
 				case spv::StorageClassUniform:
 				case spv::StorageClassStorageBuffer:
+				case spv::StorageClassPhysicalStorageBuffer:
 					object.kind = Object::Kind::DescriptorSet;
 					break;
 
@@ -579,8 +580,9 @@
 
 				if(opcode == spv::OpAccessChain || opcode == spv::OpInBoundsAccessChain || opcode == spv::OpPtrAccessChain)
 				{
+					int indexId = (insn.opcode() == spv::OpPtrAccessChain) ? 5 : 4;
 					Decorations dd{};
-					ApplyDecorationsForAccessChain(&dd, &descriptorDecorations[resultId], pointerId, Span(insn, 4, insn.wordCount() - 4));
+					ApplyDecorationsForAccessChain(&dd, &descriptorDecorations[resultId], pointerId, Span(insn, indexId, insn.wordCount() - indexId));
 					// Note: offset is the one thing that does *not* propagate, as the access chain accounts for it.
 					dd.HasOffset = false;
 					decorations[resultId].Apply(dd);
@@ -1733,6 +1735,9 @@
 		return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
 		                          : OutOfBoundsBehavior::UndefinedBehavior;
 
+	case spv::StorageClassPhysicalStorageBuffer:
+		return OutOfBoundsBehavior::UndefinedBehavior;
+
 	case spv::StorageClassImage:
 		// VK_EXT_image_robustness requires nullifying out-of-bounds accesses.
 		// TODO(b/162327166): Only perform bounds checks when VK_EXT_image_robustness is enabled.
@@ -2275,7 +2280,8 @@
 
 	if(type.storageClass == spv::StorageClassPushConstant ||
 	   type.storageClass == spv::StorageClassUniform ||
-	   type.storageClass == spv::StorageClassStorageBuffer)
+	   type.storageClass == spv::StorageClassStorageBuffer ||
+	   type.storageClass == spv::StorageClassPhysicalStorageBuffer)
 	{
 		auto ptr = WalkExplicitLayoutAccessChain(baseId, elementId, Span(insn, indexId, insn.wordCount() - indexId), nonUniform, state);
 		state->createPointer(resultId, ptr);
diff --git a/src/Pipeline/SpirvShaderMemory.cpp b/src/Pipeline/SpirvShaderMemory.cpp
index 40affe3..f27cbd4 100644
--- a/src/Pipeline/SpirvShaderMemory.cpp
+++ b/src/Pipeline/SpirvShaderMemory.cpp
@@ -198,6 +198,7 @@
 		break;
 	case spv::StorageClassUniform:
 	case spv::StorageClassStorageBuffer:
+	case spv::StorageClassPhysicalStorageBuffer:
 		{
 			const auto &d = descriptorDecorations.at(resultId);
 			ASSERT(d.DescriptorSet >= 0);
@@ -542,6 +543,7 @@
 	{
 	case spv::StorageClassUniform:
 	case spv::StorageClassStorageBuffer:
+	case spv::StorageClassPhysicalStorageBuffer:
 	case spv::StorageClassImage:
 		return false;
 	default:
@@ -551,10 +553,14 @@
 
 bool SpirvShader::IsExplicitLayout(spv::StorageClass storageClass)
 {
+	// From the Vulkan spec:
+	// "Composite objects in the StorageBuffer, PhysicalStorageBuffer, Uniform,
+	//  and PushConstant Storage Classes must be explicitly laid out."
 	switch(storageClass)
 	{
 	case spv::StorageClassUniform:
 	case spv::StorageClassStorageBuffer:
+	case spv::StorageClassPhysicalStorageBuffer:
 	case spv::StorageClassPushConstant:
 		return true;
 	default:
@@ -585,6 +591,7 @@
 	{
 	case spv::StorageClassUniform:
 	case spv::StorageClassStorageBuffer:
+	case spv::StorageClassPhysicalStorageBuffer:
 	case spv::StorageClassPushConstant:
 	case spv::StorageClassWorkgroup:
 	case spv::StorageClassImage: