• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan ShaderRenderCase
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktShaderRender.hpp"
27 
28 #include "tcuImageCompare.hpp"
29 #include "tcuImageIO.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuVector.hpp"
34 
35 #include "deFilePath.hpp"
36 #include "deMath.h"
37 #include "deUniquePtr.hpp"
38 
39 #include "vkDeviceUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPlatform.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRef.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkStrUtil.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 #include "vkObjUtil.hpp"
49 
50 #include <vector>
51 #include <string>
52 
53 namespace vkt
54 {
55 namespace sr
56 {
57 
58 using namespace vk;
59 
textureTypeToImageViewType(TextureBinding::Type type)60 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type)
61 {
62 	switch (type)
63 	{
64 		case TextureBinding::TYPE_1D:			return VK_IMAGE_VIEW_TYPE_1D;
65 		case TextureBinding::TYPE_2D:			return VK_IMAGE_VIEW_TYPE_2D;
66 		case TextureBinding::TYPE_3D:			return VK_IMAGE_VIEW_TYPE_3D;
67 		case TextureBinding::TYPE_CUBE_MAP:		return VK_IMAGE_VIEW_TYPE_CUBE;
68 		case TextureBinding::TYPE_1D_ARRAY:		return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
69 		case TextureBinding::TYPE_2D_ARRAY:		return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
70 		case TextureBinding::TYPE_CUBE_ARRAY:	return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
71 
72 		default:
73 			DE_FATAL("Impossible");
74 			return (VkImageViewType)0;
75 	}
76 }
77 
viewTypeToImageType(VkImageViewType type)78 VkImageType viewTypeToImageType (VkImageViewType type)
79 {
80 	switch (type)
81 	{
82 		case VK_IMAGE_VIEW_TYPE_1D:
83 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:		return VK_IMAGE_TYPE_1D;
84 		case VK_IMAGE_VIEW_TYPE_2D:
85 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:		return VK_IMAGE_TYPE_2D;
86 		case VK_IMAGE_VIEW_TYPE_3D:				return VK_IMAGE_TYPE_3D;
87 		case VK_IMAGE_VIEW_TYPE_CUBE:
88 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:		return VK_IMAGE_TYPE_2D;
89 
90 		default:
91 			DE_FATAL("Impossible");
92 			return (VkImageType)0;
93 	}
94 }
95 
textureUsageFlags(void)96 vk::VkImageUsageFlags textureUsageFlags (void)
97 {
98 	return (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
99 }
100 
textureCreateFlags(vk::VkImageViewType viewType,ShaderRenderCaseInstance::ImageBackingMode backingMode)101 vk::VkImageCreateFlags textureCreateFlags (vk::VkImageViewType viewType, ShaderRenderCaseInstance::ImageBackingMode backingMode)
102 {
103 	const bool			isCube				= (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
104 	VkImageCreateFlags	imageCreateFlags	= (isCube ? static_cast<VkImageCreateFlags>(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) : 0u);
105 
106 	if (backingMode == ShaderRenderCaseInstance::IMAGE_BACKING_MODE_SPARSE)
107 		imageCreateFlags |= (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
108 
109 	return imageCreateFlags;
110 }
111 
112 namespace
113 {
114 
115 static const deUint32	MAX_RENDER_WIDTH	= 128;
116 static const deUint32	MAX_RENDER_HEIGHT	= 128;
117 static const tcu::Vec4	DEFAULT_CLEAR_COLOR	= tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
118 
119 /*! Gets the next multiple of a given divisor */
getNextMultiple(deUint32 divisor,deUint32 value)120 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
121 {
122 	if (value % divisor == 0)
123 	{
124 		return value;
125 	}
126 	return value + divisor - (value % divisor);
127 }
128 
129 /*! Gets the next value that is multiple of all given divisors */
getNextMultiple(const std::vector<deUint32> & divisors,deUint32 value)130 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
131 {
132 	deUint32	nextMultiple		= value;
133 	bool		nextMultipleFound	= false;
134 
135 	while (true)
136 	{
137 		nextMultipleFound = true;
138 
139 		for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
140 			nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
141 
142 		if (nextMultipleFound)
143 			break;
144 
145 		DE_ASSERT(nextMultiple < ~((deUint32)0u));
146 		nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
147 	}
148 
149 	return nextMultiple;
150 }
151 
152 } // anonymous
153 
154 // QuadGrid.
155 
156 class QuadGrid
157 {
158 public:
159 											QuadGrid				(int									gridSize,
160 																	 int									screenWidth,
161 																	 int									screenHeight,
162 																	 const tcu::Vec4&						constCoords,
163 																	 const std::vector<tcu::Mat4>&			userAttribTransforms,
164 																	 const std::vector<TextureBindingSp>&	textures);
165 											~QuadGrid				(void);
166 
getGridSize(void) const167 	int										getGridSize				(void) const { return m_gridSize; }
getNumVertices(void) const168 	int										getNumVertices			(void) const { return m_numVertices; }
getNumTriangles(void) const169 	int										getNumTriangles			(void) const { return m_numTriangles; }
getConstCoords(void) const170 	const tcu::Vec4&						getConstCoords			(void) const { return m_constCoords; }
getUserAttribTransforms(void) const171 	const std::vector<tcu::Mat4>			getUserAttribTransforms	(void) const { return m_userAttribTransforms; }
getTextures(void) const172 	const std::vector<TextureBindingSp>&	getTextures				(void) const { return m_textures; }
173 
getPositions(void) const174 	const tcu::Vec4*						getPositions			(void) const { return &m_positions[0]; }
getAttribOne(void) const175 	const float*							getAttribOne			(void) const { return &m_attribOne[0]; }
getCoords(void) const176 	const tcu::Vec4*						getCoords				(void) const { return &m_coords[0]; }
getUnitCoords(void) const177 	const tcu::Vec4*						getUnitCoords			(void) const { return &m_unitCoords[0]; }
178 
getUserAttrib(int attribNdx) const179 	const tcu::Vec4*						getUserAttrib			(int attribNdx) const { return &m_userAttribs[attribNdx][0]; }
getIndices(void) const180 	const deUint16*							getIndices				(void) const { return &m_indices[0]; }
181 
182 	tcu::Vec4								getCoords				(float sx, float sy) const;
183 	tcu::Vec4								getUnitCoords			(float sx, float sy) const;
184 
getNumUserAttribs(void) const185 	int										getNumUserAttribs		(void) const { return (int)m_userAttribTransforms.size(); }
186 	tcu::Vec4								getUserAttrib			(int attribNdx, float sx, float sy) const;
187 
188 private:
189 	const int								m_gridSize;
190 	const int								m_numVertices;
191 	const int								m_numTriangles;
192 	const tcu::Vec4							m_constCoords;
193 	const std::vector<tcu::Mat4>			m_userAttribTransforms;
194 
195 	const std::vector<TextureBindingSp>&	m_textures;
196 
197 	std::vector<tcu::Vec4>					m_screenPos;
198 	std::vector<tcu::Vec4>					m_positions;
199 	std::vector<tcu::Vec4>					m_coords;		//!< Near-unit coordinates, roughly [-2.0 .. 2.0].
200 	std::vector<tcu::Vec4>					m_unitCoords;	//!< Positive-only coordinates [0.0 .. 1.5].
201 	std::vector<float>						m_attribOne;
202 	std::vector<tcu::Vec4>					m_userAttribs[ShaderEvalContext::MAX_TEXTURES];
203 	std::vector<deUint16>					m_indices;
204 };
205 
QuadGrid(int gridSize,int width,int height,const tcu::Vec4 & constCoords,const std::vector<tcu::Mat4> & userAttribTransforms,const std::vector<TextureBindingSp> & textures)206 QuadGrid::QuadGrid (int										gridSize,
207 					int										width,
208 					int										height,
209 					const tcu::Vec4&						constCoords,
210 					const std::vector<tcu::Mat4>&			userAttribTransforms,
211 					const std::vector<TextureBindingSp>&	textures)
212 	: m_gridSize				(gridSize)
213 	, m_numVertices				((gridSize + 1) * (gridSize + 1))
214 	, m_numTriangles			(gridSize * gridSize * 2)
215 	, m_constCoords				(constCoords)
216 	, m_userAttribTransforms	(userAttribTransforms)
217 	, m_textures				(textures)
218 {
219 	const tcu::Vec4 viewportScale	((float)width, (float)height, 0.0f, 0.0f);
220 
221 	// Compute vertices.
222 	m_screenPos.resize(m_numVertices);
223 	m_positions.resize(m_numVertices);
224 	m_coords.resize(m_numVertices);
225 	m_unitCoords.resize(m_numVertices);
226 	m_attribOne.resize(m_numVertices);
227 
228 	// User attributes.
229 	for (int attrNdx = 0; attrNdx < DE_LENGTH_OF_ARRAY(m_userAttribs); attrNdx++)
230 		m_userAttribs[attrNdx].resize(m_numVertices);
231 
232 	for (int y = 0; y < gridSize+1; y++)
233 	for (int x = 0; x < gridSize+1; x++)
234 	{
235 		float		sx			= (float)x / (float)gridSize;
236 		float		sy			= (float)y / (float)gridSize;
237 		float		fx			= 2.0f * sx - 1.0f;
238 		float		fy			= 2.0f * sy - 1.0f;
239 		int			vtxNdx		= ((y * (gridSize+1)) + x);
240 
241 		m_positions[vtxNdx]		= tcu::Vec4(fx, fy, 0.0f, 1.0f);
242 		m_coords[vtxNdx]		= getCoords(sx, sy);
243 		m_unitCoords[vtxNdx]	= getUnitCoords(sx, sy);
244 		m_attribOne[vtxNdx]		= 1.0f;
245 
246 		m_screenPos[vtxNdx]		= tcu::Vec4(sx, sy, 0.0f, 1.0f) * viewportScale;
247 
248 		for (int attribNdx = 0; attribNdx < getNumUserAttribs(); attribNdx++)
249 			m_userAttribs[attribNdx][vtxNdx] = getUserAttrib(attribNdx, sx, sy);
250 	}
251 
252 	// Compute indices.
253 	m_indices.resize(3 * m_numTriangles);
254 	for (int y = 0; y < gridSize; y++)
255 	for (int x = 0; x < gridSize; x++)
256 	{
257 		int stride				= gridSize + 1;
258 		int v00					= (y * stride) + x;
259 		int v01					= (y * stride) + x + 1;
260 		int v10					= ((y+1) * stride) + x;
261 		int v11					= ((y+1) * stride) + x + 1;
262 
263 		int baseNdx				= ((y * gridSize) + x) * 6;
264 		m_indices[baseNdx + 0]	= (deUint16)v10;
265 		m_indices[baseNdx + 1]	= (deUint16)v00;
266 		m_indices[baseNdx + 2]	= (deUint16)v01;
267 
268 		m_indices[baseNdx + 3]	= (deUint16)v10;
269 		m_indices[baseNdx + 4]	= (deUint16)v01;
270 		m_indices[baseNdx + 5]	= (deUint16)v11;
271 	}
272 }
273 
~QuadGrid(void)274 QuadGrid::~QuadGrid (void)
275 {
276 }
277 
getCoords(float sx,float sy) const278 inline tcu::Vec4 QuadGrid::getCoords (float sx, float sy) const
279 {
280 	const float fx = 2.0f * sx - 1.0f;
281 	const float fy = 2.0f * sy - 1.0f;
282 	return tcu::Vec4(fx, fy, -fx + 0.33f*fy, -0.275f*fx - fy);
283 }
284 
getUnitCoords(float sx,float sy) const285 inline tcu::Vec4 QuadGrid::getUnitCoords (float sx, float sy) const
286 {
287 	return tcu::Vec4(sx, sy, 0.33f*sx + 0.5f*sy, 0.5f*sx + 0.25f*sy);
288 }
289 
getUserAttrib(int attribNdx,float sx,float sy) const290 inline tcu::Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
291 {
292 	// homogeneous normalized screen-space coordinates
293 	return m_userAttribTransforms[attribNdx] * tcu::Vec4(sx, sy, 0.0f, 1.0f);
294 }
295 
296 // TextureBinding
297 
TextureBinding(const tcu::Archive & archive,const char * filename,const Type type,const tcu::Sampler & sampler)298 TextureBinding::TextureBinding (const tcu::Archive&	archive,
299 								const char*			filename,
300 								const Type			type,
301 								const tcu::Sampler&	sampler)
302 	: m_type	(type)
303 	, m_sampler	(sampler)
304 {
305 	switch(m_type)
306 	{
307 		case TYPE_2D: m_binding.tex2D = loadTexture2D(archive, filename).release(); break;
308 		default:
309 			DE_FATAL("Unsupported texture type");
310 	}
311 }
312 
TextureBinding(const tcu::Texture1D * tex1D,const tcu::Sampler & sampler)313 TextureBinding::TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler)
314 	: m_type	(TYPE_1D)
315 	, m_sampler	(sampler)
316 {
317 	m_binding.tex1D = tex1D;
318 }
319 
TextureBinding(const tcu::Texture2D * tex2D,const tcu::Sampler & sampler)320 TextureBinding::TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler)
321 	: m_type	(TYPE_2D)
322 	, m_sampler	(sampler)
323 {
324 	m_binding.tex2D = tex2D;
325 }
326 
TextureBinding(const tcu::Texture3D * tex3D,const tcu::Sampler & sampler)327 TextureBinding::TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler)
328 	: m_type	(TYPE_3D)
329 	, m_sampler	(sampler)
330 {
331 	m_binding.tex3D = tex3D;
332 }
333 
TextureBinding(const tcu::TextureCube * texCube,const tcu::Sampler & sampler)334 TextureBinding::TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler)
335 	: m_type	(TYPE_CUBE_MAP)
336 	, m_sampler	(sampler)
337 {
338 	m_binding.texCube = texCube;
339 }
340 
TextureBinding(const tcu::Texture1DArray * tex1DArray,const tcu::Sampler & sampler)341 TextureBinding::TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler)
342 	: m_type	(TYPE_1D_ARRAY)
343 	, m_sampler	(sampler)
344 {
345 	m_binding.tex1DArray = tex1DArray;
346 }
347 
TextureBinding(const tcu::Texture2DArray * tex2DArray,const tcu::Sampler & sampler)348 TextureBinding::TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler)
349 	: m_type	(TYPE_2D_ARRAY)
350 	, m_sampler	(sampler)
351 {
352 	m_binding.tex2DArray = tex2DArray;
353 }
354 
TextureBinding(const tcu::TextureCubeArray * texCubeArray,const tcu::Sampler & sampler)355 TextureBinding::TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler)
356 	: m_type	(TYPE_CUBE_ARRAY)
357 	, m_sampler	(sampler)
358 {
359 	m_binding.texCubeArray = texCubeArray;
360 }
361 
~TextureBinding(void)362 TextureBinding::~TextureBinding (void)
363 {
364 	switch(m_type)
365 	{
366 		case TYPE_1D:			delete m_binding.tex1D;			break;
367 		case TYPE_2D:			delete m_binding.tex2D;			break;
368 		case TYPE_3D:			delete m_binding.tex3D;			break;
369 		case TYPE_CUBE_MAP:		delete m_binding.texCube;		break;
370 		case TYPE_1D_ARRAY:		delete m_binding.tex1DArray;	break;
371 		case TYPE_2D_ARRAY:		delete m_binding.tex2DArray;	break;
372 		case TYPE_CUBE_ARRAY:	delete m_binding.texCubeArray;	break;
373 		default:												break;
374 	}
375 }
376 
loadTexture2D(const tcu::Archive & archive,const char * filename)377 de::MovePtr<tcu::Texture2D> TextureBinding::loadTexture2D (const tcu::Archive& archive, const char* filename)
378 {
379 	tcu::TextureLevel level;
380 	tcu::ImageIO::loadImage(level, archive, filename);
381 
382 	TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
383 					   level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
384 
385 	// \todo [2015-10-08 elecro] for some reason we get better when using RGBA texture even in RGB case, this needs to be investigated
386 	de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight()));
387 
388 	// Fill level 0.
389 	texture->allocLevel(0);
390 	tcu::copy(texture->getLevel(0), level.getAccess());
391 
392 	return texture;
393 }
394 
395 // ShaderEvalContext.
396 
ShaderEvalContext(const QuadGrid & quadGrid)397 ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid)
398 	: constCoords	(quadGrid.getConstCoords())
399 	, isDiscarded	(false)
400 	, m_quadGrid	(quadGrid)
401 {
402 	const std::vector<TextureBindingSp>& bindings = m_quadGrid.getTextures();
403 	DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
404 
405 	// Fill in texture array.
406 	for (int ndx = 0; ndx < (int)bindings.size(); ndx++)
407 	{
408 		const TextureBinding& binding = *bindings[ndx];
409 
410 		if (binding.getType() == TextureBinding::TYPE_NONE)
411 			continue;
412 
413 		textures[ndx].sampler = binding.getSampler();
414 
415 		switch (binding.getType())
416 		{
417 			case TextureBinding::TYPE_1D:			textures[ndx].tex1D			= &binding.get1D();			break;
418 			case TextureBinding::TYPE_2D:			textures[ndx].tex2D			= &binding.get2D();			break;
419 			case TextureBinding::TYPE_3D:			textures[ndx].tex3D			= &binding.get3D();			break;
420 			case TextureBinding::TYPE_CUBE_MAP:		textures[ndx].texCube		= &binding.getCube();		break;
421 			case TextureBinding::TYPE_1D_ARRAY:		textures[ndx].tex1DArray	= &binding.get1DArray();	break;
422 			case TextureBinding::TYPE_2D_ARRAY:		textures[ndx].tex2DArray	= &binding.get2DArray();	break;
423 			case TextureBinding::TYPE_CUBE_ARRAY:	textures[ndx].texCubeArray	= &binding.getCubeArray();	break;
424 			default:
425 				TCU_THROW(InternalError, "Handling of texture binding type not implemented");
426 		}
427 	}
428 }
429 
~ShaderEvalContext(void)430 ShaderEvalContext::~ShaderEvalContext (void)
431 {
432 }
433 
reset(float sx,float sy)434 void ShaderEvalContext::reset (float sx, float sy)
435 {
436 	// Clear old values
437 	color		= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
438 	isDiscarded	= false;
439 
440 	// Compute coords
441 	coords		= m_quadGrid.getCoords(sx, sy);
442 	unitCoords	= m_quadGrid.getUnitCoords(sx, sy);
443 
444 	// Compute user attributes.
445 	const int numAttribs = m_quadGrid.getNumUserAttribs();
446 	DE_ASSERT(numAttribs <= MAX_USER_ATTRIBS);
447 	for (int attribNdx = 0; attribNdx < numAttribs; attribNdx++)
448 		in[attribNdx] = m_quadGrid.getUserAttrib(attribNdx, sx, sy);
449 }
450 
texture2D(int unitNdx,const tcu::Vec2 & texCoords)451 tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
452 {
453 	if (textures[unitNdx].tex2D)
454 		return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
455 	else
456 		return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
457 }
458 
459 // ShaderEvaluator.
460 
ShaderEvaluator(void)461 ShaderEvaluator::ShaderEvaluator (void)
462 	: m_evalFunc(DE_NULL)
463 {
464 }
465 
ShaderEvaluator(ShaderEvalFunc evalFunc)466 ShaderEvaluator::ShaderEvaluator (ShaderEvalFunc evalFunc)
467 	: m_evalFunc(evalFunc)
468 {
469 }
470 
~ShaderEvaluator(void)471 ShaderEvaluator::~ShaderEvaluator (void)
472 {
473 }
474 
evaluate(ShaderEvalContext & ctx) const475 void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) const
476 {
477 	DE_ASSERT(m_evalFunc);
478 	m_evalFunc(ctx);
479 }
480 
481 // UniformSetup.
482 
UniformSetup(void)483 UniformSetup::UniformSetup (void)
484 	: m_setupFunc(DE_NULL)
485 {
486 }
487 
UniformSetup(UniformSetupFunc setupFunc)488 UniformSetup::UniformSetup (UniformSetupFunc setupFunc)
489 	: m_setupFunc(setupFunc)
490 {
491 }
492 
~UniformSetup(void)493 UniformSetup::~UniformSetup (void)
494 {
495 }
496 
setup(ShaderRenderCaseInstance & instance,const tcu::Vec4 & constCoords) const497 void UniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
498 {
499 	if (m_setupFunc)
500 		m_setupFunc(instance, constCoords);
501 }
502 
503 // ShaderRenderCase.
504 
ShaderRenderCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const bool isVertexCase,const ShaderEvalFunc evalFunc,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc)505 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&			testCtx,
506 									const std::string&			name,
507 									const std::string&			description,
508 									const bool					isVertexCase,
509 									const ShaderEvalFunc		evalFunc,
510 									const UniformSetup*			uniformSetup,
511 									const AttributeSetupFunc	attribFunc)
512 	: vkt::TestCase		(testCtx, name, description)
513 	, m_isVertexCase	(isVertexCase)
514 	, m_evaluator		(new ShaderEvaluator(evalFunc))
515 	, m_uniformSetup	(uniformSetup ? uniformSetup : new UniformSetup())
516 	, m_attribFunc		(attribFunc)
517 {}
518 
ShaderRenderCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const bool isVertexCase,const ShaderEvaluator * evaluator,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc)519 ShaderRenderCase::ShaderRenderCase (tcu::TestContext&			testCtx,
520 									const std::string&			name,
521 									const std::string&			description,
522 									const bool					isVertexCase,
523 									const ShaderEvaluator*		evaluator,
524 									const UniformSetup*			uniformSetup,
525 									const AttributeSetupFunc	attribFunc)
526 	: vkt::TestCase		(testCtx, name, description)
527 	, m_isVertexCase	(isVertexCase)
528 	, m_evaluator		(evaluator)
529 	, m_uniformSetup	(uniformSetup ? uniformSetup : new UniformSetup())
530 	, m_attribFunc		(attribFunc)
531 {}
532 
~ShaderRenderCase(void)533 ShaderRenderCase::~ShaderRenderCase (void)
534 {
535 }
536 
initPrograms(vk::SourceCollections & programCollection) const537 void ShaderRenderCase::initPrograms (vk::SourceCollections& programCollection) const
538 {
539 	programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
540 	programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
541 }
542 
createInstance(Context & context) const543 TestInstance* ShaderRenderCase::createInstance (Context& context) const
544 {
545 	DE_ASSERT(m_evaluator != DE_NULL);
546 	DE_ASSERT(m_uniformSetup != DE_NULL);
547 	return new ShaderRenderCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_attribFunc);
548 }
549 
550 // ShaderRenderCaseInstance.
551 
ShaderRenderCaseInstance(Context & context)552 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context)
553 	: vkt::TestInstance		(context)
554 	, m_imageBackingMode	(IMAGE_BACKING_MODE_REGULAR)
555 	, m_quadGridSize		(static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
556 	, m_memAlloc			(getAllocator())
557 	, m_clearColor			(DEFAULT_CLEAR_COLOR)
558 	, m_isVertexCase		(false)
559 	, m_vertexShaderName	("vert")
560 	, m_fragmentShaderName	("frag")
561 	, m_renderSize			(MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
562 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
563 	, m_evaluator			(DE_NULL)
564 	, m_uniformSetup		(DE_NULL)
565 	, m_attribFunc			(DE_NULL)
566 	, m_sampleCount			(VK_SAMPLE_COUNT_1_BIT)
567 	, m_fuzzyCompare		(true)
568 {
569 }
570 
571 
ShaderRenderCaseInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const AttributeSetupFunc attribFunc,const ImageBackingMode imageBackingMode,const deUint32 gridSize,const bool fuzzyCompare)572 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&					context,
573 													const bool					isVertexCase,
574 													const ShaderEvaluator&		evaluator,
575 													const UniformSetup&			uniformSetup,
576 													const AttributeSetupFunc	attribFunc,
577 													const ImageBackingMode		imageBackingMode,
578 													const deUint32				gridSize,
579 													const bool					fuzzyCompare)
580 	: vkt::TestInstance		(context)
581 	, m_imageBackingMode	(imageBackingMode)
582 	, m_quadGridSize		(gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
583 							 ? (isVertexCase
584 								? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
585 								: static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
586 							 : gridSize)
587 	, m_memAlloc			(getAllocator())
588 	, m_clearColor			(DEFAULT_CLEAR_COLOR)
589 	, m_isVertexCase		(isVertexCase)
590 	, m_vertexShaderName	("vert")
591 	, m_fragmentShaderName	("frag")
592 	, m_renderSize			(MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
593 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
594 	, m_evaluator			(&evaluator)
595 	, m_uniformSetup		(&uniformSetup)
596 	, m_attribFunc			(attribFunc)
597 	, m_sampleCount			(VK_SAMPLE_COUNT_1_BIT)
598 	, m_fuzzyCompare		(fuzzyCompare)
599 {
600 }
601 
ShaderRenderCaseInstance(Context & context,const bool isVertexCase,const ShaderEvaluator * evaluator,const UniformSetup * uniformSetup,const AttributeSetupFunc attribFunc,const ImageBackingMode imageBackingMode,const deUint32 gridSize)602 ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context&					context,
603 													const bool					isVertexCase,
604 													const ShaderEvaluator*		evaluator,
605 													const UniformSetup*			uniformSetup,
606 													const AttributeSetupFunc	attribFunc,
607 													const ImageBackingMode		imageBackingMode,
608 													const deUint32				gridSize)
609 	: vkt::TestInstance		(context)
610 	, m_imageBackingMode	(imageBackingMode)
611 	, m_quadGridSize		(gridSize == static_cast<deUint32>(GRID_SIZE_DEFAULTS)
612 							 ? (isVertexCase
613 								? static_cast<deUint32>(GRID_SIZE_DEFAULT_VERTEX)
614 								: static_cast<deUint32>(GRID_SIZE_DEFAULT_FRAGMENT))
615 							 : gridSize)
616 	, m_memAlloc			(getAllocator())
617 	, m_clearColor			(DEFAULT_CLEAR_COLOR)
618 	, m_isVertexCase		(isVertexCase)
619 	, m_vertexShaderName	("vert")
620 	, m_fragmentShaderName	("frag")
621 	, m_renderSize			(MAX_RENDER_WIDTH, MAX_RENDER_HEIGHT)
622 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
623 	, m_evaluator			(evaluator)
624 	, m_uniformSetup		(uniformSetup)
625 	, m_attribFunc			(attribFunc)
626 	, m_sampleCount			(VK_SAMPLE_COUNT_1_BIT)
627 	, m_fuzzyCompare		(false)
628 {
629 }
630 
getAllocator(void) const631 vk::Allocator& ShaderRenderCaseInstance::getAllocator (void) const
632 {
633 	return m_context.getDefaultAllocator();
634 }
635 
~ShaderRenderCaseInstance(void)636 ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
637 {
638 }
639 
getDevice(void) const640 VkDevice ShaderRenderCaseInstance::getDevice (void) const
641 {
642 	return m_context.getDevice();
643 }
644 
getUniversalQueueFamilyIndex(void) const645 deUint32 ShaderRenderCaseInstance::getUniversalQueueFamilyIndex	(void) const
646 {
647 	return m_context.getUniversalQueueFamilyIndex();
648 }
649 
getSparseQueueFamilyIndex(void) const650 deUint32 ShaderRenderCaseInstance::getSparseQueueFamilyIndex (void) const
651 {
652 	return m_context.getSparseQueueFamilyIndex();
653 }
654 
getDeviceInterface(void) const655 const DeviceInterface& ShaderRenderCaseInstance::getDeviceInterface (void) const
656 {
657 	return m_context.getDeviceInterface();
658 }
659 
getUniversalQueue(void) const660 VkQueue ShaderRenderCaseInstance::getUniversalQueue (void) const
661 {
662 	return m_context.getUniversalQueue();
663 }
664 
getSparseQueue(void) const665 VkQueue ShaderRenderCaseInstance::getSparseQueue (void) const
666 {
667 	return m_context.getSparseQueue();
668 }
669 
getPhysicalDevice(void) const670 VkPhysicalDevice ShaderRenderCaseInstance::getPhysicalDevice (void) const
671 {
672 	return m_context.getPhysicalDevice();
673 }
674 
getInstanceInterface(void) const675 const InstanceInterface& ShaderRenderCaseInstance::getInstanceInterface (void) const
676 {
677 	return m_context.getInstanceInterface();
678 }
679 
iterate(void)680 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
681 {
682 	setup();
683 
684 	// Create quad grid.
685 	const tcu::UVec2	viewportSize	= getViewportSize();
686 	const int			width			= viewportSize.x();
687 	const int			height			= viewportSize.y();
688 
689 	m_quadGrid							= de::MovePtr<QuadGrid>(new QuadGrid(m_quadGridSize, width, height, getDefaultConstCoords(), m_userAttribTransforms, m_textures));
690 
691 	// Render result.
692 	tcu::Surface		resImage		(width, height);
693 
694 	render(m_quadGrid->getNumVertices(), m_quadGrid->getNumTriangles(), m_quadGrid->getIndices(), m_quadGrid->getConstCoords());
695 	tcu::copy(resImage.getAccess(), m_resultImage.getAccess());
696 
697 	// Compute reference.
698 	tcu::Surface		refImage		(width, height);
699 	if (m_isVertexCase)
700 		computeVertexReference(refImage, *m_quadGrid);
701 	else
702 		computeFragmentReference(refImage, *m_quadGrid);
703 
704 	// Compare.
705 	const bool			compareOk		= compareImages(resImage, refImage, 0.2f);
706 
707 	if (compareOk)
708 		return tcu::TestStatus::pass("Result image matches reference");
709 	else
710 		return tcu::TestStatus::fail("Image mismatch");
711 }
712 
setup(void)713 void ShaderRenderCaseInstance::setup (void)
714 {
715 	m_resultImage					= tcu::TextureLevel();
716 	m_descriptorSetLayoutBuilder	= de::MovePtr<DescriptorSetLayoutBuilder>	(new DescriptorSetLayoutBuilder());
717 	m_descriptorPoolBuilder			= de::MovePtr<DescriptorPoolBuilder>		(new DescriptorPoolBuilder());
718 	m_descriptorSetUpdateBuilder	= de::MovePtr<DescriptorSetUpdateBuilder>	(new DescriptorSetUpdateBuilder());
719 
720 	m_uniformInfos.clear();
721 	m_vertexBindingDescription.clear();
722 	m_vertexAttributeDescription.clear();
723 	m_vertexBuffers.clear();
724 	m_vertexBufferAllocs.clear();
725 	m_pushConstantRanges.clear();
726 }
727 
setupUniformData(deUint32 bindingLocation,size_t size,const void * dataPtr)728 void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr)
729 {
730 	const VkDevice					vkDevice			= getDevice();
731 	const DeviceInterface&			vk					= getDeviceInterface();
732 	const deUint32					queueFamilyIndex	= getUniversalQueueFamilyIndex();
733 
734 	const VkBufferCreateInfo		uniformBufferParams	=
735 	{
736 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
737 		DE_NULL,									// const void*			pNext;
738 		0u,											// VkBufferCreateFlags	flags;
739 		size,										// VkDeviceSize			size;
740 		VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,			// VkBufferUsageFlags	usage;
741 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
742 		1u,											// deUint32				queueFamilyCount;
743 		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
744 	};
745 
746 	Move<VkBuffer>					buffer				= createBuffer(vk, vkDevice, &uniformBufferParams);
747 	de::MovePtr<Allocation>			alloc				= m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
748 	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
749 
750 	deMemcpy(alloc->getHostPtr(), dataPtr, size);
751 	flushAlloc(vk, vkDevice, *alloc);
752 
753 	de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
754 	uniformInfo->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
755 	uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
756 	uniformInfo->location = bindingLocation;
757 	uniformInfo->buffer = VkBufferSp(new vk::Unique<VkBuffer>(buffer));
758 	uniformInfo->alloc = AllocationSp(alloc.release());
759 
760 	m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
761 }
762 
addUniform(deUint32 bindingLocation,vk::VkDescriptorType descriptorType,size_t dataSize,const void * data)763 void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, size_t dataSize, const void* data)
764 {
765 	m_descriptorSetLayoutBuilder->addSingleBinding(descriptorType, vk::VK_SHADER_STAGE_ALL);
766 	m_descriptorPoolBuilder->addType(descriptorType);
767 
768 	setupUniformData(bindingLocation, dataSize, data);
769 }
770 
addAttribute(deUint32 bindingLocation,vk::VkFormat format,deUint32 sizePerElement,deUint32 count,const void * dataPtr)771 void ShaderRenderCaseInstance::addAttribute (deUint32		bindingLocation,
772 											 vk::VkFormat	format,
773 											 deUint32		sizePerElement,
774 											 deUint32		count,
775 											 const void*	dataPtr)
776 {
777 	// Portability requires stride to be multiply of minVertexInputBindingStrideAlignment
778 	// this value is usually 4 and current tests meet this requirement but
779 	// if this changes in future then this limit should be verified in checkSupport
780 #ifndef CTS_USES_VULKANSC
781 	if (m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
782 		((sizePerElement % m_context.getPortabilitySubsetProperties().minVertexInputBindingStrideAlignment) != 0))
783 	{
784 		DE_FATAL("stride is not multiply of minVertexInputBindingStrideAlignment");
785 	}
786 #endif // CTS_USES_VULKANSC
787 
788 	// Add binding specification
789 	const deUint32							binding					= (deUint32)m_vertexBindingDescription.size();
790 	const VkVertexInputBindingDescription	bindingDescription		=
791 	{
792 		binding,							// deUint32				binding;
793 		sizePerElement,						// deUint32				stride;
794 		VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	stepRate;
795 	};
796 
797 	m_vertexBindingDescription.push_back(bindingDescription);
798 
799 	// Add location and format specification
800 	const VkVertexInputAttributeDescription	attributeDescription	=
801 	{
802 		bindingLocation,			// deUint32	location;
803 		binding,					// deUint32	binding;
804 		format,						// VkFormat	format;
805 		0u,							// deUint32	offset;
806 	};
807 
808 	m_vertexAttributeDescription.push_back(attributeDescription);
809 
810 	// Upload data to buffer
811 	const VkDevice							vkDevice				= getDevice();
812 	const DeviceInterface&					vk						= getDeviceInterface();
813 	const deUint32							queueFamilyIndex		= getUniversalQueueFamilyIndex();
814 
815 	const VkDeviceSize						inputSize				= sizePerElement * count;
816 	const VkBufferCreateInfo				vertexBufferParams		=
817 	{
818 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
819 		DE_NULL,									// const void*			pNext;
820 		0u,											// VkBufferCreateFlags	flags;
821 		inputSize,									// VkDeviceSize			size;
822 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
823 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
824 		1u,											// deUint32				queueFamilyCount;
825 		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
826 	};
827 
828 	Move<VkBuffer>							buffer					= createBuffer(vk, vkDevice, &vertexBufferParams);
829 	de::MovePtr<vk::Allocation>				alloc					= m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
830 	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
831 
832 	deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
833 	flushAlloc(vk, vkDevice, *alloc);
834 
835 	m_vertexBuffers.push_back(VkBufferSp(new vk::Unique<VkBuffer>(buffer)));
836 	m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
837 }
838 
useAttribute(deUint32 bindingLocation,BaseAttributeType type)839 void ShaderRenderCaseInstance::useAttribute (deUint32 bindingLocation, BaseAttributeType type)
840 {
841 	const EnabledBaseAttribute attribute =
842 	{
843 		bindingLocation,	// deUint32				location;
844 		type				// BaseAttributeType	type;
845 	};
846 	m_enabledBaseAttributes.push_back(attribute);
847 }
848 
setupUniforms(const tcu::Vec4 & constCoords)849 void ShaderRenderCaseInstance::setupUniforms (const tcu::Vec4& constCoords)
850 {
851 	if (m_uniformSetup)
852 		m_uniformSetup->setup(*this, constCoords);
853 }
854 
useUniform(deUint32 bindingLocation,BaseUniformType type)855 void ShaderRenderCaseInstance::useUniform (deUint32 bindingLocation, BaseUniformType type)
856 {
857 	#define UNIFORM_CASE(type, value) case type: addUniform(bindingLocation, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, value); break
858 
859 	switch(type)
860 	{
861 		// Bool
862 		UNIFORM_CASE(UB_FALSE,	0);
863 		UNIFORM_CASE(UB_TRUE,	1);
864 
865 		// BVec4
866 		UNIFORM_CASE(UB4_FALSE,	tcu::Vec4(0));
867 		UNIFORM_CASE(UB4_TRUE,	tcu::Vec4(1));
868 
869 		// Integer
870 		UNIFORM_CASE(UI_ZERO,	0);
871 		UNIFORM_CASE(UI_ONE,	1);
872 		UNIFORM_CASE(UI_TWO,	2);
873 		UNIFORM_CASE(UI_THREE,	3);
874 		UNIFORM_CASE(UI_FOUR,	4);
875 		UNIFORM_CASE(UI_FIVE,	5);
876 		UNIFORM_CASE(UI_SIX,	6);
877 		UNIFORM_CASE(UI_SEVEN,	7);
878 		UNIFORM_CASE(UI_EIGHT,	8);
879 		UNIFORM_CASE(UI_ONEHUNDREDONE, 101);
880 
881 		// IVec2
882 		UNIFORM_CASE(UI2_MINUS_ONE,	tcu::IVec2(-1));
883 		UNIFORM_CASE(UI2_ZERO,		tcu::IVec2(0));
884 		UNIFORM_CASE(UI2_ONE,		tcu::IVec2(1));
885 		UNIFORM_CASE(UI2_TWO,		tcu::IVec2(2));
886 		UNIFORM_CASE(UI2_THREE,		tcu::IVec2(3));
887 		UNIFORM_CASE(UI2_FOUR,		tcu::IVec2(4));
888 		UNIFORM_CASE(UI2_FIVE,		tcu::IVec2(5));
889 
890 		// IVec3
891 		UNIFORM_CASE(UI3_MINUS_ONE,	tcu::IVec3(-1));
892 		UNIFORM_CASE(UI3_ZERO,		tcu::IVec3(0));
893 		UNIFORM_CASE(UI3_ONE,		tcu::IVec3(1));
894 		UNIFORM_CASE(UI3_TWO,		tcu::IVec3(2));
895 		UNIFORM_CASE(UI3_THREE,		tcu::IVec3(3));
896 		UNIFORM_CASE(UI3_FOUR,		tcu::IVec3(4));
897 		UNIFORM_CASE(UI3_FIVE,		tcu::IVec3(5));
898 
899 		// IVec4
900 		UNIFORM_CASE(UI4_MINUS_ONE, tcu::IVec4(-1));
901 		UNIFORM_CASE(UI4_ZERO,		tcu::IVec4(0));
902 		UNIFORM_CASE(UI4_ONE,		tcu::IVec4(1));
903 		UNIFORM_CASE(UI4_TWO,		tcu::IVec4(2));
904 		UNIFORM_CASE(UI4_THREE,		tcu::IVec4(3));
905 		UNIFORM_CASE(UI4_FOUR,		tcu::IVec4(4));
906 		UNIFORM_CASE(UI4_FIVE,		tcu::IVec4(5));
907 
908 		// Float
909 		UNIFORM_CASE(UF_ZERO,		0.0f);
910 		UNIFORM_CASE(UF_ONE,		1.0f);
911 		UNIFORM_CASE(UF_TWO,		2.0f);
912 		UNIFORM_CASE(UF_THREE,		3.0f);
913 		UNIFORM_CASE(UF_FOUR,		4.0f);
914 		UNIFORM_CASE(UF_FIVE,		5.0f);
915 		UNIFORM_CASE(UF_SIX,		6.0f);
916 		UNIFORM_CASE(UF_SEVEN,		7.0f);
917 		UNIFORM_CASE(UF_EIGHT,		8.0f);
918 
919 		UNIFORM_CASE(UF_HALF,		1.0f / 2.0f);
920 		UNIFORM_CASE(UF_THIRD,		1.0f / 3.0f);
921 		UNIFORM_CASE(UF_FOURTH,		1.0f / 4.0f);
922 		UNIFORM_CASE(UF_FIFTH,		1.0f / 5.0f);
923 		UNIFORM_CASE(UF_SIXTH,		1.0f / 6.0f);
924 		UNIFORM_CASE(UF_SEVENTH,	1.0f / 7.0f);
925 		UNIFORM_CASE(UF_EIGHTH,		1.0f / 8.0f);
926 
927 		// Vec2
928 		UNIFORM_CASE(UV2_MINUS_ONE,	tcu::Vec2(-1.0f));
929 		UNIFORM_CASE(UV2_ZERO,		tcu::Vec2(0.0f));
930 		UNIFORM_CASE(UV2_ONE,		tcu::Vec2(1.0f));
931 		UNIFORM_CASE(UV2_TWO,		tcu::Vec2(2.0f));
932 		UNIFORM_CASE(UV2_THREE,		tcu::Vec2(3.0f));
933 
934 		UNIFORM_CASE(UV2_HALF,		tcu::Vec2(1.0f / 2.0f));
935 
936 		// Vec3
937 		UNIFORM_CASE(UV3_MINUS_ONE,	tcu::Vec3(-1.0f));
938 		UNIFORM_CASE(UV3_ZERO,		tcu::Vec3(0.0f));
939 		UNIFORM_CASE(UV3_ONE,		tcu::Vec3(1.0f));
940 		UNIFORM_CASE(UV3_TWO,		tcu::Vec3(2.0f));
941 		UNIFORM_CASE(UV3_THREE,		tcu::Vec3(3.0f));
942 
943 		UNIFORM_CASE(UV3_HALF,		tcu::Vec3(1.0f / 2.0f));
944 
945 		// Vec4
946 		UNIFORM_CASE(UV4_MINUS_ONE,	tcu::Vec4(-1.0f));
947 		UNIFORM_CASE(UV4_ZERO,		tcu::Vec4(0.0f));
948 		UNIFORM_CASE(UV4_ONE,		tcu::Vec4(1.0f));
949 		UNIFORM_CASE(UV4_TWO,		tcu::Vec4(2.0f));
950 		UNIFORM_CASE(UV4_THREE,		tcu::Vec4(3.0f));
951 
952 		UNIFORM_CASE(UV4_HALF,		tcu::Vec4(1.0f / 2.0f));
953 
954 		UNIFORM_CASE(UV4_BLACK,		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
955 		UNIFORM_CASE(UV4_GRAY,		tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
956 		UNIFORM_CASE(UV4_WHITE,		tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
957 
958 		default:
959 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unknown Uniform type: " << type << tcu::TestLog::EndMessage;
960 			break;
961 	}
962 
963 	#undef UNIFORM_CASE
964 }
965 
getViewportSize(void) const966 const tcu::UVec2 ShaderRenderCaseInstance::getViewportSize (void) const
967 {
968 	return tcu::UVec2(de::min(m_renderSize.x(), MAX_RENDER_WIDTH),
969 					  de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
970 }
971 
setSampleCount(VkSampleCountFlagBits sampleCount)972 void ShaderRenderCaseInstance::setSampleCount (VkSampleCountFlagBits sampleCount)
973 {
974 	m_sampleCount	= sampleCount;
975 }
976 
isMultiSampling(void) const977 bool ShaderRenderCaseInstance::isMultiSampling (void) const
978 {
979 	return m_sampleCount != VK_SAMPLE_COUNT_1_BIT;
980 }
981 
uploadImage(const tcu::TextureFormat & texFormat,const TextureData & textureData,const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage)982 void ShaderRenderCaseInstance::uploadImage (const tcu::TextureFormat&			texFormat,
983 											const TextureData&					textureData,
984 											const tcu::Sampler&					refSampler,
985 											deUint32							mipLevels,
986 											deUint32							arrayLayers,
987 											VkImage								destImage)
988 {
989 	const VkDevice					vkDevice				= getDevice();
990 	const DeviceInterface&			vk						= getDeviceInterface();
991 	const VkQueue					queue					= getUniversalQueue();
992 	const deUint32					queueFamilyIndex		= getUniversalQueueFamilyIndex();
993 
994 	const bool						isShadowSampler			= refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
995 	const VkImageAspectFlags		aspectMask				= isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
996 	deUint32						bufferSize				= 0u;
997 	Move<VkBuffer>					buffer;
998 	de::MovePtr<Allocation>			bufferAlloc;
999 	std::vector<VkBufferImageCopy>	copyRegions;
1000 	std::vector<deUint32>			offsetMultiples;
1001 
1002 	offsetMultiples.push_back(4u);
1003 	offsetMultiples.push_back(texFormat.getPixelSize());
1004 
1005 	// Calculate buffer size
1006 	for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1007 	{
1008 		for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1009 		{
1010 			const tcu::ConstPixelBufferAccess&	access	= *lit;
1011 
1012 			bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1013 			bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1014 		}
1015 	}
1016 
1017 	// Create source buffer
1018 	{
1019 		const VkBufferCreateInfo bufferParams =
1020 		{
1021 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1022 			DE_NULL,									// const void*			pNext;
1023 			0u,											// VkBufferCreateFlags	flags;
1024 			bufferSize,									// VkDeviceSize			size;
1025 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1026 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1027 			0u,											// deUint32				queueFamilyIndexCount;
1028 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
1029 		};
1030 
1031 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
1032 		bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1033 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1034 	}
1035 
1036 	// Get copy regions and write buffer data
1037 	{
1038 		deUint32	layerDataOffset		= 0;
1039 		deUint8*	destPtr				= (deUint8*)bufferAlloc->getHostPtr();
1040 
1041 		for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1042 		{
1043 			const TextureLayerData&		layerData	= textureData[levelNdx];
1044 
1045 			for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1046 			{
1047 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1048 
1049 				const tcu::ConstPixelBufferAccess&	access		= layerData[layerNdx];
1050 				const tcu::PixelBufferAccess		destAccess	(access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1051 
1052 				const VkBufferImageCopy				layerRegion =
1053 				{
1054 					layerDataOffset,						// VkDeviceSize				bufferOffset;
1055 					(deUint32)access.getWidth(),			// deUint32					bufferRowLength;
1056 					(deUint32)access.getHeight(),			// deUint32					bufferImageHeight;
1057 					{										// VkImageSubresourceLayers	imageSubresource;
1058 						aspectMask,								// VkImageAspectFlags		aspectMask;
1059 						(deUint32)levelNdx,						// uint32_t					mipLevel;
1060 						(deUint32)layerNdx,						// uint32_t					baseArrayLayer;
1061 						1u										// uint32_t					layerCount;
1062 					},
1063 					{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
1064 					{										// VkExtent3D			imageExtent;
1065 						(deUint32)access.getWidth(),
1066 						(deUint32)access.getHeight(),
1067 						(deUint32)access.getDepth()
1068 					}
1069 				};
1070 
1071 				copyRegions.push_back(layerRegion);
1072 				tcu::copy(destAccess, access);
1073 
1074 				layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1075 			}
1076 		}
1077 	}
1078 
1079 	flushAlloc(vk, vkDevice, *bufferAlloc);
1080 
1081 	if(m_externalCommandPool.get() != DE_NULL)
1082 		copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, &(m_externalCommandPool.get()->get()));
1083 	else
1084 		copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, mipLevels, arrayLayers, destImage);
1085 }
1086 
clearImage(const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage)1087 void ShaderRenderCaseInstance::clearImage (const tcu::Sampler&					refSampler,
1088 										   deUint32								mipLevels,
1089 										   deUint32								arrayLayers,
1090 										   VkImage								destImage)
1091 {
1092 	const VkDevice					vkDevice				= m_context.getDevice();
1093 	const DeviceInterface&			vk						= m_context.getDeviceInterface();
1094 	const VkQueue					queue					= m_context.getUniversalQueue();
1095 	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
1096 
1097 	const bool						isShadowSampler			= refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1098 	const VkImageAspectFlags		aspectMask				= isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1099 	Move<VkCommandPool>				cmdPool;
1100 	Move<VkCommandBuffer>			cmdBuffer;
1101 
1102 	VkClearValue					clearValue;
1103 	deMemset(&clearValue, 0, sizeof(clearValue));
1104 
1105 
1106 	// Create command pool
1107 	VkCommandPool activeCmdPool;
1108 	if (m_externalCommandPool.get() == DE_NULL)
1109 	{
1110 		// Create local command pool
1111 		cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1112 		activeCmdPool = *cmdPool;
1113 	}
1114 	else
1115 	{
1116 		// Use external command pool if available
1117 		activeCmdPool = m_externalCommandPool.get()->get();
1118 	}
1119 	// Create command buffer
1120 	cmdBuffer	= allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1121 
1122 	const VkImageMemoryBarrier preImageBarrier =
1123 	{
1124 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
1125 		DE_NULL,										// const void*				pNext;
1126 		0u,												// VkAccessFlags			srcAccessMask;
1127 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
1128 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
1129 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
1130 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
1131 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
1132 		destImage,										// VkImage					image;
1133 		{												// VkImageSubresourceRange	subresourceRange;
1134 			aspectMask,								// VkImageAspect	aspect;
1135 			0u,										// deUint32			baseMipLevel;
1136 			mipLevels,								// deUint32			mipLevels;
1137 			0u,										// deUint32			baseArraySlice;
1138 			arrayLayers								// deUint32			arraySize;
1139 		}
1140 	};
1141 
1142 	const VkImageMemoryBarrier postImageBarrier =
1143 	{
1144 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
1145 		DE_NULL,										// const void*				pNext;
1146 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
1147 		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
1148 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
1149 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout;
1150 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
1151 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
1152 		destImage,										// VkImage					image;
1153 		{												// VkImageSubresourceRange	subresourceRange;
1154 			aspectMask,								// VkImageAspect	aspect;
1155 			0u,										// deUint32			baseMipLevel;
1156 			mipLevels,								// deUint32			mipLevels;
1157 			0u,										// deUint32			baseArraySlice;
1158 			arrayLayers								// deUint32			arraySize;
1159 		}
1160 	};
1161 
1162 	const VkImageSubresourceRange clearRange		=
1163 	{
1164 		aspectMask,										// VkImageAspectFlags	aspectMask;
1165 		0u,												// deUint32				baseMipLevel;
1166 		mipLevels,										// deUint32				levelCount;
1167 		0u,												// deUint32				baseArrayLayer;
1168 		arrayLayers										// deUint32				layerCount;
1169 	};
1170 
1171 	// Copy buffer to image
1172 	beginCommandBuffer(vk, *cmdBuffer);
1173 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
1174 	if (aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
1175 	{
1176 		vk.cmdClearColorImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange);
1177 	}
1178 	else
1179 	{
1180 		vk.cmdClearDepthStencilImage(*cmdBuffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &clearRange);
1181 	}
1182 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
1183 	endCommandBuffer(vk, *cmdBuffer);
1184 
1185 	submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
1186 }
1187 
mipLevelExtents(const VkExtent3D & baseExtents,const deUint32 mipLevel)1188 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
1189 {
1190 	VkExtent3D result;
1191 
1192 	result.width	= std::max(baseExtents.width  >> mipLevel, 1u);
1193 	result.height	= std::max(baseExtents.height >> mipLevel, 1u);
1194 	result.depth	= std::max(baseExtents.depth  >> mipLevel, 1u);
1195 
1196 	return result;
1197 }
1198 
alignedDivide(const VkExtent3D & extent,const VkExtent3D & divisor)1199 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
1200 {
1201 	tcu::UVec3 result;
1202 
1203 	result.x() = extent.width  / divisor.width  + ((extent.width  % divisor.width != 0)  ? 1u : 0u);
1204 	result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
1205 	result.z() = extent.depth  / divisor.depth  + ((extent.depth  % divisor.depth != 0)  ? 1u : 0u);
1206 
1207 	return result;
1208 }
1209 
isImageSizeSupported(const VkImageType imageType,const tcu::UVec3 & imageSize,const vk::VkPhysicalDeviceLimits & limits)1210 bool isImageSizeSupported (const VkImageType imageType, const tcu::UVec3& imageSize, const vk::VkPhysicalDeviceLimits& limits)
1211 {
1212 	switch (imageType)
1213 	{
1214 		case VK_IMAGE_TYPE_1D:
1215 			return (imageSize.x() <= limits.maxImageDimension1D
1216 				 && imageSize.y() == 1
1217 				 && imageSize.z() == 1);
1218 		case VK_IMAGE_TYPE_2D:
1219 			return (imageSize.x() <= limits.maxImageDimension2D
1220 				 && imageSize.y() <= limits.maxImageDimension2D
1221 				 && imageSize.z() == 1);
1222 		case VK_IMAGE_TYPE_3D:
1223 			return (imageSize.x() <= limits.maxImageDimension3D
1224 				 && imageSize.y() <= limits.maxImageDimension3D
1225 				 && imageSize.z() <= limits.maxImageDimension3D);
1226 		default:
1227 			DE_FATAL("Unknown image type");
1228 			return false;
1229 	}
1230 }
1231 
checkSparseSupport(const VkImageCreateInfo & imageInfo) const1232 void ShaderRenderCaseInstance::checkSparseSupport (const VkImageCreateInfo& imageInfo) const
1233 {
1234 #ifdef CTS_USES_VULKANSC
1235 	TCU_THROW(NotSupportedError, "Vulkan SC does not support sparse operations");
1236 #endif // CTS_USES_VULKANSC
1237 	const InstanceInterface&		instance		= getInstanceInterface();
1238 	const VkPhysicalDevice			physicalDevice	= getPhysicalDevice();
1239 	const VkPhysicalDeviceFeatures	deviceFeatures	= getPhysicalDeviceFeatures(instance, physicalDevice);
1240 #ifndef CTS_USES_VULKANSC
1241 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
1242 		instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1243 #endif // CTS_USES_VULKANSC
1244 
1245 	if (!deviceFeatures.shaderResourceResidency)
1246 		TCU_THROW(NotSupportedError, "Required feature: shaderResourceResidency.");
1247 
1248 	if (!deviceFeatures.sparseBinding)
1249 		TCU_THROW(NotSupportedError, "Required feature: sparseBinding.");
1250 
1251 	if (imageInfo.imageType == VK_IMAGE_TYPE_2D && !deviceFeatures.sparseResidencyImage2D)
1252 		TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage2D.");
1253 
1254 	if (imageInfo.imageType == VK_IMAGE_TYPE_3D && !deviceFeatures.sparseResidencyImage3D)
1255 		TCU_THROW(NotSupportedError, "Required feature: sparseResidencyImage3D.");
1256 #ifndef CTS_USES_VULKANSC
1257 	if (sparseImageFormatPropVec.size() == 0)
1258 		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
1259 #endif // CTS_USES_VULKANSC
1260 }
1261 
1262 #ifndef CTS_USES_VULKANSC
uploadSparseImage(const tcu::TextureFormat & texFormat,const TextureData & textureData,const tcu::Sampler & refSampler,const deUint32 mipLevels,const deUint32 arrayLayers,const VkImage sparseImage,const VkImageCreateInfo & imageCreateInfo,const tcu::UVec3 texSize)1263 void ShaderRenderCaseInstance::uploadSparseImage (const tcu::TextureFormat&		texFormat,
1264 												  const TextureData&			textureData,
1265 												  const tcu::Sampler&			refSampler,
1266 												  const deUint32				mipLevels,
1267 												  const deUint32				arrayLayers,
1268 												  const VkImage					sparseImage,
1269 												  const VkImageCreateInfo&		imageCreateInfo,
1270 												  const tcu::UVec3				texSize)
1271 {
1272 	const VkDevice							vkDevice				= getDevice();
1273 	const DeviceInterface&					vk						= getDeviceInterface();
1274 	const VkPhysicalDevice					physicalDevice			= getPhysicalDevice();
1275 	const VkQueue							queue					= getUniversalQueue();
1276 	const VkQueue							sparseQueue				= getSparseQueue();
1277 	const deUint32							queueFamilyIndex		= getUniversalQueueFamilyIndex();
1278 	const InstanceInterface&				instance				= getInstanceInterface();
1279 	const VkPhysicalDeviceProperties		deviceProperties		= getPhysicalDeviceProperties(instance, physicalDevice);
1280 	const bool								isShadowSampler			= refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1281 	const VkImageAspectFlags				aspectMask				= isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1282 	const Unique<VkSemaphore>				imageMemoryBindSemaphore(createSemaphore(vk, vkDevice));
1283 	Move<VkBuffer>							buffer;
1284 	deUint32								bufferSize				= 0u;
1285 	de::MovePtr<Allocation>					bufferAlloc;
1286 	std::vector<VkBufferImageCopy>			copyRegions;
1287 	std::vector<deUint32>					offsetMultiples;
1288 
1289 	offsetMultiples.push_back(4u);
1290 	offsetMultiples.push_back(texFormat.getPixelSize());
1291 
1292 	if (isImageSizeSupported(imageCreateInfo.imageType, texSize, deviceProperties.limits) == false)
1293 		TCU_THROW(NotSupportedError, "Image size not supported for device.");
1294 
1295 	allocateAndBindSparseImage(vk, vkDevice, physicalDevice, instance, imageCreateInfo, *imageMemoryBindSemaphore, sparseQueue, m_memAlloc, m_allocations, texFormat, sparseImage);
1296 
1297 	// Calculate buffer size
1298 	for (TextureData::const_iterator mit = textureData.begin(); mit != textureData.end(); ++mit)
1299 	{
1300 		for (TextureLayerData::const_iterator lit = mit->begin(); lit != mit->end(); ++lit)
1301 		{
1302 			const tcu::ConstPixelBufferAccess&	access	= *lit;
1303 
1304 			bufferSize = getNextMultiple(offsetMultiples, bufferSize);
1305 			bufferSize += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1306 		}
1307 	}
1308 
1309 	{
1310 		// Create source buffer
1311 		const VkBufferCreateInfo bufferParams =
1312 		{
1313 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1314 			DE_NULL,								// const void*			pNext;
1315 			0u,										// VkBufferCreateFlags	flags;
1316 			bufferSize,								// VkDeviceSize			size;
1317 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage;
1318 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1319 			0u,										// deUint32				queueFamilyIndexCount;
1320 			DE_NULL,								// const deUint32*		pQueueFamilyIndices;
1321 		};
1322 
1323 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
1324 		bufferAlloc = m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
1325 
1326 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1327 	}
1328 
1329 	// Get copy regions and write buffer data
1330 	{
1331 		deUint32	layerDataOffset		= 0;
1332 		deUint8*	destPtr				= (deUint8*)bufferAlloc->getHostPtr();
1333 
1334 		for (size_t levelNdx = 0; levelNdx < textureData.size(); levelNdx++)
1335 		{
1336 			const TextureLayerData&		layerData	= textureData[levelNdx];
1337 
1338 			for (size_t layerNdx = 0; layerNdx < layerData.size(); layerNdx++)
1339 			{
1340 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
1341 
1342 				const tcu::ConstPixelBufferAccess&	access		= layerData[layerNdx];
1343 				const tcu::PixelBufferAccess		destAccess	(access.getFormat(), access.getSize(), destPtr + layerDataOffset);
1344 
1345 				const VkBufferImageCopy				layerRegion =
1346 				{
1347 					layerDataOffset,						// VkDeviceSize				bufferOffset;
1348 					(deUint32)access.getWidth(),			// deUint32					bufferRowLength;
1349 					(deUint32)access.getHeight(),			// deUint32					bufferImageHeight;
1350 					{										// VkImageSubresourceLayers	imageSubresource;
1351 						aspectMask,								// VkImageAspectFlags		aspectMask;
1352 						(deUint32)levelNdx,						// uint32_t					mipLevel;
1353 						(deUint32)layerNdx,						// uint32_t					baseArrayLayer;
1354 						1u										// uint32_t					layerCount;
1355 					},
1356 					{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
1357 					{										// VkExtent3D			imageExtent;
1358 						(deUint32)access.getWidth(),
1359 						(deUint32)access.getHeight(),
1360 						(deUint32)access.getDepth()
1361 					}
1362 				};
1363 
1364 				copyRegions.push_back(layerRegion);
1365 				tcu::copy(destAccess, access);
1366 
1367 				layerDataOffset += access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
1368 			}
1369 		}
1370 	}
1371 	copyBufferToImage(vk, vkDevice, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), aspectMask, mipLevels, arrayLayers, sparseImage);
1372 }
1373 #endif // CTS_USES_VULKANSC
1374 
useSampler(deUint32 bindingLocation,deUint32 textureId)1375 void ShaderRenderCaseInstance::useSampler (deUint32 bindingLocation, deUint32 textureId)
1376 {
1377 	DE_ASSERT(textureId < m_textures.size());
1378 
1379 	const TextureBinding&				textureBinding		= *m_textures[textureId];
1380 	const TextureBinding::Type			textureType			= textureBinding.getType();
1381 	const tcu::Sampler&					refSampler			= textureBinding.getSampler();
1382 	const TextureBinding::Parameters&	textureParams		= textureBinding.getParameters();
1383 	const bool							isMSTexture			= textureParams.samples != vk::VK_SAMPLE_COUNT_1_BIT;
1384 	deUint32							mipLevels			= 1u;
1385 	deUint32							arrayLayers			= 1u;
1386 	tcu::TextureFormat					texFormat;
1387 	tcu::UVec3							texSize;
1388 	TextureData							textureData;
1389 
1390 	if (textureType == TextureBinding::TYPE_2D)
1391 	{
1392 		const tcu::Texture2D&			texture		= textureBinding.get2D();
1393 
1394 		texFormat									= texture.getFormat();
1395 		texSize										= tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1396 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1397 		arrayLayers									= 1u;
1398 
1399 		textureData.resize(mipLevels);
1400 
1401 		for (deUint32 level = 0; level < mipLevels; ++level)
1402 		{
1403 			if (texture.isLevelEmpty(level))
1404 				continue;
1405 
1406 			textureData[level].push_back(texture.getLevel(level));
1407 		}
1408 	}
1409 	else if (textureType == TextureBinding::TYPE_CUBE_MAP)
1410 	{
1411 		const tcu::TextureCube&			texture		= textureBinding.getCube();
1412 
1413 		texFormat									= texture.getFormat();
1414 		texSize										= tcu::UVec3(texture.getSize(), texture.getSize(), 1u);
1415 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1416 		arrayLayers									= 6u;
1417 
1418 		static const tcu::CubeFace		cubeFaceMapping[tcu::CUBEFACE_LAST] =
1419 		{
1420 			tcu::CUBEFACE_POSITIVE_X,
1421 			tcu::CUBEFACE_NEGATIVE_X,
1422 			tcu::CUBEFACE_POSITIVE_Y,
1423 			tcu::CUBEFACE_NEGATIVE_Y,
1424 			tcu::CUBEFACE_POSITIVE_Z,
1425 			tcu::CUBEFACE_NEGATIVE_Z
1426 		};
1427 
1428 		textureData.resize(mipLevels);
1429 
1430 		for (deUint32 level = 0; level < mipLevels; ++level)
1431 		{
1432 			for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1433 			{
1434 				tcu::CubeFace face = cubeFaceMapping[faceNdx];
1435 
1436 				if (texture.isLevelEmpty(face, level))
1437 					continue;
1438 
1439 				textureData[level].push_back(texture.getLevelFace(level, face));
1440 			}
1441 		}
1442 	}
1443 	else if (textureType == TextureBinding::TYPE_2D_ARRAY)
1444 	{
1445 		const tcu::Texture2DArray&		texture		= textureBinding.get2DArray();
1446 
1447 		texFormat									= texture.getFormat();
1448 		texSize										= tcu::UVec3(texture.getWidth(), texture.getHeight(), 1u);
1449 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1450 		arrayLayers									= (deUint32)texture.getNumLayers();
1451 
1452 		textureData.resize(mipLevels);
1453 
1454 		for (deUint32 level = 0; level < mipLevels; ++level)
1455 		{
1456 			if (texture.isLevelEmpty(level))
1457 				continue;
1458 
1459 			const tcu::ConstPixelBufferAccess&	levelLayers		= texture.getLevel(level);
1460 			const deUint32						layerSize		= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1461 
1462 			for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1463 			{
1464 				const deUint32					layerOffset		= layerSize * layer;
1465 				tcu::ConstPixelBufferAccess		layerData		(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1466 				textureData[level].push_back(layerData);
1467 			}
1468 		}
1469 	}
1470 	else if (textureType == TextureBinding::TYPE_3D)
1471 	{
1472 		const tcu::Texture3D&			texture		= textureBinding.get3D();
1473 
1474 		texFormat									= texture.getFormat();
1475 		texSize										= tcu::UVec3(texture.getWidth(), texture.getHeight(), texture.getDepth());
1476 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1477 		arrayLayers									= 1u;
1478 
1479 		textureData.resize(mipLevels);
1480 
1481 		for (deUint32 level = 0; level < mipLevels; ++level)
1482 		{
1483 			if (texture.isLevelEmpty(level))
1484 				continue;
1485 
1486 			textureData[level].push_back(texture.getLevel(level));
1487 		}
1488 	}
1489 	else if (textureType == TextureBinding::TYPE_1D)
1490 	{
1491 		const tcu::Texture1D&			texture		= textureBinding.get1D();
1492 
1493 		texFormat									= texture.getFormat();
1494 		texSize										= tcu::UVec3(texture.getWidth(), 1, 1);
1495 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1496 		arrayLayers									= 1u;
1497 
1498 		textureData.resize(mipLevels);
1499 
1500 		for (deUint32 level = 0; level < mipLevels; ++level)
1501 		{
1502 			if (texture.isLevelEmpty(level))
1503 				continue;
1504 
1505 			textureData[level].push_back(texture.getLevel(level));
1506 		}
1507 	}
1508 	else if (textureType == TextureBinding::TYPE_1D_ARRAY)
1509 	{
1510 		const tcu::Texture1DArray&		texture		= textureBinding.get1DArray();
1511 
1512 		texFormat									= texture.getFormat();
1513 		texSize										= tcu::UVec3(texture.getWidth(), 1, 1);
1514 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1515 		arrayLayers									= (deUint32)texture.getNumLayers();
1516 
1517 		textureData.resize(mipLevels);
1518 
1519 		for (deUint32 level = 0; level < mipLevels; ++level)
1520 		{
1521 			if (texture.isLevelEmpty(level))
1522 				continue;
1523 
1524 			const tcu::ConstPixelBufferAccess&	levelLayers		= texture.getLevel(level);
1525 			const deUint32						layerSize		= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1526 
1527 			for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1528 			{
1529 				const deUint32					layerOffset		= layerSize * layer;
1530 				tcu::ConstPixelBufferAccess		layerData		(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1531 				textureData[level].push_back(layerData);
1532 			}
1533 		}
1534 	}
1535 	else if (textureType == TextureBinding::TYPE_CUBE_ARRAY)
1536 	{
1537 		const tcu::TextureCubeArray&	texture		= textureBinding.getCubeArray();
1538 		texFormat									= texture.getFormat();
1539 		texSize										= tcu::UVec3(texture.getSize(), texture.getSize(), 1);
1540 		mipLevels									= isMSTexture ? 1u : (deUint32)texture.getNumLevels();
1541 		arrayLayers									= texture.getDepth();
1542 
1543 		textureData.resize(mipLevels);
1544 
1545 		for (deUint32 level = 0; level < mipLevels; ++level)
1546 		{
1547 			if (texture.isLevelEmpty(level))
1548 				continue;
1549 
1550 			const tcu::ConstPixelBufferAccess&	levelLayers		= texture.getLevel(level);
1551 			const deUint32						layerSize		= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1552 
1553 			for (deUint32 layer = 0; layer < arrayLayers; ++layer)
1554 			{
1555 				const deUint32					layerOffset		= layerSize * layer;
1556 				tcu::ConstPixelBufferAccess		layerData		(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1557 				textureData[level].push_back(layerData);
1558 			}
1559 		}
1560 	}
1561 	else
1562 	{
1563 		TCU_THROW(InternalError, "Invalid texture type");
1564 	}
1565 
1566 	createSamplerUniform(bindingLocation, textureType, textureBinding.getParameters().initialization, texFormat, texSize, textureData, refSampler, mipLevels, arrayLayers, textureParams);
1567 }
1568 
setPushConstantRanges(const deUint32 rangeCount,const vk::VkPushConstantRange * const pcRanges)1569 void ShaderRenderCaseInstance::setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges)
1570 {
1571 	m_pushConstantRanges.clear();
1572 	for (deUint32 i = 0; i < rangeCount; ++i)
1573 	{
1574 		m_pushConstantRanges.push_back(pcRanges[i]);
1575 	}
1576 }
1577 
updatePushConstants(vk::VkCommandBuffer,vk::VkPipelineLayout)1578 void ShaderRenderCaseInstance::updatePushConstants (vk::VkCommandBuffer, vk::VkPipelineLayout)
1579 {
1580 }
1581 
createSamplerUniform(deUint32 bindingLocation,TextureBinding::Type textureType,TextureBinding::Init textureInit,const tcu::TextureFormat & texFormat,const tcu::UVec3 texSize,const TextureData & textureData,const tcu::Sampler & refSampler,deUint32 mipLevels,deUint32 arrayLayers,TextureBinding::Parameters textureParams)1582 void ShaderRenderCaseInstance::createSamplerUniform (deUint32						bindingLocation,
1583 													 TextureBinding::Type			textureType,
1584 													 TextureBinding::Init			textureInit,
1585 													 const tcu::TextureFormat&		texFormat,
1586 													 const tcu::UVec3				texSize,
1587 													 const TextureData&				textureData,
1588 													 const tcu::Sampler&			refSampler,
1589 													 deUint32						mipLevels,
1590 													 deUint32						arrayLayers,
1591 													 TextureBinding::Parameters		textureParams)
1592 {
1593 	const VkDevice					vkDevice			= getDevice();
1594 	const DeviceInterface&			vk					= getDeviceInterface();
1595 	const deUint32					queueFamilyIndex	= getUniversalQueueFamilyIndex();
1596 	const deUint32					sparseFamilyIndex	= (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE) ? getSparseQueueFamilyIndex() : queueFamilyIndex;
1597 
1598 	const bool						isShadowSampler		= refSampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1599 
1600 	// when isShadowSampler is true mapSampler utill will set compareEnabled in
1601 	// VkSamplerCreateInfo to true and in portability this functionality is under
1602 	// feature flag - note that this is safety check as this is known at the
1603 	// TestCase level and NotSupportedError should be thrown from checkSupport
1604 #ifndef CTS_USES_VULKANSC
1605 	if (isShadowSampler &&
1606 		m_context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1607 		!m_context.getPortabilitySubsetFeatures().mutableComparisonSamplers)
1608 	{
1609 		DE_FATAL("mutableComparisonSamplers support should be checked in checkSupport");
1610 	}
1611 #endif // CTS_USES_VULKANSC
1612 
1613 	const VkImageAspectFlags		aspectMask			= isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1614 	const VkImageViewType			imageViewType		= textureTypeToImageViewType(textureType);
1615 	const VkImageType				imageType			= viewTypeToImageType(imageViewType);
1616 	const VkSharingMode				sharingMode			= (queueFamilyIndex != sparseFamilyIndex) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
1617 	const VkFormat					format				= mapTextureFormat(texFormat);
1618 	const VkImageUsageFlags			imageUsageFlags		= textureUsageFlags();
1619 	const VkImageCreateFlags		imageCreateFlags	= textureCreateFlags(imageViewType, m_imageBackingMode);
1620 
1621 	const deUint32					queueIndexCount		= (queueFamilyIndex != sparseFamilyIndex) ? 2 : 1;
1622 	const deUint32					queueIndices[]		=
1623 	{
1624 		queueFamilyIndex,
1625 		sparseFamilyIndex
1626 	};
1627 
1628 	Move<VkImage>					vkTexture;
1629 	de::MovePtr<Allocation>			allocation;
1630 
1631 	// Create image
1632 	const VkImageCreateInfo			imageParams =
1633 	{
1634 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
1635 		DE_NULL,														// const void*				pNext;
1636 		imageCreateFlags,												// VkImageCreateFlags		flags;
1637 		imageType,														// VkImageType				imageType;
1638 		format,															// VkFormat					format;
1639 		{																// VkExtent3D				extent;
1640 			texSize.x(),
1641 			texSize.y(),
1642 			texSize.z()
1643 		},
1644 		mipLevels,														// deUint32					mipLevels;
1645 		arrayLayers,													// deUint32					arrayLayers;
1646 		textureParams.samples,											// VkSampleCountFlagBits	samples;
1647 		VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
1648 		imageUsageFlags,												// VkImageUsageFlags		usage;
1649 		sharingMode,													// VkSharingMode			sharingMode;
1650 		queueIndexCount,												// deUint32					queueFamilyIndexCount;
1651 		queueIndices,													// const deUint32*			pQueueFamilyIndices;
1652 		VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout;
1653 	};
1654 
1655 	if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1656 	{
1657 		checkSparseSupport(imageParams);
1658 	}
1659 
1660 	vkTexture		= createImage(vk, vkDevice, &imageParams);
1661 	allocation		= m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
1662 
1663 	if (m_imageBackingMode != IMAGE_BACKING_MODE_SPARSE)
1664 	{
1665 		VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
1666 	}
1667 
1668 	switch (textureInit)
1669 	{
1670 		case TextureBinding::INIT_UPLOAD_DATA:
1671 		{
1672 			// upload*Image functions use cmdCopyBufferToImage, which is invalid for multisample images
1673 			DE_ASSERT(textureParams.samples == VK_SAMPLE_COUNT_1_BIT);
1674 
1675 			if (m_imageBackingMode == IMAGE_BACKING_MODE_SPARSE)
1676 			{
1677 #ifndef CTS_USES_VULKANSC
1678 				uploadSparseImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture, imageParams, texSize);
1679 #endif // CTS_USES_VULKANSC
1680 			}
1681 			else
1682 			{
1683 				// Upload texture data
1684 				uploadImage(texFormat, textureData, refSampler, mipLevels, arrayLayers, *vkTexture);
1685 			}
1686 			break;
1687 		}
1688 		case TextureBinding::INIT_CLEAR:
1689 			clearImage(refSampler, mipLevels, arrayLayers, *vkTexture);
1690 			break;
1691 		default:
1692 			DE_FATAL("Impossible");
1693 	}
1694 
1695 	// Create sampler
1696 	const auto&						minMaxLod		= textureParams.minMaxLod;
1697 	const VkSamplerCreateInfo		samplerParams	= (minMaxLod
1698 														? mapSampler(refSampler, texFormat, minMaxLod.get().minLod, minMaxLod.get().maxLod)
1699 														: mapSampler(refSampler, texFormat));
1700 	Move<VkSampler>					sampler			= createSampler(vk, vkDevice, &samplerParams);
1701 	const deUint32					baseMipLevel	= textureParams.baseMipLevel;
1702 	const vk::VkComponentMapping	components		= textureParams.componentMapping;
1703 	const VkImageViewCreateInfo		viewParams		=
1704 	{
1705 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
1706 		NULL,										// const voide*				pNext;
1707 		0u,											// VkImageViewCreateFlags	flags;
1708 		*vkTexture,									// VkImage					image;
1709 		imageViewType,								// VkImageViewType			viewType;
1710 		format,										// VkFormat					format;
1711 		components,									// VkChannelMapping			channels;
1712 		{
1713 			aspectMask,						// VkImageAspectFlags	aspectMask;
1714 			baseMipLevel,					// deUint32				baseMipLevel;
1715 			mipLevels - baseMipLevel,		// deUint32				mipLevels;
1716 			0,								// deUint32				baseArraySlice;
1717 			arrayLayers						// deUint32				arraySize;
1718 		},											// VkImageSubresourceRange	subresourceRange;
1719 	};
1720 
1721 	Move<VkImageView>				imageView		= createImageView(vk, vkDevice, &viewParams);
1722 
1723 	const vk::VkDescriptorImageInfo	descriptor		=
1724 	{
1725 		sampler.get(),								// VkSampler				sampler;
1726 		imageView.get(),							// VkImageView				imageView;
1727 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			imageLayout;
1728 	};
1729 
1730 	de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
1731 	uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1732 	uniform->descriptor = descriptor;
1733 	uniform->location = bindingLocation;
1734 	uniform->image = VkImageSp(new vk::Unique<VkImage>(vkTexture));
1735 	uniform->imageView = VkImageViewSp(new vk::Unique<VkImageView>(imageView));
1736 	uniform->sampler = VkSamplerSp(new vk::Unique<VkSampler>(sampler));
1737 	uniform->alloc = AllocationSp(allocation.release());
1738 
1739 	m_descriptorSetLayoutBuilder->addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_ALL, DE_NULL);
1740 	m_descriptorPoolBuilder->addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1741 
1742 	m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
1743 }
1744 
setupDefaultInputs(void)1745 void ShaderRenderCaseInstance::setupDefaultInputs (void)
1746 {
1747 	/* Configuration of the vertex input attributes:
1748 		a_position   is at location 0
1749 		a_coords     is at location 1
1750 		a_unitCoords is at location 2
1751 		a_one        is at location 3
1752 
1753 	  User attributes starts from at the location 4.
1754 	*/
1755 
1756 	DE_ASSERT(m_quadGrid);
1757 	const QuadGrid&		quadGrid	= *m_quadGrid;
1758 
1759 	addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getPositions());
1760 	addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getCoords());
1761 	addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords());
1762 	addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne());
1763 
1764 	static const struct
1765 	{
1766 		BaseAttributeType	type;
1767 		int					userNdx;
1768 	} userAttributes[] =
1769 	{
1770 		{ A_IN0, 0 },
1771 		{ A_IN1, 1 },
1772 		{ A_IN2, 2 },
1773 		{ A_IN3, 3 }
1774 	};
1775 
1776 	static const struct
1777 	{
1778 		BaseAttributeType	matrixType;
1779 		int					numCols;
1780 		int					numRows;
1781 	} matrices[] =
1782 	{
1783 		{ MAT2,		2, 2 },
1784 		{ MAT2x3,	2, 3 },
1785 		{ MAT2x4,	2, 4 },
1786 		{ MAT3x2,	3, 2 },
1787 		{ MAT3,		3, 3 },
1788 		{ MAT3x4,	3, 4 },
1789 		{ MAT4x2,	4, 2 },
1790 		{ MAT4x3,	4, 3 },
1791 		{ MAT4,		4, 4 }
1792 	};
1793 
1794 	for (size_t attrNdx = 0; attrNdx < m_enabledBaseAttributes.size(); attrNdx++)
1795 	{
1796 		for (int userNdx = 0; userNdx < DE_LENGTH_OF_ARRAY(userAttributes); userNdx++)
1797 		{
1798 			if (userAttributes[userNdx].type != m_enabledBaseAttributes[attrNdx].type)
1799 				continue;
1800 
1801 			addAttribute(m_enabledBaseAttributes[attrNdx].location, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(tcu::Vec4), quadGrid.getNumVertices(), quadGrid.getUserAttrib(userNdx));
1802 		}
1803 
1804 		for (int matNdx = 0; matNdx < DE_LENGTH_OF_ARRAY(matrices); matNdx++)
1805 		{
1806 
1807 			if (matrices[matNdx].matrixType != m_enabledBaseAttributes[attrNdx].type)
1808 				continue;
1809 
1810 			const int numCols = matrices[matNdx].numCols;
1811 
1812 			for (int colNdx = 0; colNdx < numCols; colNdx++)
1813 			{
1814 				addAttribute(m_enabledBaseAttributes[attrNdx].location + colNdx, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(4 * sizeof(float)), quadGrid.getNumVertices(), quadGrid.getUserAttrib(colNdx));
1815 			}
1816 		}
1817 	}
1818 }
1819 
render(deUint32 numVertices,deUint32 numTriangles,const deUint16 * indices,const tcu::Vec4 & constCoords)1820 void ShaderRenderCaseInstance::render (deUint32				numVertices,
1821 									   deUint32				numTriangles,
1822 									   const deUint16*		indices,
1823 									   const tcu::Vec4&		constCoords)
1824 {
1825 	render(numVertices, numTriangles * 3, indices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, constCoords);
1826 }
1827 
render(deUint32 numVertices,deUint32 numIndices,const deUint16 * indices,VkPrimitiveTopology topology,const tcu::Vec4 & constCoords)1828 void ShaderRenderCaseInstance::render (deUint32				numVertices,
1829 									   deUint32				numIndices,
1830 									   const deUint16*		indices,
1831 									   VkPrimitiveTopology	topology,
1832 									   const tcu::Vec4&		constCoords)
1833 {
1834 	const VkDevice										vkDevice					= getDevice();
1835 	const DeviceInterface&								vk							= getDeviceInterface();
1836 	const VkQueue										queue						= getUniversalQueue();
1837 	const deUint32										queueFamilyIndex			= getUniversalQueueFamilyIndex();
1838 
1839 	vk::Move<vk::VkImage>								colorImage;
1840 	de::MovePtr<vk::Allocation>							colorImageAlloc;
1841 	vk::Move<vk::VkImageView>							colorImageView;
1842 	vk::Move<vk::VkImage>								resolvedImage;
1843 	de::MovePtr<vk::Allocation>							resolvedImageAlloc;
1844 	vk::Move<vk::VkImageView>							resolvedImageView;
1845 	vk::Move<vk::VkRenderPass>							renderPass;
1846 	vk::Move<vk::VkFramebuffer>							framebuffer;
1847 	vk::Move<vk::VkPipelineLayout>						pipelineLayout;
1848 	vk::Move<vk::VkPipeline>							graphicsPipeline;
1849 	vk::Move<vk::VkShaderModule>						vertexShaderModule;
1850 	vk::Move<vk::VkShaderModule>						fragmentShaderModule;
1851 	vk::Move<vk::VkBuffer>								indexBuffer;
1852 	de::MovePtr<vk::Allocation>							indexBufferAlloc;
1853 	vk::Move<vk::VkDescriptorSetLayout>					descriptorSetLayout;
1854 	vk::Move<vk::VkDescriptorPool>						descriptorPool;
1855 	vk::Move<vk::VkDescriptorSet>						descriptorSet;
1856 	vk::Move<vk::VkCommandPool>							cmdPool;
1857 	vk::Move<vk::VkCommandBuffer>						cmdBuffer;
1858 
1859 	// Create color image
1860 	{
1861 		const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1862 		VkImageFormatProperties	properties;
1863 
1864 		if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1865 																		   m_colorFormat,
1866 																		   VK_IMAGE_TYPE_2D,
1867 																		   VK_IMAGE_TILING_OPTIMAL,
1868 																		   imageUsage,
1869 																		   0u,
1870 																		   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1871 		{
1872 			TCU_THROW(NotSupportedError, "Format not supported");
1873 		}
1874 
1875 		if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
1876 		{
1877 			TCU_THROW(NotSupportedError, "Format not supported");
1878 		}
1879 
1880 		const VkImageCreateInfo							colorImageParams			=
1881 		{
1882 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType		sType;
1883 			DE_NULL,																	// const void*			pNext;
1884 			0u,																			// VkImageCreateFlags	flags;
1885 			VK_IMAGE_TYPE_2D,															// VkImageType			imageType;
1886 			m_colorFormat,																// VkFormat				format;
1887 			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D			extent;
1888 			1u,																			// deUint32				mipLevels;
1889 			1u,																			// deUint32				arraySize;
1890 			m_sampleCount,																// deUint32				samples;
1891 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling		tiling;
1892 			imageUsage,																	// VkImageUsageFlags	usage;
1893 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode		sharingMode;
1894 			1u,																			// deUint32				queueFamilyCount;
1895 			&queueFamilyIndex,															// const deUint32*		pQueueFamilyIndices;
1896 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout		initialLayout;
1897 		};
1898 
1899 		colorImage = createImage(vk, vkDevice, &colorImageParams);
1900 
1901 		// Allocate and bind color image memory
1902 		colorImageAlloc = m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
1903 		VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
1904 	}
1905 
1906 	// Create color attachment view
1907 	{
1908 		const VkImageViewCreateInfo						colorImageViewParams		=
1909 		{
1910 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
1911 			DE_NULL,											// const void*				pNext;
1912 			0u,													// VkImageViewCreateFlags	flags;
1913 			*colorImage,										// VkImage					image;
1914 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
1915 			m_colorFormat,										// VkFormat					format;
1916 			{
1917 				VK_COMPONENT_SWIZZLE_R,			// VkChannelSwizzle		r;
1918 				VK_COMPONENT_SWIZZLE_G,			// VkChannelSwizzle		g;
1919 				VK_COMPONENT_SWIZZLE_B,			// VkChannelSwizzle		b;
1920 				VK_COMPONENT_SWIZZLE_A			// VkChannelSwizzle		a;
1921 			},													// VkChannelMapping			channels;
1922 			{
1923 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
1924 				0,								// deUint32				baseMipLevel;
1925 				1,								// deUint32				mipLevels;
1926 				0,								// deUint32				baseArraySlice;
1927 				1								// deUint32				arraySize;
1928 			},													// VkImageSubresourceRange	subresourceRange;
1929 		};
1930 
1931 		colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
1932 	}
1933 
1934 	if (isMultiSampling())
1935 	{
1936 		// Resolved Image
1937 		{
1938 			const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1939 			VkImageFormatProperties	properties;
1940 
1941 			if ((getInstanceInterface().getPhysicalDeviceImageFormatProperties(getPhysicalDevice(),
1942 																			   m_colorFormat,
1943 																			   VK_IMAGE_TYPE_2D,
1944 																			   VK_IMAGE_TILING_OPTIMAL,
1945 																			   imageUsage,
1946 																			   0,
1947 																			   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1948 			{
1949 				TCU_THROW(NotSupportedError, "Format not supported");
1950 			}
1951 
1952 			const VkImageCreateInfo					imageCreateInfo			=
1953 			{
1954 				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
1955 				DE_NULL,									// const void*				pNext;
1956 				0u,											// VkImageCreateFlags		flags;
1957 				VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
1958 				m_colorFormat,								// VkFormat					format;
1959 				{ m_renderSize.x(),	m_renderSize.y(), 1u },	// VkExtent3D				extent;
1960 				1u,											// deUint32					mipLevels;
1961 				1u,											// deUint32					arrayLayers;
1962 				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
1963 				VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
1964 				imageUsage,									// VkImageUsageFlags		usage;
1965 				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
1966 				1u,											// deUint32					queueFamilyIndexCount;
1967 				&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
1968 				VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
1969 			};
1970 
1971 			resolvedImage		= vk::createImage(vk, vkDevice, &imageCreateInfo, DE_NULL);
1972 			resolvedImageAlloc	= m_memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *resolvedImage), MemoryRequirement::Any);
1973 			VK_CHECK(vk.bindImageMemory(vkDevice, *resolvedImage, resolvedImageAlloc->getMemory(), resolvedImageAlloc->getOffset()));
1974 		}
1975 
1976 		// Resolved Image View
1977 		{
1978 			const VkImageViewCreateInfo				imageViewCreateInfo		=
1979 			{
1980 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
1981 				DE_NULL,									// const void*					pNext;
1982 				0u,											// VkImageViewCreateFlags		flags;
1983 				*resolvedImage,								// VkImage						image;
1984 				VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
1985 				m_colorFormat,								// VkFormat						format;
1986 				{
1987 					VK_COMPONENT_SWIZZLE_R,					// VkChannelSwizzle		r;
1988 					VK_COMPONENT_SWIZZLE_G,					// VkChannelSwizzle		g;
1989 					VK_COMPONENT_SWIZZLE_B,					// VkChannelSwizzle		b;
1990 					VK_COMPONENT_SWIZZLE_A					// VkChannelSwizzle		a;
1991 				},
1992 				{
1993 					VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
1994 					0u,											// deUint32						baseMipLevel;
1995 					1u,											// deUint32						mipLevels;
1996 					0u,											// deUint32						baseArrayLayer;
1997 					1u,											// deUint32						arraySize;
1998 				},											// VkImageSubresourceRange		subresourceRange;
1999 			};
2000 
2001 			resolvedImageView = vk::createImageView(vk, vkDevice, &imageViewCreateInfo, DE_NULL);
2002 		}
2003 	}
2004 
2005 	// Create render pass
2006 	{
2007 		const VkAttachmentDescription					attachmentDescription[]		=
2008 		{
2009 			{
2010 				(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
2011 				m_colorFormat,										// VkFormat							format;
2012 				m_sampleCount,										// deUint32							samples;
2013 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2014 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2015 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2016 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2017 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2018 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
2019 			},
2020 			{
2021 				(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
2022 				m_colorFormat,										// VkFormat							format;
2023 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2024 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				loadOp;
2025 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2026 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2027 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2028 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2029 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
2030 			}
2031 		};
2032 
2033 		const VkAttachmentReference						attachmentReference			=
2034 		{
2035 			0u,													// deUint32			attachment;
2036 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2037 		};
2038 
2039 		const VkAttachmentReference						resolveAttachmentRef		=
2040 		{
2041 			1u,													// deUint32			attachment;
2042 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2043 		};
2044 
2045 		const VkSubpassDescription						subpassDescription			=
2046 		{
2047 			0u,													// VkSubpassDescriptionFlags	flags;
2048 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
2049 			0u,													// deUint32						inputCount;
2050 			DE_NULL,											// constVkAttachmentReference*	pInputAttachments;
2051 			1u,													// deUint32						colorCount;
2052 			&attachmentReference,								// constVkAttachmentReference*	pColorAttachments;
2053 			isMultiSampling() ? &resolveAttachmentRef : DE_NULL,// constVkAttachmentReference*	pResolveAttachments;
2054 			DE_NULL,											// VkAttachmentReference		depthStencilAttachment;
2055 			0u,													// deUint32						preserveCount;
2056 			DE_NULL												// constVkAttachmentReference*	pPreserveAttachments;
2057 		};
2058 
2059 		const VkRenderPassCreateInfo					renderPassParams			=
2060 		{
2061 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
2062 			DE_NULL,											// const void*						pNext;
2063 			0u,													// VkRenderPassCreateFlags			flags;
2064 			isMultiSampling() ? 2u : 1u,						// deUint32							attachmentCount;
2065 			attachmentDescription,								// const VkAttachmentDescription*	pAttachments;
2066 			1u,													// deUint32							subpassCount;
2067 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
2068 			0u,													// deUint32							dependencyCount;
2069 			DE_NULL												// const VkSubpassDependency*		pDependencies;
2070 		};
2071 
2072 		renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2073 	}
2074 
2075 	// Create framebuffer
2076 	{
2077 		const VkImageView								attachments[]				=
2078 		{
2079 			*colorImageView,
2080 			*resolvedImageView
2081 		};
2082 
2083 		const VkFramebufferCreateInfo					framebufferParams			=
2084 		{
2085 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
2086 			DE_NULL,											// const void*					pNext;
2087 			(VkFramebufferCreateFlags)0,
2088 			*renderPass,										// VkRenderPass					renderPass;
2089 			isMultiSampling() ? 2u : 1u,						// deUint32						attachmentCount;
2090 			attachments,										// const VkImageView*			pAttachments;
2091 			(deUint32)m_renderSize.x(),							// deUint32						width;
2092 			(deUint32)m_renderSize.y(),							// deUint32						height;
2093 			1u													// deUint32						layers;
2094 		};
2095 
2096 		framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2097 	}
2098 
2099 	// Create descriptors
2100 	{
2101 		setupUniforms(constCoords);
2102 
2103 		descriptorSetLayout = m_descriptorSetLayoutBuilder->build(vk, vkDevice);
2104 		if (!m_uniformInfos.empty())
2105 		{
2106 			descriptorPool									= m_descriptorPoolBuilder->build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2107 			const VkDescriptorSetAllocateInfo	allocInfo	=
2108 			{
2109 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2110 				DE_NULL,
2111 				*descriptorPool,
2112 				1u,
2113 				&descriptorSetLayout.get(),
2114 			};
2115 
2116 			descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2117 		}
2118 
2119 		for (deUint32 i = 0; i < m_uniformInfos.size(); i++)
2120 		{
2121 			const UniformInfo* uniformInfo = m_uniformInfos[i].get()->get();
2122 			deUint32 location = uniformInfo->location;
2123 
2124 			if (uniformInfo->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
2125 			{
2126 				const BufferUniform*	bufferInfo	= dynamic_cast<const BufferUniform*>(uniformInfo);
2127 
2128 				m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &bufferInfo->descriptor);
2129 			}
2130 			else if (uniformInfo->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2131 			{
2132 				const SamplerUniform*	samplerInfo	= dynamic_cast<const SamplerUniform*>(uniformInfo);
2133 
2134 				m_descriptorSetUpdateBuilder->writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), uniformInfo->type, &samplerInfo->descriptor);
2135 			}
2136 			else
2137 				DE_FATAL("Impossible");
2138 		}
2139 
2140 		m_descriptorSetUpdateBuilder->update(vk, vkDevice);
2141 	}
2142 
2143 	// Create pipeline layout
2144 	{
2145 		const VkPushConstantRange* const				pcRanges					= m_pushConstantRanges.empty() ? DE_NULL : &m_pushConstantRanges[0];
2146 		const VkPipelineLayoutCreateInfo				pipelineLayoutParams		=
2147 		{
2148 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
2149 			DE_NULL,											// const void*					pNext;
2150 			(VkPipelineLayoutCreateFlags)0,
2151 			1u,													// deUint32						descriptorSetCount;
2152 			&*descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
2153 			deUint32(m_pushConstantRanges.size()),				// deUint32						pushConstantRangeCount;
2154 			pcRanges											// const VkPushConstantRange*	pPushConstantRanges;
2155 		};
2156 
2157 		pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2158 	}
2159 
2160 	// Create shaders
2161 	{
2162 		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_vertexShaderName), 0);
2163 		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(m_fragmentShaderName), 0);
2164 	}
2165 
2166 	// Create pipeline
2167 	{
2168 		// Add test case specific attributes
2169 		if (m_attribFunc)
2170 			m_attribFunc(*this, numVertices);
2171 
2172 		// Add base attributes
2173 		setupDefaultInputs();
2174 
2175 		const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams		=
2176 		{
2177 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
2178 			DE_NULL,														// const void*								pNext;
2179 			(VkPipelineVertexInputStateCreateFlags)0,
2180 			(deUint32)m_vertexBindingDescription.size(),					// deUint32									bindingCount;
2181 			&m_vertexBindingDescription[0],									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2182 			(deUint32)m_vertexAttributeDescription.size(),					// deUint32									attributeCount;
2183 			&m_vertexAttributeDescription[0],								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
2184 		};
2185 
2186 		const std::vector<VkViewport>					viewports					(1, makeViewport(m_renderSize));
2187 		const std::vector<VkRect2D>						scissors					(1, makeRect2D(m_renderSize));
2188 
2189 		const VkPipelineMultisampleStateCreateInfo		multisampleStateParams =
2190 		{
2191 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
2192 			DE_NULL,														// const void*								pNext;
2193 			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
2194 			m_sampleCount,													// VkSampleCountFlagBits					rasterizationSamples;
2195 			VK_FALSE,														// VkBool32									sampleShadingEnable;
2196 			0.0f,															// float									minSampleShading;
2197 			DE_NULL,														// const VkSampleMask*						pSampleMask;
2198 			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
2199 			VK_FALSE														// VkBool32									alphaToOneEnable;
2200 		};
2201 
2202 		graphicsPipeline = makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
2203 												vkDevice,					// const VkDevice                                device
2204 												*pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
2205 												*vertexShaderModule,		// const VkShaderModule                          vertexShaderModule
2206 												DE_NULL,					// const VkShaderModule                          tessellationControlShaderModule
2207 												DE_NULL,					// const VkShaderModule                          tessellationEvalShaderModule
2208 												DE_NULL,					// const VkShaderModule                          geometryShaderModule
2209 												*fragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
2210 												*renderPass,				// const VkRenderPass                            renderPass
2211 												viewports,					// const std::vector<VkViewport>&                viewports
2212 												scissors,					// const std::vector<VkRect2D>&                  scissors
2213 												topology,					// const VkPrimitiveTopology                     topology
2214 												0u,							// const deUint32                                subpass
2215 												0u,							// const deUint32                                patchControlPoints
2216 												&vertexInputStateParams,	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
2217 												DE_NULL,					// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2218 												&multisampleStateParams);	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
2219 	}
2220 
2221 	// Create vertex indices buffer
2222 	if (numIndices != 0)
2223 	{
2224 		const VkDeviceSize								indexBufferSize			= numIndices * sizeof(deUint16);
2225 		const VkBufferCreateInfo						indexBufferParams		=
2226 		{
2227 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2228 			DE_NULL,									// const void*			pNext;
2229 			0u,											// VkBufferCreateFlags	flags;
2230 			indexBufferSize,							// VkDeviceSize			size;
2231 			VK_BUFFER_USAGE_INDEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
2232 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2233 			1u,											// deUint32				queueFamilyCount;
2234 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
2235 		};
2236 
2237 		indexBuffer			= createBuffer(vk, vkDevice, &indexBufferParams);
2238 		indexBufferAlloc	= m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *indexBuffer), MemoryRequirement::HostVisible);
2239 
2240 		VK_CHECK(vk.bindBufferMemory(vkDevice, *indexBuffer, indexBufferAlloc->getMemory(), indexBufferAlloc->getOffset()));
2241 
2242 		// Load vertice indices into buffer
2243 		deMemcpy(indexBufferAlloc->getHostPtr(), indices, (size_t)indexBufferSize);
2244 		flushAlloc(vk, vkDevice, *indexBufferAlloc);
2245 	}
2246 
2247 	VkCommandPool activeCmdPool;
2248 	if (m_externalCommandPool.get() == DE_NULL)
2249 	{
2250 		// Create local command pool
2251 		cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2252 		activeCmdPool = *cmdPool;
2253 	}
2254 	else
2255 	{
2256 		// Use external command pool if available
2257 		activeCmdPool = m_externalCommandPool.get()->get();
2258 	}
2259 
2260 	// Create command buffer
2261 	{
2262 		cmdBuffer = allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2263 
2264 		beginCommandBuffer(vk, *cmdBuffer);
2265 
2266 		{
2267 			const VkImageMemoryBarrier					imageBarrier				=
2268 			{
2269 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,										// VkStructureType			sType;
2270 				DE_NULL,																	// const void*				pNext;
2271 				0u,																			// VkAccessFlags			srcAccessMask;
2272 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,										// VkAccessFlags			dstAccessMask;
2273 				VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			oldLayout;
2274 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,									// VkImageLayout			newLayout;
2275 				VK_QUEUE_FAMILY_IGNORED,													// deUint32					srcQueueFamilyIndex;
2276 				VK_QUEUE_FAMILY_IGNORED,													// deUint32					dstQueueFamilyIndex;
2277 				*colorImage,																// VkImage					image;
2278 				{																			// VkImageSubresourceRange	subresourceRange;
2279 					VK_IMAGE_ASPECT_COLOR_BIT,												// VkImageAspectFlags		aspectMask;
2280 					0u,																		// deUint32					baseMipLevel;
2281 					1u,																		// deUint32					mipLevels;
2282 					0u,																		// deUint32					baseArrayLayer;
2283 					1u,																		// deUint32					arraySize;
2284 				}
2285 			};
2286 
2287 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &imageBarrier);
2288 
2289 			if (isMultiSampling()) {
2290 				// add multisample barrier
2291 				const VkImageMemoryBarrier				multiSampleImageBarrier		=
2292 				{
2293 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,										// VkStructureType			sType;
2294 					DE_NULL,																	// const void*				pNext;
2295 					0u,																			// VkAccessFlags			srcAccessMask;
2296 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,										// VkAccessFlags			dstAccessMask;
2297 					VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			oldLayout;
2298 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,									// VkImageLayout			newLayout;
2299 					VK_QUEUE_FAMILY_IGNORED,													// deUint32					srcQueueFamilyIndex;
2300 					VK_QUEUE_FAMILY_IGNORED,													// deUint32					dstQueueFamilyIndex;
2301 					*resolvedImage,																// VkImage					image;
2302 					{																			// VkImageSubresourceRange	subresourceRange;
2303 						VK_IMAGE_ASPECT_COLOR_BIT,												// VkImageAspectFlags		aspectMask;
2304 						0u,																		// deUint32					baseMipLevel;
2305 						1u,																		// deUint32					mipLevels;
2306 						0u,																		// deUint32					baseArrayLayer;
2307 						1u,																		// deUint32					arraySize;
2308 					}
2309 				};
2310 
2311 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1, &multiSampleImageBarrier);
2312 			}
2313 		}
2314 
2315 		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), m_clearColor);
2316 
2317 		updatePushConstants(*cmdBuffer, *pipelineLayout);
2318 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2319 		if (!m_uniformInfos.empty())
2320 			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
2321 
2322 		const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
2323 		const std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
2324 
2325 		std::vector<VkBuffer> buffers(numberOfVertexAttributes);
2326 		for (size_t i = 0; i < numberOfVertexAttributes; i++)
2327 		{
2328 			buffers[i] = m_vertexBuffers[i].get()->get();
2329 		}
2330 
2331 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
2332 		if (numIndices != 0)
2333 		{
2334 			vk.cmdBindIndexBuffer(*cmdBuffer, *indexBuffer, 0, VK_INDEX_TYPE_UINT16);
2335 			vk.cmdDrawIndexed(*cmdBuffer, numIndices, 1, 0, 0, 0);
2336 		}
2337 		else
2338 			vk.cmdDraw(*cmdBuffer, numVertices,  1, 0, 0);
2339 
2340 		endRenderPass(vk, *cmdBuffer);
2341 		endCommandBuffer(vk, *cmdBuffer);
2342 	}
2343 
2344 	// Execute Draw
2345 	submitCommandsAndWait(vk, vkDevice, queue, cmdBuffer.get());
2346 
2347 	// Read back the result
2348 	{
2349 		const tcu::TextureFormat						resultFormat				= mapVkFormat(m_colorFormat);
2350 		const VkDeviceSize								imageSizeBytes				= (VkDeviceSize)(resultFormat.getPixelSize() * m_renderSize.x() * m_renderSize.y());
2351 		const VkBufferCreateInfo						readImageBufferParams		=
2352 		{
2353 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		//  VkStructureType		sType;
2354 			DE_NULL,									//  const void*			pNext;
2355 			0u,											//  VkBufferCreateFlags	flags;
2356 			imageSizeBytes,								//  VkDeviceSize		size;
2357 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			//  VkBufferUsageFlags	usage;
2358 			VK_SHARING_MODE_EXCLUSIVE,					//  VkSharingMode		sharingMode;
2359 			1u,											//  deUint32			queueFamilyCount;
2360 			&queueFamilyIndex,							//  const deUint32*		pQueueFamilyIndices;
2361 		};
2362 		const Unique<VkBuffer>							readImageBuffer				(createBuffer(vk, vkDevice, &readImageBufferParams));
2363 		const de::UniquePtr<Allocation>					readImageBufferMemory		(m_memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2364 
2365 		VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2366 
2367 		// Copy image to buffer
2368 		const Move<VkCommandBuffer>						resultCmdBuffer				= allocateCommandBuffer(vk, vkDevice, activeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2369 
2370 		beginCommandBuffer(vk, *resultCmdBuffer);
2371 
2372 		copyImageToBuffer(vk, *resultCmdBuffer, isMultiSampling() ? *resolvedImage : *colorImage, *readImageBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()));
2373 
2374 		endCommandBuffer(vk, *resultCmdBuffer);
2375 
2376 		submitCommandsAndWait(vk, vkDevice, queue, resultCmdBuffer.get());
2377 
2378 		invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
2379 
2380 		const tcu::ConstPixelBufferAccess				resultAccess				(resultFormat, m_renderSize.x(), m_renderSize.y(), 1, readImageBufferMemory->getHostPtr());
2381 
2382 		m_resultImage.setStorage(resultFormat, m_renderSize.x(), m_renderSize.y());
2383 		tcu::copy(m_resultImage.getAccess(), resultAccess);
2384 	}
2385 }
2386 
computeVertexReference(tcu::Surface & result,const QuadGrid & quadGrid)2387 void ShaderRenderCaseInstance::computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid)
2388 {
2389 	DE_ASSERT(m_evaluator);
2390 
2391 	// Buffer info.
2392 	const int				width		= result.getWidth();
2393 	const int				height		= result.getHeight();
2394 	const int				gridSize	= quadGrid.getGridSize();
2395 	const int				stride		= gridSize + 1;
2396 	const bool				hasAlpha	= true; // \todo [2015-09-07 elecro] add correct alpha check
2397 	ShaderEvalContext		evalCtx		(quadGrid);
2398 
2399 	// Evaluate color for each vertex.
2400 	std::vector<tcu::Vec4>	colors		((gridSize + 1) * (gridSize + 1));
2401 	for (int y = 0; y < gridSize+1; y++)
2402 	for (int x = 0; x < gridSize+1; x++)
2403 	{
2404 		const float	sx			= (float)x / (float)gridSize;
2405 		const float	sy			= (float)y / (float)gridSize;
2406 		const int	vtxNdx		= ((y * (gridSize+1)) + x);
2407 
2408 		evalCtx.reset(sx, sy);
2409 		m_evaluator->evaluate(evalCtx);
2410 		DE_ASSERT(!evalCtx.isDiscarded); // Discard is not available in vertex shader.
2411 		tcu::Vec4 color = evalCtx.color;
2412 
2413 		if (!hasAlpha)
2414 			color.w() = 1.0f;
2415 
2416 		colors[vtxNdx] = color;
2417 	}
2418 
2419 	// Render quads.
2420 	for (int y = 0; y < gridSize; y++)
2421 	for (int x = 0; x < gridSize; x++)
2422 	{
2423 		const float		x0		= (float)x       / (float)gridSize;
2424 		const float		x1		= (float)(x + 1) / (float)gridSize;
2425 		const float		y0		= (float)y       / (float)gridSize;
2426 		const float		y1		= (float)(y + 1) / (float)gridSize;
2427 
2428 		const float		sx0		= x0 * (float)width;
2429 		const float		sx1		= x1 * (float)width;
2430 		const float		sy0		= y0 * (float)height;
2431 		const float		sy1		= y1 * (float)height;
2432 		const float		oosx	= 1.0f / (sx1 - sx0);
2433 		const float		oosy	= 1.0f / (sy1 - sy0);
2434 
2435 		const int		ix0		= deCeilFloatToInt32(sx0 - 0.5f);
2436 		const int		ix1		= deCeilFloatToInt32(sx1 - 0.5f);
2437 		const int		iy0		= deCeilFloatToInt32(sy0 - 0.5f);
2438 		const int		iy1		= deCeilFloatToInt32(sy1 - 0.5f);
2439 
2440 		const int		v00		= (y * stride) + x;
2441 		const int		v01		= (y * stride) + x + 1;
2442 		const int		v10		= ((y + 1) * stride) + x;
2443 		const int		v11		= ((y + 1) * stride) + x + 1;
2444 		const tcu::Vec4	c00		= colors[v00];
2445 		const tcu::Vec4	c01		= colors[v01];
2446 		const tcu::Vec4	c10		= colors[v10];
2447 		const tcu::Vec4	c11		= colors[v11];
2448 
2449 		//printf("(%d,%d) -> (%f..%f, %f..%f) (%d..%d, %d..%d)\n", x, y, sx0, sx1, sy0, sy1, ix0, ix1, iy0, iy1);
2450 
2451 		for (int iy = iy0; iy < iy1; iy++)
2452 		for (int ix = ix0; ix < ix1; ix++)
2453 		{
2454 			DE_ASSERT(deInBounds32(ix, 0, width));
2455 			DE_ASSERT(deInBounds32(iy, 0, height));
2456 
2457 			const float			sfx		= (float)ix + 0.5f;
2458 			const float			sfy		= (float)iy + 0.5f;
2459 			const float			fx1		= deFloatClamp((sfx - sx0) * oosx, 0.0f, 1.0f);
2460 			const float			fy1		= deFloatClamp((sfy - sy0) * oosy, 0.0f, 1.0f);
2461 
2462 			// Triangle quad interpolation.
2463 			const bool			tri		= fx1 + fy1 <= 1.0f;
2464 			const float			tx		= tri ? fx1 : (1.0f-fx1);
2465 			const float			ty		= tri ? fy1 : (1.0f-fy1);
2466 			const tcu::Vec4&	t0		= tri ? c00 : c11;
2467 			const tcu::Vec4&	t1		= tri ? c01 : c10;
2468 			const tcu::Vec4&	t2		= tri ? c10 : c01;
2469 			const tcu::Vec4		color	= t0 + (t1-t0)*tx + (t2-t0)*ty;
2470 
2471 			result.setPixel(ix, iy, tcu::RGBA(color));
2472 		}
2473 	}
2474 }
2475 
computeFragmentReference(tcu::Surface & result,const QuadGrid & quadGrid)2476 void ShaderRenderCaseInstance::computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid)
2477 {
2478 	DE_ASSERT(m_evaluator);
2479 
2480 	// Buffer info.
2481 	const int			width		= result.getWidth();
2482 	const int			height		= result.getHeight();
2483 	const bool			hasAlpha	= true;  // \todo [2015-09-07 elecro] add correct alpha check
2484 	ShaderEvalContext	evalCtx		(quadGrid);
2485 
2486 	// Render.
2487 	for (int y = 0; y < height; y++)
2488 	for (int x = 0; x < width; x++)
2489 	{
2490 		const float sx = ((float)x + 0.5f) / (float)width;
2491 		const float sy = ((float)y + 0.5f) / (float)height;
2492 
2493 		evalCtx.reset(sx, sy);
2494 		m_evaluator->evaluate(evalCtx);
2495 		// Select either clear color or computed color based on discarded bit.
2496 		tcu::Vec4 color = evalCtx.isDiscarded ? m_clearColor : evalCtx.color;
2497 
2498 		if (!hasAlpha)
2499 			color.w() = 1.0f;
2500 
2501 		result.setPixel(x, y, tcu::RGBA(color));
2502 	}
2503 }
2504 
compareImages(const tcu::Surface & resImage,const tcu::Surface & refImage,float errorThreshold)2505 bool ShaderRenderCaseInstance::compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold)
2506 {
2507 	if (m_fuzzyCompare)
2508 		return tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, errorThreshold, tcu::COMPARE_LOG_EVERYTHING);
2509 	else
2510 		return tcu::pixelThresholdCompare(m_context.getTestContext().getLog(), "ComparisonResult", "Image comparison result", refImage, resImage, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_EVERYTHING);
2511 }
2512 
2513 } // sr
2514 } // vkt
2515