Tests for VK_KHR_buffer_device_address

Components: Vulkan
Affects: dEQP-VK.binding_model.buffer_device_address*
Affects: dEQP-VK.compute.cooperative_matrix*phys*
Affects: dEQP-VK.memory_model.*phys*
Affects: dEQP-VK.ssbo.*phys*
Affects: dEQP-VK.spirv_assembly.*phys*
Change-Id: I045b5832e9857f6e826957e204237a32e0bcbce4
diff --git a/external/vulkancts/framework/vulkan/vkMemUtil.cpp b/external/vulkancts/framework/vulkan/vkMemUtil.cpp
index 328f5e6..0642cd0 100644
--- a/external/vulkancts/framework/vulkan/vkMemUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkMemUtil.cpp
@@ -124,6 +124,7 @@
 const MemoryRequirement MemoryRequirement::Local			= MemoryRequirement(MemoryRequirement::FLAG_LOCAL);
 const MemoryRequirement MemoryRequirement::Cached			= MemoryRequirement(MemoryRequirement::FLAG_CACHED);
 const MemoryRequirement MemoryRequirement::NonLocal			= MemoryRequirement(MemoryRequirement::FLAG_NON_LOCAL);
+const MemoryRequirement MemoryRequirement::DeviceAddress	= MemoryRequirement(MemoryRequirement::FLAG_DEVICE_ADDRESS);
 
 bool MemoryRequirement::matchesHeap (VkMemoryPropertyFlags heapFlags) const
 {
@@ -218,7 +219,7 @@
 MovePtr<Allocation> SimpleAllocator::allocate (const VkMemoryRequirements& memReqs, MemoryRequirement requirement)
 {
 	const deUint32				memoryTypeNdx	= selectMatchingMemoryType(m_memProps, memReqs.memoryTypeBits, requirement);
-	const VkMemoryAllocateInfo	allocInfo		=
+	VkMemoryAllocateInfo		allocInfo		=
 	{
 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
 		DE_NULL,								//	const void*				pNext;
@@ -226,6 +227,20 @@
 		memoryTypeNdx,							//	deUint32				memoryTypeIndex;
 	};
 
+	VkMemoryAllocateFlagsInfo	allocFlagsInfo =
+	{
+		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,	//	VkStructureType	sType
+		DE_NULL,										//	const void*		pNext
+		0,												//	VkMemoryAllocateFlags    flags
+		0,												//	uint32_t                 deviceMask
+	};
+
+	if (requirement & MemoryRequirement::DeviceAddress)
+	{
+		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
+		allocInfo.pNext = &allocFlagsInfo;
+	}
+
 	Move<VkDeviceMemory>		mem				= allocateMemory(m_vk, m_device, &allocInfo);
 	MovePtr<HostPtr>			hostPtr;
 
@@ -238,13 +253,13 @@
 	return MovePtr<Allocation>(new SimpleAllocation(mem, hostPtr));
 }
 
-static MovePtr<Allocation> allocateDedicated (const InstanceInterface&		vki,
-											  const DeviceInterface&		vkd,
-											  const VkPhysicalDevice&		physDevice,
-											  const VkDevice				device,
-											  const VkMemoryRequirements&	memReqs,
-											  const MemoryRequirement		requirement,
-											  const void*					pNext)
+MovePtr<Allocation> allocateExtended (const InstanceInterface&		vki,
+									  const DeviceInterface&		vkd,
+									  const VkPhysicalDevice&		physDevice,
+									  const VkDevice				device,
+									  const VkMemoryRequirements&	memReqs,
+									  const MemoryRequirement		requirement,
+									  const void*					pNext)
 {
 	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
 	const deUint32							memoryTypeNdx		= selectMatchingMemoryType(memoryProperties, memReqs.memoryTypeBits, requirement);
@@ -283,7 +298,7 @@
 		buffer																// VkBuffer				buffer
 	};
 
-	return allocateDedicated(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
+	return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
 }
 
 de::MovePtr<Allocation> allocateDedicated (const InstanceInterface&	vki,
@@ -302,7 +317,7 @@
 		DE_NULL															// VkBuffer				buffer
 	};
 
-	return allocateDedicated(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
+	return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
 }
 
 void* mapMemory (const DeviceInterface& vkd, VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags)
diff --git a/external/vulkancts/framework/vulkan/vkMemUtil.hpp b/external/vulkancts/framework/vulkan/vkMemUtil.hpp
index 34083ce..30ae4db 100644
--- a/external/vulkancts/framework/vulkan/vkMemUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkMemUtil.hpp
@@ -89,6 +89,7 @@
 	static const MemoryRequirement	Local;
 	static const MemoryRequirement	Cached;
 	static const MemoryRequirement	NonLocal;
+	static const MemoryRequirement	DeviceAddress;
 
 	inline MemoryRequirement		operator|			(MemoryRequirement requirement) const
 	{
@@ -118,6 +119,7 @@
 		FLAG_LOCAL				= 1u << 4u,
 		FLAG_CACHED				= 1u << 5u,
 		FLAG_NON_LOCAL			= 1u << 6u,
+		FLAG_DEVICE_ADDRESS		= 1u << 7u,
 	};
 };
 
