18bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner/*------------------------------------------------------------------------
28bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * Vulkan Conformance Tests
38bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * ------------------------
48bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *
58bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * Copyright (c) 2015 The Khronos Group Inc.
68bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7c05b7f1437e619205c96eaa31c0b79ec97a0d47dPyry Haulos * Copyright (c) 2016 The Android Open Source Project
88bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *
9d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
10d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * you may not use this file except in compliance with the License.
11d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * You may obtain a copy of the License at
128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *
13d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *
15d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * Unless required by applicable law or agreed to in writing, software
16d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
17d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * See the License for the specific language governing permissions and
19d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * limitations under the License.
208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *
218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *//*!
228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * \file
238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner * \brief Opaque type (sampler, buffer, atomic counter, ...) indexing tests.
248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner *//*--------------------------------------------------------------------*/
258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "vktOpaqueTypeIndexingTests.hpp"
278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
28b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "vkRefUtil.hpp"
29b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "vkImageUtil.hpp"
30b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "vkMemUtil.hpp"
31b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "vkTypeUtil.hpp"
32b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "vkQueryUtil.hpp"
33b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "tcuTexture.hpp"
358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "tcuTestLog.hpp"
368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "tcuVectorUtil.hpp"
378ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos#include "tcuTextureUtil.hpp"
388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "deStringUtil.hpp"
40b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos#include "deSharedPtr.hpp"
418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "deRandom.hpp"
42de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos#include "deSTLUtil.hpp"
438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include "vktShaderExecutor.hpp"
458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner#include <sstream>
478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnernamespace vkt
498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnernamespace shaderexecutor
518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnernamespace
548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
56b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosusing de::UniquePtr;
57b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosusing de::MovePtr;
58b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosusing de::SharedPtr;
59b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosusing std::vector;
60b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
61b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosusing namespace vk;
62b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
63b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulostypedef SharedPtr<Unique<VkSampler> > VkSamplerSp;
64b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
65b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos// Buffer helper
66b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
67b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosclass Buffer
68b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
69b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulospublic:
70b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos								Buffer				(Context& context, VkBufferUsageFlags usage, size_t size);
71b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
72b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	VkBuffer					getBuffer			(void) const { return *m_buffer;					}
73b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	void*						getHostPtr			(void) const { return m_allocation->getHostPtr();	}
74b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	void						flush				(void);
75b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	void						invalidate			(void);
76b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
77b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosprivate:
78b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const DeviceInterface&		m_vkd;
79b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkDevice				m_device;
80b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const Unique<VkBuffer>		m_buffer;
81b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const UniquePtr<Allocation>	m_allocation;
82b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos};
83b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
84b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulostypedef de::SharedPtr<Buffer> BufferSp;
85b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
86b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosMove<VkBuffer> createBuffer (const DeviceInterface& vkd, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usageFlags)
87b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
88b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkBufferCreateInfo	createInfo		=
89b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
90b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
91b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
92b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(VkBufferCreateFlags)0,
93b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		size,
94b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		usageFlags,
95b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
96b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		0u,
97b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL
98b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	};
99b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return createBuffer(vkd, device, &createInfo);
100b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
101b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
102b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosMovePtr<Allocation> allocateAndBindMemory (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, VkBuffer buffer)
103b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
104b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	MovePtr<Allocation>		alloc	(allocator.allocate(getBufferMemoryRequirements(vkd, device, buffer), MemoryRequirement::HostVisible));
105b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
106b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	VK_CHECK(vkd.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
107b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
108b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return alloc;
109b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
110b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
111b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosBuffer::Buffer (Context& context, VkBufferUsageFlags usage, size_t size)
112b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: m_vkd			(context.getDeviceInterface())
113b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_device		(context.getDevice())
114b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_buffer		(createBuffer			(context.getDeviceInterface(),
115b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 context.getDevice(),
116b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 (VkDeviceSize)size,
117b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 usage))
118b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_allocation	(allocateAndBindMemory	(context.getDeviceInterface(),
119b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 context.getDevice(),
120b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 context.getDefaultAllocator(),
121b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											 *m_buffer))
122b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
123b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
124b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
125b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosvoid Buffer::flush (void)
126b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
127b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	flushMappedMemoryRange(m_vkd, m_device, m_allocation->getMemory(), m_allocation->getOffset(), VK_WHOLE_SIZE);
128b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
129b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
130b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosvoid Buffer::invalidate (void)
131b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
132b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	invalidateMappedMemoryRange(m_vkd, m_device, m_allocation->getMemory(), m_allocation->getOffset(), VK_WHOLE_SIZE);
133b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
134b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
135b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosMovePtr<Buffer> createUniformIndexBuffer (Context& context, int numIndices, const int* indices)
136b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
137b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	MovePtr<Buffer>		buffer	(new Buffer(context, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(int)*numIndices));
138b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	int* const			bufPtr	= (int*)buffer->getHostPtr();
139b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
140b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (int ndx = 0; ndx < numIndices; ++ndx)
141b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		bufPtr[ndx] = indices[ndx];
142b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
143b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	buffer->flush();
144b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
145b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return buffer;
146b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
147b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
148b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos// Tests
149b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerenum IndexExprType
1518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
1528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	INDEX_EXPR_TYPE_CONST_LITERAL	= 0,
1538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	INDEX_EXPR_TYPE_CONST_EXPRESSION,
1548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	INDEX_EXPR_TYPE_UNIFORM,
1558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	INDEX_EXPR_TYPE_DYNAMIC_UNIFORM,
1568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	INDEX_EXPR_TYPE_LAST
1588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
1598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerenum TextureType
1618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
1628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_1D = 0,
1638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_2D,
1648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_CUBE,
1658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_2D_ARRAY,
1668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_3D,
1678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	TEXTURE_TYPE_LAST
1698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
1708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass OpaqueTypeIndexingCase : public TestCase
1728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
1738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
1748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										OpaqueTypeIndexingCase		(tcu::TestContext&			testCtx,
1758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const char*				name,
1768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const char*				description,
1778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const glu::ShaderType		shaderType,
1788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const IndexExprType		indexExprType);
1798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual								~OpaqueTypeIndexingCase		(void);
180b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual void						initPrograms				(vk::SourceCollections& programCollection) const
1828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										{
183b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos											generateSources(m_shaderType, m_shaderSpec, programCollection);
1848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										}
1858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprotected:
1878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*							m_name;
1888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::ShaderType				m_shaderType;
1898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const IndexExprType					m_indexExprType;
1908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	ShaderSpec							m_shaderSpec;
1918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
1928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
193b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosOpaqueTypeIndexingCase::OpaqueTypeIndexingCase (tcu::TestContext&			testCtx,
194b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos												const char*					name,
195b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos												const char*					description,
196b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos												const glu::ShaderType		shaderType,
197b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos												const IndexExprType			indexExprType)
198b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: TestCase			(testCtx, name, description)
199b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_name			(name)
200b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_shaderType		(shaderType)
201b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_indexExprType	(indexExprType)
202b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
203b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
204b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
205b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosOpaqueTypeIndexingCase::~OpaqueTypeIndexingCase (void)
206b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
207b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
208b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
2098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass OpaqueTypeIndexingTestInstance : public TestInstance
2108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
2118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
2128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										OpaqueTypeIndexingTestInstance		(Context&					context,
2138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																			 const glu::ShaderType		shaderType,
2148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																			 const ShaderSpec&			shaderSpec,
2158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																			 const char*				name,
2168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																			 const IndexExprType		indexExprType);
2178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual								~OpaqueTypeIndexingTestInstance		(void);
2188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual tcu::TestStatus				iterate								(void) = 0;
2208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprotected:
222b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	void								checkSupported						(const VkDescriptorType descriptorType);
223b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
224b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirnerprotected:
2258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	tcu::TestContext&					m_testCtx;
2268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::ShaderType				m_shaderType;
2278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const ShaderSpec&					m_shaderSpec;
2288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*							m_name;
2298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const IndexExprType					m_indexExprType;
2308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
2318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerOpaqueTypeIndexingTestInstance::OpaqueTypeIndexingTestInstance (Context&					context,
2338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const glu::ShaderType		shaderType,
2348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const ShaderSpec&			shaderSpec,
2358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const char*					name,
2368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const IndexExprType			indexExprType)
2378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	: TestInstance		(context)
2388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_testCtx			(context.getTestContext())
2398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_shaderType		(shaderType)
2408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_shaderSpec		(shaderSpec)
2418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_name			(name)
2428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_indexExprType	(indexExprType)
2438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
2448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
2458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerOpaqueTypeIndexingTestInstance::~OpaqueTypeIndexingTestInstance (void)
2478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
2488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
2498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
250b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirnervoid OpaqueTypeIndexingTestInstance::checkSupported (const VkDescriptorType descriptorType)
251b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner{
252b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	const VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
253b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
254b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
255b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	{
256b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner		switch (descriptorType)
257b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner		{
258b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner			case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
259b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				if (!deviceFeatures.shaderSampledImageArrayDynamicIndexing)
260b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner					TCU_THROW(NotSupportedError, "Dynamic indexing of sampler arrays is not supported");
261b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				break;
262b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
263b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner			case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
264b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				if (!deviceFeatures.shaderUniformBufferArrayDynamicIndexing)
265b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner					TCU_THROW(NotSupportedError, "Dynamic indexing of uniform buffer arrays is not supported");
266b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				break;
267b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
268b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner			case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
269b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				if (!deviceFeatures.shaderStorageBufferArrayDynamicIndexing)
270b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner					TCU_THROW(NotSupportedError, "Dynamic indexing of storage buffer arrays is not supported");
271b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				break;
272b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
273b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner			default:
274b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner				break;
275b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner		}
276b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	}
277b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner}
278b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
279b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosstatic void declareUniformIndexVars (std::ostream& str, deUint32 bindingLocation, const char* varPrefix, int numVars)
2808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
281b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	str << "layout(set = " << EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX << ", binding = " << bindingLocation << ", std140) uniform Indices\n{\n";
2828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int varNdx = 0; varNdx < numVars; varNdx++)
284b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		str << "\thighp int " << varPrefix << varNdx << ";\n";
2858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
286b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	str << "};\n";
2878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
2888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic TextureType getTextureType (glu::DataType samplerType)
2908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
2918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (samplerType)
2928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
2938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_1D:
2948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_1D:
2958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_1D:
2968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_1D_SHADOW:
2978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return TEXTURE_TYPE_1D;
2988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D:
3008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_2D:
3018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_2D:
3028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_SHADOW:
3038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return TEXTURE_TYPE_2D;
3048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_CUBE:
3068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_CUBE:
3078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_CUBE:
3088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_CUBE_SHADOW:
3098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return TEXTURE_TYPE_CUBE;
3108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_ARRAY:
3128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
3138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
3148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
3158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return TEXTURE_TYPE_2D_ARRAY;
3168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_3D:
3188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_3D:
3198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_3D:
3208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return TEXTURE_TYPE_3D;
3218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
3238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			throw tcu::InternalError("Invalid sampler type");
3248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
3258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
3268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic bool isShadowSampler (glu::DataType samplerType)
3288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
3298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	return samplerType == glu::TYPE_SAMPLER_1D_SHADOW		||
3308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		   samplerType == glu::TYPE_SAMPLER_2D_SHADOW		||
3318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		   samplerType == glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	||
3328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		   samplerType == glu::TYPE_SAMPLER_CUBE_SHADOW;
3338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
3348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic glu::DataType getSamplerOutputType (glu::DataType samplerType)
3368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
3378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (samplerType)
3388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
3398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_1D:
3408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D:
3418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_CUBE:
3428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_ARRAY:
3438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_3D:
3448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return glu::TYPE_FLOAT_VEC4;
3458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_1D_SHADOW:
3478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_SHADOW:
3488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_CUBE_SHADOW:
3498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
3508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return glu::TYPE_FLOAT;
3518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_1D:
3538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_2D:
3548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_CUBE:
3558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
3568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT_SAMPLER_3D:
3578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return glu::TYPE_INT_VEC4;
3588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_1D:
3608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_2D:
3618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_CUBE:
3628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
3638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT_SAMPLER_3D:
3648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return glu::TYPE_UINT_VEC4;
3658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
3678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			throw tcu::InternalError("Invalid sampler type");
3688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
3698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
3708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic tcu::TextureFormat getSamplerTextureFormat (glu::DataType samplerType)
3728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
3738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType		outType			= getSamplerOutputType(samplerType);
3748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType		outScalarType	= glu::getDataTypeScalarType(outType);
3758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (outScalarType)
3778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
3788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_FLOAT:
3798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			if (isShadowSampler(samplerType))
3808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			else
3828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
3838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_INT:		return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8);
3858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case glu::TYPE_UINT:	return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8);
3868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
3888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			throw tcu::InternalError("Invalid sampler type");
3898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
3908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
3918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic glu::DataType getSamplerCoordType (glu::DataType samplerType)
3938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
3948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const TextureType	texType		= getTextureType(samplerType);
3958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	int					numCoords	= 0;
3968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
3978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (texType)
3988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
3998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_1D:		numCoords = 1;	break;
4008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D:		numCoords = 2;	break;
4018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D_ARRAY:	numCoords = 3;	break;
4028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_CUBE:		numCoords = 3;	break;
4038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_3D:		numCoords = 3;	break;
4048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
4058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			DE_ASSERT(false);
4068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
4078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (isShadowSampler(samplerType))
4098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		numCoords += 1;
4108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	DE_ASSERT(de::inRange(numCoords, 1, 4));
4128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	return numCoords == 1 ? glu::TYPE_FLOAT : glu::getDataTypeFloatVec(numCoords);
4148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
4158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic void fillTextureData (const tcu::PixelBufferAccess& access, de::Random& rnd)
4178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
4188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	DE_ASSERT(access.getHeight() == 1 && access.getDepth() == 1);
4198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (access.getFormat().order == tcu::TextureFormat::D)
4218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
4228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// \note Texture uses odd values, lookup even values to avoid precision issues.
4238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const float values[] = { 0.1f, 0.3f, 0.5f, 0.7f, 0.9f };
4248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int ndx = 0; ndx < access.getWidth(); ndx++)
4268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			access.setPixDepth(rnd.choose<float>(DE_ARRAY_BEGIN(values), DE_ARRAY_END(values)), ndx, 0);
4278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
4288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	else
4298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
4308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		TCU_CHECK_INTERNAL(access.getFormat().order == tcu::TextureFormat::RGBA && access.getFormat().getPixelSize() == 4);
4318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int ndx = 0; ndx < access.getWidth(); ndx++)
4338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			*((deUint32*)access.getDataPtr() + ndx) = rnd.getUint32();
4348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
4358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
4368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic vk::VkImageType getVkImageType (TextureType texType)
4388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
4398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (texType)
4408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
4418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_1D:			return vk::VK_IMAGE_TYPE_1D;
4428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D:
4438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D_ARRAY:		return vk::VK_IMAGE_TYPE_2D;
4441217b5594596822a129239d29259f7d7befd332eAkos Dirner		case TEXTURE_TYPE_CUBE:			return vk::VK_IMAGE_TYPE_2D;
4458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_3D:			return vk::VK_IMAGE_TYPE_3D;
4468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
4478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			DE_FATAL("Impossible");
4488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return (vk::VkImageType)0;
4498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
4508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
4518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
4528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerstatic vk::VkImageViewType getVkImageViewType (TextureType texType)
4538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
4548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	switch (texType)
4558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
4568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_1D:			return vk::VK_IMAGE_VIEW_TYPE_1D;
4578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D:			return vk::VK_IMAGE_VIEW_TYPE_2D;
4588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_2D_ARRAY:		return vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY;
4591217b5594596822a129239d29259f7d7befd332eAkos Dirner		case TEXTURE_TYPE_CUBE:			return vk::VK_IMAGE_VIEW_TYPE_CUBE;
4608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		case TEXTURE_TYPE_3D:			return vk::VK_IMAGE_VIEW_TYPE_3D;
4618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		default:
4628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			DE_FATAL("Impossible");
4638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			return (vk::VkImageViewType)0;
4648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
4658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
4668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
467b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos//! Test image with 1-pixel dimensions and no mipmaps
468b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosclass TestImage
469b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
470b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulospublic:
471b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos								TestImage		(Context& context, TextureType texType, tcu::TextureFormat format, const void* colorValue);
472b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
473b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	VkImageView					getImageView	(void) const { return *m_imageView; }
474b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
475b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosprivate:
476b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const Unique<VkImage>		m_image;
477b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const UniquePtr<Allocation>	m_allocation;
478b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const Unique<VkImageView>	m_imageView;
479b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos};
480b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
481b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosMove<VkImage> createTestImage (const DeviceInterface& vkd, VkDevice device, TextureType texType, tcu::TextureFormat format)
482b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
483b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkImageCreateInfo		createInfo		=
484b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
485b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
486b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
487b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(texType == TEXTURE_TYPE_CUBE ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0),
488b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		getVkImageType(texType),
489b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		mapTextureFormat(format),
490b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		makeExtent3D(1, 1, 1),
491b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		1u,
492b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(texType == TEXTURE_TYPE_CUBE) ? 6u : 1u,
493b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_SAMPLE_COUNT_1_BIT,
494b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_IMAGE_TILING_OPTIMAL,
495b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
496b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
497b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		0u,
498b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
499b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_IMAGE_LAYOUT_UNDEFINED
500b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	};
501b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
502b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return createImage(vkd, device, &createInfo);
503b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
504b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
505b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulosde::MovePtr<Allocation> allocateAndBindMemory (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, VkImage image)
506b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
507b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	de::MovePtr<Allocation>		alloc	= allocator.allocate(getImageMemoryRequirements(vkd, device, image), MemoryRequirement::Any);
508b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
509b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	VK_CHECK(vkd.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
510b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
511b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return alloc;
512b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
513b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
514b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosMove<VkImageView> createTestImageView (const DeviceInterface& vkd, VkDevice device, VkImage image, TextureType texType, tcu::TextureFormat format)
515b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
516b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const bool					isDepthImage	= format.order == tcu::TextureFormat::D;
517b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkImageViewCreateInfo	createInfo		=
518b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
519b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
520b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
521b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(VkImageViewCreateFlags)0,
522b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		image,
523b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		getVkImageViewType(texType),
524b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		mapTextureFormat(format),
525b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
526b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_COMPONENT_SWIZZLE_IDENTITY,
527b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_COMPONENT_SWIZZLE_IDENTITY,
528b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_COMPONENT_SWIZZLE_IDENTITY,
529b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_COMPONENT_SWIZZLE_IDENTITY,
530b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		},
531b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
532b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkImageAspectFlags)(isDepthImage ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
533b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
534b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
535b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
536b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(texType == TEXTURE_TYPE_CUBE ? 6u : 1u)
537b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		}
538b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	};
539b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
540b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return createImageView(vkd, device, &createInfo);
541b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
542b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
543b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry HaulosTestImage::TestImage (Context& context, TextureType texType, tcu::TextureFormat format, const void* colorValue)
544b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: m_image		(createTestImage		(context.getDeviceInterface(), context.getDevice(), texType, format))
545b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_allocation	(allocateAndBindMemory	(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_image))
546b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	, m_imageView	(createTestImageView	(context.getDeviceInterface(), context.getDevice(), *m_image, texType, format))
547b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos{
548b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const DeviceInterface&		vkd					= context.getDeviceInterface();
549b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkDevice				device				= context.getDevice();
550b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
551b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const size_t				pixelSize			= (size_t)format.getPixelSize();
552b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const deUint32				numLayers			= (texType == TEXTURE_TYPE_CUBE) ? 6u : 1u;
553b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const size_t				numReplicas			= (size_t)numLayers;
554b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const size_t				stagingBufferSize	= pixelSize*numReplicas;
555b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
556b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkBufferCreateInfo	stagingBufferInfo	=
557b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
558b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
559b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
560b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(VkBufferCreateFlags)0u,
561b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(VkDeviceSize)stagingBufferSize,
562b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		(VkBufferCreateFlags)VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
563b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
564b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		0u,
565b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		DE_NULL,
566b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	};
567b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const Unique<VkBuffer>		stagingBuffer		(createBuffer(vkd, device, &stagingBufferInfo));
568b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const UniquePtr<Allocation>	alloc				(context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vkd, device, *stagingBuffer), MemoryRequirement::HostVisible));
569b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
570b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	VK_CHECK(vkd.bindBufferMemory(device, *stagingBuffer, alloc->getMemory(), alloc->getOffset()));
571b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
572b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (size_t ndx = 0; ndx < numReplicas; ++ndx)
573b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		deMemcpy((deUint8*)alloc->getHostPtr() + ndx*pixelSize, colorValue, pixelSize);
574b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
5756d7fc9ee1cfc7f9503de9607905e4ed9c32017c8Gary Sweet	flushMappedMemoryRange(vkd, device, alloc->getMemory(), alloc->getOffset(), VK_WHOLE_SIZE);
5766d7fc9ee1cfc7f9503de9607905e4ed9c32017c8Gary Sweet
577b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
5788e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const Unique<VkCommandPool>		cmdPool			(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex()));
5798e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const Unique<VkCommandBuffer>	cmdBuf			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
5808e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const VkCommandBufferBeginInfo	beginInfo		=
581b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
582b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
583b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
584b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkCommandBufferUsageFlags)VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
585b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkCommandBufferInheritanceInfo*)DE_NULL,
586b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
5878e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const VkImageAspectFlags		imageAspect		= (VkImageAspectFlags)(format.order == tcu::TextureFormat::D ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT);
5888e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const VkBufferImageCopy			copyInfo		=
589b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
590b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
591b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
592b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
593b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
594b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				imageAspect,
595b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
596b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
597b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				numLayers
598b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			},
599b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 0u, 0u, 0u },
600b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 1u, 1u, 1u }
601b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
6028e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const VkImageMemoryBarrier		preCopyBarrier	=
603b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
604b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
605b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
606b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkAccessFlags)0u,
607b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkAccessFlags)VK_ACCESS_TRANSFER_WRITE_BIT,
608b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_IMAGE_LAYOUT_UNDEFINED,
609b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
610b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_QUEUE_FAMILY_IGNORED,
611b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_QUEUE_FAMILY_IGNORED,
612b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*m_image,
613b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
614b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				imageAspect,
615b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
616b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				1u,
617b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
618b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				numLayers
619b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			}
620b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
6218e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos		const VkImageMemoryBarrier		postCopyBarrier	=
622b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
623b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
624b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
625b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkAccessFlags)VK_ACCESS_TRANSFER_WRITE_BIT,
626b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,
627b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
628b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
629b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_QUEUE_FAMILY_IGNORED,
630b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_QUEUE_FAMILY_IGNORED,
631b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*m_image,
632b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
633b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				imageAspect,
634b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
635b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				1u,
636b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
637b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				numLayers
638b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			}
639b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
640b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
641b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_CHECK(vkd.beginCommandBuffer(*cmdBuf, &beginInfo));
642b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.cmdPipelineBarrier(*cmdBuf,
643b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
644b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT,
645b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkDependencyFlags)0u,
646b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   0u,
647b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (const VkMemoryBarrier*)DE_NULL,
648b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   0u,
649b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (const VkBufferMemoryBarrier*)DE_NULL,
650b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   1u,
651b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   &preCopyBarrier);
652b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.cmdCopyBufferToImage(*cmdBuf, *stagingBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyInfo);
653b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.cmdPipelineBarrier(*cmdBuf,
654b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT,
655b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
656b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (VkDependencyFlags)0u,
657b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   0u,
658b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (const VkMemoryBarrier*)DE_NULL,
659b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   0u,
660b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   (const VkBufferMemoryBarrier*)DE_NULL,
661b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   1u,
662b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos							   &postCopyBarrier);
663b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		VK_CHECK(vkd.endCommandBuffer(*cmdBuf));
664b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
665b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
6668e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos			const Unique<VkFence>	fence		(createFence(vkd, device));
6678e88bf0360fc67241c8beaefd9299e56eece9f7aPyry Haulos			const VkSubmitInfo		submitInfo	=
668b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
669b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				VK_STRUCTURE_TYPE_SUBMIT_INFO,
670b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				DE_NULL,
671b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
672b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				(const VkSemaphore*)DE_NULL,
673b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				(const VkPipelineStageFlags*)DE_NULL,
674b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				1u,
675b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				&cmdBuf.get(),
676b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				0u,
677b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				(const VkSemaphore*)DE_NULL,
678b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			};
679b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
680b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_CHECK(vkd.queueSubmit(context.getUniversalQueue(), 1u, &submitInfo, *fence));
681b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_CHECK(vkd.waitForFences(device, 1u, &fence.get(), VK_TRUE, ~0ull));
682b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		}
683b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
684b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos}
685b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
686b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulostypedef SharedPtr<TestImage> TestImageSp;
687b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
6888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner// SamplerIndexingCaseInstance
6898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
6908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass SamplerIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
6918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
6928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
6938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	enum
6948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
6958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_INVOCATIONS		= 64,
6968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_SAMPLERS		= 8,
6978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_LOOKUPS			= 4
6988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	};
6998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								SamplerIndexingCaseInstance		(Context&					context,
7018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 const glu::ShaderType		shaderType,
7028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 const ShaderSpec&			shaderSpec,
7038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 const char*				name,
7048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 glu::DataType				samplerType,
7058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 const IndexExprType		indexExprType,
7068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																 const std::vector<int>&	lookupIndices);
7078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual						~SamplerIndexingCaseInstance	(void);
7088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual tcu::TestStatus		iterate							(void);
7108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprotected:
7128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType			m_samplerType;
713b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const std::vector<int>		m_lookupIndices;
7148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
7158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerSamplerIndexingCaseInstance::SamplerIndexingCaseInstance (Context&						context,
7178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  const glu::ShaderType			shaderType,
7188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  const ShaderSpec&				shaderSpec,
7198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  const char*					name,
7208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  glu::DataType					samplerType,
7218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  const IndexExprType			indexExprType,
7228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner														  const std::vector<int>&		lookupIndices)
723b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, name, indexExprType)
7248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_samplerType						(samplerType)
7258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_lookupIndices					(lookupIndices)
7268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
7278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
7288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerSamplerIndexingCaseInstance::~SamplerIndexingCaseInstance (void)
7308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
7318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
7328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
7338ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulosbool isIntegerFormat (const tcu::TextureFormat& format)
7348ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos{
7358ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos	const tcu::TextureChannelClass	chnClass	= tcu::getTextureChannelClass(format.type);
7368ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos
7378ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos	return chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
7388ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos		   chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
7398ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos}
7408ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos
7418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnertcu::TestStatus SamplerIndexingCaseInstance::iterate (void)
7428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
7438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int						numInvocations		= SamplerIndexingCaseInstance::NUM_INVOCATIONS;
7448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int						numSamplers			= SamplerIndexingCaseInstance::NUM_SAMPLERS;
7458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int						numLookups			= SamplerIndexingCaseInstance::NUM_LOOKUPS;
7468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType				coordType			= getSamplerCoordType(m_samplerType);
7478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType				outputType			= getSamplerOutputType(m_samplerType);
7488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const tcu::TextureFormat		texFormat			= getSamplerTextureFormat(m_samplerType);
7498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int						outLookupStride		= numInvocations*getDataTypeScalarSize(outputType);
750b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<float>					coords;
751b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<deUint32>				outData;
752b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<deUint8>					texData				(numSamplers * texFormat.getPixelSize());
7538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const tcu::PixelBufferAccess	refTexAccess		(texFormat, numSamplers, 1, 1, &texData[0]);
7548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	de::Random						rnd					(deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
7558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const TextureType				texType				= getTextureType(m_samplerType);
7568ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos	const tcu::Sampler::FilterMode	filterMode			= (isShadowSampler(m_samplerType) || isIntegerFormat(texFormat)) ? tcu::Sampler::NEAREST : tcu::Sampler::LINEAR;
7575f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski
7585f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski	// The shadow sampler with unnormalized coordinates is only used with the reference texture. Actual samplers in shaders use normalized coords.
7598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const tcu::Sampler				refSampler			= isShadowSampler(m_samplerType)
7608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																? tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
7618ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos																				filterMode, filterMode, 0.0f, false /* non-normalized */,
7628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																				tcu::Sampler::COMPAREMODE_LESS)
7638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																: tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
7648ff4c85abb1f134b2ba77112c3ee7a708595ee8bPyry Haulos																				filterMode, filterMode);
7658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
766b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
767b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkDevice					device				= m_context.getDevice();
768b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<TestImageSp>				images;
769b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<VkSamplerSp>				samplers;
770b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	MovePtr<Buffer>					indexBuffer;
771b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSetLayout>		extraResourcesLayout;
772b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorPool>			extraResourcesSetPool;
773b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSet>			extraResourcesSet;
774b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
775b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	checkSupported(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
776b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
7778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	coords.resize(numInvocations * getDataTypeScalarSize(coordType));
7788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
779b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow	if (texType == TEXTURE_TYPE_CUBE)
780b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow	{
781b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		if (isShadowSampler(m_samplerType))
782b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		{
78340dad1426baeb79f2109d0c8c2f7dc64df06dbb7Pyry Haulos			for (size_t i = 0; i < coords.size() / 4; i++)
784b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow			{
785b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow				coords[4 * i] = 1.0f;
786b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow				coords[4 * i + 1] = coords[4 * i + 2] = coords[4 * i + 3] = 0.0f;
787b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow			}
788b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		}
789b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		else
790b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		{
79140dad1426baeb79f2109d0c8c2f7dc64df06dbb7Pyry Haulos			for (size_t i = 0; i < coords.size() / 3; i++)
792b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow			{
793b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow				coords[3 * i] = 1.0f;
794b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow				coords[3 * i + 1] = coords[3 * i + 2] = 0.0f;
795b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow			}
796b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow		}
797b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow	}
798b0eaaa9f2c1d0e3bf719c3f0707691f06fae3b0easokolow
7998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (isShadowSampler(m_samplerType))
8008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
8018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// Use different comparison value per invocation.
8028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// \note Texture uses odd values, comparison even values.
8038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const int	numCoordComps	= getDataTypeScalarSize(coordType);
8048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const float	cmpValues[]		= { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f };
8058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
8068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
8078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			coords[invocationNdx*numCoordComps + (numCoordComps-1)] = rnd.choose<float>(DE_ARRAY_BEGIN(cmpValues), DE_ARRAY_END(cmpValues));
8088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
8098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
8108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	fillTextureData(refTexAccess, rnd);
8118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
8128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	outData.resize(numLookups*outLookupStride);
8138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
814b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (int ndx = 0; ndx < numSamplers; ++ndx)
8158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
816b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		images.push_back(TestImageSp(new TestImage(m_context, texType, texFormat, &texData[ndx * texFormat.getPixelSize()])));
8178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
818b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
819b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			tcu::Sampler	samplerCopy	(refSampler);
820b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			samplerCopy.normalizedCoords = true;
821b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
822b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
823b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				const VkSamplerCreateInfo	samplerParams	= mapSampler(samplerCopy, texFormat);
824b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				samplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vkd, device, &samplerParams))));
825b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			}
826b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		}
827b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
8288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
829b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
830b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		indexBuffer = createUniformIndexBuffer(m_context, numLookups, &m_lookupIndices[0]);
8318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
832b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
833b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutBinding		bindings[]	=
8345f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski		{
835b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 0u,						VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	(deUint32)numSamplers,		VK_SHADER_STAGE_ALL,	DE_NULL		},
836b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ (deUint32)numSamplers,	VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			1u,							VK_SHADER_STAGE_ALL,	DE_NULL		}
837b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
838b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutCreateInfo	layoutInfo	=
8395f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski		{
840b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
841b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
842b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorSetLayoutCreateFlags)0u,
843b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(bindings),
844b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bindings,
845b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
846b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
847b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesLayout = createDescriptorSetLayout(vkd, device, &layoutInfo);
848b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
8495f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski
850b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
851b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolSize			poolSizes[]	=
852b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
853b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	(deUint32)numSamplers	},
854b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			1u,						}
855b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
856b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolCreateInfo	poolInfo	=
857b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
858b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
859b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
860b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
861b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,		// maxSets
862b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(poolSizes),
863b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			poolSizes,
864b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
865b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
866b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSetPool = createDescriptorPool(vkd, device, &poolInfo);
867b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
8685f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski
869b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
870b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetAllocateInfo	allocInfo	=
871b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
872b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
873b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
874b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSetPool,
875b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
876b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&extraResourcesLayout.get(),
877b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
878b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
879b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSet = allocateDescriptorSet(vkd, device, &allocInfo);
880b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
881b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
882b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
883b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vector<VkDescriptorImageInfo>	imageInfos			(numSamplers);
884b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
885b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
886b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
887b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
888b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
889b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstBinding
890b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstArrayElement
891b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(deUint32)numSamplers,
892b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
893b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&imageInfos[0],
894b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorBufferInfo*)DE_NULL,
895b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
896b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
897b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
898b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		for (int ndx = 0; ndx < numSamplers; ++ndx)
899b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
900b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			imageInfos[ndx].sampler		= **samplers[ndx];
901b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			imageInfos[ndx].imageView	= images[ndx]->getImageView();
902b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			imageInfos[ndx].imageLayout	= VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
9035f8fd3ca8504c8c39531e91583e4d3ee31a4bfcaMaciej Jesionowski		}
9048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
905b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
906b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
907b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
908b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (indexBuffer)
909b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
910b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorBufferInfo	bufferInfo	=
911b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
912b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			indexBuffer->getBuffer(),
913b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
914b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_WHOLE_SIZE
915b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
916b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
917b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
918b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
919b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
920b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
921b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(deUint32)numSamplers,	// dstBinding
922b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,						// dstArrayElement
923b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
924b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
925b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorImageInfo*)DE_NULL,
926b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&bufferInfo,
927b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
928b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
929b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
930b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
931b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
932b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
933b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
934b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		std::vector<void*>			inputs;
935b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		std::vector<void*>			outputs;
936b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		std::vector<int>			expandedIndices;
937b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		UniquePtr<ShaderExecutor>	executor		(createExecutor(m_context, m_shaderType, m_shaderSpec, *extraResourcesLayout));
938b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
939b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		inputs.push_back(&coords[0]);
940b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
9418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
9428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
9438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			expandedIndices.resize(numInvocations * m_lookupIndices.size());
9448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
9458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
9468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				for (int invNdx = 0; invNdx < numInvocations; invNdx++)
9478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					expandedIndices[lookupNdx*numInvocations + invNdx] = m_lookupIndices[lookupNdx];
9488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
9498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
9518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				inputs.push_back(&expandedIndices[lookupNdx*numInvocations]);
9528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
9538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
9558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			outputs.push_back(&outData[outLookupStride*lookupNdx]);
9568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
957b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		executor->execute(numInvocations, &inputs[0], &outputs[0], *extraResourcesSet);
9588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
9598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
9618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		tcu::TestLog&		log				= m_context.getTestContext().getLog();
9628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		tcu::TestStatus		testResult		= tcu::TestStatus::pass("Pass");
9638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (isShadowSampler(m_samplerType))
9658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
9668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const int			numCoordComps	= getDataTypeScalarSize(coordType);
9678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			TCU_CHECK_INTERNAL(getDataTypeScalarSize(outputType) == 1);
9698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			// Each invocation may have different results.
9718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
9728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
9738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const float	coord	= coords[invocationNdx*numCoordComps + (numCoordComps-1)];
9748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
9768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
9778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const int		texNdx		= m_lookupIndices[lookupNdx];
9788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const float		result		= *((const float*)(const deUint8*)&outData[lookupNdx*outLookupStride + invocationNdx]);
9798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const float		reference	= refTexAccess.sample2DCompare(refSampler, tcu::Sampler::NEAREST, coord, (float)texNdx, 0.0f, tcu::IVec3(0));
9808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					if (de::abs(result-reference) > 0.005f)
9828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					{
9838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						log << tcu::TestLog::Message << "ERROR: at invocation " << invocationNdx << ", lookup " << lookupNdx << ": expected "
9848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< reference << ", got " << result
9858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::TestLog::EndMessage;
9868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						if (testResult.getCode() == QP_TEST_RESULT_PASS)
9888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							testResult = tcu::TestStatus::fail("Got invalid lookup result");
9898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					}
9908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
9918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
9928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
9938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else
9948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
9958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			TCU_CHECK_INTERNAL(getDataTypeScalarSize(outputType) == 4);
9968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
9978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			// Validate results from first invocation
9988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
9998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
10008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const int		texNdx	= m_lookupIndices[lookupNdx];
10018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const deUint8*	resPtr	= (const deUint8*)&outData[lookupNdx*outLookupStride];
10028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				bool			isOk;
10038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				if (outputType == glu::TYPE_FLOAT_VEC4)
10058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
10068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const float			threshold		= 1.0f / 256.0f;
10078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const tcu::Vec4		reference		= refTexAccess.getPixel(texNdx, 0);
10088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const float*		floatPtr		= (const float*)resPtr;
10098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const tcu::Vec4		result			(floatPtr[0], floatPtr[1], floatPtr[2], floatPtr[3]);
10108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					isOk = boolAll(lessThanEqual(abs(reference-result), tcu::Vec4(threshold)));
10128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					if (!isOk)
10148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					{
10158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						log << tcu::TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
10168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< reference << ", got " << result
10178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::TestLog::EndMessage;
10188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					}
10198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
10208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				else
10218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
10228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const tcu::UVec4	reference		= refTexAccess.getPixelUint(texNdx, 0);
10238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const deUint32*		uintPtr			= (const deUint32*)resPtr;
10248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const tcu::UVec4	result			(uintPtr[0], uintPtr[1], uintPtr[2], uintPtr[3]);
10258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					isOk = boolAll(equal(reference, result));
10278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					if (!isOk)
10298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					{
10308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						log << tcu::TestLog::Message << "ERROR: at lookup " << lookupNdx << ": expected "
10318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< reference << ", got " << result
10328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::TestLog::EndMessage;
10338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					}
10348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
10358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				if (!isOk && testResult.getCode() == QP_TEST_RESULT_PASS)
10378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					testResult = tcu::TestStatus::fail("Got invalid lookup result");
10388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
10398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			// Check results of other invocations against first one
10418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int invocationNdx = 1; invocationNdx < numInvocations; invocationNdx++)
10428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
10438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				for (int lookupNdx = 0; lookupNdx < numLookups; lookupNdx++)
10448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
10458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const deUint32*		refPtr		= &outData[lookupNdx*outLookupStride];
10468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const deUint32*		resPtr		= refPtr + invocationNdx*4;
10478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					bool				isOk		= true;
10488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					for (int ndx = 0; ndx < 4; ndx++)
10508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						isOk = isOk && (refPtr[ndx] == resPtr[ndx]);
10518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					if (!isOk)
10538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					{
10548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						log << tcu::TestLog::Message << "ERROR: invocation " << invocationNdx << " result "
10558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::formatArray(tcu::Format::HexIterator<deUint32>(resPtr), tcu::Format::HexIterator<deUint32>(resPtr+4))
10568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< " for lookup " << lookupNdx << " doesn't match result from first invocation "
10578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::formatArray(tcu::Format::HexIterator<deUint32>(refPtr), tcu::Format::HexIterator<deUint32>(refPtr+4))
10588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							<< tcu::TestLog::EndMessage;
10598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						if (testResult.getCode() == QP_TEST_RESULT_PASS)
10618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner							testResult = tcu::TestStatus::fail("Inconsistent lookup results");
10628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					}
10638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
10648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
10658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
10668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		return testResult;
10688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
10698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
10708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass SamplerIndexingCase : public OpaqueTypeIndexingCase
10728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
10738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
10748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								SamplerIndexingCase			(tcu::TestContext&			testCtx,
10758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				name,
10768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				description,
10778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const glu::ShaderType		shaderType,
10788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 glu::DataType				samplerType,
10798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 IndexExprType				indexExprType);
10808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual						~SamplerIndexingCase		(void);
10818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual TestInstance*		createInstance				(Context& ctx) const;
10838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprivate:
10858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								SamplerIndexingCase			(const SamplerIndexingCase&);
10868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	SamplerIndexingCase&		operator=					(const SamplerIndexingCase&);
10878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	void						createShaderSpec			(void);
10898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType			m_samplerType;
10918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					m_numSamplers;
10928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					m_numLookups;
10938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<int>			m_lookupIndices;
10948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
10958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
10968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerSamplerIndexingCase::SamplerIndexingCase (tcu::TestContext&			testCtx,
10978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										  const char*				name,
10988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										  const char*				description,
10998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										  const glu::ShaderType		shaderType,
11008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										  glu::DataType				samplerType,
11018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										  IndexExprType				indexExprType)
11028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
11038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_samplerType				(samplerType)
11048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_numSamplers				(SamplerIndexingCaseInstance::NUM_SAMPLERS)
11058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_numLookups				(SamplerIndexingCaseInstance::NUM_LOOKUPS)
11068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_lookupIndices			(m_numLookups)
11078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	createShaderSpec();
11098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	init();
11108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
11118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerSamplerIndexingCase::~SamplerIndexingCase (void)
11138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
11158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerTestInstance* SamplerIndexingCase::createInstance (Context& ctx) const
11178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	return new SamplerIndexingCaseInstance(ctx,
11198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_shaderType,
11208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_shaderSpec,
11218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_name,
11228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_samplerType,
11238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_indexExprType,
11248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner										   m_lookupIndices);
11258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
11268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnervoid SamplerIndexingCase::createShaderSpec (void)
11288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	de::Random			rnd				(deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
11308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			samplersName	= "texSampler";
11318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			coordsName		= "coords";
11328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			indicesPrefix	= "index";
11338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			resultPrefix	= "result";
11348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType	coordType		= getSamplerCoordType(m_samplerType);
11358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const glu::DataType	outType			= getSamplerOutputType(m_samplerType);
11368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::ostringstream	global, code;
11378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int ndx = 0; ndx < m_numLookups; ndx++)
11398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_lookupIndices[ndx] = rnd.getInt(0, m_numSamplers-1);
11408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	m_shaderSpec.inputs.push_back(Symbol(coordsName, glu::VarType(coordType, glu::PRECISION_HIGHP)));
11428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
11448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		global << "#extension GL_EXT_gpu_shader5 : require\n";
11458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
11478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		global << "const highp int indexBase = 1;\n";
11488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	global <<
1150b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		"layout(set = " << EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX << ", binding = 0) uniform highp " << getDataTypeName(m_samplerType) << " " << samplersName << "[" << m_numSamplers << "];\n";
11518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
11538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
11548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int lookupNdx = 0; lookupNdx < m_numLookups; lookupNdx++)
11558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
11568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const std::string varName = indicesPrefix + de::toString(lookupNdx);
11578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			m_shaderSpec.inputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
11588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
11598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
11608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
1161b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		declareUniformIndexVars(global, (deUint32)m_numSamplers, indicesPrefix, m_numLookups);
11628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int lookupNdx = 0; lookupNdx < m_numLookups; lookupNdx++)
11648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
11658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const std::string varName = resultPrefix + de::toString(lookupNdx);
11668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_shaderSpec.outputs.push_back(Symbol(varName, glu::VarType(outType, glu::PRECISION_HIGHP)));
11678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
11688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int lookupNdx = 0; lookupNdx < m_numLookups; lookupNdx++)
11708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
11718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		code << resultPrefix << "" << lookupNdx << " = texture(" << samplersName << "[";
11728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
11748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << m_lookupIndices[lookupNdx];
11758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
11768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << "indexBase + " << (m_lookupIndices[lookupNdx]-1);
11778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else
11788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << indicesPrefix << lookupNdx;
11798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		code << "], " << coordsName << ");\n";
11818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
11828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	m_shaderSpec.globalDeclarations	= global.str();
11848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	m_shaderSpec.source				= code.str();
11858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
11868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerenum BlockType
11888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	BLOCKTYPE_UNIFORM = 0,
11908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	BLOCKTYPE_BUFFER,
11918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	BLOCKTYPE_LAST
11938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
11948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
11958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass BlockArrayIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
11968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
11978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
11988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	enum
11998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
12008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_INVOCATIONS		= 32,
12018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_INSTANCES		= 4,
12028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_READS			= 4
12038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	};
12048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1205de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	enum Flags
1206de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	{
1207de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		FLAG_USE_STORAGE_BUFFER	= (1<<0)	// Use VK_KHR_storage_buffer_storage_class
1208de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	};
1209de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos
12108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner									BlockArrayIndexingCaseInstance	(Context&						context,
12118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const glu::ShaderType			shaderType,
12128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const ShaderSpec&				shaderSpec,
12138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const char*					name,
12148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 BlockType						blockType,
1215de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos																	 const deUint32					flags,
12168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const IndexExprType			indexExprType,
12178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const std::vector<int>&		readIndices,
12188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const std::vector<deUint32>&	inValues);
12198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual							~BlockArrayIndexingCaseInstance	(void);
12208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
12218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual tcu::TestStatus			iterate							(void);
12228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
12238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprivate:
12248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const BlockType					m_blockType;
1225de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	const deUint32					m_flags;
12268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const std::vector<int>&			m_readIndices;
12278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const std::vector<deUint32>&	m_inValues;
12288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
12298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
12308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerBlockArrayIndexingCaseInstance::BlockArrayIndexingCaseInstance (Context&						context,
12318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const glu::ShaderType			shaderType,
12328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const ShaderSpec&				shaderSpec,
12338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const char*						name,
12348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																BlockType						blockType,
1235de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos																const deUint32					flags,
12368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const IndexExprType				indexExprType,
12378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const std::vector<int>&			readIndices,
12388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																const std::vector<deUint32>&	inValues)
1239b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, name, indexExprType)
12408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_blockType						(blockType)
1241de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	, m_flags							(flags)
12428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_readIndices						(readIndices)
12438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_inValues						(inValues)
12448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
12458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
12468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
12478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerBlockArrayIndexingCaseInstance::~BlockArrayIndexingCaseInstance (void)
12488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
12498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
12508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
12518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnertcu::TestStatus BlockArrayIndexingCaseInstance::iterate (void)
12528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
12538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					numInvocations		= NUM_INVOCATIONS;
12548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					numReads			= NUM_READS;
12558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<deUint32>		outValues			(numInvocations*numReads);
12568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1257b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	tcu::TestLog&				log					= m_context.getTestContext().getLog();
1258b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	tcu::TestStatus				testResult			= tcu::TestStatus::pass("Pass");
1259b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1260b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	std::vector<int>			expandedIndices;
1261b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	std::vector<void*>			inputs;
1262b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	std::vector<void*>			outputs;
1263b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkBufferUsageFlags	bufferUsage			= m_blockType == BLOCKTYPE_UNIFORM ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1264b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkDescriptorType		descriptorType		= m_blockType == BLOCKTYPE_UNIFORM ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1265b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1266b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const DeviceInterface&		vkd					= m_context.getDeviceInterface();
1267b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	const VkDevice				device				= m_context.getDevice();
1268b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1269b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	// \note Using separate buffer per element - might want to test
1270b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	// offsets & single buffer in the future.
1271b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	vector<BufferSp>			buffers				(m_inValues.size());
1272b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	MovePtr<Buffer>				indexBuffer;
1273b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1274b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSetLayout>	extraResourcesLayout;
1275b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorPool>		extraResourcesSetPool;
1276b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSet>		extraResourcesSet;
1277b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1278b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	checkSupported(descriptorType);
1279b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1280de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	if ((m_flags & FLAG_USE_STORAGE_BUFFER) != 0)
1281de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	{
1282e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_storage_buffer_storage_class"))
1283de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos			TCU_THROW(NotSupportedError, "VK_KHR_storage_buffer_storage_class is not supported");
1284de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	}
1285de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos
1286b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (size_t bufferNdx = 0; bufferNdx < m_inValues.size(); ++bufferNdx)
12878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
1288b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		buffers[bufferNdx] = BufferSp(new Buffer(m_context, bufferUsage, sizeof(deUint32)));
1289b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		*(deUint32*)buffers[bufferNdx]->getHostPtr() = m_inValues[bufferNdx];
1290b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		buffers[bufferNdx]->flush();
1291b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
12928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1293b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
1294b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		indexBuffer = createUniformIndexBuffer(m_context, numReads, &m_readIndices[0]);
1295b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
1296b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1297b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutBinding		bindings[]	=
1298b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1299b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 0u,							descriptorType,						(deUint32)m_inValues.size(),	VK_SHADER_STAGE_ALL,	DE_NULL		},
1300b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ (deUint32)m_inValues.size(),	VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	1u,								VK_SHADER_STAGE_ALL,	DE_NULL		}
1301b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1302b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutCreateInfo	layoutInfo	=
1303b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1304b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1305b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1306b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorSetLayoutCreateFlags)0u,
1307b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(bindings),
1308b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bindings,
1309b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1310b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1311b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesLayout = createDescriptorSetLayout(vkd, device, &layoutInfo);
1312b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
13138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1314b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1315b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolSize			poolSizes[]	=
1316b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1317b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ descriptorType,						(deUint32)m_inValues.size()	},
1318b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	1u,							}
1319b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1320b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolCreateInfo	poolInfo	=
13218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
1322b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1323b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1324b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1325b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,		// maxSets
1326b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(poolSizes),
1327b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			poolSizes,
1328b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1329b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1330b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSetPool = createDescriptorPool(vkd, device, &poolInfo);
1331b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
13328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1333b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1334b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetAllocateInfo	allocInfo	=
1335b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1336b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1337b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1338b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSetPool,
1339b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
1340b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&extraResourcesLayout.get(),
1341b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1342b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1343b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSet = allocateDescriptorSet(vkd, device, &allocInfo);
1344b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
13458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1346b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1347b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vector<VkDescriptorBufferInfo>	bufferInfos			(m_inValues.size());
1348b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
1349b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1350b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1351b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1352b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
1353b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstBinding
1354b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstArrayElement
1355b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(deUint32)m_inValues.size(),
1356b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			descriptorType,
1357b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorImageInfo*)DE_NULL,
1358b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&bufferInfos[0],
1359b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
1360b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1361b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1362b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		for (size_t ndx = 0; ndx < m_inValues.size(); ++ndx)
1363b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1364b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bufferInfos[ndx].buffer		= buffers[ndx]->getBuffer();
1365b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bufferInfos[ndx].offset		= 0u;
1366b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bufferInfos[ndx].range		= VK_WHOLE_SIZE;
1367b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		}
1368b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1369b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
1370b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1371b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1372b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (indexBuffer)
1373b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1374b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorBufferInfo	bufferInfo	=
1375b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1376b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			indexBuffer->getBuffer(),
1377b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
1378b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_WHOLE_SIZE
1379b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1380b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
1381b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1382b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1383b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1384b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
1385b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(deUint32)m_inValues.size(),	// dstBinding
1386b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,								// dstArrayElement
1387b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
1388b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1389b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorImageInfo*)DE_NULL,
1390b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&bufferInfo,
1391b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
1392b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1393b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1394b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
1395b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1396b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1397b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
1398b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1399b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		expandedIndices.resize(numInvocations * m_readIndices.size());
1400b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1401b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		for (int readNdx = 0; readNdx < numReads; readNdx++)
1402b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1403b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			int* dst = &expandedIndices[numInvocations*readNdx];
1404b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			std::fill(dst, dst+numInvocations, m_readIndices[readNdx]);
14058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
14068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int readNdx = 0; readNdx < numReads; readNdx++)
1408b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			inputs.push_back(&expandedIndices[readNdx*numInvocations]);
1409b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
14108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1411b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (int readNdx = 0; readNdx < numReads; readNdx++)
1412b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		outputs.push_back(&outValues[readNdx*numInvocations]);
14138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1414b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1415b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		UniquePtr<ShaderExecutor>	executor	(createExecutor(m_context, m_shaderType, m_shaderSpec, *extraResourcesLayout));
14168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1417b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		executor->execute(numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0], *extraResourcesSet);
1418b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1419b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1420b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
1421b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1422b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		for (int readNdx = 0; readNdx < numReads; readNdx++)
14238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
1424b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			const deUint32	refValue	= m_inValues[m_readIndices[readNdx]];
1425b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			const deUint32	resValue	= outValues[readNdx*numInvocations + invocationNdx];
14268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1427b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			if (refValue != resValue)
1428b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{
1429b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				log << tcu::TestLog::Message << "ERROR: at invocation " << invocationNdx
1430b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos					<< ", read " << readNdx << ": expected "
1431b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos					<< tcu::toHex(refValue) << ", got " << tcu::toHex(resValue)
1432b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos					<< tcu::TestLog::EndMessage;
14338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1434b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos				if (testResult.getCode() == QP_TEST_RESULT_PASS)
1435b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos					testResult = tcu::TestStatus::fail("Invalid result value");
14368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
14378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
14388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
1439b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1440b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	return testResult;
14418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
14428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass BlockArrayIndexingCase : public OpaqueTypeIndexingCase
14448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
14458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
14468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								BlockArrayIndexingCase		(tcu::TestContext&			testCtx,
14478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				name,
14488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				description,
14498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 BlockType					blockType,
14508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 IndexExprType				indexExprType,
1451de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos															 const glu::ShaderType		shaderType,
1452de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos															 deUint32					flags = 0u);
14538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual						~BlockArrayIndexingCase		(void);
14548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual TestInstance*		createInstance				(Context& ctx) const;
14568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprivate:
14588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								BlockArrayIndexingCase		(const BlockArrayIndexingCase&);
14598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	BlockArrayIndexingCase&		operator=					(const BlockArrayIndexingCase&);
14608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	void						createShaderSpec			(void);
14628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const BlockType				m_blockType;
1464de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	const deUint32				m_flags;
14658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<int>			m_readIndices;
14668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<deUint32>		m_inValues;
14678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
14688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerBlockArrayIndexingCase::BlockArrayIndexingCase (tcu::TestContext&			testCtx,
14708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												const char*					name,
14718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												const char*					description,
14728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												BlockType					blockType,
14738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												IndexExprType				indexExprType,
1474de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos												const glu::ShaderType		shaderType,
1475de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos												deUint32					flags)
14768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
14778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_blockType				(blockType)
1478de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	, m_flags					(flags)
14798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_readIndices				(BlockArrayIndexingCaseInstance::NUM_READS)
14808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_inValues				(BlockArrayIndexingCaseInstance::NUM_INSTANCES)
14818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
14828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	createShaderSpec();
14838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	init();
14848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
14858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerBlockArrayIndexingCase::~BlockArrayIndexingCase (void)
14878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
14888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
14898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
14908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerTestInstance* BlockArrayIndexingCase::createInstance (Context& ctx) const
14918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
14928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	return new BlockArrayIndexingCaseInstance(ctx,
14938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_shaderType,
14948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_shaderSpec,
14958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_name,
14968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_blockType,
1497de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos											  m_flags,
14988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_indexExprType,
14998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_readIndices,
15008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner											  m_inValues);
15018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
15028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnervoid BlockArrayIndexingCase::createShaderSpec (void)
15048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
15058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int			numInstances	= BlockArrayIndexingCaseInstance::NUM_INSTANCES;
15068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int			numReads		= BlockArrayIndexingCaseInstance::NUM_READS;
15078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	de::Random			rnd				(deInt32Hash(m_shaderType) ^ deInt32Hash(m_blockType) ^ deInt32Hash(m_indexExprType));
15088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			blockName		= "Block";
15098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			instanceName	= "block";
15108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			indicesPrefix	= "index";
15118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			resultPrefix	= "result";
15128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const char*			interfaceName	= m_blockType == BLOCKTYPE_UNIFORM ? "uniform" : "buffer";
15138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::ostringstream	global, code;
15148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int readNdx = 0; readNdx < numReads; readNdx++)
15168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_readIndices[readNdx] = rnd.getInt(0, numInstances-1);
15178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
15198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_inValues[instanceNdx] = rnd.getUint32();
15208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
15228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		global << "#extension GL_EXT_gpu_shader5 : require\n";
15238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
15258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		global << "const highp int indexBase = 1;\n";
15268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	global <<
1528b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		"layout(set = " << EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX << ", binding = 0) " << interfaceName << " " << blockName << "\n"
15298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		"{\n"
15308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		"	highp uint value;\n"
15318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		"} " << instanceName << "[" << numInstances << "];\n";
15328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
15348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
15358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int readNdx = 0; readNdx < numReads; readNdx++)
15368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
15378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const std::string varName = indicesPrefix + de::toString(readNdx);
15388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			m_shaderSpec.inputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
15398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
15408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
15418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
1542b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		declareUniformIndexVars(global, (deUint32)m_inValues.size(), indicesPrefix, numReads);
15438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int readNdx = 0; readNdx < numReads; readNdx++)
15458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
15468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const std::string varName = resultPrefix + de::toString(readNdx);
15478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_shaderSpec.outputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
15488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
15498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int readNdx = 0; readNdx < numReads; readNdx++)
15518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
15528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		code << resultPrefix << readNdx << " = " << instanceName << "[";
15538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
15558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << m_readIndices[readNdx];
15568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
15578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << "indexBase + " << (m_readIndices[readNdx]-1);
15588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else
15598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << indicesPrefix << readNdx;
15608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		code << "].value;\n";
15628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
15638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	m_shaderSpec.globalDeclarations	= global.str();
15658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	m_shaderSpec.source				= code.str();
1566de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos
1567de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos	if ((m_flags & BlockArrayIndexingCaseInstance::FLAG_USE_STORAGE_BUFFER) != 0)
156875bc5afcbeddef9465b8c5c54fcd76c4f6f165a5Ari Suonpää		m_shaderSpec.buildOptions.flags |= vk::ShaderBuildOptions::FLAG_USE_STORAGE_BUFFER_STORAGE_CLASS;
15698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
15708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass AtomicCounterIndexingCaseInstance : public OpaqueTypeIndexingTestInstance
15728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
15738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
15748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	enum
15758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
15768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_INVOCATIONS		= 32,
15778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_COUNTERS		= 4,
15788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		NUM_OPS				= 4
15798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	};
15808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								AtomicCounterIndexingCaseInstance	(Context&					context,
15828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const glu::ShaderType		shaderType,
15838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const ShaderSpec&			shaderSpec,
15848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const char*				name,
15858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const std::vector<int>&	opIndices,
15868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	 const IndexExprType		indexExprType);
15878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual						~AtomicCounterIndexingCaseInstance	(void);
15888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual	tcu::TestStatus		iterate								(void);
15908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprivate:
15928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const std::vector<int>&		m_opIndices;
15938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
15948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
15958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerAtomicCounterIndexingCaseInstance::AtomicCounterIndexingCaseInstance (Context&					context,
15968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	  const glu::ShaderType		shaderType,
15978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	  const ShaderSpec&			shaderSpec,
15988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	  const char*				name,
15998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	  const std::vector<int>&	opIndices,
16008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner																	  const IndexExprType		indexExprType)
1601b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	: OpaqueTypeIndexingTestInstance	(context, shaderType, shaderSpec, name, indexExprType)
16028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_opIndices						(opIndices)
16038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
16048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
16058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
16068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerAtomicCounterIndexingCaseInstance::~AtomicCounterIndexingCaseInstance (void)
16078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
16088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
16098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
16108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnertcu::TestStatus AtomicCounterIndexingCaseInstance::iterate (void)
16118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
16128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					numInvocations		= NUM_INVOCATIONS;
16138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					numCounters			= NUM_COUNTERS;
16148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int					numOps				= NUM_OPS;
16158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<int>			expandedIndices;
16168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<void*>			inputs;
16178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<void*>			outputs;
16188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<deUint32>		outValues			(numInvocations*numOps);
16198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1620a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	const DeviceInterface&			vkd				= m_context.getDeviceInterface();
1621a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	const VkDevice					device			= m_context.getDevice();
1622a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	const VkPhysicalDeviceFeatures& deviceFeatures	= m_context.getDeviceFeatures();
1623a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin
1624a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	//Check stores and atomic operation support.
1625a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	switch (m_shaderType)
1626a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	{
1627a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_VERTEX:
1628a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_TESSELLATION_CONTROL:
1629a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_TESSELLATION_EVALUATION:
1630a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_GEOMETRY:
1631a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			if(!deviceFeatures.vertexPipelineStoresAndAtomics)
1632a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin				TCU_THROW(NotSupportedError, "Stores and atomic operations are not supported in Vertex, Tessellation, and Geometry shader.");
1633a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			break;
1634a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_FRAGMENT:
1635a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			if(!deviceFeatures.fragmentStoresAndAtomics)
1636a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin				TCU_THROW(NotSupportedError, "Stores and atomic operations are not supported in fragment shader.");
1637a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			break;
1638a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		case glu::SHADERTYPE_COMPUTE:
1639a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			break;
1640a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin		default:
1641a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin			throw tcu::InternalError("Unsupported shader type");
1642a83de3aef04e238468b3987cd30a3179f8da259aAlexander Galazin	}
1643b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1644b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	// \note Using separate buffer per element - might want to test
1645b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	// offsets & single buffer in the future.
1646b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Buffer						atomicOpBuffer		(m_context, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, sizeof(deUint32)*numCounters);
1647b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	MovePtr<Buffer>				indexBuffer;
1648b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1649b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSetLayout>	extraResourcesLayout;
1650b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorPool>		extraResourcesSetPool;
1651b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	Move<VkDescriptorSet>		extraResourcesSet;
16521520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka
1653b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner	checkSupported(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1654b5ba423b562d54a93b99926d5390b36b7bead15cAkos Dirner
1655b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	deMemset(atomicOpBuffer.getHostPtr(), 0, sizeof(deUint32)*numCounters);
1656b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	atomicOpBuffer.flush();
1657b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1658b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
1659b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		indexBuffer = createUniformIndexBuffer(m_context, numOps, &m_opIndices[0]);
1660b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
16618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
1662b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutBinding		bindings[]	=
1663b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1664b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 0u,	VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	1u,	VK_SHADER_STAGE_ALL,	DE_NULL		},
1665b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ 1u,	VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	1u,	VK_SHADER_STAGE_ALL,	DE_NULL		}
1666b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1667b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetLayoutCreateInfo	layoutInfo	=
1668b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1669b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1670b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1671b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorSetLayoutCreateFlags)0u,
1672b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(bindings),
1673b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			bindings,
1674b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1675b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1676b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesLayout = createDescriptorSetLayout(vkd, device, &layoutInfo);
1677b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
16788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1679b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1680b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolSize			poolSizes[]	=
16818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
1682b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	1u,	},
1683b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	1u,	}
1684b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1685b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorPoolCreateInfo	poolInfo	=
1686b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1687b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1688b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1689b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1690b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,		// maxSets
1691b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_LENGTH_OF_ARRAY(poolSizes),
1692b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			poolSizes,
1693b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1694b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1695b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSetPool = createDescriptorPool(vkd, device, &poolInfo);
1696b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
16978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1698b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1699b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorSetAllocateInfo	allocInfo	=
1700b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1701b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1702b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1703b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSetPool,
1704b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
1705b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&extraResourcesLayout.get(),
1706b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1707b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1708b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		extraResourcesSet = allocateDescriptorSet(vkd, device, &allocInfo);
1709b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
17108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1711b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1712b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorBufferInfo	bufferInfo			=
1713b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1714b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			atomicOpBuffer.getBuffer(),
1715b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
1716b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_WHOLE_SIZE
1717b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1718b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
1719b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1720b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1721b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1722b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
1723b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstBinding
1724b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstArrayElement
1725b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
1726b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1727b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorImageInfo*)DE_NULL,
1728b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&bufferInfo,
1729b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
1730b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1731b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1732b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
1733b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1734b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1735b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (indexBuffer)
1736b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1737b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkDescriptorBufferInfo	bufferInfo	=
1738b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1739b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			indexBuffer->getBuffer(),
1740b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,
1741b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_WHOLE_SIZE
1742b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1743b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		const VkWriteDescriptorSet		descriptorWrite		=
1744b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1745b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1746b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			DE_NULL,
1747b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			*extraResourcesSet,
1748b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,		// dstBinding
1749b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			0u,		// dstArrayElement
1750b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			1u,
1751b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1752b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkDescriptorImageInfo*)DE_NULL,
1753b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			&bufferInfo,
1754b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			(const VkBufferView*)DE_NULL,
1755b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		};
1756b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1757b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
1758b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1759b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1760b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
1761b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1762b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		expandedIndices.resize(numInvocations * m_opIndices.size());
1763b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1764b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		for (int opNdx = 0; opNdx < numOps; opNdx++)
1765b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		{
1766b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			int* dst = &expandedIndices[numInvocations*opNdx];
1767b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			std::fill(dst, dst+numInvocations, m_opIndices[opNdx]);
17688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
17698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
17708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int opNdx = 0; opNdx < numOps; opNdx++)
1771b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			inputs.push_back(&expandedIndices[opNdx*numInvocations]);
1772b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	}
1773b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos
1774b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	for (int opNdx = 0; opNdx < numOps; opNdx++)
1775b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		outputs.push_back(&outValues[opNdx*numInvocations]);
17768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1777b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos	{
1778b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		UniquePtr<ShaderExecutor>	executor	(createExecutor(m_context, m_shaderType, m_shaderSpec, *extraResourcesLayout));
17798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1780b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos		executor->execute(numInvocations, inputs.empty() ? DE_NULL : &inputs[0], &outputs[0], *extraResourcesSet);
17818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
17828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
17838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
17848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		tcu::TestLog&					log				= m_context.getTestContext().getLog();
17858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		tcu::TestStatus					testResult		= tcu::TestStatus::pass("Pass");
17868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		std::vector<int>				numHits			(numCounters, 0);	// Number of hits per counter.
17878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		std::vector<deUint32>			counterValues	(numCounters);
17888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		std::vector<std::vector<bool> >	counterMasks	(numCounters);
17898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
17908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int opNdx = 0; opNdx < numOps; opNdx++)
17918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			numHits[m_opIndices[opNdx]] += 1;
17928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
17931520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka		// Read counter values
17941520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka		{
1795b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			const void* mapPtr = atomicOpBuffer.getHostPtr();
17961520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka			DE_ASSERT(mapPtr != DE_NULL);
1797b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			atomicOpBuffer.invalidate();
17981520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka			std::copy((const deUint32*)mapPtr, (const deUint32*)mapPtr + numCounters, &counterValues[0]);
17991520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka		}
18001520e856bc1169fcdb43cd5a8e2d6caa1ef5c6d3Robert Sipka
18018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// Verify counter values
18028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int counterNdx = 0; counterNdx < numCounters; counterNdx++)
18038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
18048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const deUint32		refCount	= (deUint32)(numHits[counterNdx]*numInvocations);
18058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const deUint32		resCount	= counterValues[counterNdx];
18068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			if (refCount != resCount)
18088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
18098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				log << tcu::TestLog::Message << "ERROR: atomic counter " << counterNdx << " has value " << resCount
18108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					<< ", expected " << refCount
18118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					<< tcu::TestLog::EndMessage;
18128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				if (testResult.getCode() == QP_TEST_RESULT_PASS)
18148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					testResult = tcu::TestStatus::fail("Invalid atomic counter value");
18158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
18168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
18178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// Allocate bitmasks - one bit per each valid result value
18198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int counterNdx = 0; counterNdx < numCounters; counterNdx++)
18208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
18218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const int	counterValue	= numHits[counterNdx]*numInvocations;
18228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			counterMasks[counterNdx].resize(counterValue, false);
18238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
18248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		// Verify result values from shaders
18268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int invocationNdx = 0; invocationNdx < numInvocations; invocationNdx++)
18278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
18288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int opNdx = 0; opNdx < numOps; opNdx++)
18298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
18308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const int		counterNdx	= m_opIndices[opNdx];
18318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const deUint32	resValue	= outValues[opNdx*numInvocations + invocationNdx];
18328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const bool		rangeOk		= de::inBounds(resValue, 0u, (deUint32)counterMasks[counterNdx].size());
18338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const bool		notSeen		= rangeOk && !counterMasks[counterNdx][resValue];
18348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const bool		isOk		= rangeOk && notSeen;
18358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				if (!isOk)
18378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
18388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					log << tcu::TestLog::Message << "ERROR: at invocation " << invocationNdx
18398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						<< ", op " << opNdx << ": got invalid result value "
18408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						<< resValue
18418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						<< tcu::TestLog::EndMessage;
18428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					if (testResult.getCode() == QP_TEST_RESULT_PASS)
18448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner						testResult = tcu::TestStatus::fail("Invalid result value");
18458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
18468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				else
18478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
18488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					// Mark as used - no other invocation should see this value from same counter.
18498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					counterMasks[counterNdx][resValue] = true;
18508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
18518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
18528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
18538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (testResult.getCode() == QP_TEST_RESULT_PASS)
18558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
18568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			// Consistency check - all masks should be 1 now
18578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int counterNdx = 0; counterNdx < numCounters; counterNdx++)
18588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
18598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				for (std::vector<bool>::const_iterator i = counterMasks[counterNdx].begin(); i != counterMasks[counterNdx].end(); i++)
18608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					TCU_CHECK_INTERNAL(*i);
18618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
18628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
18638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		return testResult;
18658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
18668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
18678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerclass AtomicCounterIndexingCase : public OpaqueTypeIndexingCase
18698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
18708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerpublic:
18718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								AtomicCounterIndexingCase	(tcu::TestContext&			testCtx,
18728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				name,
18738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const char*				description,
18748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 IndexExprType				indexExprType,
18758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner															 const glu::ShaderType		shaderType);
18768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual						~AtomicCounterIndexingCase	(void);
18778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	virtual TestInstance*		createInstance				(Context& ctx) const;
18798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnerprivate:
18818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner								AtomicCounterIndexingCase	(const BlockArrayIndexingCase&);
18828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	AtomicCounterIndexingCase&	operator=					(const BlockArrayIndexingCase&);
18838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	void						createShaderSpec			(void);
18858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	std::vector<int>			m_opIndices;
18878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner};
18888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
18898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerAtomicCounterIndexingCase::AtomicCounterIndexingCase (tcu::TestContext&			testCtx,
18908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner													  const char*				name,
18918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner													  const char*				description,
18928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner													  IndexExprType				indexExprType,
18938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner													  const glu::ShaderType		shaderType)
18948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	: OpaqueTypeIndexingCase	(testCtx, name, description, shaderType, indexExprType)
18958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	, m_opIndices				(AtomicCounterIndexingCaseInstance::NUM_OPS)
18968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
18978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	createShaderSpec();
18988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	init();
18998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerAtomicCounterIndexingCase::~AtomicCounterIndexingCase (void)
19028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerTestInstance* AtomicCounterIndexingCase::createInstance (Context& ctx) const
19068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	return new AtomicCounterIndexingCaseInstance(ctx,
19088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												 m_shaderType,
19098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												 m_shaderSpec,
19108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												 m_name,
19118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												 m_opIndices,
19128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner												 m_indexExprType);
19138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnervoid AtomicCounterIndexingCase::createShaderSpec (void)
19168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int				numCounters		= AtomicCounterIndexingCaseInstance::NUM_COUNTERS;
19188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	const int				numOps			= AtomicCounterIndexingCaseInstance::NUM_OPS;
19198bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	de::Random				rnd				(deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
19208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	for (int opNdx = 0; opNdx < numOps; opNdx++)
19228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_opIndices[opNdx] = rnd.getInt(0, numOps-1);
19238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
19258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const char*			indicesPrefix	= "index";
19268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const char*			resultPrefix	= "result";
19278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		std::ostringstream	global, code;
19288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
19308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			global << "#extension GL_EXT_gpu_shader5 : require\n";
19318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
19338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			global << "const highp int indexBase = 1;\n";
19348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		global <<
1936b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			"layout(set = " << EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX << ", binding = 0, std430) buffer AtomicBuffer { highp uint counter[" << numCounters << "]; };\n";
19378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		if (m_indexExprType == INDEX_EXPR_TYPE_DYNAMIC_UNIFORM)
19398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
19408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int opNdx = 0; opNdx < numOps; opNdx++)
19418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
19428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const std::string varName = indicesPrefix + de::toString(opNdx);
19438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				m_shaderSpec.inputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
19448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
19458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
19468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		else if (m_indexExprType == INDEX_EXPR_TYPE_UNIFORM)
1947b95a9d798050499a8720ec4ada9a70a2093e24f0Pyry Haulos			declareUniformIndexVars(global, 1, indicesPrefix, numOps);
19488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int opNdx = 0; opNdx < numOps; opNdx++)
19508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
19518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const std::string varName = resultPrefix + de::toString(opNdx);
19528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			m_shaderSpec.outputs.push_back(Symbol(varName, glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
19538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
19548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int opNdx = 0; opNdx < numOps; opNdx++)
19568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
19578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << resultPrefix << opNdx << " = atomicAdd(counter[";
19588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			if (m_indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL)
19608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				code << m_opIndices[opNdx];
19618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			else if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
19628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				code << "indexBase + " << (m_opIndices[opNdx]-1);
19638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			else
19648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				code << indicesPrefix << opNdx;
19658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19668bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			code << "], uint(1));\n";
19678bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
19688bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19698bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_shaderSpec.globalDeclarations	= global.str();
19708bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		m_shaderSpec.source				= code.str();
19718bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
19728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
1974cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulosclass OpaqueTypeIndexingTests : public tcu::TestCaseGroup
1975cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos{
1976cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulospublic:
1977cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos								OpaqueTypeIndexingTests		(tcu::TestContext& testCtx);
1978cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos	virtual						~OpaqueTypeIndexingTests	(void);
1979cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos
1980cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos	virtual void				init						(void);
1981cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos
1982cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulosprivate:
1983cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos								OpaqueTypeIndexingTests		(const OpaqueTypeIndexingTests&);
1984cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos	OpaqueTypeIndexingTests&	operator=					(const OpaqueTypeIndexingTests&);
1985cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos};
19868bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19878bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerOpaqueTypeIndexingTests::OpaqueTypeIndexingTests (tcu::TestContext& testCtx)
19888bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	: tcu::TestCaseGroup(testCtx, "opaque_type_indexing", "Opaque Type Indexing Tests")
19898bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19928bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos DirnerOpaqueTypeIndexingTests::~OpaqueTypeIndexingTests (void)
19938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
19958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
19968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirnervoid OpaqueTypeIndexingTests::init (void)
19978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner{
19988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	static const struct
19998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
20008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		IndexExprType	type;
20018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const char*		name;
20028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const char*		description;
20038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	} indexingTypes[] =
20048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
20058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{ INDEX_EXPR_TYPE_CONST_LITERAL,	"const_literal",		"Indexing by constant literal"					},
20068bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{ INDEX_EXPR_TYPE_CONST_EXPRESSION,	"const_expression",		"Indexing by constant expression"				},
20078bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{ INDEX_EXPR_TYPE_UNIFORM,			"uniform",				"Indexing by uniform value"						},
20088bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{ INDEX_EXPR_TYPE_DYNAMIC_UNIFORM,	"dynamically_uniform",	"Indexing by dynamically uniform expression"	}
20098bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	};
20108bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20118bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	static const struct
20128bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
20138bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		glu::ShaderType	type;
20148bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		const char*		name;
20158bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	} shaderTypes[] =
20168bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
2017582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_VERTEX,					"vertex"	},
2018582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_FRAGMENT,					"fragment"	},
2019582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_GEOMETRY,					"geometry"	},
2020582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_TESSELLATION_CONTROL,		"tess_ctrl"	},
2021582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_TESSELLATION_EVALUATION,	"tess_eval"	},
2022582748922fcc30d6fb9094c821bfc86bc76fc36ePyry Haulos		{ glu::SHADERTYPE_COMPUTE,					"compute"	}
20238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	};
20248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20258bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	// .sampler
20268bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
20278bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		static const glu::DataType samplerTypes[] =
20288bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
20298bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			// \note 1D images will be added by a later extension.
20308bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner//			glu::TYPE_SAMPLER_1D,
20318bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_2D,
20328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_CUBE,
20338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_2D_ARRAY,
20348bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_3D,
20358bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner//			glu::TYPE_SAMPLER_1D_SHADOW,
20368bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_2D_SHADOW,
20378bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_CUBE_SHADOW,
20388bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
20398bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner//			glu::TYPE_INT_SAMPLER_1D,
20408bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_INT_SAMPLER_2D,
20418bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_INT_SAMPLER_CUBE,
20428bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_INT_SAMPLER_2D_ARRAY,
20438bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_INT_SAMPLER_3D,
20448bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner//			glu::TYPE_UINT_SAMPLER_1D,
20458bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_UINT_SAMPLER_2D,
20468bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_UINT_SAMPLER_CUBE,
20478bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_UINT_SAMPLER_2D_ARRAY,
20488bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			glu::TYPE_UINT_SAMPLER_3D,
20498bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		};
20508bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20518bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler Array Indexing Tests");
20528bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		addChild(samplerGroup);
20538bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20548bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int indexTypeNdx = 0; indexTypeNdx < DE_LENGTH_OF_ARRAY(indexingTypes); indexTypeNdx++)
20558bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
20568bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const IndexExprType			indexExprType	= indexingTypes[indexTypeNdx].type;
20578bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			tcu::TestCaseGroup* const	indexGroup		= new tcu::TestCaseGroup(m_testCtx, indexingTypes[indexTypeNdx].name, indexingTypes[indexTypeNdx].description);
20588bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			samplerGroup->addChild(indexGroup);
20598bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20608bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(shaderTypes); shaderTypeNdx++)
20618bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
20628bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const glu::ShaderType		shaderType		= shaderTypes[shaderTypeNdx].type;
20638bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				tcu::TestCaseGroup* const	shaderGroup		= new tcu::TestCaseGroup(m_testCtx, shaderTypes[shaderTypeNdx].name, "");
20648bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				indexGroup->addChild(shaderGroup);
20658bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2066de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				// \note [pyry] In Vulkan CTS 1.0.2 sampler groups should not cover tess/geom stages
2067de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				if ((shaderType != glu::SHADERTYPE_VERTEX)		&&
2068de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					(shaderType != glu::SHADERTYPE_FRAGMENT)	&&
2069de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					(shaderType != glu::SHADERTYPE_COMPUTE))
2070de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					continue;
2071de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos
20728bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				for (int samplerTypeNdx = 0; samplerTypeNdx < DE_LENGTH_OF_ARRAY(samplerTypes); samplerTypeNdx++)
20738bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				{
20748bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const glu::DataType	samplerType	= samplerTypes[samplerTypeNdx];
20758bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const char*			samplerName	= getDataTypeName(samplerType);
20768bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					const std::string	caseName	= de::toLower(samplerName);
20778bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20788bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner					shaderGroup->addChild(new SamplerIndexingCase(m_testCtx, caseName.c_str(), "", shaderType, samplerType, indexExprType));
20798bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				}
20808bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
20818bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
20828bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
20838bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20848bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	// .ubo / .ssbo / .atomic_counter
20858bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	{
2086de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		tcu::TestCaseGroup* const	uboGroup			= new tcu::TestCaseGroup(m_testCtx, "ubo",								"Uniform Block Instance Array Indexing Tests");
2087de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		tcu::TestCaseGroup* const	ssboGroup			= new tcu::TestCaseGroup(m_testCtx, "ssbo",								"Buffer Block Instance Array Indexing Tests");
2088de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		tcu::TestCaseGroup* const	ssboStorageBufGroup	= new tcu::TestCaseGroup(m_testCtx, "ssbo_storage_buffer_decoration",	"Buffer Block (new StorageBuffer decoration) Instance Array Indexing Tests");
2089de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		tcu::TestCaseGroup* const	acGroup				= new tcu::TestCaseGroup(m_testCtx, "atomic_counter",					"Atomic Counter Array Indexing Tests");
20908bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		addChild(uboGroup);
20918bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		addChild(ssboGroup);
2092de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos		addChild(ssboStorageBufGroup);
20938bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		addChild(acGroup);
20948bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
20958bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		for (int indexTypeNdx = 0; indexTypeNdx < DE_LENGTH_OF_ARRAY(indexingTypes); indexTypeNdx++)
20968bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		{
20978bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const IndexExprType		indexExprType		= indexingTypes[indexTypeNdx].type;
20988bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const char*				indexExprName		= indexingTypes[indexTypeNdx].name;
20998bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			const char*				indexExprDesc		= indexingTypes[indexTypeNdx].description;
21008bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
21018bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(shaderTypes); shaderTypeNdx++)
21028bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			{
21038bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const glu::ShaderType	shaderType		= shaderTypes[shaderTypeNdx].type;
21048bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				const std::string		name			= std::string(indexExprName) + "_" + shaderTypes[shaderTypeNdx].name;
21058bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2106de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				// \note [pyry] In Vulkan CTS 1.0.2 ubo/ssbo/atomic_counter groups should not cover tess/geom stages
2107de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				if ((shaderType == glu::SHADERTYPE_VERTEX)		||
2108de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					(shaderType == glu::SHADERTYPE_FRAGMENT)	||
2109de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					(shaderType == glu::SHADERTYPE_COMPUTE))
2110de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				{
2111de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					uboGroup->addChild	(new BlockArrayIndexingCase		(m_testCtx, name.c_str(), indexExprDesc, BLOCKTYPE_UNIFORM,	indexExprType, shaderType));
2112de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					acGroup->addChild	(new AtomicCounterIndexingCase	(m_testCtx, name.c_str(), indexExprDesc, indexExprType, shaderType));
2113de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos
2114de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					if (indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL || indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
2115de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos						ssboGroup->addChild	(new BlockArrayIndexingCase	(m_testCtx, name.c_str(), indexExprDesc, BLOCKTYPE_BUFFER, indexExprType, shaderType));
2116de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos				}
21178bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
21188bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner				if (indexExprType == INDEX_EXPR_TYPE_CONST_LITERAL || indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
2119de7ecd11b6156599ee528e12b7d3420d5465e141Pyry Haulos					ssboStorageBufGroup->addChild	(new BlockArrayIndexingCase	(m_testCtx, name.c_str(), indexExprDesc, BLOCKTYPE_BUFFER, indexExprType, shaderType, (deUint32)BlockArrayIndexingCaseInstance::FLAG_USE_STORAGE_BUFFER));
21208bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner			}
21218bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner		}
21228bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner	}
21238bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner}
21248bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner
2125cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos} // anonymous
2126cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos
2127cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulostcu::TestCaseGroup* createOpaqueTypeIndexingTests (tcu::TestContext& testCtx)
2128cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos{
2129cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos	return new OpaqueTypeIndexingTests(testCtx);
2130cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos}
2131cb0b0a96977768bb6e83ca3bd2ae856d9eb2ca26Pyry Haulos
21328bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner} // shaderexecutor
21338bbf784b9515b34c9fa9bc931a68631bfb80a42cAkos Dirner} // vkt
2134