Add VK_KHR_workgroup_memory_explicit_layout maximum size tests

Dynamic generation of shaders based on properties reported by devices
is not allowed in the CTS, and in this case we can't use a
specialization constant as the array size.  So the test have a few
variants with common maximum values.

Component: Vulkan
VK-GL-CTS Issue: 2524
New Tests: dEQP-VK.compute.workgroup_memory_explicit_layout.size.*

Change-Id: Ic960d22277b0a7bff428eae99e1f3107d9b4c85e
diff --git a/android/cts/master/vk-master-2020-03-01.txt b/android/cts/master/vk-master-2020-03-01.txt
index 487f712..131a128 100644
--- a/android/cts/master/vk-master-2020-03-01.txt
+++ b/android/cts/master/vk-master-2020-03-01.txt
@@ -208936,6 +208936,13 @@
 dEQP-VK.compute.workgroup_memory_explicit_layout.padding.uint8_t_28_uint8_t_29
 dEQP-VK.compute.workgroup_memory_explicit_layout.padding.uint8_t_29_uint8_t_30
 dEQP-VK.compute.workgroup_memory_explicit_layout.padding.uint8_t_30_uint8_t_31
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.8
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.64
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.4096
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.16384
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.32768
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.49152
+dEQP-VK.compute.workgroup_memory_explicit_layout.size.65536
 dEQP-VK.image.store.with_format.1d.b10g11r11_ufloat_pack32
 dEQP-VK.image.store.with_format.1d.r32g32_sfloat
 dEQP-VK.image.store.with_format.1d.r16g16_sfloat
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index 7a2e183..e49f3cd 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
Binary files differ
diff --git a/external/vulkancts/modules/vulkan/compute/vktComputeWorkgroupMemoryExplicitLayoutTests.cpp b/external/vulkancts/modules/vulkan/compute/vktComputeWorkgroupMemoryExplicitLayoutTests.cpp
index a00a485..8a03b5b 100644
--- a/external/vulkancts/modules/vulkan/compute/vktComputeWorkgroupMemoryExplicitLayoutTests.cpp
+++ b/external/vulkancts/modules/vulkan/compute/vktComputeWorkgroupMemoryExplicitLayoutTests.cpp
@@ -1211,6 +1211,118 @@
 	}
 }
 
+class SizeTest : public vkt::TestCase
+{
+public:
+	SizeTest(tcu::TestContext& testCtx, deUint32 size)
+		: TestCase(testCtx, de::toString(size), de::toString(size))
+		, m_size(size)
+	{
+		DE_ASSERT(size % 8 == 0);
+	}
+
+	virtual void checkSupport(Context& context) const;
+	void initPrograms(SourceCollections& sourceCollections) const;
+
+	class Instance : public vkt::TestInstance
+	{
+	public:
+		Instance(Context& context)
+			: TestInstance(context)
+		{
+		}
+
+		tcu::TestStatus iterate(void)
+		{
+			return runCompute(m_context, 1u);
+		}
+	};
+
+	TestInstance* createInstance(Context& context) const
+	{
+		return new Instance(context);
+	}
+
+private:
+	deUint32 m_size;
+};
+
+void SizeTest::checkSupport(Context& context) const
+{
+	context.requireDeviceFunctionality("VK_KHR_workgroup_memory_explicit_layout");
+	context.requireDeviceFunctionality("VK_KHR_spirv_1_4");
+
+	if (context.getDeviceProperties().limits.maxComputeSharedMemorySize < m_size)
+		TCU_THROW(NotSupportedError, "Not enough shared memory supported.");
+}
+
+void SizeTest::initPrograms(SourceCollections& sourceCollections) const
+{
+	using namespace glu;
+
+	std::ostringstream src;
+
+	src << "#version 450\n";
+	src << "#extension GL_EXT_shared_memory_block : enable\n";
+	src << "#extension GL_EXT_shader_explicit_arithmetic_types : enable\n";
+	src << "layout(local_size_x = 8, local_size_y = 1, local_size_z = 1) in;\n";
+
+	for (deUint32 i = 0; i < 8; ++i)
+		src << "shared B" << i << " { uint32_t words[" << (m_size / 4) << "]; } b" << i << ";\n";
+
+	src << "layout(set = 0, binding = 0) buffer Result { uint result; };\n";
+
+	src	<< "void main() {\n";
+	src << "  int index = int(gl_LocalInvocationIndex);\n";
+	src << "  int size = " << (m_size / 4) << ";\n";
+
+	src << "  if (index == 0) for (int x = 0; x < size; x++) b0.words[x] = 0xFFFF;\n";
+	src << "  barrier();\n";
+
+	src << "  for (int x = 0; x < size; x++) {\n";
+	src << "    if (x % 8 != index) continue;\n";
+	for (deUint32 i = 0; i < 8; ++i)
+		src << "    if (index == " << i << ") b" << i << ".words[x] = (x << 3) | " << i << ";\n";
+	src << "  }\n";
+
+	src << "  barrier();\n";
+	src << "  if (index != 0) return;\n";
+
+	src << "  int r = size;\n";
+	src << "  for (int x = 0; x < size; x++) {\n";
+	src << "    int expected = (x << 3) | (x % 8);\n";
+	src << "    if (b0.words[x] == expected) r--;\n";
+	src << "  }\n";
+	src << "  result = r;\n";
+	src << "}\n";
+
+	sourceCollections.glslSources.add("comp")
+		<< ComputeSource(src.str())
+		<< vk::ShaderBuildOptions(sourceCollections.usedVulkanVersion, vk::SPIRV_VERSION_1_4,
+								  vk::ShaderBuildOptions::Flags(0u));
+}
+
+void AddSizeTests(tcu::TestCaseGroup* group)
+{
+	deUint32 sizes[] =
+	{
+		8u,
+		64u,
+		4096u,
+
+		// Dynamic generation of shaders based on properties reported
+		// by devices is not allowed in the CTS, so let's create a few
+		// variants based on common known maximum sizes.
+		16384u,
+		32768u,
+		49152u,
+		65536u,
+	};
+
+	for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(sizes); ++i)
+		group->addChild(new SizeTest(group->getTestContext(), sizes[i]));
+}
+
 } // anonymous
 
 tcu::TestCaseGroup* createWorkgroupMemoryExplicitLayoutTests(tcu::TestContext& testCtx)
@@ -1229,6 +1341,10 @@
 	AddPaddingTests(padding);
 	tests->addChild(padding);
 
+	tcu::TestCaseGroup* size = new tcu::TestCaseGroup(testCtx, "size", "Test blocks of various sizes");
+	AddSizeTests(size);
+	tests->addChild(size);
+
 	return tests.release();
 }
 
diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt
index d66c8e0..82f4efd 100644
--- a/external/vulkancts/mustpass/master/vk-default.txt
+++ b/external/vulkancts/mustpass/master/vk-default.txt
Binary files differ