@@ -147,6 +149,7 @@
 	const VkPhysicalDeviceMemoryProperties	m_memProps;
 };
 
+de::MovePtr<Allocation>	allocateExtended			(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkMemoryRequirements& memReqs, const MemoryRequirement requirement, const void* pNext);
 de::MovePtr<Allocation>	allocateDedicated			(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkBuffer buffer, MemoryRequirement requirement);
 de::MovePtr<Allocation>	allocateDedicated			(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkImage image, MemoryRequirement requirement);
 
diff --git a/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp b/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
index 072b5dc..d7c3a9b 100644
--- a/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
+++ b/external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
@@ -56,6 +56,9 @@
 using namespace vk;
 using namespace std;
 
+typedef de::MovePtr<Unique<VkBuffer> >	VkBufferSp;
+typedef de::MovePtr<Allocation>			AllocationSp;
+
 static const deUint32 DIM = 8;
 
 typedef enum
@@ -154,7 +157,7 @@
 
 void BufferAddressTestCase::checkSupport (Context& context) const
 {
-	if (!context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+	if (!(context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddress || context.getBufferDeviceAddressFeatures().bufferDeviceAddress))
 		TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");
 
 	if (m_data.stage == STAGE_VERTEX && !context.getDeviceFeatures().vertexPipelineStoresAndAtomics)
@@ -164,7 +167,7 @@
 		TCU_THROW(NotSupportedError, "descriptor set number not supported");
 
 	if (m_data.bufType == BT_REPLAY &&
-		!context.getBufferDeviceAddressFeatures().bufferDeviceAddressCaptureReplay)
+		!(context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddressCaptureReplay || context.getBufferDeviceAddressFeatures().bufferDeviceAddressCaptureReplay))
 		TCU_THROW(NotSupportedError, "Capture/replay of physical storage buffer pointers not supported");
 
 	if (m_data.layout == LAYOUT_SCALAR && !context.getScalarBlockLayoutFeatures().scalarBlockLayout)
@@ -438,9 +441,12 @@
 
 tcu::TestStatus BufferAddressTestInstance::iterate (void)
 {
+	const InstanceInterface&vki						= m_context.getInstanceInterface();
 	const DeviceInterface&	vk						= m_context.getDeviceInterface();
+	const VkPhysicalDevice&	physDevice				= m_context.getPhysicalDevice();
 	const VkDevice			device					= m_context.getDevice();
 	Allocator&				allocator				= m_context.getDefaultAllocator();
+	const bool				useKHR					= !!m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress;
 
 
 	VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
@@ -536,60 +542,123 @@
 		numBindings = numBindings*3+1;
 	}
 
-	VkBufferDeviceAddressCreateInfoEXT addressCreateInfo =
+	VkBufferDeviceAddressCreateInfoEXT addressCreateInfoEXT =
 	{
 		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT,	// VkStructureType	 sType;
 		DE_NULL,													// const void*		 pNext;
-		0x000000000ULL,												// VkDeviceSize		deviceAddress
+		0x000000000ULL,												// VkDeviceSize		 deviceAddress
+	};
+
+	VkBufferOpaqueCaptureAddressCreateInfoKHR bufferOpaqueCaptureAddressCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR,	// VkStructureType	 sType;
+		DE_NULL,															// const void*		 pNext;
+		0x000000000ULL,														// VkDeviceSize		 opaqueCaptureAddress
 	};
 
 	std::vector<deUint8 *> cpuAddrs(numBindings);
 	std::vector<VkDeviceAddress> gpuAddrs(numBindings);
+	std::vector<deUint64> opaqueBufferAddrs(numBindings);
+	std::vector<deUint64> opaqueMemoryAddrs(numBindings);
 
-	VkBufferDeviceAddressInfo info =
+	VkBufferDeviceAddressInfoEXT bufferDeviceAddressInfo =
 	{
 		VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT,	// VkStructureType	 sType;
 		DE_NULL,											// const void*		 pNext;
-		0,													// VkBuffer			buffer
+		0,													// VkBuffer			 buffer
+	};
+
+	VkDeviceMemoryOpaqueCaptureAddressInfoKHR deviceMemoryOpaqueCaptureAddressInfo =
+	{
+		VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR,	// VkStructureType	 sType;
+		DE_NULL,															// const void*		 pNext;
+		0,																	// VkDeviceMemory	 memory;
 	};
 
 	bool multiBuffer = m_data.bufType != BT_SINGLE;
 	deUint32 numBuffers = multiBuffer ? numBindings : 1;
 	VkDeviceSize bufferSize = multiBuffer ? align : (align*numBindings);
 
-	vector<de::SharedPtr<BufferWithMemory> > buffers(numBuffers);
-	for (deUint32 i = 0; i < numBuffers; ++i)
-	{
-		buffers[i] = de::SharedPtr<BufferWithMemory>(new BufferWithMemory(
-			vk, device, allocator, makeBufferCreateInfo(DE_NULL, bufferSize,
+	vector<VkBufferSp>			buffers(numBuffers);
+	vector<AllocationSp>		allocations(numBuffers);
+
+	VkBufferCreateInfo			bufferCreateInfo = makeBufferCreateInfo(DE_NULL, bufferSize,
 														VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
 														VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
 														VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT,
-														m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT : 0),
-														MemoryRequirement::HostVisible));
+														m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT : 0);
+
+	// VkMemoryAllocateFlags to be filled out later
+	VkMemoryAllocateFlagsInfo	allocFlagsInfo =
+	{
+		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,	//	VkStructureType	sType
+		DE_NULL,										//	const void*		pNext
+		0,												//	VkMemoryAllocateFlags    flags
+		0,												//	uint32_t                 deviceMask
+	};
+
+	VkMemoryOpaqueCaptureAddressAllocateInfoKHR memoryOpaqueCaptureAddressAllocateInfo =
+	{
+		VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR,	// VkStructureType    sType;
+		DE_NULL,															// const void*        pNext;
+		0,																	// uint64_t           opaqueCaptureAddress;
+	};
+
+	if (useKHR)
+		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
+
+	if (useKHR && m_data.bufType == BT_REPLAY)
+	{
+		allocFlagsInfo.flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR;
+		allocFlagsInfo.pNext = &memoryOpaqueCaptureAddressAllocateInfo;
+	}
+
+	for (deUint32 i = 0; i < numBuffers; ++i)
+	{
+		buffers[i] = VkBufferSp(new Unique<VkBuffer>(createBuffer(vk, device, &bufferCreateInfo)));
+
+		// query opaque capture address before binding memory
+		if (useKHR) {
+			bufferDeviceAddressInfo.buffer = **buffers[i];
+			opaqueBufferAddrs[i] = vk.getBufferOpaqueCaptureAddress(device, &bufferDeviceAddressInfo);
+		}
+
+		allocations[i] = AllocationSp(allocateExtended(vki, vk, physDevice, device, getBufferMemoryRequirements(vk, device, **buffers[i]), MemoryRequirement::HostVisible, &allocFlagsInfo));
+
+		if (useKHR) {
+			deviceMemoryOpaqueCaptureAddressInfo.memory = allocations[i]->getMemory();
+			opaqueMemoryAddrs[i] = vk.getDeviceMemoryOpaqueCaptureAddress(device, &deviceMemoryOpaqueCaptureAddressInfo);
+		}
+
+		VK_CHECK(vk.bindBufferMemory(device, **buffers[i], allocations[i]->getMemory(), 0));
 	}
 
 	if (m_data.bufType == BT_REPLAY)
 	{
 		for (deUint32 i = 0; i < numBuffers; ++i)
 		{
-			info.buffer = **buffers[i];
-			gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &info);
+			bufferDeviceAddressInfo.buffer = **buffers[i];
+			gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
 		}
 		buffers.clear();
 		buffers.resize(numBuffers);
+		allocations.clear();
+		allocations.resize(numBuffers);
+
+		bufferCreateInfo.pNext = useKHR ? (void *)&bufferOpaqueCaptureAddressCreateInfo : (void *)&addressCreateInfoEXT;
+
 		for (deInt32 i = numBuffers-1; i >= 0; --i)
 		{
-			addressCreateInfo.deviceAddress = gpuAddrs[i];
-			buffers[i] = de::SharedPtr<BufferWithMemory>(new BufferWithMemory(
-				vk, device, allocator, makeBufferCreateInfo(&addressCreateInfo, bufferSize,
-															VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
-															VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
-															VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT,
-															m_data.bufType == BT_REPLAY ? VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT : 0),
-															MemoryRequirement::HostVisible));
-			info.buffer = **buffers[i];
-			VkDeviceSize newAddr = vk.getBufferDeviceAddressEXT(device, &info);
+			addressCreateInfoEXT.deviceAddress = gpuAddrs[i];
+			bufferOpaqueCaptureAddressCreateInfo.opaqueCaptureAddress = opaqueBufferAddrs[i];
+			memoryOpaqueCaptureAddressAllocateInfo.opaqueCaptureAddress = opaqueMemoryAddrs[i];
+
+			buffers[i] = VkBufferSp(new Unique<VkBuffer>(createBuffer(vk, device, &bufferCreateInfo)));
+			allocations[i] = AllocationSp(allocateExtended(vki, vk, physDevice, device, getBufferMemoryRequirements(vk, device, **buffers[i]), MemoryRequirement::HostVisible, &allocFlagsInfo));
+			VK_CHECK(vk.bindBufferMemory(device, **buffers[i], allocations[i]->getMemory(), 0));
+
+			bufferDeviceAddressInfo.buffer = **buffers[i];
+			VkDeviceSize newAddr = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
 			if (newAddr != gpuAddrs[i])
 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "address mismatch");
 		}
@@ -598,10 +667,10 @@
 	// Create a buffer and compute the address for each "align" bytes.
 	for (deUint32 i = 0; i < numBindings; ++i)
 	{
-		info.buffer = **buffers[multiBuffer ? i : 0];
+		bufferDeviceAddressInfo.buffer = **buffers[multiBuffer ? i : 0];
 
-		gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &info);
-		cpuAddrs[i] = (deUint8 *)buffers[multiBuffer ? i : 0]->getAllocation().getHostPtr();
+		gpuAddrs[i] = vk.getBufferDeviceAddressEXT(device, &bufferDeviceAddressInfo);
+		cpuAddrs[i] = (deUint8 *)allocations[multiBuffer ? i : 0]->getHostPtr();
 		if (!multiBuffer)
 		{
 			cpuAddrs[i] = cpuAddrs[i] + align*i;
@@ -613,7 +682,7 @@
 	fillBuffer(cpuAddrs, gpuAddrs, 0, 0);
 
 	for (deUint32 i = 0; i < numBuffers; ++i)
-		flushAlloc(vk, device, buffers[i]->getAllocation());
+		flushAlloc(vk, device, *allocations[i]);
 
 	const VkQueue					queue					= m_context.getUniversalQueue();
 	Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex());
diff --git a/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp b/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
index 0ad38c4..2fa6dc8 100644
--- a/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
+++ b/external/vulkancts/modules/vulkan/compute/vktComputeCooperativeMatrixTests.cpp
@@ -180,7 +180,7 @@
 	}
 
 	if (m_data.storageClass == SC_PHYSICAL_STORAGE_BUFFER &&
-		!context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+		!(context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddress || context.getBufferDeviceAddressFeatures().bufferDeviceAddress))
 	{
 		TCU_THROW(NotSupportedError, "buffer device address not supported");
 	}
@@ -574,6 +574,8 @@
 	const DeviceInterface&	vk						= m_context.getDeviceInterface();
 	const VkDevice			device					= m_context.getDevice();
 	Allocator&				allocator				= m_context.getDefaultAllocator();
+	MemoryRequirement		memoryDeviceAddress		= m_data.storageClass == SC_PHYSICAL_STORAGE_BUFFER &&
+														m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress ? MemoryRequirement::DeviceAddress : MemoryRequirement::Any;
 
 	deRandom rnd;
 	deRandom_init(&rnd, 1234);
@@ -648,13 +650,13 @@
 		{
 			buffers[i] = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
 				vk, device, allocator, makeBufferCreateInfo(bufferSizes[i], VK_BUFFER_USAGE_STORAGE_BUFFER_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT),
-				MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent));
+				MemoryRequirement::HostVisible | MemoryRequirement::Cached | MemoryRequirement::Coherent | memoryDeviceAddress));
 		}
 		catch (const tcu::NotSupportedError&)
 		{
 			buffers[i] = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
 				vk, device, allocator, makeBufferCreateInfo(bufferSizes[i], VK_BUFFER_USAGE_STORAGE_BUFFER_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT),
-				MemoryRequirement::HostVisible));
+				MemoryRequirement::HostVisible | memoryDeviceAddress));
 		}
 
 		bufferDescriptors[i] = makeDescriptorBufferInfo(**buffers[i], 0, bufferSizes[i]);
diff --git a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
index 2ba8fdc..49fa0b5 100644
--- a/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
+++ b/external/vulkancts/modules/vulkan/memory_model/vktMemoryModelMessagePassing.cpp
@@ -235,7 +235,7 @@
 		TCU_THROW(NotSupportedError, "vulkanMemoryModelAvailabilityVisibilityChains not supported");
 
 	if ((m_data.payloadSC == SC_PHYSBUFFER || m_data.guardSC == SC_PHYSBUFFER) &&
-		!context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+		!(context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddress || context.getBufferDeviceAddressFeatures().bufferDeviceAddress))
 		TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");
 
 	if (m_data.stage == STAGE_VERTEX)
@@ -975,6 +975,8 @@
 
 		vk::VkFlags usageFlags = vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 
+		bool memoryDeviceAddress = false;
+
 		bool local;
 		switch (i)
 		{
@@ -984,14 +986,22 @@
 				continue;
 			local = m_data.payloadMemLocal;
 			if (m_data.payloadSC == SC_PHYSBUFFER)
+			{
 				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT;
+				if (m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+					memoryDeviceAddress = true;
+			}
 			break;
 		case 1:
 			if (m_data.guardSC != SC_BUFFER && m_data.guardSC != SC_PHYSBUFFER)
 				continue;
 			local = m_data.guardMemLocal;
 			if (m_data.guardSC == SC_PHYSBUFFER)
+			{
 				usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT;
+				if (m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+					memoryDeviceAddress = true;
+			}
 			break;
 		case 2: local = true; break;
 		}
@@ -1000,7 +1010,8 @@
 		{
 			buffers[i] = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
 				vk, device, allocator, makeBufferCreateInfo(bufferSizes[i], usageFlags),
-				local ? MemoryRequirement::Local : MemoryRequirement::NonLocal));
+				(memoryDeviceAddress ? MemoryRequirement::DeviceAddress : MemoryRequirement::Any) |
+				(local ? MemoryRequirement::Local : MemoryRequirement::NonLocal)));
 		}
 		catch (const tcu::NotSupportedError&)
 		{
@@ -1448,7 +1459,7 @@
 			bufferSizes[2]							// size
 		};
 
-    deUint32 NUM_SUBMITS = 2;
+	deUint32 NUM_SUBMITS = 2;
 
 	for (deUint32 x = 0; x < NUM_SUBMITS; ++x)
 	{
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
index 938e9e2..537b266 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmComputeShaderCase.cpp
@@ -60,7 +60,8 @@
  * The memory is created as host visible and passed back as a vk::Allocation
  * instance via outMemory.
  *//*--------------------------------------------------------------------*/
-Move<VkBuffer> createBufferAndBindMemory (const DeviceInterface&	vkdi,
+Move<VkBuffer> createBufferAndBindMemory (vkt::Context&				context,
+										  const DeviceInterface&	vkdi,
 										  const VkDevice&			device,
 										  VkDescriptorType			dtype,
 										  Allocator&				allocator,
@@ -98,7 +99,10 @@
 
 	Move<VkBuffer>				buffer			(createBuffer(vkdi, device, &bufferCreateInfo));
 	const VkMemoryRequirements	requirements	= getBufferMemoryRequirements(vkdi, device, *buffer);
-	AllocationMp				bufferMemory	= allocator.allocate(requirements, coherent ? MemoryRequirement::Coherent | MemoryRequirement::HostVisible : MemoryRequirement::HostVisible);
+	AllocationMp				bufferMemory	= allocator.allocate(requirements,
+													(coherent ? MemoryRequirement::Coherent : MemoryRequirement::Any) |
+													(context.getBufferDeviceAddressFeatures().bufferDeviceAddress && physStorageBuffer ? MemoryRequirement::DeviceAddress : MemoryRequirement::Any) |
+													MemoryRequirement::HostVisible);
 
 	VK_CHECK(vkdi.bindBufferMemory(device, *buffer, bufferMemory->getMemory(), bufferMemory->getOffset()));
 	*outMemory = bufferMemory;
@@ -491,7 +495,8 @@
 		if (!isFloatControlsFeaturesSupported(m_context, m_shaderSpec.requestedVulkanFeatures.floatControlsProperties))
 			TCU_THROW(NotSupportedError, "Requested Float Controls features not supported");
 
-        if (m_shaderSpec.usesPhysStorageBuffer && !m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+		if (m_shaderSpec.usesPhysStorageBuffer &&
+			!(m_context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddress || m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress))
 			TCU_THROW(NotSupportedError, "Request physical storage buffer feature not supported");
 	}
 
@@ -529,7 +534,7 @@
 			const size_t		numBytes		= inputBytes.size();
 
 			AllocationMp		bufferAlloc;
-			BufferHandleUp*		buffer			= new BufferHandleUp(createBufferAndBindMemory(vkdi, device, descType, allocator, numBytes, &bufferAlloc, m_shaderSpec.usesPhysStorageBuffer, m_shaderSpec.coherentMemory));
+			BufferHandleUp*		buffer			= new BufferHandleUp(createBufferAndBindMemory(m_context, vkdi, device, descType, allocator, numBytes, &bufferAlloc, m_shaderSpec.usesPhysStorageBuffer, m_shaderSpec.coherentMemory));
 
 			setMemory(vkdi, device, &*bufferAlloc, numBytes, &inputBytes.front(), m_shaderSpec.coherentMemory);
 			inputBuffers.push_back(BufferHandleSp(buffer));
@@ -546,7 +551,7 @@
 			const size_t				numBytes		= inputBytes.size();
 
 			AllocationMp				bufferAlloc;
-			BufferHandleUp*				buffer			= new BufferHandleUp(createBufferAndBindMemory(vkdi, device, descType, allocator, numBytes, &bufferAlloc, m_shaderSpec.usesPhysStorageBuffer));
+			BufferHandleUp*				buffer			= new BufferHandleUp(createBufferAndBindMemory(m_context, vkdi, device, descType, allocator, numBytes, &bufferAlloc, m_shaderSpec.usesPhysStorageBuffer));
 
 			AllocationMp				imageAlloc;
 			ImageHandleUp*				image			= new ImageHandleUp(createImageAndBindMemory(vkdi, device, descType, allocator, queueFamilyIndex, &imageAlloc));
@@ -744,7 +749,7 @@
 		output->getBytes(outputBytes);
 
 		const size_t		numBytes	= outputBytes.size();
-		BufferHandleUp*		buffer		= new BufferHandleUp(createBufferAndBindMemory(vkdi, device, descriptorTypes.back(), allocator, numBytes, &alloc, m_shaderSpec.usesPhysStorageBuffer, m_shaderSpec.coherentMemory));
+		BufferHandleUp*		buffer		= new BufferHandleUp(createBufferAndBindMemory(m_context, vkdi, device, descriptorTypes.back(), allocator, numBytes, &alloc, m_shaderSpec.usesPhysStorageBuffer, m_shaderSpec.coherentMemory));
 
 		fillMemoryWithValue(vkdi, device, &*alloc, numBytes, 0xff, m_shaderSpec.coherentMemory);
 		descriptorInfos.push_back(vk::makeDescriptorBufferInfo(**buffer, 0u, numBytes));
@@ -783,7 +788,7 @@
 		const size_t		numBytes		= gpuAddrs.size() * sizeof(VkDeviceAddress);
 
 		AllocationMp		bufferAlloc;
-		BufferHandleUp*		buffer			= new BufferHandleUp(createBufferAndBindMemory(vkdi, device, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+		BufferHandleUp*		buffer			= new BufferHandleUp(createBufferAndBindMemory(m_context, vkdi, device, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
 																						   allocator, numBytes, &bufferAlloc, false, m_shaderSpec.coherentMemory));
 
 		setMemory(vkdi, device, &*bufferAlloc, numBytes, &gpuAddrs.front(), m_shaderSpec.coherentMemory);
diff --git a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
index 9c7de9b..ebb79b8 100644
--- a/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
+++ b/external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp
@@ -2234,8 +2234,13 @@
 	vector<BlockDataPtr>  mappedBlockPtrs;
 
 	vk::VkFlags usageFlags = vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+	bool memoryDeviceAddress = false;
 	if (m_usePhysStorageBuffer)
+	{
 		usageFlags |= vk::VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT;
+		if (m_context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
+			memoryDeviceAddress = true;
+	}
 
 	// Upload base buffers
 	const std::vector<int> bufferSizes	= computeBufferSizes(m_interface, m_refLayout);
@@ -2256,7 +2261,7 @@
 				blockLocations[blockNdx] = BlockLocation(blockNdx, 0, bufferSize);
 
 				vk::Move<vk::VkBuffer>				buffer		= createBuffer(m_context, bufferSize, usageFlags);
-				de::MovePtr<vk::Allocation>			alloc		= allocateAndBindMemory(m_context, *buffer, vk::MemoryRequirement::HostVisible);
+				de::MovePtr<vk::Allocation>			alloc		= allocateAndBindMemory(m_context, *buffer, vk::MemoryRequirement::HostVisible | (memoryDeviceAddress ? vk::MemoryRequirement::DeviceAddress : vk::MemoryRequirement::Any));
 
 				descriptors[blockNdx] = makeDescriptorBufferInfo(*buffer, 0ull, bufferSize);
 
@@ -2288,7 +2293,7 @@
 
 			const int						totalBufferSize = curOffset;
 			vk::Move<vk::VkBuffer>			buffer			= createBuffer(m_context, totalBufferSize, usageFlags);
-			de::MovePtr<vk::Allocation>		alloc			= allocateAndBindMemory(m_context, *buffer, vk::MemoryRequirement::HostVisible);
+			de::MovePtr<vk::Allocation>		alloc			= allocateAndBindMemory(m_context, *buffer, vk::MemoryRequirement::HostVisible | (memoryDeviceAddress ? vk::MemoryRequirement::DeviceAddress : vk::MemoryRequirement::Any));
 
 			mapPtrs.push_back(alloc->getHostPtr());
 
@@ -2371,7 +2376,7 @@
 		(vk::VkPipelineLayoutCreateFlags)0,
 		1u,													// deUint32						descriptorSetCount;
 		&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
-        m_usePhysStorageBuffer ? 1u : 0u,					// deUint32						pushConstantRangeCount;
+		m_usePhysStorageBuffer ? 1u : 0u,					// deUint32						pushConstantRangeCount;
 		&pushConstRange,									// const VkPushConstantRange*	pPushConstantRanges;
 	};
 	vk::Move<vk::VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, device, &pipelineLayoutParams));
@@ -2545,7 +2550,7 @@
 		TCU_THROW(NotSupportedError, "storageBuffer8BitAccess not supported");
 	if (!context.getScalarBlockLayoutFeatures().scalarBlockLayout && usesScalarLayout(m_interface))
 		TCU_THROW(NotSupportedError, "scalarBlockLayout not supported");
-	if (!context.getBufferDeviceAddressFeatures().bufferDeviceAddress && m_usePhysStorageBuffer)
+	if (!(context.getBufferDeviceAddressFeaturesEXT().bufferDeviceAddress || context.getBufferDeviceAddressFeatures().bufferDeviceAddress) && m_usePhysStorageBuffer)
 		TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");
 	return new SSBOLayoutCaseInstance(context, m_bufferMode, m_interface, m_refLayout, m_initialData, m_writeData, m_usePhysStorageBuffer);
 }
diff --git a/external/vulkancts/scripts/gen_framework.py b/external/vulkancts/scripts/gen_framework.py
index 54813d5..bf97b78 100644
--- a/external/vulkancts/scripts/gen_framework.py
+++ b/external/vulkancts/scripts/gen_framework.py
@@ -1589,8 +1589,12 @@
 
 def genericDeviceFeaturesWriter(dfDefs, pattern, filename):
 	stream = []
-	for _, _, extStruct, _, _, _ in dfDefs:
-		nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
+	for sType, sSuffix, extStruct, _, _, _ in dfDefs:
+		# Special case to treat BufferDeviceAddressFeaturesEXT differently than BufferDeviceAddressFeaturesKHR
+		if sType == "BUFFER_DEVICE_ADDRESS" and sSuffix == "_EXT":
+			nameSubStr = extStruct.replace("VkPhysicalDevice", "")
+		else:
+			nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
 		stream.append(pattern.format(extStruct, nameSubStr))
 	writeInlFile(filename, INL_HEADER, indentLines(stream))